From 2f90b68558dca7a683bedc77019858594c2f0a32 Mon Sep 17 00:00:00 2001 From: Craig Condon Date: Sat, 21 May 2022 16:43:38 -0400 Subject: [PATCH] add designer package --- .prettierignore | 1 + packages/tandem-designer/.gitignore | 2 + packages/tandem-designer/LICENSE | 674 +++ packages/tandem-designer/README.md | 13 + packages/tandem-designer/app.tdproject | 9 + packages/tandem-designer/design/app.sketch | Bin 0 -> 19016 bytes packages/tandem-designer/design/split-2.svg | 1 + packages/tandem-designer/index.d.ts | 1 + packages/tandem-designer/index.js | 1 + packages/tandem-designer/package.json | 83 + .../src/actions/bottom-left-corner.svg | 1 + packages/tandem-designer/src/actions/index.ts | 2030 +++++++ .../components/main/controller.tsx | 26 + .../src/bug-reporting/components/main/view.pc | 269 + .../src/bug-reporting/index.ts | 23 + .../src/components/atoms/view.pc | 207 + .../src/components/box-shadows-enhancer.tsx | 0 .../src/components/component-picker/all.pc | 149 + .../component-picker/cell-controller.tsx | 11 + .../src/components/component-picker/cell.pc | 87 + .../component-picker/modal-controller.tsx | 35 + .../src/components/component-picker/modal.pc | 123 + .../component-picker/picker-controller.tsx | 74 + .../src/components/component-picker/picker.pc | 943 ++++ .../component-picker/picker2-controller.tsx | 129 + .../components/configure-build/controller.tsx | 59 + .../src/components/configure-build/view.pc | 306 ++ .../components/context-menu/controller.tsx | 19 + .../src/components/context-menu/view.pc | 239 + .../src/components/contexts/index.ts | 14 + .../src/components/dev/comments.pc | 161 + .../src/components/draggable/index.tsx | 51 + .../src/components/focus/controller.tsx | 15 + .../src/components/focus/index.tsx | 33 + .../src/components/gutter/index.scss | 7 + .../src/components/gutter/index.tsx | 12 + .../src/components/inputs/atoms.pc | 50 + .../inputs/button-bar/controller.tsx | 39 + .../src/components/inputs/button-bar/item.pc | 129 + .../src/components/inputs/button-bar/view.pc | 275 + .../components/inputs/button-group/index.scss | 0 .../components/inputs/button-group/index.tsx | 0 .../src/components/inputs/button/index.scss | 0 .../src/components/inputs/button/index.tsx | 0 .../src/components/inputs/button/view.pc | 99 + .../components/inputs/checkbox/controller.tsx | 27 + .../src/components/inputs/checkbox/index.scss | 0 .../inputs/color/canvas-controller.tsx | 145 + .../inputs/color/color-input-controller.tsx | 88 + .../inputs/color/color-swatch-controller.tsx | 157 + .../inputs/color/hex-input-controller.tsx | 11 + .../src/components/inputs/color/index.scss | 48 + .../inputs/color/login-form-controller.tsx | 0 .../inputs/color/picker-controller.tsx | 378 ++ .../src/components/inputs/color/picker.pc | 1320 +++++ .../inputs/color/presets/index.scss | 5 + .../components/inputs/color/presets/index.tsx | 21 + .../inputs/color/raw-input/index.scss | 34 + .../inputs/color/raw-input/index.tsx | 78 + .../inputs/color/rgba-input-controller.tsx | 53 + .../src/components/inputs/color/utils.ts | 0 .../src/components/inputs/color/view.pc | 267 + .../components/inputs/dropdown/controller.tsx | 170 + .../src/components/inputs/dropdown/index.scss | 0 .../src/components/inputs/dropdown/menu.pc | 88 + .../src/components/inputs/dropdown/view.pc | 923 ++++ .../inputs/file-picker/controller.tsx | 88 + .../src/components/inputs/file-picker/view.pc | 98 + .../src/components/inputs/molecules.pc | 362 ++ .../components/inputs/slider/controller.tsx | 95 + .../src/components/inputs/slider/index.scss | 0 .../src/components/inputs/slider/view.pc | 75 + .../components/inputs/switch/controller.tsx | 18 + .../src/components/inputs/switch/view.pc | 128 + .../src/components/inputs/table/view.pc | 605 ++ .../inputs/text/auto-complete-controller.tsx | 92 + .../src/components/inputs/text/controller.tsx | 115 + .../src/components/inputs/text/index.scss | 3 + .../src/components/inputs/text/view.pc | 411 ++ .../components/inputs/textarea/controller.tsx | 18 + .../src/components/inputs/textarea/view.pc | 74 + .../src/components/inputs/view.pc | 127 + .../src/components/isolated/index.tsx | 169 + .../src/components/light-ide/index.scss | 26 + .../src/components/light-ide/index.tsx | 64 + .../src/components/light-ide/preview.scss | 5 + .../src/components/light-ide/preview.tsx | 20 + .../src/components/light-ide/state.ts | 4 + .../src/components/light-ide/utils.ts | 7 + .../src/components/menubar/view.pc | 546 ++ .../src/components/pane/index.scss | 32 + .../src/components/pane/index.tsx | 27 + .../src/components/pane/view.pc | 182 + .../components/popover/content-controller.tsx | 151 + .../src/components/popover/controller.tsx | 95 + .../src/components/popover/view.pc | 307 ++ .../src/components/popups/view.pc | 86 + .../src/components/portal/controller.tsx | 42 + .../src/components/prompt/controller.tsx | 46 + .../src/components/prompt/view.pc | 251 + .../src/components/quick-search/index.scss | 29 + .../src/components/quick-search/index.tsx | 75 + .../quick-search/modal-controller.tsx | 35 + .../quick-search/quick-search-controller.tsx | 96 + .../src/components/quick-search/row.pc | 268 + .../quick-search/search-result-controller.tsx | 56 + .../src/components/quick-search/view.pc | 537 ++ .../src/components/root/chrome-controller.tsx | 96 + .../src/components/root/chrome.pc | 831 +++ .../src/components/root/index.scss | 3 + .../src/components/root/index.tsx | 74 + .../root/tools/build-button-controller.tsx | 153 + .../src/components/root/tools/view.pc | 483 ++ .../src/components/root/view.pc | 68 + .../components/root/welcome/controller.tsx | 124 + .../src/components/root/welcome/test.json | 205 + .../src/components/root/welcome/view.pc | 947 ++++ .../bottom-gutter/console-controller.tsx | 54 + .../bottom-gutter/console-logs-controller.tsx | 31 + .../workspace/bottom-gutter/controller.tsx | 37 + .../root/workspace/bottom-gutter/view.pc | 532 ++ .../components/root/workspace/controller.tsx | 93 + .../workspace/editors/editor-controller.tsx | 159 + .../editors/editor-windows-controller.tsx | 31 + .../root/workspace/editors/editor-windows.pc | 74 + .../root/workspace/editors/editor.pc | 240 + .../editors/footer/breadcrumbs-controller.tsx | 120 + .../workspace/editors/footer/controller.tsx | 42 + .../root/workspace/editors/footer/view.pc | 801 +++ .../root/workspace/editors/image/index.scss | 13 + .../root/workspace/editors/image/index.tsx | 20 + .../root/workspace/editors/index.scss | 10 + .../editors/paperclip/stage/canvas/index.scss | 36 + .../editors/paperclip/stage/canvas/index.tsx | 294 + .../stage/canvas/preview-layer/document.scss | 7 + .../stage/canvas/preview-layer/document.tsx | 68 + .../stage/canvas/preview-layer/index.scss | 5 + .../stage/canvas/preview-layer/index.tsx | 41 + .../canvas/tools-layer/document-overlay.scss | 8 + .../canvas/tools-layer/document-overlay.tsx | 253 + .../tools-layer/edit-text-controller.tsx | 88 + .../stage/canvas/tools-layer/edit-text.pc | 33 + .../canvas/tools-layer/frame-controller.tsx | 118 + .../canvas/tools-layer/frames-controller.tsx | 80 + .../stage/canvas/tools-layer/frames-view.pc | 469 ++ .../stage/canvas/tools-layer/index.scss | 4 + .../stage/canvas/tools-layer/index.tsx | 219 + .../canvas/tools-layer/insert-layer.scss | 31 + .../stage/canvas/tools-layer/insert-layer.tsx | 164 + .../stage/canvas/tools-layer/node-overlay.pc | 125 + .../stage/canvas/tools-layer/selectables.scss | 2 + .../stage/canvas/tools-layer/selectables.tsx | 19 + .../canvas/tools-layer/selection/index.scss | 3 + .../canvas/tools-layer/selection/index.tsx | 138 + .../canvas/tools-layer/selection/label.scss | 12 + .../canvas/tools-layer/selection/label.tsx | 0 .../canvas/tools-layer/selection/path.scss | 21 + .../canvas/tools-layer/selection/path.tsx | 120 + .../canvas/tools-layer/selection/resizer.scss | 33 + .../canvas/tools-layer/selection/resizer.tsx | 168 + .../editors/paperclip/stage/footer/index.scss | 2 + .../editors/paperclip/stage/footer/index.tsx | 6 + .../editors/paperclip/stage/index.scss | 7 + .../editors/paperclip/stage/index.tsx | 78 + .../root/workspace/editors/text/index.scss | 5 + .../root/workspace/editors/text/index.tsx | 55 + .../root/workspace/editors/text/view.pc | 180 + .../workspace/editors/toolbar/controller.tsx | 142 + .../root/workspace/editors/toolbar/index.tsx | 6 + .../root/workspace/editors/toolbar/tab.pc | 213 + .../root/workspace/editors/toolbar/view.pc | 790 +++ .../src/components/root/workspace/index.scss | 6 + .../left-gutter/components/index.tsx | 79 + .../root/workspace/left-gutter/controller.tsx | 101 + .../left-gutter/file-navigator/contexts.tsx | 36 + .../left-gutter/file-navigator/controller.tsx | 166 + .../file-navigator/layer-controller.tsx | 308 ++ .../file-navigator/new-file-controller.tsx | 58 + .../left-gutter/file-navigator/view.pc | 833 +++ .../open-files/after-dnd-controller.tsx | 16 + .../open-files/before-dnd-controller.tsx | 16 + .../left-gutter/open-files/contexts.tsx | 35 + .../left-gutter/open-files/dnd-controller.tsx | 190 + .../left-gutter/open-files/drop-zones.pc | 183 + .../open-files/layer-controller.tsx | 462 ++ .../workspace/left-gutter/open-files/layer.pc | 1144 ++++ .../open-files/layers-pane-controller.tsx | 100 + .../open-files/open-module-controller.tsx | 20 + .../left-gutter/open-files/open-module.pc | 501 ++ .../workspace/left-gutter/open-files/utils.ts | 16 + .../workspace/left-gutter/open-files/view.pc | 428 ++ .../root/workspace/left-gutter/view.pc | 207 + .../root/workspace/prompt-controller.tsx | 53 + .../workspace/right-gutter/conditions/view.pc | 25 + .../workspace/right-gutter/controller.tsx | 157 + .../global-properties-controller.tsx | 46 + .../root/workspace/right-gutter/index.scss | 2 + .../right-gutter/properties/a-controller.tsx | 40 + .../properties/component-controller.tsx | 113 + .../properties/controller-item-controller.tsx | 37 + .../properties/controller-item.pc | 181 + .../properties/element-controller.tsx | 229 + .../properties/exports-controller.tsx | 57 + .../exports-name-input-controller.tsx | 55 + .../properties/exports-name-input.tsx | 54 + .../properties/frame-controller.tsx | 174 + .../right-gutter/properties/frame.pc | 424 ++ .../properties/img-controller.tsx | 51 + .../properties/input-controller.tsx | 71 + .../right-gutter/properties/input.pc | 196 + .../properties/properties-controller.tsx | 86 + .../properties/text-controller.tsx | 47 + .../workspace/right-gutter/properties/text.pc | 0 .../workspace/right-gutter/properties/view.pc | 2285 ++++++++ .../right-gutter/queries/controller.tsx | 47 + .../right-gutter/queries/item-controller.tsx | 53 + .../media-query-options-controller.tsx | 47 + .../queries/query-item-controller.tsx | 44 + .../queries/query-options-controller.tsx | 53 + .../workspace/right-gutter/queries/utils.ts | 13 + .../variable-query-options-controller.tsx | 87 + .../workspace/right-gutter/queries/view.pc | 970 ++++ .../styles/behavior/controller.tsx | 30 + .../behavior/trigger-item-controller.tsx | 121 + .../styles/behavior/triggers-controller.tsx | 101 + .../right-gutter/styles/behavior/triggers.pc | 625 +++ .../right-gutter/styles/behavior/view.pc | 59 + .../right-gutter/styles/controller.tsx | 163 + .../workspace/right-gutter/styles/index.scss | 2 + .../right-gutter/styles/pretty/index.scss | 28 + .../right-gutter/styles/pretty/index.tsx | 123 + .../panes/background-item-controller.tsx | 57 + .../pretty/panes/backgrounds-controller.tsx | 127 + .../styles/pretty/panes/backgrounds.pc | 925 ++++ .../panes/border-color-input-controller.tsx | 104 + .../pretty/panes/border-style-controller.tsx | 119 + .../pretty/panes/border-styles-controller.tsx | 143 + .../pretty/panes/borders-2-controller.tsx | 47 + .../pretty/panes/borders-controller.tsx | 106 + .../styles/pretty/panes/borders.pc | 2768 ++++++++++ .../panes/box-shadow-item-controller.tsx | 139 + .../styles/pretty/panes/box-shadow.pc | 274 + .../pretty/panes/box-shadows-controller.tsx | 212 + .../panes/box-shadows-inner-controller.tsx | 17 + .../styles/pretty/panes/box-shadows.pc | 524 ++ .../right-gutter/styles/pretty/panes/code.pc | 122 + .../right-gutter/styles/pretty/panes/code.tsx | 46 + .../styles/pretty/panes/filters.pc | 172 + .../pretty/panes/inherit-controller.tsx | 133 + .../pretty/panes/inherit-item-controller.tsx | 65 + .../styles/pretty/panes/inherit-item.pc | 313 ++ .../styles/pretty/panes/inherit.pc | 381 ++ .../inputs/background-input-controller.tsx | 30 + .../panes/inputs/background/controller.tsx | 100 + .../inputs/background/image-controller.tsx | 58 + .../background/linear-gradient-controller.tsx | 36 + .../inputs/background/solid-controller.tsx | 42 + .../panes/inputs/background/state-test.ts | 72 + .../pretty/panes/inputs/background/state.ts | 417 ++ .../pretty/panes/inputs/background/view.pc | 1189 ++++ .../panes/inputs/dropdown-controller.tsx | 7 + .../inline-labeled-input-controller.tsx | 30 + .../panes/inputs/labeled-input-controller.tsx | 39 + .../panes/inputs/style-value-controller.tsx | 48 + .../panes/inputs/tblr-input-controller.tsx | 83 + .../styles/pretty/panes/inputs/view.pc | 1750 ++++++ .../styles/pretty/panes/inspector/view.pc | 628 +++ .../pretty/panes/instance-pane-controller.tsx | 190 + .../styles/pretty/panes/instance.pc | 370 ++ .../styles/pretty/panes/layout-controller.tsx | 349 ++ .../styles/pretty/panes/layout.pc | 1605 ++++++ .../pretty/panes/opacity-controller.tsx | 43 + .../styles/pretty/panes/opacity.pc | 151 + .../styles/pretty/panes/radius-controller.tsx | 118 + .../pretty/panes/spacing-2-controller.tsx | 86 + .../pretty/panes/spacing-controller.tsx | 124 + .../pretty/panes/spacing-input-controller.tsx | 98 + .../styles/pretty/panes/spacing.pc | 568 ++ .../right-gutter/styles/pretty/panes/style.pc | 560 ++ .../pretty/panes/typography-controller.tsx | 261 + .../styles/pretty/panes/typography.pc | 763 +++ .../right-gutter/styles/pretty/panes/utils.ts | 41 + .../pretty/panes/variant-controller.tsx | 12 + .../right-gutter/styles/pretty/view.pc | 546 ++ .../workspace/right-gutter/styles/state.ts | 14 + .../styles/variants/controller.tsx | 72 + .../styles/variants/controller2.tsx | 121 + .../styles/variants/option-controller.tsx | 120 + .../right-gutter/styles/variants/option.pc | 362 ++ .../right-gutter/styles/variants/pill.pc | 64 + .../variants/variant-input-controller.tsx | 67 + .../styles/variants/variant-input.pc | 353 ++ .../right-gutter/styles/variants/view.pc | 246 + .../workspace/right-gutter/styles/view.pc | 614 +++ .../root/workspace/right-gutter/tab.pc | 104 + .../right-gutter/variables/controller.tsx | 63 + .../variables/row-item-controller.tsx | 89 + .../right-gutter/variables/tab-controller.tsx | 44 + .../workspace/right-gutter/variables/view.pc | 1171 ++++ .../root/workspace/right-gutter/view.pc | 965 ++++ .../src/components/root/workspace/view.pc | 428 ++ .../side-panel/button-controller.tsx | 101 + .../src/components/side-panel/view.pc | 379 ++ .../tandem-designer/src/components/test.pc | 7 + .../src/components/tree/index.scss | 2 + .../src/components/tree/index.tsx | 6 + .../src/components/tree/view.pc | 246 + .../src/components/warn/view.pc | 65 + packages/tandem-designer/src/entry.ts | 28 + .../tandem-designer/src/fonts/ionicons.eot | Bin 0 -> 120724 bytes .../tandem-designer/src/fonts/ionicons.svg | 2230 ++++++++ .../tandem-designer/src/fonts/ionicons.ttf | Bin 0 -> 188508 bytes .../tandem-designer/src/fonts/ionicons.woff | Bin 0 -> 67904 bytes packages/tandem-designer/src/global.pc | 184 + packages/tandem-designer/src/icons/add.svg | 5 + .../tandem-designer/src/icons/airplane.svg | 17 + .../tandem-designer/src/icons/all-border.svg | 1 + .../tandem-designer/src/icons/arrow-down.svg | 3 + packages/tandem-designer/src/icons/bolt.svg | 1 + .../src/icons/bottom-left-corner.svg | 1 + .../src/icons/bottom-right-corner.svg | 1 + .../tandem-designer/src/icons/brush-2.svg | 1 + packages/tandem-designer/src/icons/brush.svg | 1 + packages/tandem-designer/src/icons/circle.svg | 1 + packages/tandem-designer/src/icons/code.svg | 1 + .../src/icons/color-palette.svg | 1 + .../tandem-designer/src/icons/component.svg | 1 + .../tandem-designer/src/icons/corners.svg | 1 + .../tandem-designer/src/icons/dotted-box.svg | 1 + packages/tandem-designer/src/icons/drop.svg | 1 + packages/tandem-designer/src/icons/file.svg | 1 + packages/tandem-designer/src/icons/folder.svg | 1 + packages/tandem-designer/src/icons/image.svg | 1 + .../src/icons/individual-border.svg | 13 + .../src/icons/individual-border2.svg | 10 + packages/tandem-designer/src/icons/insert.svg | 1 + .../tandem-designer/src/icons/joystick.svg | 1 + packages/tandem-designer/src/icons/minus.svg | 5 + packages/tandem-designer/src/icons/more.svg | 1 + packages/tandem-designer/src/icons/open-2.svg | 1 + packages/tandem-designer/src/icons/open.svg | 1 + packages/tandem-designer/src/icons/pause.svg | 1 + .../tandem-designer/src/icons/pencil-2.svg | 1 + packages/tandem-designer/src/icons/pencil.svg | 5 + packages/tandem-designer/src/icons/play-2.svg | 1 + packages/tandem-designer/src/icons/play.svg | 1 + packages/tandem-designer/src/icons/plus.svg | 5 + .../tandem-designer/src/icons/pointer.svg | 1 + packages/tandem-designer/src/icons/puzzle.svg | 1 + .../tandem-designer/src/icons/rectangle.svg | 1 + .../tandem-designer/src/icons/replace.svg | 1 + .../tandem-designer/src/icons/reset-2.svg | 1 + packages/tandem-designer/src/icons/reset.svg | 1 + .../src/icons/round-square.svg | 1 + packages/tandem-designer/src/icons/shadow.svg | 3 + .../tandem-designer/src/icons/split-2.svg | 19 + .../tandem-designer/src/icons/split-down.svg | 9 + .../tandem-designer/src/icons/text-center.svg | 1 + .../src/icons/text-justify.svg | 1 + .../tandem-designer/src/icons/text-left.svg | 1 + .../tandem-designer/src/icons/text-right.svg | 1 + packages/tandem-designer/src/icons/text.svg | 1 + .../src/icons/top-left-corner.svg | 1 + .../src/icons/top-right-corner.svg | 1 + packages/tandem-designer/src/icons/trash.svg | 1 + packages/tandem-designer/src/icons/view.pc | 4847 +++++++++++++++++ packages/tandem-designer/src/icons/wand.svg | 1 + .../images/20180703190744-rollsafe-meme.jpeg | Bin 0 -> 28184 bytes packages/tandem-designer/src/images/NEDM.jpg | Bin 0 -> 48313 bytes .../src/images/inter-trigger2.gif | Bin 0 -> 721374 bytes packages/tandem-designer/src/index.html | 11 + packages/tandem-designer/src/index.ts | 169 + .../tandem-designer/src/paperclip.worker.ts | 2 + .../tandem-designer/src/reducers/index.ts | 3499 ++++++++++++ .../tandem-designer/src/sagas/copy-paste.ts | 81 + packages/tandem-designer/src/sagas/index.ts | 66 + packages/tandem-designer/src/sagas/popup.ts | 20 + packages/tandem-designer/src/sagas/process.ts | 34 + packages/tandem-designer/src/sagas/project.ts | 146 + packages/tandem-designer/src/sagas/react.ts | 46 + .../tandem-designer/src/sagas/shortcuts.ts | 494 ++ .../src/sagas/synthetic-browser.ts | 111 + .../Screenshot 2018-06-12 21.58.14.png | Bin 0 -> 102056 bytes .../Screenshot 2018-06-12 22.03.05.png | Bin 0 -> 287580 bytes packages/tandem-designer/src/scss/all.scss | 2 + packages/tandem-designer/src/scss/fix.scss | 7 + packages/tandem-designer/src/scss/global.scss | 56 + .../src/scss/ionicons/_ionicons-font.scss | 31 + .../src/scss/ionicons/_ionicons-icons.scss | 2938 ++++++++++ .../scss/ionicons/_ionicons-variables.scss | 741 +++ .../src/scss/ionicons/ionicons.scss | 15 + .../tandem-designer/src/scss/modules.scss | 26 + .../tandem-designer/src/scss/variables.scss | 85 + .../src/starter-kits/blank/form.pc | 26 + .../src/starter-kits/form-controller.tsx | 92 + .../tandem-designer/src/starter-kits/form.pc | 292 + .../src/starter-kits/index.tsx | 4 + .../src/starter-kits/react/form.pc | 78 + packages/tandem-designer/src/state/index.ts | 1831 +++++++ packages/tandem-designer/src/utils/index.ts | 1 + packages/tandem-designer/src/utils/react.ts | 5 + packages/tandem-designer/tsconfig.json | 18 + .../tandem-designer/webpack-base.config.js | 78 + .../webpack-tandem-preview.config.js | 36 + packages/tandem-designer/webpack.config.js | 20 + 405 files changed, 78212 insertions(+) create mode 100644 .prettierignore create mode 100644 packages/tandem-designer/.gitignore create mode 100644 packages/tandem-designer/LICENSE create mode 100644 packages/tandem-designer/README.md create mode 100644 packages/tandem-designer/app.tdproject create mode 100644 packages/tandem-designer/design/app.sketch create mode 100644 packages/tandem-designer/design/split-2.svg create mode 100644 packages/tandem-designer/index.d.ts create mode 100644 packages/tandem-designer/index.js create mode 100644 packages/tandem-designer/package.json create mode 100644 packages/tandem-designer/src/actions/bottom-left-corner.svg create mode 100644 packages/tandem-designer/src/actions/index.ts create mode 100644 packages/tandem-designer/src/bug-reporting/components/main/controller.tsx create mode 100644 packages/tandem-designer/src/bug-reporting/components/main/view.pc create mode 100644 packages/tandem-designer/src/bug-reporting/index.ts create mode 100644 packages/tandem-designer/src/components/atoms/view.pc create mode 100644 packages/tandem-designer/src/components/box-shadows-enhancer.tsx create mode 100644 packages/tandem-designer/src/components/component-picker/all.pc create mode 100644 packages/tandem-designer/src/components/component-picker/cell-controller.tsx create mode 100644 packages/tandem-designer/src/components/component-picker/cell.pc create mode 100644 packages/tandem-designer/src/components/component-picker/modal-controller.tsx create mode 100644 packages/tandem-designer/src/components/component-picker/modal.pc create mode 100644 packages/tandem-designer/src/components/component-picker/picker-controller.tsx create mode 100644 packages/tandem-designer/src/components/component-picker/picker.pc create mode 100644 packages/tandem-designer/src/components/component-picker/picker2-controller.tsx create mode 100644 packages/tandem-designer/src/components/configure-build/controller.tsx create mode 100644 packages/tandem-designer/src/components/configure-build/view.pc create mode 100644 packages/tandem-designer/src/components/context-menu/controller.tsx create mode 100644 packages/tandem-designer/src/components/context-menu/view.pc create mode 100644 packages/tandem-designer/src/components/contexts/index.ts create mode 100644 packages/tandem-designer/src/components/dev/comments.pc create mode 100644 packages/tandem-designer/src/components/draggable/index.tsx create mode 100644 packages/tandem-designer/src/components/focus/controller.tsx create mode 100644 packages/tandem-designer/src/components/focus/index.tsx create mode 100644 packages/tandem-designer/src/components/gutter/index.scss create mode 100644 packages/tandem-designer/src/components/gutter/index.tsx create mode 100644 packages/tandem-designer/src/components/inputs/atoms.pc create mode 100644 packages/tandem-designer/src/components/inputs/button-bar/controller.tsx create mode 100644 packages/tandem-designer/src/components/inputs/button-bar/item.pc create mode 100644 packages/tandem-designer/src/components/inputs/button-bar/view.pc create mode 100644 packages/tandem-designer/src/components/inputs/button-group/index.scss create mode 100644 packages/tandem-designer/src/components/inputs/button-group/index.tsx create mode 100644 packages/tandem-designer/src/components/inputs/button/index.scss create mode 100644 packages/tandem-designer/src/components/inputs/button/index.tsx create mode 100644 packages/tandem-designer/src/components/inputs/button/view.pc create mode 100644 packages/tandem-designer/src/components/inputs/checkbox/controller.tsx create mode 100644 packages/tandem-designer/src/components/inputs/checkbox/index.scss create mode 100644 packages/tandem-designer/src/components/inputs/color/canvas-controller.tsx create mode 100644 packages/tandem-designer/src/components/inputs/color/color-input-controller.tsx create mode 100644 packages/tandem-designer/src/components/inputs/color/color-swatch-controller.tsx create mode 100644 packages/tandem-designer/src/components/inputs/color/hex-input-controller.tsx create mode 100644 packages/tandem-designer/src/components/inputs/color/index.scss create mode 100644 packages/tandem-designer/src/components/inputs/color/login-form-controller.tsx create mode 100644 packages/tandem-designer/src/components/inputs/color/picker-controller.tsx create mode 100644 packages/tandem-designer/src/components/inputs/color/picker.pc create mode 100644 packages/tandem-designer/src/components/inputs/color/presets/index.scss create mode 100644 packages/tandem-designer/src/components/inputs/color/presets/index.tsx create mode 100644 packages/tandem-designer/src/components/inputs/color/raw-input/index.scss create mode 100644 packages/tandem-designer/src/components/inputs/color/raw-input/index.tsx create mode 100644 packages/tandem-designer/src/components/inputs/color/rgba-input-controller.tsx create mode 100644 packages/tandem-designer/src/components/inputs/color/utils.ts create mode 100644 packages/tandem-designer/src/components/inputs/color/view.pc create mode 100644 packages/tandem-designer/src/components/inputs/dropdown/controller.tsx create mode 100644 packages/tandem-designer/src/components/inputs/dropdown/index.scss create mode 100644 packages/tandem-designer/src/components/inputs/dropdown/menu.pc create mode 100644 packages/tandem-designer/src/components/inputs/dropdown/view.pc create mode 100644 packages/tandem-designer/src/components/inputs/file-picker/controller.tsx create mode 100644 packages/tandem-designer/src/components/inputs/file-picker/view.pc create mode 100644 packages/tandem-designer/src/components/inputs/molecules.pc create mode 100644 packages/tandem-designer/src/components/inputs/slider/controller.tsx create mode 100644 packages/tandem-designer/src/components/inputs/slider/index.scss create mode 100644 packages/tandem-designer/src/components/inputs/slider/view.pc create mode 100644 packages/tandem-designer/src/components/inputs/switch/controller.tsx create mode 100644 packages/tandem-designer/src/components/inputs/switch/view.pc create mode 100644 packages/tandem-designer/src/components/inputs/table/view.pc create mode 100644 packages/tandem-designer/src/components/inputs/text/auto-complete-controller.tsx create mode 100644 packages/tandem-designer/src/components/inputs/text/controller.tsx create mode 100644 packages/tandem-designer/src/components/inputs/text/index.scss create mode 100644 packages/tandem-designer/src/components/inputs/text/view.pc create mode 100644 packages/tandem-designer/src/components/inputs/textarea/controller.tsx create mode 100644 packages/tandem-designer/src/components/inputs/textarea/view.pc create mode 100644 packages/tandem-designer/src/components/inputs/view.pc create mode 100644 packages/tandem-designer/src/components/isolated/index.tsx create mode 100644 packages/tandem-designer/src/components/light-ide/index.scss create mode 100644 packages/tandem-designer/src/components/light-ide/index.tsx create mode 100644 packages/tandem-designer/src/components/light-ide/preview.scss create mode 100644 packages/tandem-designer/src/components/light-ide/preview.tsx create mode 100644 packages/tandem-designer/src/components/light-ide/state.ts create mode 100644 packages/tandem-designer/src/components/light-ide/utils.ts create mode 100644 packages/tandem-designer/src/components/menubar/view.pc create mode 100644 packages/tandem-designer/src/components/pane/index.scss create mode 100644 packages/tandem-designer/src/components/pane/index.tsx create mode 100644 packages/tandem-designer/src/components/pane/view.pc create mode 100644 packages/tandem-designer/src/components/popover/content-controller.tsx create mode 100644 packages/tandem-designer/src/components/popover/controller.tsx create mode 100644 packages/tandem-designer/src/components/popover/view.pc create mode 100644 packages/tandem-designer/src/components/popups/view.pc create mode 100644 packages/tandem-designer/src/components/portal/controller.tsx create mode 100644 packages/tandem-designer/src/components/prompt/controller.tsx create mode 100644 packages/tandem-designer/src/components/prompt/view.pc create mode 100644 packages/tandem-designer/src/components/quick-search/index.scss create mode 100644 packages/tandem-designer/src/components/quick-search/index.tsx create mode 100644 packages/tandem-designer/src/components/quick-search/modal-controller.tsx create mode 100644 packages/tandem-designer/src/components/quick-search/quick-search-controller.tsx create mode 100644 packages/tandem-designer/src/components/quick-search/row.pc create mode 100644 packages/tandem-designer/src/components/quick-search/search-result-controller.tsx create mode 100644 packages/tandem-designer/src/components/quick-search/view.pc create mode 100644 packages/tandem-designer/src/components/root/chrome-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/chrome.pc create mode 100644 packages/tandem-designer/src/components/root/index.scss create mode 100644 packages/tandem-designer/src/components/root/index.tsx create mode 100644 packages/tandem-designer/src/components/root/tools/build-button-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/tools/view.pc create mode 100644 packages/tandem-designer/src/components/root/view.pc create mode 100644 packages/tandem-designer/src/components/root/welcome/controller.tsx create mode 100644 packages/tandem-designer/src/components/root/welcome/test.json create mode 100644 packages/tandem-designer/src/components/root/welcome/view.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/bottom-gutter/console-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/bottom-gutter/console-logs-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/bottom-gutter/controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/bottom-gutter/view.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/editor-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/editor-windows-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/editor-windows.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/editor.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/footer/breadcrumbs-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/footer/controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/footer/view.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/image/index.scss create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/image/index.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/index.scss create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/paperclip/stage/canvas/index.scss create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/paperclip/stage/canvas/index.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/paperclip/stage/canvas/preview-layer/document.scss create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/paperclip/stage/canvas/preview-layer/document.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/paperclip/stage/canvas/preview-layer/index.scss create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/paperclip/stage/canvas/preview-layer/index.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/paperclip/stage/canvas/tools-layer/document-overlay.scss create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/paperclip/stage/canvas/tools-layer/document-overlay.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/paperclip/stage/canvas/tools-layer/edit-text-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/paperclip/stage/canvas/tools-layer/edit-text.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/paperclip/stage/canvas/tools-layer/frame-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/paperclip/stage/canvas/tools-layer/frames-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/paperclip/stage/canvas/tools-layer/frames-view.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/paperclip/stage/canvas/tools-layer/index.scss create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/paperclip/stage/canvas/tools-layer/index.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/paperclip/stage/canvas/tools-layer/insert-layer.scss create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/paperclip/stage/canvas/tools-layer/insert-layer.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/paperclip/stage/canvas/tools-layer/node-overlay.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/paperclip/stage/canvas/tools-layer/selectables.scss create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/paperclip/stage/canvas/tools-layer/selectables.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/paperclip/stage/canvas/tools-layer/selection/index.scss create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/paperclip/stage/canvas/tools-layer/selection/index.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/paperclip/stage/canvas/tools-layer/selection/label.scss create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/paperclip/stage/canvas/tools-layer/selection/label.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/paperclip/stage/canvas/tools-layer/selection/path.scss create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/paperclip/stage/canvas/tools-layer/selection/path.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/paperclip/stage/canvas/tools-layer/selection/resizer.scss create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/paperclip/stage/canvas/tools-layer/selection/resizer.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/paperclip/stage/footer/index.scss create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/paperclip/stage/footer/index.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/paperclip/stage/index.scss create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/paperclip/stage/index.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/text/index.scss create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/text/index.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/text/view.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/toolbar/controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/toolbar/index.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/toolbar/tab.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/editors/toolbar/view.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/index.scss create mode 100644 packages/tandem-designer/src/components/root/workspace/left-gutter/components/index.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/left-gutter/controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/left-gutter/file-navigator/contexts.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/left-gutter/file-navigator/controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/left-gutter/file-navigator/layer-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/left-gutter/file-navigator/new-file-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/left-gutter/file-navigator/view.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/left-gutter/open-files/after-dnd-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/left-gutter/open-files/before-dnd-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/left-gutter/open-files/contexts.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/left-gutter/open-files/dnd-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/left-gutter/open-files/drop-zones.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/left-gutter/open-files/layer-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/left-gutter/open-files/layer.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/left-gutter/open-files/layers-pane-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/left-gutter/open-files/open-module-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/left-gutter/open-files/open-module.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/left-gutter/open-files/utils.ts create mode 100644 packages/tandem-designer/src/components/root/workspace/left-gutter/open-files/view.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/left-gutter/view.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/prompt-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/conditions/view.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/global-properties-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/index.scss create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/properties/a-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/properties/component-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/properties/controller-item-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/properties/controller-item.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/properties/element-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/properties/exports-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/properties/exports-name-input-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/properties/exports-name-input.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/properties/frame-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/properties/frame.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/properties/img-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/properties/input-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/properties/input.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/properties/properties-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/properties/text-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/properties/text.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/properties/view.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/queries/controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/queries/item-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/queries/media-query-options-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/queries/query-item-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/queries/query-options-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/queries/utils.ts create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/queries/variable-query-options-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/queries/view.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/behavior/controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/behavior/trigger-item-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/behavior/triggers-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/behavior/triggers.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/behavior/view.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/index.scss create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/index.scss create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/index.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/background-item-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/backgrounds-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/backgrounds.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/border-color-input-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/border-style-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/border-styles-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/borders-2-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/borders-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/borders.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/box-shadow-item-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/box-shadow.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/box-shadows-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/box-shadows-inner-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/box-shadows.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/code.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/code.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/filters.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/inherit-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/inherit-item-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/inherit-item.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/inherit.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/inputs/background-input-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/inputs/background/controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/inputs/background/image-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/inputs/background/linear-gradient-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/inputs/background/solid-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/inputs/background/state-test.ts create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/inputs/background/state.ts create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/inputs/background/view.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/inputs/dropdown-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/inputs/inline-labeled-input-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/inputs/labeled-input-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/inputs/style-value-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/inputs/tblr-input-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/inputs/view.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/inspector/view.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/instance-pane-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/instance.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/layout-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/layout.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/opacity-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/opacity.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/radius-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/spacing-2-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/spacing-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/spacing-input-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/spacing.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/style.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/typography-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/typography.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/utils.ts create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/panes/variant-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/pretty/view.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/state.ts create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/variants/controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/variants/controller2.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/variants/option-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/variants/option.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/variants/pill.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/variants/variant-input-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/variants/variant-input.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/variants/view.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/styles/view.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/tab.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/variables/controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/variables/row-item-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/variables/tab-controller.tsx create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/variables/view.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/right-gutter/view.pc create mode 100644 packages/tandem-designer/src/components/root/workspace/view.pc create mode 100644 packages/tandem-designer/src/components/side-panel/button-controller.tsx create mode 100644 packages/tandem-designer/src/components/side-panel/view.pc create mode 100644 packages/tandem-designer/src/components/test.pc create mode 100644 packages/tandem-designer/src/components/tree/index.scss create mode 100644 packages/tandem-designer/src/components/tree/index.tsx create mode 100644 packages/tandem-designer/src/components/tree/view.pc create mode 100644 packages/tandem-designer/src/components/warn/view.pc create mode 100644 packages/tandem-designer/src/entry.ts create mode 100755 packages/tandem-designer/src/fonts/ionicons.eot create mode 100755 packages/tandem-designer/src/fonts/ionicons.svg create mode 100755 packages/tandem-designer/src/fonts/ionicons.ttf create mode 100755 packages/tandem-designer/src/fonts/ionicons.woff create mode 100644 packages/tandem-designer/src/global.pc create mode 100644 packages/tandem-designer/src/icons/add.svg create mode 100644 packages/tandem-designer/src/icons/airplane.svg create mode 100644 packages/tandem-designer/src/icons/all-border.svg create mode 100644 packages/tandem-designer/src/icons/arrow-down.svg create mode 100644 packages/tandem-designer/src/icons/bolt.svg create mode 100644 packages/tandem-designer/src/icons/bottom-left-corner.svg create mode 100644 packages/tandem-designer/src/icons/bottom-right-corner.svg create mode 100644 packages/tandem-designer/src/icons/brush-2.svg create mode 100644 packages/tandem-designer/src/icons/brush.svg create mode 100644 packages/tandem-designer/src/icons/circle.svg create mode 100644 packages/tandem-designer/src/icons/code.svg create mode 100644 packages/tandem-designer/src/icons/color-palette.svg create mode 100644 packages/tandem-designer/src/icons/component.svg create mode 100644 packages/tandem-designer/src/icons/corners.svg create mode 100644 packages/tandem-designer/src/icons/dotted-box.svg create mode 100644 packages/tandem-designer/src/icons/drop.svg create mode 100644 packages/tandem-designer/src/icons/file.svg create mode 100644 packages/tandem-designer/src/icons/folder.svg create mode 100644 packages/tandem-designer/src/icons/image.svg create mode 100644 packages/tandem-designer/src/icons/individual-border.svg create mode 100644 packages/tandem-designer/src/icons/individual-border2.svg create mode 100644 packages/tandem-designer/src/icons/insert.svg create mode 100644 packages/tandem-designer/src/icons/joystick.svg create mode 100644 packages/tandem-designer/src/icons/minus.svg create mode 100644 packages/tandem-designer/src/icons/more.svg create mode 100644 packages/tandem-designer/src/icons/open-2.svg create mode 100644 packages/tandem-designer/src/icons/open.svg create mode 100644 packages/tandem-designer/src/icons/pause.svg create mode 100644 packages/tandem-designer/src/icons/pencil-2.svg create mode 100644 packages/tandem-designer/src/icons/pencil.svg create mode 100644 packages/tandem-designer/src/icons/play-2.svg create mode 100644 packages/tandem-designer/src/icons/play.svg create mode 100644 packages/tandem-designer/src/icons/plus.svg create mode 100644 packages/tandem-designer/src/icons/pointer.svg create mode 100644 packages/tandem-designer/src/icons/puzzle.svg create mode 100644 packages/tandem-designer/src/icons/rectangle.svg create mode 100644 packages/tandem-designer/src/icons/replace.svg create mode 100644 packages/tandem-designer/src/icons/reset-2.svg create mode 100644 packages/tandem-designer/src/icons/reset.svg create mode 100644 packages/tandem-designer/src/icons/round-square.svg create mode 100644 packages/tandem-designer/src/icons/shadow.svg create mode 100644 packages/tandem-designer/src/icons/split-2.svg create mode 100644 packages/tandem-designer/src/icons/split-down.svg create mode 100644 packages/tandem-designer/src/icons/text-center.svg create mode 100644 packages/tandem-designer/src/icons/text-justify.svg create mode 100644 packages/tandem-designer/src/icons/text-left.svg create mode 100644 packages/tandem-designer/src/icons/text-right.svg create mode 100644 packages/tandem-designer/src/icons/text.svg create mode 100644 packages/tandem-designer/src/icons/top-left-corner.svg create mode 100644 packages/tandem-designer/src/icons/top-right-corner.svg create mode 100644 packages/tandem-designer/src/icons/trash.svg create mode 100644 packages/tandem-designer/src/icons/view.pc create mode 100644 packages/tandem-designer/src/icons/wand.svg create mode 100644 packages/tandem-designer/src/images/20180703190744-rollsafe-meme.jpeg create mode 100644 packages/tandem-designer/src/images/NEDM.jpg create mode 100644 packages/tandem-designer/src/images/inter-trigger2.gif create mode 100644 packages/tandem-designer/src/index.html create mode 100644 packages/tandem-designer/src/index.ts create mode 100644 packages/tandem-designer/src/paperclip.worker.ts create mode 100644 packages/tandem-designer/src/reducers/index.ts create mode 100644 packages/tandem-designer/src/sagas/copy-paste.ts create mode 100644 packages/tandem-designer/src/sagas/index.ts create mode 100644 packages/tandem-designer/src/sagas/popup.ts create mode 100644 packages/tandem-designer/src/sagas/process.ts create mode 100644 packages/tandem-designer/src/sagas/project.ts create mode 100644 packages/tandem-designer/src/sagas/react.ts create mode 100644 packages/tandem-designer/src/sagas/shortcuts.ts create mode 100644 packages/tandem-designer/src/sagas/synthetic-browser.ts create mode 100644 packages/tandem-designer/src/screenshots/Screenshot 2018-06-12 21.58.14.png create mode 100644 packages/tandem-designer/src/screenshots/Screenshot 2018-06-12 22.03.05.png create mode 100644 packages/tandem-designer/src/scss/all.scss create mode 100644 packages/tandem-designer/src/scss/fix.scss create mode 100644 packages/tandem-designer/src/scss/global.scss create mode 100755 packages/tandem-designer/src/scss/ionicons/_ionicons-font.scss create mode 100755 packages/tandem-designer/src/scss/ionicons/_ionicons-icons.scss create mode 100755 packages/tandem-designer/src/scss/ionicons/_ionicons-variables.scss create mode 100755 packages/tandem-designer/src/scss/ionicons/ionicons.scss create mode 100644 packages/tandem-designer/src/scss/modules.scss create mode 100644 packages/tandem-designer/src/scss/variables.scss create mode 100644 packages/tandem-designer/src/starter-kits/blank/form.pc create mode 100644 packages/tandem-designer/src/starter-kits/form-controller.tsx create mode 100644 packages/tandem-designer/src/starter-kits/form.pc create mode 100644 packages/tandem-designer/src/starter-kits/index.tsx create mode 100644 packages/tandem-designer/src/starter-kits/react/form.pc create mode 100644 packages/tandem-designer/src/state/index.ts create mode 100644 packages/tandem-designer/src/utils/index.ts create mode 100644 packages/tandem-designer/src/utils/react.ts create mode 100644 packages/tandem-designer/tsconfig.json create mode 100644 packages/tandem-designer/webpack-base.config.js create mode 100644 packages/tandem-designer/webpack-tandem-preview.config.js create mode 100644 packages/tandem-designer/webpack.config.js diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 000000000..6fd0ef029 --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +*.pc diff --git a/packages/tandem-designer/.gitignore b/packages/tandem-designer/.gitignore new file mode 100644 index 000000000..8ce5e9e8f --- /dev/null +++ b/packages/tandem-designer/.gitignore @@ -0,0 +1,2 @@ +lib +*.pc.d.ts diff --git a/packages/tandem-designer/LICENSE b/packages/tandem-designer/LICENSE new file mode 100644 index 000000000..7a3b7c2f6 --- /dev/null +++ b/packages/tandem-designer/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. \ No newline at end of file diff --git a/packages/tandem-designer/README.md b/packages/tandem-designer/README.md new file mode 100644 index 000000000..a79c6a9b4 --- /dev/null +++ b/packages/tandem-designer/README.md @@ -0,0 +1,13 @@ +Front-end for Tandem visual editor. + +TODO: + +```javascript +import { Designer } from "tandem-designer"; + +const designer = new Designer({ + io: { + async openProject(projectId) {}, + }, +}); +``` diff --git a/packages/tandem-designer/app.tdproject b/packages/tandem-designer/app.tdproject new file mode 100644 index 000000000..ed30435f5 --- /dev/null +++ b/packages/tandem-designer/app.tdproject @@ -0,0 +1,9 @@ +{ + "exclude": [ + "node_modules" + ], + "globalFilePath": "./src/global.pc", + "rootDir": ".", + "scripts": { + } +} \ No newline at end of file diff --git a/packages/tandem-designer/design/app.sketch b/packages/tandem-designer/design/app.sketch new file mode 100644 index 0000000000000000000000000000000000000000..abbe878383a68fe44acb9aba0aff44ce56519849 GIT binary patch literal 19016 zcmeIabySpJ7e5L(=l}wPv>+g;Gy_OThlHS{bf;Bfd_s@IRcUZHA=b3Zn?7h$4pB?9%NAc-35D^*%8W`>3rD1c-3Pndl zbHYGF!v(HQ?2KJ(Ol_UnES>CZUn^=WG_n(&L47hEzBn@4l_GD2A|6dgMA!<kc>K@3_meP8KEj?FpIzFM~cllTwn9WM7Qh zdli9AF2i&zesA{P&o-GLT4&hxuy^WR>-WNj%~j)X%T)BY(sJqVwvXqgHH-dYWiGuQ zzD9A{OnDqNTsG3{-Cr5xobE_7h*l?H#qooj{A=Y)A2%IxoQ29-^&4L-ocdT#g;+!B&=7+c8 z_{+LSyKzys^$ai{krj^6J;h-T=giC1P3OeT;_2g zmdwPKyZE-4#)*-x{k|BA|B!6BTwjbl4jP(XG8!5bkgUC-nW+<0f|FD15w{pGD-Yje zNmedysmH8*++32Zd|Z+b`Pjw9xVZTEE@h9>)wVU05G~7^K*qj*TKZytQy}>xRpn{f1~62d>AsO9|xoAE{r7NDqEyxlwd| z=f{IPIyYMnQx5me2bA{s;bC`MVJ0v%osVEe5{gu^u$O5BN{Tn4m`rczE*)~oz3}@s zNSjmQ&Et;Q*Ftm3-y5=nyC9i02iTBuI`Gsksk6hcv4!-75OV~#1c(MggO4fYclH|Tn zifYHM;dJ14VF&o|&I4*6**0ce>JrYXWUa+KqxWTVwH=*INBjyeTzRJa60*3Te${Fg zFJyBrod3gon0Q~)Ddm_psZEZnRK+=-wFxX03m9R?jMNax#OMzp1+{y-u#L7$;;f*Xa zH>p5>@H>tlL1J$rnxFP~Ro+&5qb#1r@aZNY7I9NTN%waCGktB{!^)#lSu?dCc450R zrgEJu>r$TzQ9i?s?;g^r-?*LPY%T2qW&0ZZKDKLPXM$il0}~g7pKtJ zI7T{Tj>l(}e+5(L+dvw*mPo~VSja@-Sp&ZN7DY7$JS~q;w+r@5afGK* z8<`oOvQS?Y(sUq>JP;4uex2M&I^Igk9|d)Oq;F55zo}Ro4|7wuN*wz63!!)8VN`Kg zcoc@R1&$vH#W_Ez_1UKf^7IcW(ul`NU~^=A zNv+003@5z*krj}f{kZq(uWdi2A8XGG_L7C2Z__XQurXfM&gguRBeNLWJ!n6;iC<+h zP7;{ZdwnSTn&9_23Qx-1S%ue@GA-ErBh%~XAA<**X68X?8qIIaiP5@Mzzp2QIK{+$ zp!6Uty0-&nX6VZhTD)RqqFWEl&Cu^ti8I_ylNG&pPhHMgG;lxu`Mpn{A=t_kqJnU> z55{b7n|nfcT-~9c$cT zsyiihT;UO(;u;Q88;fJF5Xm$-Baa~t)&?|~2Emr11X!?v0CaLlC&O?kw#yqT|B_h< z+z#^mS^vP}(M`;s%jXyiLTDT4?)WqARP_%mv6fjx9)Dl3uYd#_wcMS=mpu1xA9UDL znhQL}jZiXeqG}~JY9D{{1hKeFMeX!5AiR%1o^JP+{tA}a2=9V~wN-76U%MFjfw1zh zPo<|pL;10J3_v!ZK%(=6yhu@Pt0%9q=EWqT50U><0;;z`T`!C!A#cv zS)$_EV3k2C=kO|AKKXfvn`1}Hr*E?hp0i-aCz$%aw!Jz+JU`IP@>9Ogu4m=r2tD~F zQ}%RcG~(LlW%`9KyktGsKAfk|tU8E8VQLcSOzC9pG~mfVyvM|hulygrx*sU{%k+Al zDzY*CgLKAMu?&6O+-$n=&* zqLmEt+8>=M>iUOf9_vOaOM=lS!S6|Lu^ei2qz~}5$O@eajf+%@wuP`IN9At3t?4^^ zPtC9QBe3V;@>%|UR8^YtH*Rb`llo>hv%>6>>}GNU^k85buitYiax9=qw}I;*d6hEl2FB#PLfhNeDh&!SE9$Bu^YXV3Up;4z_hPddF%WSe zYM>-&A&8ArW>h!v8Xdx}9CJXZ@s}%kIX*IbBHNK+vd;*SDd`-0Rp`~j!=D`ZPy#X= zCDsUOP%h{hYbuO+*uyHKF|LTt{4GLb$=X~yPK8KGEGjCBDrCrJys{*7f+=_W(Vp1p zL5rOU7=;UH=WDqapG@mvEH115^0Icb+7G;<4!o~FVn+2n z+ekukcdcALszr0hEG*tm*2YnZ5A&jwGz(rYun|^}+PnAYoag+Y_*tGG@14Cpzm<;+ zOT)h5NX`s;kDfdHhhdw(bSI3bv?%+2PXXqe$$GGr1AhLY*GxZlj8i0oNv&33K8vi8kD3rfoF)$PgB z#N6Bxv}Nf*cyDb%A|1pSVmKf$f|ufjVyUmtB!+vj#(_dT~uQI~k{#=^=OPa)z6__>w|yjGPZG z{mkFMDNXT4!mz5I^ZmH_S~o{z`DdEYYvIhGUfMp!w4EH!hgqKEgTO~=VYx&NBOrl^X#SWtRKzfxX&yuDb3KRx{F}ZC z)LB(f*YMTi@V0p!!(qQxy~pdbaJ|Q8+AXe;F^AEF!&IJJyPb|^E`Cq()7wW_^P~RV z6H6zul^wg7nBS(Hv=Y zaB?PWMD@!x8i$Fn?cIC#bZ_QoL;tJ!hp_aTf`>Em$Po6N4=$q1TBtd>&fx@IlX>{{ z+$y{}z23EWjnH%Mltmc?yRA0(QRx2UIr=|Cb2{hc%@80YPXgXpz}v;i)bTRt7W!6$ z=g&?gI;+m%W-I4qVP(fF5&G(Ff&lD#Jlg#emJhX6<>kH|d;(m>Q`bcbXI$fQheeu7 zguTtH9)BiU3zu9ww$$>zCV%fbZ}Y^;Nh2=tef1+f`+?japF2aFxz&Sz{?b`F1nWDQ zH-Yh7-!Y8JXh*(mpl_Yk-AlL;X!b1>E|u29LN3PW^FI`i-o%F90@5^cAWgfV*v8b^ z@RH)B2>qu`>_jbfPm_@YA~MJ|)}CMmq~ez3e#GZ75}n8oCa;u^CTj?yu!84SYXY5o zm!3TtH|#@ajkr~!TruY(zvC%APHSf&#?cDe$%NPp_F>~Fr-Q=0iv%AEIf-ekdxnz` zRJ9t%(dGH{xzPveqc6q}f;gk5~(~W?G5_7d_- z2;pBJ)UTQ*NDREc!Mdvy*tHWFth`AkZ6DzGU`-4+p2EV*X8)s~su)!+nG^Q#&exR& zQqJ;gO4c=6MWZiv4&c5&Meirg-L=g0Lt#*+=mbTP!xA1X(~%A17M@ETIdvCxc~7HX z59Qt{#UIu+C||YPmxq8rmT6CISR!?`Z03Vd~}t{rwM{ zy{#GgARkNXTSa+kT>Wskoz~ChPK8Wome5N_)SF>DQ1#CuF#`A4FCgq>(XzM?`O2e*lq_xY=Cate@)l z8dfLTW`aRL*dPj#ens%c?FX$?6NQ{(7}v*UQt4f)r9?z+Y31VwTI!GT|4imP z`kB`mZC|S+g<8D6b`qs)nx0-zzKEzhwaMY6zv7A?tn(Qh1e{TR8uNONLa@d(Bln zRDKTz8V5AkRe%-iw@g&g#qv7S|M1zzMq^%zw2-+X6p{^$qDmG0+fHDvK-)?Ar&n~o z6jc@N%iYet_uFXT02e4%tv|!$V)&~?OW(h;1kqGo(LPJW;Gba>i6QV@L8d=6pn$ej zNilzh$$gosx}fxj26Ivfd>jS;GmHvAK2x~t9~!D&rViO={bv{^ntxfnn7e;x^~!ku zRp8%v^{=g7!PLL7bcM+OBJl5M<6mcUc1hxRaE+K2=Q+S@&D&=pOV$w zXGvgsOh-rO!0^imH)JH_?d6Q;>&}>qty<|Hk1ryp&-TY_D5nWPbNp{tTO=-_a+u8? zo=U9PI6MxGZ35xhGrs8ZD7ik&U#+X?2aa}|fM(Y4bE|gCiXQpy*0alg9^eTEbDz^y{b{&2 z7Pj`114mf+c0>g6$j9H@iOoofG2>~BYBgDGc-<6N)7P)L%qW+^I)bu;wN(^$zR>5Z zu@)9~@&+srx{Uev`4l=a^R_G(t=L>k^%ZuZlHF$}C1xIAh!4xbt&i`)NcFw9WD>IJ z*_k(i`i(`I&Rv)>n3581L?2LKoEW^b^0=M9Xs70T|JiEQRH+9rT@@ZHIa%A%F=nT8 zhXd7#iwiP?8qnUP)>pYo!fYXU@M+=3Dycfe`C)Ij2vGUqIo~Ki%&8=Roe3Yw_664v zmQ^OD54o_I6s$*0eY|$`%kLP`T{V5W-d*E`%%YXeW)jfAP|aUjIKWIHDlc;|q9~Kq z{Z@+qy30b&_uTuyeg`NO$n{kU*2M5*0UFeDhNYdc&Csn zZEtrl{9FO)4!5kX-Y^VBhQ^joD;QYw=uH*v4fVGg!~Kp?2;T64?3lNrcCf_}f$y#? zXLRfYafA#A%f*#e)51^1Zx(z&bL0i*r_|@gha-N6vE8RcaMyHbQ}$3{c*l`#6}(|> z+vM1}jw9SZ`s@WV^f=zS=yY<^D?)r&|NLmA`}}m{e9B!aPp5lP2t;*W=OZL6nF8pL zhPVM)hC9*h13A7gSqqckcKZbOkr*_hJ!IHmO=Fi?1zaC7O-HBY@HT-20)dl=?h}B( zEOZcr|2C<4Kz2t|(|1K4y<}@w)Jl1``{DTY$Y6(rt!3cl;=5!9E9tozv1OZA2S5`>m)M(Ba{i^@|QOhTaZReX`V=Q!j+6V2nk$W6>F? zPDkr=cA-Gk@o0~n@TF?_wB_0}`O)5oT3x4Z9_uOh%#)6ZXAZFPWoX2QU)`wMS~8%Co`%#SjOX+0Gdr z1Tsq4v=y+4h%^q_60MfF^B$>6m2~PH6ATz29@Le)l*{;S^hu;5fO3nr#yOx24bBWWHgB}g-)1NHd6&j~PjQGI zm;zcwDR?pyI@6-5!T@Un*ub=zDR_Q==HO!iL&(uKjW?c^5?SQ_>UKzf@2=qVgVVc? zgs^0wLZqPULrC)_yWUnJFH~9Lk*t@Zl&O)PRAuKol)nb!lbvnPAj-ltnJ8Q*6x8pS z^S#dXF%9y}=bOwUvSVgW82>5N8aTkDmp>+)P!;TU@R4N@eDCpk0*64v5g9><9c`Z`Al{q#UVwNB%WuKo5ac-`i$V=h!(FzxbnI3Aaa#5g_p zA$s!*`k+&vqN#)Q*H(7LmVhWXY4xMq1W1hmun2;(b)h{K;Yv>I=XfsFdKhY0YNiRm zkn^alRZ{_!^j)62#IZRe&NbF<+P+(E9P^$4xvap9k_?NWV{~CPlP+y8kke^wnNsQh z;0PP(`lMQ9*4ftT3X?yIGBut+y zZhzjU)+HBLJ@a~#PD6qqb_yVS&4z;N&&0n{P3$2)Xens&&hx0~8l+Fk0g9)Y^izg} z8tI~-f|CikN*9f@VBJu&Xpt(yySbr`VbbM}GuRPeEdts%JQd~|YzTtV>36r1tEV>w z^%IT%sZ4ApxO8lMH$QK}abz+CQL1<UWnf{zSjwrvAK{Zrjfe|w+j+Wtv#}WPX3(DcA8hyfi1!F~_ zzKePFBA_FnxP5B9_v~eTBgPiJ`}XRcfu$H4RjKsOhuQ>1o#x-7-{+|aPd;$fKmNgO z9GNmAE5@=o%ZKO&l&ja=gG^Zdea=_F2+1{m0Y*r#Nc9GKmsz;t1U9d$8EP)c&al(J zE~$xU7+Er*5W3#1G9G`qVxE18O zGy3V)=Qj~t1P>&o@J??$^zIO5}3FNCK+M@?R?NiyC;qPP7BJ z*5t^2DqoPkDb7Km3a!d=h^^{|IuJNkiX-1AG3&~^DWR;~f2m0b)(@p%cjlALZ;EF# zVBK_r?Co!=){)ZXtzNuQsIs^GDD~x7>93%Its%RLNPtHyH3YyTG(s9a$BRFRYTDw$ zlQ$)L(EA)Mf#Ni{a_h5CXTr61%M-zL?%HNnHzEj}e{Lln4Q7hj$sl=#YT^uzcKsxH zpeI%4XwGn#x!WlMF!M0!Vz_>WK4>ivpNho`b_D+l^y}G%3z%c95(Q}oa>Va_{|P(T zGFPE=(S+`JCvb>sK3neM71u1JxKU(dbB2I3?+iRpxAf!m-SP~iY?oddriD=fwurCl zbBo4a0Ap)`uNv-58Dq3-bW)pD?bH+mtYm4<+dMFQdc1eo!WU-M@;^ZOC=g9G`971K zCv<1@_jjwhJEzRHrh3(xJI{AQ`t!Z>`0$z~Qquv+5U7s;l3|9_6`r$W z7I-ZW8=lQki>t4-98~0Ihs;D|!R02-kOi@GTu>-Y7%hshai#)WM2wluY7hfhO~Ggv z_D6%g2F;D^1sB`2~r8j;FN?sSw%X;cOi{3_%WV?vMAGxs!H^D`g~P= z9m3pe9#@oidjYE#LN0r9FYD7V_{=3WWc}Wl5fzsmLl!JLVV2q@lP|#PkNZtW$BCoD zO7Y(g9Z2?VhYs&DA*RFto?qqy3mvx7GYW$zX=!W#v7~BAfDTY#ct|k&*w@}y5m)-wr6N_7xs$D6T7?WOE%Q!A>Pwl~~1lg^0+VczM>i)6&=%w;?;4!K<;dzta z|DONpdm-bEWhELo2>BNb!t3y%Og)+{}^0vktKsaDK-u02?A=e>nN~f7$IIaTz6-v~iTdtjzOT=j?SJ9P z^i_H-HB%AL^fA~Iq-!o`g(^yF1Y7VkePx}DX>$xHB5Mh@utipsl-PVL6%nd)C#y}| zc@+5IA29`3iw*)Lwx8MPqBXl&IS?yp%XJ53CD+M97IOA(1czYb(p&awLue{v(C$|PWRonL|~Cs zERVUU2Z*SZY0g^>LoERrIpElHM)&73w=B3C62&ZV)|D8lgj0c_F7q~Bjvr%f-c;!dRk(AaJ{ovu$mH6L{Zd8CjP^`Xg7|K3Qdl*OxL6 zo+%r=_O;6joZUFo4vbwIRptdqrYLv^kgP>hM=Ts>zVORD1Alt*cKk$V$Tp`ZaRbvd zXQ(DN(S7TMxdZwKsG^Br-BU&p&T6L%2q2fdqt5R3NdrhXpQ{caofr+3e>gIbBSoGd*R{b? zg#>eQ9V6n%h*Wly z+;6OH+db-m2uLK6%ek(`nLkb)z=*V+7W#73KkagSrf7i^A6-yNbr1Q3)Ga|a1M z8~zkH`*`dh2&WVbxPXI(efY^}%7je1%KVM_B0-4A_k}x9WOPYKbpQj34m-nwjFF}8 zNrdit>UoREdBxc0|8eQ|?``k2GDr$Ss1dk3MEctnpYmgWnMvwuvLS9h-3+cQ@nK|M z%?R7iLXnP0RNn!h{VzCB)YG_4N4y~UnINJQmCboXv{NE@cG|2=B9QMxqkHx-jh#{0 zYBR*XW{cfBQSEOZk}8<4Dg`&%WfT{is105a>}H8&FGC9RlGmg0l`|fz=qh8mtPfzl)9WkapV$sArza&#)b~ z)B>5O05=Ig0PS}iTmVmAf^M-npJbjB659i#>-AS&PHs=PzC z%ApngrlfF!>f5|dles$8!nkc*LR%R}G}P`gR(R!}+e?bKs;&Ew+XVJjWSPT#}fPXq=2MR^X({nCpnt@z6mF-=1gSjiJCWkD62%kYlFBEaT%QMs@YE#u; z#hTF6$wQc2A|GD1smc#c%sWuxI$_k)_n28q-xAohN)J`Kd)OcB#5#Oay@Eu)g1e+5gD0eFN^LDxnIsAbl;a{;L zjYtY{@8oA_A7wr*OElx_%q<|_j_S{+%%t_kon^99A1JF_MO9lPuvcLsLrY3saW{vkO*j$g)PLT)kcLOhJ<(W8=-;LbXrKlm4A36 zJPp8%b{iIWW^I!@9e)P*hjNM&?ieB|3ynNRZAWa$mYEhjxFn8I;Mts`77r5m2mhRZ zfZ9d`^&5qh_-iWOp4it2-Wdr=aXKC8z4OwCa&`ql!E&=eE+NP!a%3B zaCgZ;gUPG7>P{SX=i?32s%p90{hf5$78y~o9^b7}j8t#W;zT~*59uSLO97&}zbt-R zJCFcQ3lg-reIt9TY(eb6VQivg--+pc)0^1F9`y}byFn<16V{KaJ0+s2uK=|`SB(XM zC*Fxx*u?2?u!laAoM6)bdEc|;D0=&D)WS>lHBWDXSQiw6!D>6iiOC$7v`X{u@TPA3 z?j&9(0y21GNn6`OPfDZH?slti^g=d}bZ(XGGg=o8K^t8>GXcx~uT<$HY9Bov4epO! z9x=zmO|R+r#8hkle6$na6F*(!zO{u&qil%Pw$tk7N=50g0-ywDd1e?O5|VPab6-3y zQwe5Vivq4zC8ew25<0>X}SU zZ=ST|;r1P*#t6(Nb)%Ya{oO|>3>7ApE{^a%BG@NT?j6~vw$DCgj4!l56pZ8?x0o*o zi80IP{8hAIfb^Q-_L{c<{=WVTPIy7D^+W4;vv3>zM$Kh~T2I@g|2BG2%v-O@sGScBwCKWR6kUQ(C8h2P|~{ zyEInc#3j2$BgI4|{Ed!vt0CNoZ*e&bl*a(=;?v6Dsql?kI=bs@0R*>*!HRd(|BOw} z4~x#V*1mc}fHjPLf+y)&$I?gcdWI>>*LBwilWf%P&D_@N?{H?gSpC_QfGt}YC6Cr$ zzqq>GY;p|LdXD+Vg0I#QY3z;B#a3HQZvWYgxDPhv7X)4d zzzVfw!hE$X{jxp`&`yd-i>qxcV8|#ipX0q9YQIN=Q2-8)_rc)RVm^fCOA4^bG9|L$ z4=ubvUS<0%^Kvx?AizKbsGp0_YhNr+U65xB)E+0}o?ZJhm@hz!uY4Kp@6jeSMEfc^ zKK@}1b_%$r(?n~@-=mcm12s8gPTW6(9b*COT|OIL)5wiT8smo}lvGysY)fjVkWM=~KF|ftRy5 z(}BTT>vHge4T^x2u(9^IFiLUOV4dmo*3Mt-IZJ#BY%AVxRLdlGlKWLJUZj0Nyf zp(~{ztOrO@>Pm`x7vjg#T&;TY&PAeexcJ`Q<4fvk0omU-N$Rwyt2reqv;DJ`bQ?n& z2l$n3`VAEkrBVK&hh}vb8#8AzF(&ml><90Z02S#=`V3exq$&EfaDwLl=;(j5tE)SN zfL37`MPCR6m^6D9K;bn$9R1!c41NY^4OWoq9~~2 zZB&lNZ?F+yN-BXwtcix+_Fff4$S|7N4nbOf;+W&uH}?lxj4Qj>Dj`@$4o z=qZ0vpC7b!(~BH-wCTN?9iAneQMuaU-~2kn)OqEyK4PCNK>a!p^>YXu zITsjvF!Hsb>*PIiUHbIjJ0^1Kr_axRonQxEOt%@+=8q=41ov)9jiCqlO(V|Vuc(j4 zen$PKZk@fx)=BS$z6hPxj<4(=n7jeF{TqZUza23RJ8&YSyNcmIFbTNzJI}KJPr&+q#cf$Qn=C$y|R<&*uUqwrRp@|@ zYAmm)w$fwvH7SqZVVC|3FJkx$O`^*qH82;PZ$OvYUo{D_`o11JFnn)=$s2w@(!Eai zMtFOLeoZX)`kn0<3yB;q&Kb)Q{mwG12;KL`%y{dLCpQA}-w;wXaIH1k^J8f}Cs@6T zIlqB~PiFD$^t@1|-NyhJJrvlUzhgW4+EC*iy_i+L;m1p`Nc<=|vF*7Kt>6%m>>~IFCu#nbnzV24=-Hr@Pb?G#luD!xyDVUx2JVk{P?eX}oi`dM(@>h(F^y2I`;U&4n|$$Q;)zR&ykGYD<;ujsJB zYPK70VWuwh3Tv=IjVPy36x9T!dJImtbETDjC*S6~l7R%~8Q|(|g}2{_f2*yXk-*Qf zK+NxvZXsW9%^cT82G0J9F1hk{j~>H#r@ftaIsih~9;+oDxhtq?1a#C!rj`~(p?;%2 zR`uSncEVDMpYKj9gT8`Uq~MEh z&Z&LucicRsAGZLfG|^-v$CHo#x9k5t%;%!d zRaY(GBx2x9- b-v9miSjDH97l&ZcFoC}(0J|$sF0TGB+z$(L literal 0 HcmV?d00001 diff --git a/packages/tandem-designer/design/split-2.svg b/packages/tandem-designer/design/split-2.svg new file mode 100644 index 000000000..289b409b7 --- /dev/null +++ b/packages/tandem-designer/design/split-2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/tandem-designer/index.d.ts b/packages/tandem-designer/index.d.ts new file mode 100644 index 000000000..3bd16e178 --- /dev/null +++ b/packages/tandem-designer/index.d.ts @@ -0,0 +1 @@ +export * from "./src"; diff --git a/packages/tandem-designer/index.js b/packages/tandem-designer/index.js new file mode 100644 index 000000000..58b33d298 --- /dev/null +++ b/packages/tandem-designer/index.js @@ -0,0 +1 @@ +module.exports = require("./lib/front-end/index.bundle.js"); diff --git a/packages/tandem-designer/package.json b/packages/tandem-designer/package.json new file mode 100644 index 000000000..392ebc4b4 --- /dev/null +++ b/packages/tandem-designer/package.json @@ -0,0 +1,83 @@ +{ + "name": "tandem-designer", + "version": "10.1.35", + "description": "Visual editor for web components", + "main": "index.js", + "scripts": { + "test": "mocha ./lib/**/*-test.js", + "build": "npm run build:types && webpack", + "build:types": "paperclip-react-compiler \"src/**/*.pc\" --definition --write", + "build:watch": "concurrently \"paperclip-react-compiler \\\"src/**/*.pc\\\" --definition --write --watch\" \"webpack --watch\"", + "start": "node lib/back-end/entry", + "tandem-preview-server": "tandem-webpack-preview-server --config=webpack-tandem-preview.config.js --include-script=node_modules/react/dist/react.min.js --include-script=node_modules/react-dom/dist/react-dom.min.js", + "clean": "rm -rf lib && rm -rf node_modules", + "prepare": "npm run build" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/crcn/aerial.git" + }, + "author": "", + "license": "GNU v3", + "bugs": { + "url": "https://github.com/tandemcode/aerial/issues" + }, + "homepage": "https://github.com/tandemcode/aerial#readme", + "devDependencies": { + "@types/chai": "^4.0.0", + "@types/express": "^4.0.36", + "@types/http-proxy": "^1.12.1", + "@types/lodash": "^4.14.106", + "@types/mocha": "^2.2.41", + "@types/react": "^16.4.11", + "@types/react-dom": "^16.0.7", + "@types/recompose": "0.x.x", + "@types/request": "^2.0.0", + "buffer": "^6.0.3", + "chai": "^4.0.2", + "concurrently": "4.1.x", + "css-loader": "^0.28.4", + "file-loader": "^1.1.11", + "html-webpack-plugin": "^5.5.0", + "mocha": "^3.4.2", + "node-sass": "^7.0.1", + "paperclip-react-compiler": "^10.1.33", + "paperclip-react-loader": "^10.1.33", + "path-browserify": "^1.0.1", + "process": "^0.11.10", + "react-hot-loader": "^3.1.2", + "sass-loader": "^12.6.0", + "script-ext-html-webpack-plugin": "^2.1.3", + "stream-browserify": "^3.0.0", + "style-loader": "^0.18.2", + "text-loader": "^0.0.1", + "ts-loader": "^5.1.0", + "url-loader": "^1.0.1", + "util": "^0.12.4", + "webpack": "^5.72.0", + "webpack-cli": "^4.9.2", + "worker-loader": "^2.0.0", + "wrapper-webpack-plugin": "^2.0.0" + }, + "dependencies": { + "classnames": "^2.2.5", + "crc32": "^0.2.2", + "fsbox": "^10.1.33", + "lodash": "^4.17.10", + "mime-types": "^2.1.20", + "paperclip": "^10.1.33", + "paperclip-migrator": "^10.1.33", + "react": "^16.4.2", + "react-dnd": "^5.0.0", + "react-dnd-html5-backend": "^5.0.1", + "react-dom": "^16.4.2", + "react-hammerjs": "^1.0.1", + "recompose": "^0.28.2", + "redux": "^4.0.0", + "redux-saga": "^0.16.0", + "scroll-into-view-if-needed": "^2.2.16", + "tandem-common": "^10.1.33", + "tandem-starter-kits": "^10.1.33" + }, + "gitHead": "62ff73f435d5ddc97b8ff23b2356ed36f69c1486" +} diff --git a/packages/tandem-designer/src/actions/bottom-left-corner.svg b/packages/tandem-designer/src/actions/bottom-left-corner.svg new file mode 100644 index 000000000..49735270e --- /dev/null +++ b/packages/tandem-designer/src/actions/bottom-left-corner.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/tandem-designer/src/actions/index.ts b/packages/tandem-designer/src/actions/index.ts new file mode 100644 index 000000000..59c6a79c1 --- /dev/null +++ b/packages/tandem-designer/src/actions/index.ts @@ -0,0 +1,2030 @@ +import { Action } from "redux"; +import * as React from "react"; +import { + Directory, + Point, + Bounds, + Struct, + StructReference, + TreeNode, + File, + KeyValue, + TreeMoveOffset, + FSItem, + FSItemTagNames, +} from "tandem-common"; +import { publicActionCreator } from "tandem-common"; +import { + ComputedDisplayInfo, + SyntheticNativeNodeMap, + SyntheticVisibleNode, + PCNodeClip, + PCVariantTrigger, + PCVariable, + Frame, + PCComponent, + PCVariant, + PCVariantTriggerSource, + PCVariableType, + PCMediaQuery, + PCQueryType, + PCMediaQueryCondition, + PCQuery, + PCVariableQueryCondition, +} from "paperclip"; +import { RegisteredComponent } from ".."; +import { + FrameMode, + ToolType, + EditorWindow, + ProjectConfig, + ProjectInfo, + BaseQuickSearchResult, + QuickSearchResult, + ScriptProcess, + ScriptProcessLog, + Unloader, + AddFileType, +} from "../state"; +import { InspectorNode } from "paperclip"; +import { ProjectTemplate } from "tandem-starter-kits"; + +export const PROJECT_LOADED = "PROJECT_LOADED"; +export const ACTIVE_FILE_CHANGED = "ACTIVE_FILE_CHANGED"; +export const SYNTHETIC_WINDOW_OPENED = "SYNTHETIC_WINDOW_OPENED"; +export const PROJECT_DIRECTORY_LOADED = "PROJECT_DIRECTORY_LOADED"; +export const DOCUMENT_RENDERED = "DOCUMENT_RENDERERED"; + +export const CANVAS_TOOL_OVERLAY_MOUSE_LEAVE = + "CANVAS_TOOL_OVERLAY_MOUSE_LEAVE"; +export const CANVAS_TOOL_OVERLAY_MOUSE_PAN_START = + "CANVAS_TOOL_OVERLAY_MOUSE_PAN_START"; +export const CANVAS_TOOL_OVERLAY_MOUSE_PANNING = + "CANVAS_TOOL_OVERLAY_MOUSE_PANNING"; +export const CANVAS_TOOL_OVERLAY_MOUSE_PAN_END = + "CANVAS_TOOL_OVERLAY_MOUSE_PAN_END"; +export const CANVAS_TOOL_OVERLAY_MOUSE_DOUBLE_CLICKED = + "CANVAS_TOOL_OVERLAY_MOUSE_DOUBLE_CLICKED"; +export const CANVAS_TOOL_WINDOW_BACKGROUND_CLICKED = + "CANVAS_TOOL_WINDOW_BACKGROUND_CLICKED"; +export const CANVAS_TOOL_WINDOW_KEY_DOWN = "CANVAS_TOOL_WINDOW_KEY_DOWN"; +export const CANVAS_TOOL_ARTBOARD_TITLE_CLICKED = + "CANVAS_TOOL_ARTBOARD_TITLE_CLICKED"; +export const CANVAS_TOOL_PREVIEW_BUTTON_CLICKED = + "CANVAS_TOOL_PREVIEW_BUTTON_CLICKED"; +export const FILE_NAVIGATOR_ITEM_CLICKED = "FILE_NAVIGATOR_ITEM_CLICKED"; +export const FILE_NAVIGATOR_ITEM_DOUBLE_CLICKED = + "FILE_NAVIGATOR_ITEM_DOUBLE_CLICKED"; +export const FILE_NAVIGATOR_ITEM_BLURRED = "FILE_NAVIGATOR_ITEM_BLURRED"; +export const FILE_NAVIGATOR_NEW_FILE_CLICKED = + "FILE_NAVIGATOR_NEW_FILE_CLICKED"; +export const FILE_NAVIGATOR_NEW_DIRECTORY_CLICKED = + "FILE_NAVIGATOR_NEW_DIRECTORY_CLICKED"; +export const FILE_NAVIGATOR_TOGGLE_DIRECTORY_CLICKED = + "FILE_NAVIGATOR_TOGGLE_DIRECTORY_CLICKED"; +export const FILE_NAVIGATOR_BASENAME_CHANGED = + "FILE_NAVIGATOR_BASENAME_CHANGED"; +export const FILE_NAVIGATOR_NEW_FILE_ENTERED = + "FILE_NAVIGATOR_NEW_FILE_ENTERED"; +export const FILE_NAVIGATOR_DROPPED_ITEM = "FILE_NAVIGATOR_DROPPED_ITEM"; +export const TOOLBAR_TOOL_CLICKED = "TOOLBAR_TOOL_CLICKED"; +export const EDITOR_TAB_CLICKED = "EDITOR_TAB_CLICKED"; +export const EDITOR_TAB_RIGHT_CLICKED = "EDITOR_TAB_RIGHT_CLICKED"; +export const EDITOR_TAB_CLOSE_BUTTON_CLICKED = + "EDITOR_TAB_CLOSE_BUTTON_CLICKED"; +export const EDITOR_TAB_CONTEXT_MENU_OPEN_IN_BOTTOM_OPTION_CLICKED = + "EDITOR_TAB_CONTEXT_MENU_OPEN_IN_BOTTOM_OPTION_CLICKED"; +export const MODULE_CONTEXT_MENU_CLOSE_OPTION_CLICKED = + "MODULE_CONTEXT_MENU_CLOSE_OPTION_CLICKED"; +export const OPEN_FILE_ITEM_CLICKED = "OPEN_FILE_ITEM_CLICKED"; +export const OPEN_FILE_ITEM_CLOSE_CLICKED = "OPEN_FILE_ITEM_CLOSE_CLICKED"; +export const CANVAS_MOUNTED = "CANVAS_MOUNTED"; +export const CANVAS_MOUSE_MOVED = "CANVAS_MOUSE_MOVED"; +export const CANVAS_DRAGGED_OVER = "CANVAS_DRAGGED_OVER"; +export const CANVAS_MOUSE_CLICKED = "CANVAS_MOUSE_CLICKED"; +export const CANVAS_MOUSE_DOUBLE_CLICKED = "CANVAS_MOUSE_DOUBLE_CLICKED"; +export const CANVAS_WHEEL = "CANVAS_WHEEL"; +export const CANVAS_MOTION_RESTED = "CANVAS_MOTION_RESTED"; +export const CANVAS_DROPPED_ITEM = "CANVAS_DROPPED_ITEM"; +export const ADD_VARIANT_BUTTON_CLICKED = "ADD_VARIANT_BUTTON_CLICKED"; +export const REMOVE_VARIANT_BUTTON_CLICKED = "REMOVE_VARIANT_BUTTON_CLICKED"; +export const VARIANT_DEFAULT_SWITCH_CLICKED = "VARIANT_DEFAULT_SWITCH_CLICKED"; +export const VARIANT_LABEL_CHANGED = "VARIANT_LABEL_CHANGED"; +export const ADD_STYLE_BUTTON_CLICKED = "ADD_STYLE_BUTTON_CLICKED"; +export const NEW_STYLE_VARIANT_CONFIRMED = "NEW_STYLE_VARIANT_CONFIRMED"; +export const NEW_STYLE_VARIANT_BUTTON_CLICKED = + "NEW_STYLE_VARIANT_BUTTON_CLICKED"; +export const PROMPT_OK_BUTTON_CLICKED = "PROMPT_OK_BUTTON_CLICKED"; +export const PROMPT_CANCEL_BUTTON_CLICKED = "PROMPT_CANCEL_BUTTON_CLICKED"; +export const REMOVE_STYLE_BUTTON_CLICKED = "ADD_STYLE_BUTTON_CLICKED"; +export const EDIT_VARIANT_NAME_BUTTON_CLICKED = + "EDIT_VARIANT_NAME_BUTTON_CLICKED"; +export const EDIT_VARIANT_NAME_CONFIRMED = "EDIT_VARIANT_NAME_CONFIRMED"; +export const STYLE_VARIANT_DROPDOWN_CHANGED = "STYLE_VARIANT_DROPDOWN_CHANGED"; +export const ADD_VARIABLE_BUTTON_CLICKED = "ADD_VARIABLE_BUTTON_CLICKED"; +export const QUICK_SEARCH_FILTER_CHANGED = "QUICK_SEARCH_FILTER_CHANGED"; +export const QUICK_SEARCH_RESULT_LOADED = "QUICK_SEARCH_RESULT_LOADED"; +export const VARIABLE_LABEL_CHANGE_COMPLETED = + "VARIABLE_LABEL_CHANGE_COMPLETED"; +export const VARIABLE_VALUE_CHANGED = "VARIABLE_VALUE_CHANGED"; +export const VARIABLE_VALUE_CHANGE_COMPLETED = + "VARIABLE_VALUE_CHANGE_COMPLETED"; +export const COMPONENT_INSTANCE_VARIANT_TOGGLED = + "COMPONENT_INSTANCE_VARIANT_TOGGLED"; +export const INSTANCE_VARIANT_RESET_CLICKED = "INSTANCE_VARIANT_RESET_CLICKED"; +export const FRAME_MODE_CHANGE_COMPLETE = "FRAME_MODE_CHANGE_COMPLETE"; +export const RESIZER_PATH_MOUSE_MOVED = "RESIZER_PATH_MOUSE_MOVED"; +export const RESIZER_PATH_MOUSE_STOPPED_MOVING = + "RESIZER_PATH_MOUSE_STOPPED_MOVING"; +export const RESIZER_MOVED = "RESIZER_MOVED"; +export const RESIZER_STOPPED_MOVING = "RESIZER_STOPPED_MOVING"; +export const COMPONENT_PICKER_BACKGROUND_CLICK = + "COMPONENT_PICKER_BACKGROUND_CLICK"; +export const UNHANDLED_ERROR = "UNHANDLED_ERROR"; +export const COMPONENT_PICKER_ITEM_CLICK = "COMPONENT_PICKER_ITEM_CLICK"; +export const RESIZER_MOUSE_DOWN = "RESIZER_MOUSE_DOWN"; +export const RESIZER_START_DRGG = "RESIZER_START_DRGG"; +export const TD_PROJECT_LOADED = "TD_PROJECT_LOADED"; +export const CONFIRM_CLOSE_WINDOW = "CONFIRM_CLOSE_WINDOW"; +export const PROJECT_INFO_LOADED = "PROJECT_INFO_LOADED"; +export const SHORTCUT_ZOOM_IN_KEY_DOWN = "SHORTCUT_ZOOM_IN_KEY_DOWN"; +export const SHORTCUT_TOGGLE_PANEL = "SHORTCUT_TOGGLE_PANEL"; +export const SHORTCUT_ZOOM_OUT_KEY_DOWN = "SHORTCUT_ZOOM_OUT_KEY_DOWN"; +export const SHORTCUT_ESCAPE_KEY_DOWN = "SHORTCUT_ESCAPE_KEY_DOWN"; +export const SHORTCUT_SAVE_KEY_DOWN = "SHORTCUT_SAVE_KEY_DOWN"; +export const SHORTCUT_QUICK_SEARCH_KEY_DOWN = "SHORTCUT_QUICK_SEARCH_KEY_DOWN"; +export const SHORTCUT_DELETE_KEY_DOWN = "SHORTCUT_DELETE_KEY_DOWN"; +export const SHORTCUT_UNDO_KEY_DOWN = "SHORTCUT_UNDO_KEY_DOWN"; +export const SHORTCUT_REDO_KEY_DOWN = "SHORTCUT_REDO_KEY_DOWN"; +export const SHORTCUT_R_KEY_DOWN = "SHORTCUT_R_KEY_DOWN"; +export const SHORTCUT_C_KEY_DOWN = "SHORTCUT_C_KEY_DOWN"; +export const SHORTCUT_T_KEY_DOWN = "SHORTCUT_T_KEY_DOWN"; +export const SHORTCUT_SELECT_NEXT_TAB = "SHORTCUT_SELECT_NEXT_TAB"; +export const SHORTCUT_SELECT_PREVIOUS_TAB = "SHORTCUT_SELECT_PREVIOUS_TAB"; +export const SHORTCUT_CLOSE_CURRENT_TAB = "SHORTCUT_CLOSE_CURRENT_TAB"; +export const OPEN_TEXT_EDITOR_BUTTON_CLICKED = + "OPEN_TEXT_EDITOR_BUTTON_CLICKED"; +export const SHORTCUT_CONVERT_TO_COMPONENT_KEY_DOWN = + "SHORTCUT_CONVERT_TO_COMPONENT_KEY_DOWN"; +export const SHORTCUT_WRAP_IN_SLOT_KEY_DOWN = "SHORTCUT_WRAP_IN_SLOT_KEY_DOWN"; +export const SHORTCUT_TOGGLE_SIDEBAR = "SHORTCUT_TOGGLE_SIDEBAR"; +export const INHERIT_PANE_ADD_BUTTON_CLICK = "INHERIT_PANE_ADD_BUTTON_CLICK"; +export const FILE_ITEM_CONTEXT_MENU_DELETE_CLICKED = + "FILE_ITEM_CONTEXT_MENU_DELETE_CLICKED"; +export const FILE_ITEM_CONTEXT_MENU_OPEN_CLICKED = + "FILE_ITEM_CONTEXT_MENU_OPEN_CLICKED"; +export const FILE_ITEM_CONTEXT_MENU_OPEN_IN_FINDER_CLICKED = + "FILE_ITEM_CONTEXT_MENU_OPEN_IN_FINDER_CLICKED"; +export const FILE_ITEM_CONTEXT_MENU_COPY_PATH_CLICKED = + "FILE_ITEM_CONTEXT_MENU_COPY_PATH_CLICKED"; +export const FILE_ITEM_CONTEXT_MENU_RENAME_CLICKED = + "FILE_ITEM_CONTEXT_MENU_RENAME_CLICKED"; +export const FILE_ITEM_CONTEXT_MENU_CREATE_DIRECTORY_CLICKED = + "FILE_ITEM_CONTEXT_MENU_CREATE_DIRECTORY_CLICKED"; +export const FILE_ITEM_CONTEXT_MENU_CREATE_BLANK_FILE_CLICKED = + "FILE_ITEM_CONTEXT_MENU_CREATE_BLANK_FILE_CLICKED"; +export const FILE_ITEM_CONTEXT_MENU_CREATE_COMPONENT_FILE_CLICKED = + "FILE_ITEM_CONTEXT_MENU_CREATE_COMPONENT_FILE_CLICKED"; +export const INSPECTOR_NODE_CONTEXT_MENU_CONVERT_TO_COMPONENT_CLICKED = + "INSPECTOR_NODE_CONTEXT_MENU_CONVERT_TO_COMPONENT_CLICKED"; +export const INSPECTOR_NODE_CONTEXT_MENU_WRAP_IN_ELEMENT_CLICKED = + "INSPECTOR_NODE_CONTEXT_MENU_WRAP_IN_ELEMENT_CLICKED"; +export const INSPECTOR_NODE_CONTEXT_MENU_CONVERT_TO_STYLE_MIXIN_CLICKED = + "INSPECTOR_NODE_CONTEXT_MENU_CONVERT_TO_STYLE_MIXIN_CLICKED"; +export const INSPECTOR_NODE_CONTEXT_MENU_CONVERT_TEXT_STYLES_TO_MIXIN_CLICKED = + "INSPECTOR_NODE_CONTEXT_MENU_CONVERT_TEXT_STYLES_TO_MIXIN_CLICKED"; +export const INSPECTOR_NODE_CONTEXT_MENU_REMOVE_CLICKED = + "INSPECTOR_NODE_CONTEXT_MENU_REMOVE_CLICKED"; +export const INSPECTOR_NODE_CONTEXT_MENU_RENAME_CLICKED = + "INSPECTOR_NODE_CONTEXT_MENU_RENAME_CLICKED"; +export const INSPECTOR_NODE_CONTEXT_MENU_COPY_CLICKED = + "INSPECTOR_NODE_CONTEXT_MENU_COPYCLICKED"; +export const INSPECTOR_NODE_CONTEXT_MENU_PASTE_CLICKED = + "INSPECTOR_NODE_CONTEXT_MENU_PASTE_CLICKED"; +export const INSPECTOR_NODE_CONTEXT_MENU_WRAP_IN_SLOT_CLICKED = + "INSPECTOR_NODE_CONTEXT_MENU_WRAP_IN_SLOT_CLICKED"; +export const INSPECTOR_NODE_CONTEXT_MENU_SELECT_PARENT_CLICKED = + "INSPECTOR_NODE_CONTEXT_MENU_SELECT_PARENT_CLICKED"; +export const INSPECTOR_NODE_CONTEXT_MENU_SELECT_SOURCE_NODE_CLICKED = + "INSPECTOR_NODE_CONTEXT_MENU_SELECT_SOURCE_NODE_CLICKED"; +export const INSPECTOR_NODE_CONTEXT_MENU_SHOW_IN_CANVAS_CLICKED = + "INSPECTOR_NODE_CONTEXT_MENU_SHOW_IN_CANVAS_CLICKED"; +export const INHERIT_PANE_REMOVE_BUTTON_CLICK = + "INHERIT_PANE_REMOVE_BUTTON_CLICK"; +export const EXPORT_NAME_CHANGED = "EXPORT_NAME_CHANGED"; +export const ACTIVE_EDITOR_URI_DIRS_LOADED = "ACTIVE_EDITOR_URI_DIRS_LOADED"; +export const INHERIT_ITEM_COMPONENT_TYPE_CHANGE_COMPLETE = + "INHERIT_ITEM_COMPONENT_TYPE_CHANGE_COMPLETE"; + +export const INHERIT_ITEM_CLICK = "INHERIT_ITEM_CLICK"; +export const INSERT_TOOL_FINISHED = "INSERT_TOOL_FINISHED"; +export const INSPECTOR_NODES_PASTED = "INSPECTOR_NODES_PASTED"; +export const APP_LOADED = "APP_LOADED"; +export const SAVED_FILE = "SAVED_FILE"; +export const SAVED_ALL_FILES = "SAVED_ALL_FILES"; +export const FRAME_BOUNDS_CHANGED = "FRAME_BOUNDS_CHANGED"; +export const FRAME_BOUNDS_CHANGE_COMPLETED = "FRAME_BOUNDS_CHANGE_COMPLETED"; +export const NEW_FILE_ENTERED = "NEW_FILE_ENTERED"; +export const PROJECT_DIRECTORY_DIR_LOADED = "PROJECT_DIRECTORY_DIR_LOADED"; +export const NEW_DIRECTORY_ENTERED = "NEW_DIRECTORY_ENTERED"; +export const RAW_CSS_TEXT_CHANGED = "RAW_CSS_TEXT_CHANGED"; +export const CSS_PROPERTY_CHANGED = "CSS_PROPERTY_CHANGED"; +export const CSS_PROPERTIES_CHANGED = "CSS_PROPERTIES_CHANGED"; +export const QUICK_SEARCH_RESULT_ITEM_SPLIT_BUTTON_CLICKED = + "QUICK_SEARCH_RESULT_ITEM_SPLIT_BUTTON_CLICKED"; +export const CSS_PROPERTY_CHANGE_COMPLETED = "CSS_PROPERTY_CHANGE_COMPLETED"; +export const CSS_PROPERTIES_CHANGE_COMPLETED = + "CSS_PROPERTIES_CHANGE_COMPLETED"; +export const ATTRIBUTE_CHANGED = "ATTRIBUTE_CHANGED"; +export const SLOT_TOGGLE_CLICK = "SLOT_TOGGLE_CLICK"; +export const TEXT_VALUE_CHANGED = "TEXT_VALUE_CHANGED"; +export const ELEMENT_TYPE_CHANGED = "ELEMENT_TYPE_CHANGED"; +export const FILE_ITEM_RIGHT_CLICKED = "FILE_ITEM_RIGHT_CLICKED"; +export const CANVAS_RIGHT_CLICKED = "CANVAS_RIGHT_CLICKED"; +export const PC_LAYER_RIGHT_CLICKED = "PC_LAYER_RIGHT_CLICKED"; +export const PC_LAYER_DOUBLE_CLICKED = "PC_LAYER_DOUBLE_CLICKED"; +export const SOURCE_INSPECTOR_LAYER_CLICKED = "SOURCE_INSPECTOR_LAYER_CLICKED"; +export const SOURCE_INSPECTOR_LAYER_ARROW_CLICKED = + "SOURCE_INSPECTOR_LAYER_ARROW_CLICKED"; +export const SOURCE_INSPECTOR_LAYER_LABEL_CHANGED = + "SOURCE_INSPECTOR_LAYER_LABEL_CHANGED"; +export const SOURCE_INSPECTOR_LAYER_DROPPED = "SOURCE_INSPECTOR_LAYER_DROPPED"; +export const NEW_FILE_ADDED = "NEW_FILE_ADDED"; +export const QUICK_SEARCH_ITEM_CLICKED = "QUICK_SEARCH_ITEM_CLICKED"; +export const QUICK_SEARCH_INPUT_ENTERED = "QUICK_SEARCH_INPUT_ENTERED"; +export const QUICK_SEARCH_BACKGROUND_CLICK = "QUICK_SEARCH_BACKGROUND_CLICK"; +export const NEW_VARIANT_NAME_ENTERED = "NEW_VARIANT_NAME_ENTERED"; +export const COMPONENT_VARIANT_REMOVED = "COMPONENT_VARIANT_REMOVED"; +export const COMPONENT_VARIANT_NAME_CHANGED = "COMPONENT_VARIANT_NAME_CHANGED"; +export const COMPONENT_VARIANT_NAME_CLICKED = "COMPONENT_VARIANT_NAME_CLICKED"; +export const OPEN_PROJECT_BUTTON_CLICKED = "OPEN_PROJECT_BUTTON_CLICKED"; +export const CREATE_PROJECT_BUTTON_CLICKED = "CREATE_PROJECT_BUTTON_CLICKED"; +export const OPEN_CONTROLLER_BUTTON_CLICKED = "OPEN_CONTROLLER_BUTTON_CLICKED"; +export const ADD_COMPONENT_CONTROLLER_BUTTON_CLICKED = + "ADD_COMPONENT_CONTROLLER_BUTTON_CLICKED"; +export const REMOVE_COMPONENT_CONTROLLER_BUTTON_CLICKED = + "REMOVE_COMPONENT_CONTROLLER_BUTTON_CLICKED"; +export const COMPONENT_CONTROLLER_PICKED = "COMPONENT_CONTROLLER_PICKED"; +export const COMPONENT_VARIANT_NAME_DEFAULT_TOGGLE_CLICK = + "COMPONENT_VARIANT_NAME_DEFAULT_TOGGLE_CLICK"; +export const ELEMENT_VARIANT_TOGGLED = "ELEMENT_VARIANT_TOGGLED"; + +export const CONFIRM_SAVE_CHANGES = "CONFIRM_SAVE_CHANGES"; +export const CHROME_HEADER_MOUSE_DOWN = "CHROME_HEADER_MOUSE_DOWN"; +export const CHROME_CLOSE_BUTTON_CLICKED = "CHROME_CLOSE_BUTTON_CLICKED"; +export const CHROME_MINIMIZE_BUTTON_CLICKED = "CHROME_MINIMIZE_BUTTON_CLICKED"; +export const CHROME_MAXIMIZE_BUTTON_CLICKED = "CHROME_MAXIMIZE_BUTTON_CLICKED"; +export const CSS_RESET_PROPERTY_OPTION_CLICKED = + "CSS_RESET_PROPERTY_OPTION_CLICKED"; +export const IMAGE_BROWSE_BUTTON_CLICKED = "IMAGE_BROWSE_BUTTON_CLICKED"; +export const BROWSE_DIRECTORY_CLICKED = "BROWSE_DIRECTORY_CLICKED"; +export const IMAGE_SOURCE_INPUT_CHANGED = "IMAGE_SOURCE_INPUT_CHANGED"; +export const IMAGE_PATH_PICKED = "IMAGE_PATH_PICKED"; +export const DIRECTORY_PATH_PICKED = "DIRECTORY_PATH_PICKED"; +export const CSS_INHERITED_FROM_LABEL_CLICKED = + "CSS_INHERITED_FROM_LABEL_CLICKED"; + +export const CANVAS_TEXT_EDIT_CHANGE_COMPLETE = + "CANVAS_TEXT_EDIT_CHANGE_COMPLETE"; + +export const ADD_VARIANT_TRIGGER_CLICKED = "ADD_VARIANT_TRIGGER_CLICKED"; +export const REMOVE_VARIANT_TRIGGER_CLICKED = "REMOVE_VARIANT_TRIGGER_CLICKED"; + +export const VARIANT_TRIGGER_SOURCE_CHANGED = "VARIANT_TRIGGER_SOURCE_CHANGED"; +export const VARIANT_TRIGGER_TARGET_CHANGED = "VARIANT_TRIGGER_TARGET_CHANGED"; +export const ADD_QUERY_BUTTON_CLICKED = "ADD_QUERY_BUTTON_CLICKED"; +export const REMOVE_MEDIA_QUERY_BUTTON_CLICK = + "REMOVE_MEDIA_QUERY_BUTTON_CLICK"; +export const QUERY_LABEL_CHANGED = "QUERY_LABEL_CHANGED"; +export const QUERY_CONDITION_CHANGED = "QUERY_CONDITION_CHANGED"; +export const QUERY_TYPE_CHANGED = "QUERY_TYPE_CHANGED"; +export const VARIABLE_QUERY_SOURCE_VARIABLE_CHANGE = + "VARIABLE_QUERY_SOURCE_VARIABLE_CHANGE"; +export const BREAD_CRUMB_CLICKED = "BREAD_CRUMB_CLICKED"; +export const BUILD_BUTTON_START_CLICKED = "BUILD_BUTTON_START_CLICKED"; +export const BUILD_BUTTON_STOP_CLICKED = "BUILD_BUTTON_STOP_CLICKED"; +export const BUILD_BUTTON_OPEN_APP_CLICKED = "BUILD_BUTTON_OPEN_APP_CLICKED"; +export const BUILD_BUTTON_CONFIGURE_CLICKED = "BUILD_BUTTON_CONFIGURE_CLICKED"; +export const CONFIGURE_BUILD_MODAL_X_CLICKED = + "CONFIGURE_BUILD_MODAL_X_CLICKED"; +export const CONFIGURE_BUILD_MODAL_BACKGROUND_CLICKED = + "CONFIGURE_BUILD_MODAL_BACKGROUND_CLICKED"; +export const SCRIPT_PROCESS_STARTED = "SCRIPT_PROCESS_STARTED"; +export const SCRIPT_PROCESS_LOGGED = "SCRIPT_PROCESS_LOGGED"; +export const SCRIPT_PROCESS_CLOSED = "SCRIPT_PROCESS_CLOSED"; +export const BUILD_SCRIPT_STARTED = "BUILD_SCRIPT_STARTED"; +export const CLOSE_BOTTOM_GUTTER_BUTTON_CLICKED = + "CLOSE_BOTTOM_GUTTER_BUTTON_CLICKED"; +export const BUILD_SCRIPT_CONFIG_CHANGED = "BUILD_SCRIPT_CONFIG_CHANGED"; +export const OPEN_APP_SCRIPT_CONFIG_CHANGED = "OPEN_APP_SCRIPT_CONFIG_CHANGED"; +export const UNLOADING = "UNLOADING"; +export const UNLOADER_CREATED = "UNLOADER_CREATED"; +export const UNLOADER_COMPLETED = "UNLOADER_COMPLETED"; +export const RELOAD = "RELOAD"; +export const LINK_CICKED = "LINK_CICKED"; + +export type WrappedEvent = { + sourceEvent: T; +} & Action; + +export type ProjectLoaded = { + uri: string; +} & Action; + +export type DocumentRendered = { + nativeMap: SyntheticNativeNodeMap; + documentId: string; + info: ComputedDisplayInfo; +} & Action; + +export type ModuleContextMenuOptionClicked = { + uri: string; +} & Action; + +export type FileNavigatorItemClicked = { + node: FSItem; +} & Action; + +export type FileNavigatorBasenameChanged = { + item: FSItem; + basename: string; +} & Action; + +export type OpenFilesItemClick = { + uri: string; +} & WrappedEvent>; + +export type ToolbarToolClicked = { + toolType: ToolType; +} & Action; + +export type RawCSSTextChanged = { + value: string; +} & Action; + +export type AddVariableButtonClicked = { + variableType: PCVariableType; +} & Action; + +export type VariablePropertyChanged = { + variable: PCVariable; + value: string; +} & Action; + +export type CSSPropertyChanged = { + name: string; + value: string; +} & Action; + +export type CSSPropertiesChanged = { + properties: KeyValue; +} & Action; + +export type AttributeChanged = { + name: string; + value: string; +} & Action; + +export type ProjectDirectoryLoaded = { + directory: Directory; +} & Action; + +export type ProjectInfoLoaded = { + info: ProjectInfo; +} & Action; + +export type CanvasToolOverlayMousePanStart = { + documentId: string; +} & Action; + +export type CanvasToolOverlayMousePanning = { + documentId: string; + deltaY: number; + velocityY: number; + center: Point; +} & Action; + +export type LinkClicked = { + url: string; +} & Action; + +export type ResetPropertyOptionClicked = { + property: string; +} & Action; + +export type CanvasMouseMoved = { + editorWindow: EditorWindow; +} & WrappedEvent; + +export type NewFileAdded = { + uri: string; + fileType: FSItemTagNames; +} & Action; + +export type CanvasToolOverlayMousePanEnd = { + documentId: string; +} & Action; + +export type CanvasTextEditChangeComplete = { + value: string; +} & Action; + +export type CanvasToolOverlayClicked = { + documentId: string; +} & WrappedEvent>; + +export type CanvasToolOverlayMouseMoved = {} & WrappedEvent< + React.MouseEvent +>; + +export type VariantTriggerSourceChanged = { + trigger: PCVariantTrigger; + value: PCVariantTriggerSource; +} & Action; + +export type VariantTriggerTargetChanged = { + trigger: PCVariantTrigger; + value: PCVariant; +} & Action; + +export type ElementVariantToggled = { + node: SyntheticVisibleNode; + newVariants: string[]; +} & Action; + +export type CanvasWheel = { + canvasWidth: number; + canvasHeight: number; + type: string; + metaKey: boolean; + ctrlKey: boolean; + deltaX: number; + deltaY: number; +} & Action; + +export type TreeLayerMouseOver = { + node: TreeNode; +} & Action; + +export type ProjectDirectoryDirLoaded = { + items: FSItem[]; +} & Action; + +export type ImagePathPicked = { + filePath: string; +} & Action; + +export type DirectoryPathPicked = { + directoryPath: string; +} & Action; + +export type StyleVariantDropdownChanged = { + variant: PCVariant; + component: PCComponent; +} & Action; + +export type TreeLayerLabelChanged = { + label: string; + node: TreeNode; +} & Action; + +export type TreeLayerDroppedNode = { + node: TreeNode; + targetNode: TreeNode; + offset?: TreeMoveOffset; +} & Action; + +export type SourceInspectorLayerDropped = { + source: InspectorNode; + target: InspectorNode; + offset: TreeMoveOffset; +} & Action; + +export type QuickSearchResultItemSplitButtonClicked = { + item: QuickSearchResult; +} & Action; + +export type QuickSearchFilterChanged = { + value: string; +} & Action; + +export type QuickSearchResultLoaded = { + matches: QuickSearchResult[]; +} & Action; + +export type ScriptConfigChanged = { + script: string; +} & Action; + +export type TreeLayerClick = TreeLayerMouseOver & + WrappedEvent>; +export type TreeLayerExpandToggleClick = TreeLayerMouseOver; +export type TreeLayerMouseOut = TreeLayerMouseOver; + +export type InspectorLayerEvent = { + node: InspectorNode; +} & WrappedEvent>; + +export type InspectorLayerLabelChanged = { + node: InspectorNode; + label: string; +} & WrappedEvent>; + +export type BreadCrumbClicked = { + node: InspectorNode; +} & Action; + +export type CanvasMounted = { + element: HTMLDivElement; + fileUri: string; +} & Action; + +export type NewFileEntered = { + basename: string; +} & Action; + +export type CanvasToolWindowKeyDown = { + documentId: string; +} & WrappedEvent>; + +export type CanvasToolArtboardTitleClicked = { + frame: Frame; +} & WrappedEvent>; + +export type ImageSourceInputChanged = { + value: string; +} & Action; + +export type OpenTextEditorButtonClicked = { + uri: string; +} & Action; + +export type SlotToggleClick = {} & Action; + +export type NewVariantNameEntered = { + value: string; +} & Action; + +export type FileItemContextMenuAction = { + item: FSItem; +} & Action; + +export type InspectorNodeContextMenuAction = { + item: InspectorNode; +} & Action; + +export type ComponentVariantNameChanged = { + oldName: string; + newName: string; +} & Action; + +export type ComponentVariantNameClicked = { + name: string; +} & Action; + +export type CSSInheritedFromLabelClicked = { + inheritedFromNode: InspectorNode; +} & Action; + +export type ComponentControllerPicked = { + filePath: string; +} & Action; + +export type ComponentControllerItemClicked = { + relativePath: string; +} & Action; + +export type AddComponentControllerButtonClicked = { + defaultPath: string; +} & Action; + +export type InstanceVariantToggled = { + variant: PCVariant; +} & Action; + +export type ComponentVariantNameDefaultToggleClick = { + name: string; + value: boolean; +} & Action; + +export type PromptConfirmed = { + inputValue: string; +} & Action; + +export type PromptCancelButtonClicked = {} & Action; + +export type TextValueChanged = { + value: string; +} & Action; + +export type ConfirmCloseWindow = { + type: string; + closeWithoutSaving: boolean; + cancel: boolean; + save: boolean; +} & Action; + +export type ElementTypeChanged = { + value: string; +} & Action; + +export type UnhandledError = { + error: Error; +} & Action; + +export type ResizerPathMoved = { + originalBounds: Bounds; + newBounds: Bounds; + anchor: Point; +} & WrappedEvent; + +export type ResizerMoved = { + point: Point; +} & Action; + +export type AddQueryButtonClicked = { + queryType: PCQueryType; +} & Action; + +export type ResizerMouseDown = {} & WrappedEvent>; + +export type ResizerPathStoppedMoving = {} & ResizerPathMoved; + +export type QueryConditionChanged = { + target: PCQuery; + condition: Partial; +} & Action; + +export type QueryLabelChanged = { + target: PCQuery; + label?: string; +} & Action; + +export type QueryTypeChanged = { + target: PCQuery; + newType: PCQueryType; +} & Action; + +export type FrameModeChangeComplete = { + frame: Frame; + mode: FrameMode; +} & Action; + +export type SelectorDoubleClicked = { + nodeId: string; +} & WrappedEvent>; + +export type ShortcutKeyDown = {}; + +export type CreateProjectButtonClicked = { + files: Object; + directory: string; +} & Action; + +export type QuickSearchItemClicked = { + item: QuickSearchResult; +} & Action; + +export type ComponentPickerItemClick = { + component: PCComponent; +} & Action; + +export type RemoveComponentControllerButtonClicked = { + relativePath: string; +} & Action; + +export type SavedFile = { + uri: string; +} & Action; + +export type ScriptProcessStarted = { + process: ScriptProcess; +} & Action; + +export type ScriptProcessLogged = { + process: ScriptProcess; + log: ScriptProcessLog; +} & Action; + +export type ScriptProcessStopped = { + process: ScriptProcess; +} & Action; + +export type SavedAllFiles = {} & Action; + +export type InsertToolFinished = { + fileUri: string; + point: Point; +} & Action; + +export type SyntheticVisibleNodesPasted = { + clips: PCNodeClip[]; +} & Action; + +export type FileNavigatorLabelClicked = { + fileId: string; +} & Action; + +export type FrameBoundsChanged = { + newBounds: Bounds; +} & Action; + +export type FileItemRightClicked = { + event: React.MouseEvent; + type: string; + item: FSItem; +} & Action; + +export type CanvasRightClicked = { + event: React.MouseEvent; +} & Action; + +export type PCLayerRightClicked = { + item: InspectorNode; + event: React.MouseEvent; +} & Action; + +export type FileNavigatorNewFileEntered = { + directoryId: string; + basename: string; + insertType: FSItemTagNames; +} & Action; + +export type FileNavigatorDroppedItem = { + node: FSItem; + targetNode: FSItem; + offset: TreeMoveOffset; +} & Action; + +export type ExportNameChanged = { + value: string; +} & Action; + +export type VariableQuerySourceVariableChange = { + query: PCQuery; + variable: PCVariable; +} & Action; + +export type EditorTabClicked = { + event: React.MouseEvent; + uri: string; +} & Action; + +export type CanvasDroppedItem = { + editorUri: string; + item: RegisteredComponent | TreeNode; + point: Point; +} & Action; + +export type BuildScriptStarted = { + process: ScriptProcess; +} & Action; + +export type VariantClicked = { + variant: PCVariant; +} & Action; + +export type AddVariantTriggerClicked = {} & Action; + +export type RemoveVariantTriggerClicked = { + trigger: PCVariantTrigger; +} & Action; + +export type VariantDefaultSwitchClicked = { + variant: PCVariant; +} & Action; + +export type VariantLabelChanged = { + variant: PCVariant; + newLabel?: string; +} & Action; + +export type CanvasDraggingOver = { + item: any; + offset: Point; +} & Action; + +export type InheritPaneItemClick = { + componentId: string; +} & Action; + +export type InheritPaneRemoveButtonClick = { + componentId: string; +} & Action; + +export type InheritItemComponentTypeChangeComplete = { + oldComponentId: string; + newComponentId: string; +} & Action; + +export type InheritItemClick = { + componentId: string; +} & Action; + +export type UnloaderAction = { + unloader: Unloader; +} & Action; + +export type FileNavigatorNewFileClicked = { + fileType: AddFileType; +} & Action; + +export const quickSearchResultItemSplitButtonClick = ( + item: QuickSearchResult +): QuickSearchResultItemSplitButtonClicked => ({ + item, + type: QUICK_SEARCH_RESULT_ITEM_SPLIT_BUTTON_CLICKED, +}); + +export const fileNavigatorDroppedItem = ( + node: FSItem, + targetNode: Directory, + offset: TreeMoveOffset +): FileNavigatorDroppedItem => ({ + node, + targetNode, + offset, + type: FILE_NAVIGATOR_DROPPED_ITEM, +}); + +export const editorTabClicked = ( + event: React.MouseEvent, + uri: string +): EditorTabClicked => ({ + uri, + event, + type: EDITOR_TAB_CLICKED, +}); + +export const editorTabContextMenuOpenInBottomTabOptionClicked = + publicActionCreator( + (uri: string): ModuleContextMenuOptionClicked => ({ + type: EDITOR_TAB_CONTEXT_MENU_OPEN_IN_BOTTOM_OPTION_CLICKED, + uri, + }) + ); + +export const moduleContextMenuCloseOptionClicked = publicActionCreator( + (uri: string): ModuleContextMenuOptionClicked => ({ + type: MODULE_CONTEXT_MENU_CLOSE_OPTION_CLICKED, + uri, + }) +); + +export const editorTabRightClicked = ( + event: React.MouseEvent, + uri: string +): EditorTabClicked => ({ + uri, + event, + type: EDITOR_TAB_RIGHT_CLICKED, +}); + +export const fileItemContextMenuDeleteClicked = publicActionCreator( + (item: FSItem): FileItemContextMenuAction => ({ + item, + type: FILE_ITEM_CONTEXT_MENU_DELETE_CLICKED, + }) +); + +export const fileItemContextMenuCopyPathClicked = publicActionCreator( + (item: FSItem): FileItemContextMenuAction => ({ + item, + type: FILE_ITEM_CONTEXT_MENU_COPY_PATH_CLICKED, + }) +); + +export const variableQuerySourceVariableChange = ( + query: PCQuery, + variable: PCVariable +): VariableQuerySourceVariableChange => ({ + type: VARIABLE_QUERY_SOURCE_VARIABLE_CHANGE, + query, + variable, +}); + +export const queryConditionChanged = ( + target: PCQuery, + condition: Partial +): QueryConditionChanged => ({ + type: QUERY_CONDITION_CHANGED, + target, + condition, +}); + +export const queryLabelChanged = ( + target: PCQuery, + label?: string +): QueryLabelChanged => ({ + type: QUERY_LABEL_CHANGED, + target, + label, +}); + +export const breadCrumbClicked = (node: InspectorNode): BreadCrumbClicked => ({ + type: BREAD_CRUMB_CLICKED, + node, +}); + +export const queryTypeChanged = ( + target: PCQuery, + newType: PCQueryType +): QueryTypeChanged => ({ + type: QUERY_TYPE_CHANGED, + target, + newType, +}); + +export const fileItemContextMenuRenameClicked = publicActionCreator( + (item: FSItem): FileItemContextMenuAction => ({ + item, + type: FILE_ITEM_CONTEXT_MENU_RENAME_CLICKED, + }) +); + +export const fileItemContextMenuCreateDirectoryClicked = publicActionCreator( + (item: FSItem): FileItemContextMenuAction => ({ + item, + type: FILE_ITEM_CONTEXT_MENU_CREATE_DIRECTORY_CLICKED, + }) +); + +export const fileItemContextMenuCreateBlankFileClicked = publicActionCreator( + (item: FSItem): FileItemContextMenuAction => ({ + item, + type: FILE_ITEM_CONTEXT_MENU_CREATE_BLANK_FILE_CLICKED, + }) +); + +export const fileItemContextMenuCreateComponentFileClicked = + publicActionCreator( + (item: FSItem): FileItemContextMenuAction => ({ + item, + type: FILE_ITEM_CONTEXT_MENU_CREATE_COMPONENT_FILE_CLICKED, + }) + ); + +export const linkClicked = (url: string): LinkClicked => ({ + url, + type: LINK_CICKED, +}); + +export const fileItemContextMenuOpenClicked = publicActionCreator( + (item: FSItem): FileItemContextMenuAction => ({ + item, + type: FILE_ITEM_CONTEXT_MENU_OPEN_CLICKED, + }) +); + +export const buildButtonStartClicked = () => ({ + type: BUILD_BUTTON_START_CLICKED, +}); + +export const buildButtonConfigureClicked = () => ({ + type: BUILD_BUTTON_CONFIGURE_CLICKED, +}); + +export const buildButtonStopClicked = () => ({ + type: BUILD_BUTTON_STOP_CLICKED, +}); +export const buildButtonOpenAppClicked = () => ({ + type: BUILD_BUTTON_OPEN_APP_CLICKED, +}); + +export const configureBuildModalXClicked = () => ({ + type: CONFIGURE_BUILD_MODAL_X_CLICKED, +}); + +export const buildScriptConfigChanged = ( + script: string +): ScriptConfigChanged => ({ + type: BUILD_SCRIPT_CONFIG_CHANGED, + script, +}); + +export const openAppScriptConfigChanged = ( + script: string +): ScriptConfigChanged => ({ + type: OPEN_APP_SCRIPT_CONFIG_CHANGED, + script, +}); + +export const configureBuildModalBackgroundClicked = () => ({ + type: CONFIGURE_BUILD_MODAL_BACKGROUND_CLICKED, +}); + +export const unloading = () => ({ + type: UNLOADING, +}); + +export const unloaderCreated = (unloader: Unloader): UnloaderAction => ({ + unloader, + type: UNLOADER_CREATED, +}); + +export const unloaderCompleted = (unloader: Unloader): UnloaderAction => ({ + unloader, + type: UNLOADER_COMPLETED, +}); + +export const addQueryButtonClick = ( + queryType: PCQueryType +): AddQueryButtonClicked => ({ + type: ADD_QUERY_BUTTON_CLICKED, + queryType, +}); + +export const fileItemContextMenuOpenInFinderClicked = publicActionCreator( + (item: FSItem): FileItemContextMenuAction => ({ + item, + type: FILE_ITEM_CONTEXT_MENU_OPEN_IN_FINDER_CLICKED, + }) +); + +export const inspectorNodeContextMenuWrapInElementClicked = publicActionCreator( + (item: InspectorNode): InspectorNodeContextMenuAction => ({ + type: INSPECTOR_NODE_CONTEXT_MENU_WRAP_IN_ELEMENT_CLICKED, + item, + }) +); + +export const inspectorNodeContextMenuConvertToComponentClicked = + publicActionCreator( + (item: InspectorNode): InspectorNodeContextMenuAction => ({ + type: INSPECTOR_NODE_CONTEXT_MENU_CONVERT_TO_COMPONENT_CLICKED, + item, + }) + ); + +export const imageBrowseButtonClicked = publicActionCreator( + (): Action => ({ + type: IMAGE_BROWSE_BUTTON_CLICKED, + }) +); + +export const browseDirectoryClicked = publicActionCreator( + (): Action => ({ + type: BROWSE_DIRECTORY_CLICKED, + }) +); + +export const buildScriptStarted = ( + process: ScriptProcess +): BuildScriptStarted => ({ + type: BUILD_SCRIPT_STARTED, + process, +}); + +export const reload = () => ({ + type: RELOAD, +}); + +export const canvasTextEditChangeComplete = ( + value: string +): CanvasTextEditChangeComplete => ({ + value, + type: CANVAS_TEXT_EDIT_CHANGE_COMPLETE, +}); + +export const cssInheritedFromLabelClicked = ( + inheritedFromNode: InspectorNode +): CSSInheritedFromLabelClicked => ({ + type: CSS_INHERITED_FROM_LABEL_CLICKED, + inheritedFromNode, +}); + +export const imageSourceInputChanged = ( + value: string +): ImageSourceInputChanged => ({ + value, + type: IMAGE_SOURCE_INPUT_CHANGED, +}); + +export const inspectorNodeContextMenuConvertToStyleMixinClicked = + publicActionCreator( + (item: InspectorNode): InspectorNodeContextMenuAction => ({ + type: INSPECTOR_NODE_CONTEXT_MENU_CONVERT_TO_STYLE_MIXIN_CLICKED, + item, + }) + ); + +export const inspectorNodeContextMenuConvertTextStylesToMixinClicked = + publicActionCreator( + (item: InspectorNode): InspectorNodeContextMenuAction => ({ + type: INSPECTOR_NODE_CONTEXT_MENU_CONVERT_TEXT_STYLES_TO_MIXIN_CLICKED, + item, + }) + ); + +export const inspectorNodeContextMenuRemoveClicked = publicActionCreator( + (item: InspectorNode): InspectorNodeContextMenuAction => ({ + type: INSPECTOR_NODE_CONTEXT_MENU_REMOVE_CLICKED, + item, + }) +); + +export const inspectorNodeContextMenuRenameClicked = publicActionCreator( + (item: InspectorNode): InspectorNodeContextMenuAction => ({ + type: INSPECTOR_NODE_CONTEXT_MENU_RENAME_CLICKED, + item, + }) +); +export const inspectorNodeContextMenuCopyClicked = publicActionCreator( + (item: InspectorNode): InspectorNodeContextMenuAction => ({ + type: INSPECTOR_NODE_CONTEXT_MENU_COPY_CLICKED, + item, + }) +); +export const inspectorNodeContextMenuPasteClicked = publicActionCreator( + (item: InspectorNode): InspectorNodeContextMenuAction => ({ + type: INSPECTOR_NODE_CONTEXT_MENU_PASTE_CLICKED, + item, + }) +); + +export const inspectorNodeContextMenuWrapInSlotClicked = publicActionCreator( + (item: InspectorNode): InspectorNodeContextMenuAction => ({ + type: INSPECTOR_NODE_CONTEXT_MENU_WRAP_IN_SLOT_CLICKED, + item, + }) +); + +export const inspectorNodeContextMenuSelectParentClicked = publicActionCreator( + (item: InspectorNode): InspectorNodeContextMenuAction => ({ + type: INSPECTOR_NODE_CONTEXT_MENU_SELECT_PARENT_CLICKED, + item, + }) +); + +export const inspectorNodeContextMenuSelectSourceNodeClicked = + publicActionCreator( + (item: InspectorNode): InspectorNodeContextMenuAction => ({ + type: INSPECTOR_NODE_CONTEXT_MENU_SELECT_SOURCE_NODE_CLICKED, + item, + }) + ); + +export const inspectorNodeContextMenuShowInCanvasClicked = publicActionCreator( + (item: InspectorNode): InspectorNodeContextMenuAction => ({ + type: INSPECTOR_NODE_CONTEXT_MENU_SHOW_IN_CANVAS_CLICKED, + item, + }) +); + +export const cssResetPropertyOptionClicked = ( + property: string +): ResetPropertyOptionClicked => ({ + type: CSS_RESET_PROPERTY_OPTION_CLICKED, + property, +}); + +export const editorTabCloseButtonClicked = ( + event: React.MouseEvent, + uri: string +): EditorTabClicked => ({ + uri, + event, + type: EDITOR_TAB_CLOSE_BUTTON_CLICKED, +}); + +export const fileNavigatorItemClicked = ( + node: FSItem +): FileNavigatorItemClicked => ({ + node, + type: FILE_NAVIGATOR_ITEM_CLICKED, +}); + +export const fileNavigatorToggleDirectoryClicked = ( + node: FSItem +): FileNavigatorItemClicked => ({ + node, + type: FILE_NAVIGATOR_TOGGLE_DIRECTORY_CLICKED, +}); + +export const fileNavigatorBasenameChanged = ( + basename: string, + item: FSItem +): FileNavigatorBasenameChanged => ({ + item, + basename, + type: FILE_NAVIGATOR_BASENAME_CHANGED, +}); + +export const scriptProcessStarted = ( + process: ScriptProcess +): ScriptProcessStarted => ({ + type: SCRIPT_PROCESS_STARTED, + process, +}); + +export const scriptProcessLog = ( + process: ScriptProcess, + log: ScriptProcessLog +): ScriptProcessLogged => ({ + type: SCRIPT_PROCESS_LOGGED, + process, + log, +}); + +export const scriptProcessStopped = ( + process: ScriptProcess +): ScriptProcessStopped => ({ + type: SCRIPT_PROCESS_CLOSED, + process, +}); + +export const promptConfirmed = ( + inputValue: string, + actionType: string +): PromptConfirmed => ({ + inputValue, + type: actionType, +}); + +export const exportNameChanged = (value: string): ExportNameChanged => ({ + type: EXPORT_NAME_CHANGED, + value, +}); + +export const promptCancelButtonClicked = (): PromptCancelButtonClicked => ({ + type: PROMPT_CANCEL_BUTTON_CLICKED, +}); + +export const openTextEditorButtonClicked = publicActionCreator( + (uri: string): OpenTextEditorButtonClicked => ({ + uri, + type: OPEN_TEXT_EDITOR_BUTTON_CLICKED, + }) +); + +export const newFileAdded = ( + uri: string, + fileType: FSItemTagNames +): NewFileAdded => ({ + uri, + fileType, + type: NEW_FILE_ADDED, +}); + +export const elementVariantToggled = ( + newVariants: string[], + node: SyntheticVisibleNode +): ElementVariantToggled => ({ + newVariants, + node, + type: ELEMENT_VARIANT_TOGGLED, +}); + +export const closeBottomGutterButtonClicked = (): Action => ({ + type: CLOSE_BOTTOM_GUTTER_BUTTON_CLICKED, +}); + +export const fileNavigatorNewFileClicked = ( + fileType: AddFileType +): FileNavigatorNewFileClicked => ({ + fileType, + type: FILE_NAVIGATOR_NEW_FILE_CLICKED, +}); + +export const styleVariantDropdownChanged = ( + variant: PCVariant, + component: PCComponent +): StyleVariantDropdownChanged => ({ + type: STYLE_VARIANT_DROPDOWN_CHANGED, + component, + variant, +}); + +export const addVariableButtonClicked = ( + variableType: PCVariableType +): AddVariableButtonClicked => ({ + variableType, + type: ADD_VARIABLE_BUTTON_CLICKED, +}); + +export const variableLabelChangeCompleted = ( + variable: PCVariable, + value: string +): VariablePropertyChanged => ({ + variable, + type: VARIABLE_LABEL_CHANGE_COMPLETED, + value, +}); + +export const variableValueChanged = ( + variable: PCVariable, + value: string +): VariablePropertyChanged => ({ + variable, + type: VARIABLE_VALUE_CHANGED, + value, +}); + +export const variableValueChangeCompleted = ( + variable: PCVariable, + value: string +): VariablePropertyChanged => ({ + variable, + type: VARIABLE_VALUE_CHANGE_COMPLETED, + value, +}); + +export const newStyleVariantButtonClicked = (): Action => ({ + type: NEW_STYLE_VARIANT_BUTTON_CLICKED, +}); + +export const projectDirectoryDirLoaded = ( + items: FSItem[] +): ProjectDirectoryDirLoaded => ({ + type: PROJECT_DIRECTORY_DIR_LOADED, + items, +}); + +export const removeStyleButtonClicked = (): Action => ({ + type: REMOVE_STYLE_BUTTON_CLICKED, +}); + +export const editVariantNameButtonClicked = (): Action => ({ + type: EDIT_VARIANT_NAME_BUTTON_CLICKED, +}); + +export const addStyleButtonClicked = (): Action => ({ + type: ADD_STYLE_BUTTON_CLICKED, +}); + +export const fileNavigatorNewDirectoryClicked = (): Action => ({ + type: FILE_NAVIGATOR_NEW_DIRECTORY_CLICKED, +}); + +export const openProjectButtonClicked = publicActionCreator(() => ({ + type: OPEN_PROJECT_BUTTON_CLICKED, +})); + +export const createProjectButtonClicked = publicActionCreator( + (directory: string, files: Object): CreateProjectButtonClicked => ({ + directory, + type: CREATE_PROJECT_BUTTON_CLICKED, + files, + }) +); + +export const inheritPaneAddButtonClick = (): Action => ({ + type: INHERIT_PANE_ADD_BUTTON_CLICK, +}); + +export const inheritPaneRemoveButtonClick = ( + componentId: string +): InheritPaneRemoveButtonClick => ({ + componentId, + type: INHERIT_PANE_REMOVE_BUTTON_CLICK, +}); +export const projectInfoLoaded = (info: ProjectInfo): ProjectInfoLoaded => ({ + type: PROJECT_INFO_LOADED, + info, +}); + +export const inheritItemComponentTypeChangeComplete = ( + oldComponentId: string, + newComponentId: string +): InheritItemComponentTypeChangeComplete => ({ + oldComponentId, + newComponentId, + type: INHERIT_ITEM_COMPONENT_TYPE_CHANGE_COMPLETE, +}); +export const componentPickerBackgroundClick = (): Action => ({ + type: COMPONENT_PICKER_BACKGROUND_CLICK, +}); + +export const addVariantButtonClicked = (): Action => ({ + type: ADD_VARIANT_BUTTON_CLICKED, +}); + +export const addVariantTriggerButtonClicked = (): Action => ({ + type: ADD_VARIANT_TRIGGER_CLICKED, +}); + +export const variantTriggerSourceChanged = ( + trigger: PCVariantTrigger, + value: PCVariantTriggerSource +): VariantTriggerSourceChanged => ({ + type: VARIANT_TRIGGER_SOURCE_CHANGED, + value, + trigger, +}); + +export const variantTriggerTargetChanged = ( + trigger: PCVariantTrigger, + value: PCVariant +): VariantTriggerTargetChanged => ({ + type: VARIANT_TRIGGER_TARGET_CHANGED, + value, + trigger, +}); + +export const removeVariantTriggerButtonClicked = ( + trigger: PCVariantTrigger +): RemoveVariantTriggerClicked => ({ + trigger, + type: REMOVE_VARIANT_TRIGGER_CLICKED, +}); + +export const fileItemRightClicked = ( + item: FSItem, + event: React.MouseEvent +): FileItemRightClicked => ({ + type: FILE_ITEM_RIGHT_CLICKED, + event, + item, +}); + +export const canvasRightClicked = ( + event: React.MouseEvent +): CanvasRightClicked => ({ + type: CANVAS_RIGHT_CLICKED, + event, +}); + +export const pcLayerRightClicked = ( + item: InspectorNode, + event: React.MouseEvent +): PCLayerRightClicked => ({ + item, + type: PC_LAYER_RIGHT_CLICKED, + event, +}); + +export const pcLayerDoubleClicked = ( + item: InspectorNode, + event: React.MouseEvent +): PCLayerRightClicked => ({ + item, + type: PC_LAYER_DOUBLE_CLICKED, + event, +}); + +export const unhandledError = (error: Error): UnhandledError => ({ + error, + type: UNHANDLED_ERROR, +}); + +export const removeVariantButtonClicked = (): Action => ({ + type: REMOVE_VARIANT_BUTTON_CLICKED, +}); + +export const quickSearchFilterChanged = ( + value: string +): QuickSearchFilterChanged => ({ + type: QUICK_SEARCH_FILTER_CHANGED, + value, +}); + +export const quickSearchFilterResultLoaded = ( + matches: QuickSearchResult[] +): QuickSearchResultLoaded => ({ + matches, + type: QUICK_SEARCH_RESULT_LOADED, +}); + +export const variantDefaultSwitchClicked = ( + variant: PCVariant +): VariantDefaultSwitchClicked => ({ + variant, + type: VARIANT_DEFAULT_SWITCH_CLICKED, +}); + +export const instanceVariantToggled = ( + variant: PCVariant +): InstanceVariantToggled => ({ + variant, + type: COMPONENT_INSTANCE_VARIANT_TOGGLED, +}); + +export const instanceVariantResetClicked = ( + variant: PCVariant +): InstanceVariantToggled => ({ + variant, + type: INSTANCE_VARIANT_RESET_CLICKED, +}); + +export const variantLabelChanged = ( + variant: PCVariant, + newLabel: string +): VariantLabelChanged => ({ + variant, + newLabel, + type: VARIANT_LABEL_CHANGED, +}); + +export const componentPickerItemClick = ( + component: PCComponent +): ComponentPickerItemClick => ({ + component, + type: COMPONENT_PICKER_ITEM_CLICK, +}); + +export const quickSearchItemClicked = ( + item: QuickSearchResult +): QuickSearchItemClicked => ({ + item, + type: QUICK_SEARCH_ITEM_CLICKED, +}); + +export const quickSearchInputEntered = ( + item: QuickSearchResult +): QuickSearchItemClicked => ({ + item, + type: QUICK_SEARCH_INPUT_ENTERED, +}); + +export const openControllerButtonClicked = ( + relativePath: string +): ComponentControllerItemClicked => ({ + relativePath, + type: OPEN_CONTROLLER_BUTTON_CLICKED, +}); + +export const addComponentControllerButtonClicked = publicActionCreator( + (defaultPath: string): AddComponentControllerButtonClicked => ({ + defaultPath, + type: ADD_COMPONENT_CONTROLLER_BUTTON_CLICKED, + }) +); + +export const removeComponentControllerButtonClicked = ( + relativePath: string +): RemoveComponentControllerButtonClicked => ({ + relativePath, + type: REMOVE_COMPONENT_CONTROLLER_BUTTON_CLICKED, +}); + +export const componentControllerPicked = ( + filePath: string +): ComponentControllerPicked => ({ + filePath, + type: COMPONENT_CONTROLLER_PICKED, +}); + +export const quickSearchBackgroundClick = (): Action => ({ + type: QUICK_SEARCH_BACKGROUND_CLICK, +}); + +export const fileNavigatorNewFileEntered = ( + basename: string, + insertType: FSItemTagNames, + directoryId: string +): FileNavigatorNewFileEntered => ({ + basename, + directoryId, + insertType, + type: FILE_NAVIGATOR_NEW_FILE_ENTERED, +}); + +export const openFilesItemClick = ( + uri: string, + sourceEvent: React.MouseEvent +): OpenFilesItemClick => ({ + uri, + sourceEvent, + type: OPEN_FILE_ITEM_CLICKED, +}); + +export const openFilesItemCloseClick = (uri: string): OpenFilesItemClick => ({ + uri, + sourceEvent: null, + type: OPEN_FILE_ITEM_CLOSE_CLICKED, +}); + +export const activeEditorUriDirsLoaded = (): Action => ({ + type: ACTIVE_EDITOR_URI_DIRS_LOADED, +}); + +export const frameModeChangeComplete = ( + frame: Frame, + mode: FrameMode +): FrameModeChangeComplete => ({ + type: FRAME_MODE_CHANGE_COMPLETE, + frame, + mode, +}); + +export const toolbarToolClicked = (toolType: ToolType): ToolbarToolClicked => ({ + type: TOOLBAR_TOOL_CLICKED, + toolType, +}); + +export const fileNavigatorItemDoubleClicked = ( + node: FSItem +): FileNavigatorItemClicked => ({ + node, + type: FILE_NAVIGATOR_ITEM_DOUBLE_CLICKED, +}); + +export const fileNavigatorItemBlurred = ( + node: FSItem +): FileNavigatorItemClicked => ({ + node, + type: FILE_NAVIGATOR_ITEM_BLURRED, +}); + +export const sourceInspectorLayerClicked = ( + node: InspectorNode, + sourceEvent: React.MouseEvent +): InspectorLayerEvent => ({ + type: SOURCE_INSPECTOR_LAYER_CLICKED, + node, + sourceEvent, +}); + +export const sourceInspectorLayerArrowClicked = ( + node: InspectorNode, + sourceEvent: React.MouseEvent +): InspectorLayerEvent => ({ + type: SOURCE_INSPECTOR_LAYER_ARROW_CLICKED, + node, + sourceEvent, +}); + +export const sourceInspectorLayerLabelChanged = ( + node: InspectorNode, + label: string, + sourceEvent: React.KeyboardEvent +): InspectorLayerLabelChanged => ({ + type: SOURCE_INSPECTOR_LAYER_LABEL_CHANGED, + node, + label, + sourceEvent, +}); + +export const newVariantNameEntered = ( + value: string +): NewVariantNameEntered => ({ + value, + type: NEW_VARIANT_NAME_ENTERED, +}); + +export const componentComponentVariantNameChanged = ( + oldName: string, + newName: string +): ComponentVariantNameChanged => ({ + oldName, + newName, + type: COMPONENT_VARIANT_NAME_CHANGED, +}); + +export const componentComponentVariantNameClicked = ( + name: string +): ComponentVariantNameClicked => ({ + name, + type: COMPONENT_VARIANT_NAME_CLICKED, +}); + +export const componentVariantNameDefaultToggleClick = ( + name: string, + value: boolean +): ComponentVariantNameDefaultToggleClick => ({ + name, + value, + type: COMPONENT_VARIANT_NAME_DEFAULT_TOGGLE_CLICK, +}); + +export const sourceInspectorLayerDropped = ( + source: InspectorNode, + target: InspectorNode, + offset: TreeMoveOffset +): SourceInspectorLayerDropped => ({ + source, + target, + offset, + type: SOURCE_INSPECTOR_LAYER_DROPPED, +}); + +export const rawCssTextChanged = (value: string): RawCSSTextChanged => ({ + value, + type: RAW_CSS_TEXT_CHANGED, +}); + +export const cssPropertyChanged = ( + name: string, + value: string +): CSSPropertyChanged => ({ + name, + value, + type: CSS_PROPERTY_CHANGED, +}); + +export const cssPropertiesChanged = ( + properties: KeyValue +): CSSPropertiesChanged => ({ + properties, + type: CSS_PROPERTIES_CHANGED, +}); + +export const cssPropertyChangeCompleted = ( + name: string, + value: string +): CSSPropertyChanged => ({ + name, + value, + type: CSS_PROPERTY_CHANGE_COMPLETED, +}); + +export const cssPropertiesChangeCompleted = ( + properties: KeyValue +): CSSPropertiesChanged => ({ + properties, + type: CSS_PROPERTIES_CHANGE_COMPLETED, +}); + +export const attributeChanged = ( + name: string, + value: string +): AttributeChanged => ({ + name, + value, + type: ATTRIBUTE_CHANGED, +}); + +export const slotToggleClick = (): SlotToggleClick => ({ + type: SLOT_TOGGLE_CLICK, +}); + +export const textValueChanged = (value: string): TextValueChanged => ({ + value, + type: TEXT_VALUE_CHANGED, +}); + +export const elementTypeChanged = (value: string): ElementTypeChanged => ({ + value, + type: ELEMENT_TYPE_CHANGED, +}); + +export const appLoaded = publicActionCreator(() => ({ type: APP_LOADED })); + +export const newFileEntered = (basename: string): NewFileEntered => ({ + basename, + type: NEW_FILE_ENTERED, +}); + +export const newDirectoryEntered = (basename: string): NewFileEntered => ({ + basename, + type: NEW_DIRECTORY_ENTERED, +}); + +export const projectLoaded = (uri: string): ProjectLoaded => ({ + uri, + type: PROJECT_LOADED, +}); + +export const projectDirectoryLoaded = publicActionCreator( + (directory: Directory): ProjectDirectoryLoaded => ({ + directory, + type: PROJECT_DIRECTORY_LOADED, + }) +); + +export const shortcutKeyDown = publicActionCreator( + (type: string): ShortcutKeyDown => ({ + type, + }) +); + +export const inspectorNodePasted = ( + clips: PCNodeClip[] +): SyntheticVisibleNodesPasted => ({ + clips, + type: INSPECTOR_NODES_PASTED, +}); + +export const documentRendered = ( + documentId: string, + info: ComputedDisplayInfo, + nativeMap: SyntheticNativeNodeMap +): DocumentRendered => ({ + nativeMap, + documentId, + info, + type: DOCUMENT_RENDERED, +}); + +export const savedFile = (uri: string): SavedFile => ({ + uri, + type: SAVED_FILE, +}); + +export const savedAllFiles = (uri: string): SavedAllFiles => ({ + type: SAVED_ALL_FILES, +}); + +export const canvasToolOverlayMousePanStart = ( + documentId: string +): CanvasToolOverlayMousePanStart => ({ + documentId, + type: CANVAS_TOOL_OVERLAY_MOUSE_PAN_START, +}); + +export const canvasToolOverlayMousePanning = ( + documentId: string, + center: Point, + deltaY: number, + velocityY: number +): CanvasToolOverlayMousePanning => ({ + documentId, + center, + deltaY, + velocityY, + type: CANVAS_TOOL_OVERLAY_MOUSE_PANNING, +}); + +export const canvasToolOverlayMouseLeave = ( + sourceEvent: React.MouseEvent +): CanvasToolOverlayMouseMoved => ({ + type: CANVAS_TOOL_OVERLAY_MOUSE_LEAVE, + sourceEvent, +}); + +export const canvasToolOverlayMousePanEnd = ( + documentId: string +): CanvasToolOverlayMousePanEnd => ({ + documentId, + type: CANVAS_TOOL_OVERLAY_MOUSE_PAN_END, +}); + +export const canvasToolOverlayMouseDoubleClicked = ( + documentId: string, + sourceEvent: React.MouseEvent +): CanvasToolOverlayClicked => ({ + documentId, + type: CANVAS_TOOL_OVERLAY_MOUSE_DOUBLE_CLICKED, + sourceEvent, +}); + +export const canvasContainerMounted = ( + element: HTMLDivElement, + fileUri: string +): CanvasMounted => ({ + element, + fileUri, + type: CANVAS_MOUNTED, +}); + +export const canvasMouseMoved = ( + editorWindow: EditorWindow, + sourceEvent: React.MouseEvent +): CanvasMouseMoved => ({ + editorWindow, + sourceEvent, + type: CANVAS_MOUSE_MOVED, +}); + +export const canvasDraggedOver = ( + item: any, + offset: Point +): CanvasDraggingOver => ({ + item, + offset, + type: CANVAS_DRAGGED_OVER, +}); + +export const canvasMouseClicked = ( + sourceEvent: React.MouseEvent +): WrappedEvent> => ({ + sourceEvent, + type: CANVAS_MOUSE_CLICKED, +}); + +export const canvasMouseDoubleClicked = ( + sourceEvent: React.MouseEvent +): WrappedEvent> => ({ + sourceEvent, + type: CANVAS_MOUSE_DOUBLE_CLICKED, +}); + +export const canvasWheel = ( + canvasWidth: number, + canvasHeight: number, + { metaKey, ctrlKey, deltaX, deltaY, clientX, clientY }: React.WheelEvent +): CanvasWheel => ({ + metaKey, + canvasWidth, + canvasHeight, + ctrlKey, + deltaX, + deltaY, + type: CANVAS_WHEEL, +}); + +export const canvasDroppedItem = ( + item: RegisteredComponent, + point: Point, + editorUri: string +): CanvasDroppedItem => ({ + editorUri, + item, + point, + type: CANVAS_DROPPED_ITEM, +}); + +export const canvasMotionRested = () => ({ + type: CANVAS_MOTION_RESTED, +}); + +export const insertToolFinished = ( + point: Point, + fileUri: string +): InsertToolFinished => ({ + point, + fileUri, + type: INSERT_TOOL_FINISHED, +}); + +export const canvasToolWindowBackgroundClicked = ( + sourceEvent: React.KeyboardEvent +): WrappedEvent> => ({ + type: CANVAS_TOOL_WINDOW_BACKGROUND_CLICKED, + sourceEvent, +}); +export const canvasToolWindowKeyDown = ( + documentId: string, + sourceEvent: React.KeyboardEvent +): CanvasToolWindowKeyDown => ({ + type: CANVAS_TOOL_WINDOW_KEY_DOWN, + documentId, + sourceEvent, +}); +export const canvasToolDocumentTitleClicked = ( + frame: Frame, + sourceEvent: React.MouseEvent +): CanvasToolArtboardTitleClicked => ({ + type: CANVAS_TOOL_ARTBOARD_TITLE_CLICKED, + frame, + sourceEvent, +}); + +export const canvasToolPreviewButtonClicked = ( + frame: Frame, + sourceEvent: React.MouseEvent +): CanvasToolArtboardTitleClicked => ({ + type: CANVAS_TOOL_PREVIEW_BUTTON_CLICKED, + frame, + sourceEvent, +}); + +export const resizerPathMoved = ( + anchor: Point, + originalBounds: Bounds, + newBounds: Bounds, + sourceEvent: MouseEvent +): ResizerPathMoved => ({ + type: RESIZER_PATH_MOUSE_MOVED, + anchor, + originalBounds, + newBounds, + sourceEvent, +}); + +export const frameBoundsChanged = (newBounds: Bounds) => ({ + type: FRAME_BOUNDS_CHANGED, + newBounds, +}); + +export const frameBoundsChangeCompleted = (newBounds: Bounds) => ({ + type: FRAME_BOUNDS_CHANGE_COMPLETED, + newBounds, +}); + +export const resizerPathStoppedMoving = ( + anchor: Point, + originalBounds: Bounds, + newBounds: Bounds, + sourceEvent: MouseEvent +): ResizerPathMoved => ({ + type: RESIZER_PATH_MOUSE_STOPPED_MOVING, + anchor, + originalBounds, + newBounds, + sourceEvent: { ...sourceEvent }, +}); + +export const resizerMoved = (point: Point): ResizerMoved => ({ + point, + type: RESIZER_MOVED, +}); + +export const resizerStoppedMoving = (point: Point): ResizerMoved => ({ + point, + type: RESIZER_STOPPED_MOVING, +}); + +export const resizerMouseDown = ( + sourceEvent: React.MouseEvent +): ResizerMouseDown => ({ + sourceEvent, + type: RESIZER_MOUSE_DOWN, +}); + +export const resizerStartDrag = ( + sourceEvent: React.MouseEvent +): ResizerMouseDown => ({ + sourceEvent, + type: RESIZER_START_DRGG, +}); diff --git a/packages/tandem-designer/src/bug-reporting/components/main/controller.tsx b/packages/tandem-designer/src/bug-reporting/components/main/controller.tsx new file mode 100644 index 000000000..7dc7d58f1 --- /dev/null +++ b/packages/tandem-designer/src/bug-reporting/components/main/controller.tsx @@ -0,0 +1,26 @@ +import * as React from "react"; +import { BaseMainProps } from "./view.pc"; +import { Dispatch } from "redux"; +import { reload } from "../../../actions"; + +export type Props = { + dispatch: Dispatch; +}; + +export default (Base: React.ComponentClass) => + class BaseReporterController extends React.PureComponent { + onResetClick = () => { + this.props.dispatch(reload()); + + // safety measure incase reload action handler is not working + setTimeout(() => { + window.location.reload(); + }, 1000); + }; + + render() { + const { onResetClick } = this; + const { ...rest } = this.props; + return ; + } + }; diff --git a/packages/tandem-designer/src/bug-reporting/components/main/view.pc b/packages/tandem-designer/src/bug-reporting/components/main/view.pc new file mode 100644 index 000000000..aa947e514 --- /dev/null +++ b/packages/tandem-designer/src/bug-reporting/components/main/view.pc @@ -0,0 +1,269 @@ +{ + "id": "cf827dd439", + "name": "module", + "version": "0.0.6", + "children": [ + { + "label": "Main", + "is": "div", + "style": { + "box-sizing": "border-box", + "display": "block", + "background": "rgba(255, 255, 255, 0.6)", + "position": "fixed", + "left": "0px", + "top": "0px", + "width": "100vw", + "height": "100vh", + "z-index": "99999" + }, + "attributes": {}, + "id": "900e27cd182", + "name": "component", + "children": [ + { + "id": "900e27cd184", + "label": "Container", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "display": "block", + "position": "absolute", + "left": "0px", + "top": "0px", + "width": "100%", + "height": "100%" + }, + "children": [ + { + "id": "900e27cd186", + "label": "Center", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "display": "block", + "width": "400px", + "margin-right": "auto", + "margin-left": "auto", + "position": "relative", + "top": "20%", + "background": "var(--d8f6340b1442)", + "border-top-left-radius": "2px", + "border-top-right-radius": "2px", + "border-bottom-left-radius": "2px", + "border-bottom-right-radius": "2px", + "border-left": "1px solid var(--30f4693267675)", + "border-top": "1px solid var(--30f4693267675)", + "border-right": "1px solid var(--30f4693267675)", + "border-bottom": "1px solid var(--30f4693267675)", + "padding-left": "12px", + "padding-top": "12px", + "padding-right": "12px", + "padding-bottom": "12px" + }, + "children": [ + { + "id": "4325aac312606", + "name": "text", + "label": "Title", + "value": "Whoops, looks like an unexpected error occurred.", + "style": { + "font-weight": "600", + "font-size": "14px", + "color": "var(--24ce1e4d482)", + "display": "block", + "margin-bottom": "12px" + }, + "children": [], + "metadata": {}, + "styleMixins": { + "dc3b39eb1275": { + "priority": 0 + } + } + }, + { + "id": "4325aac312614", + "name": "text", + "label": "Text", + "value": "If you're able to reproduce this issue, please help us make the app better by ", + "style": { + "color": "var(--24ce1e4d482)", + "font-weight": "500", + "margin-bottom": "12px", + "display": "inline" + }, + "children": [], + "metadata": {}, + "styleMixins": { + "dc3b39eb1275": { + "priority": 0 + } + } + }, + { + "id": "2cb68e4e12627", + "label": "link button", + "is": "a", + "name": "element", + "attributes": { + "href": "https://github.com/tandemcode/tandem/issues" + }, + "style": { + "box-sizing": "border-box", + "display": "inline", + "font-weight": "600", + "color": "var(--24ce1e4d13456)" + }, + "children": [ + { + "id": "2cb68e4e12630", + "name": "text", + "label": "Text", + "value": "filing a bug ticket on GitHub.", + "style": { + "color": "var(--24ce1e4d13456)", + "text-decoration": "none" + }, + "children": [], + "metadata": {} + } + ], + "metadata": {}, + "styleMixins": { + "dc3b39eb1275": { + "priority": 0 + } + } + }, + { + "id": "2cb68e4e12635", + "label": "Element", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "display": "flex", + "margin-top": "12px", + "justify-content": "flex-end" + }, + "children": [ + { + "id": "2cb68e4e12641", + "label": "restart button", + "is": "9f364d2139415", + "name": "component-instance", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "display": "inline-block" + }, + "children": [ + { + "id": "2cb68e4e12648", + "variantId": null, + "propertyName": "text", + "targetIdPath": [ + "9f364d2139650" + ], + "value": "Restart app", + "name": "override", + "children": [] + } + ], + "metadata": {}, + "variant": {} + } + ], + "metadata": {} + } + ], + "metadata": {} + } + ], + "metadata": {} + } + ], + "metadata": { + "bounds": { + "left": 101, + "top": -60, + "right": 1541, + "bottom": 840 + } + }, + "variant": {}, + "controllers": [ + "./controller.tsx" + ] + }, + { + "id": "900e27cd237", + "label": "Preview", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "display": "block" + }, + "children": [ + { + "id": "900e27cd12658", + "is": "900e27cd182", + "label": "Main", + "name": "component-instance", + "attributes": {}, + "style": { + "z-index": "9999" + }, + "children": [], + "metadata": { + "bounds": { + "left": 101, + "top": -60, + "right": 1541, + "bottom": 840 + } + }, + "variant": {} + }, + { + "id": "900e27cd239", + "is": "33b1b6b133319", + "label": "Workspace", + "name": "component-instance", + "attributes": {}, + "style": { + "opacity": 0.982, + "display": "block" + }, + "children": [], + "metadata": { + "bounds": { + "left": -129, + "top": 991, + "right": 1833.8518233326877, + "bottom": 1974.4100056728703 + } + }, + "variant": {} + } + ], + "metadata": { + "bounds": { + "left": 2207, + "top": 64, + "right": 4221, + "bottom": 1247 + } + } + } + ], + "metadata": {} +} \ No newline at end of file diff --git a/packages/tandem-designer/src/bug-reporting/index.ts b/packages/tandem-designer/src/bug-reporting/index.ts new file mode 100644 index 000000000..fed0b1ab9 --- /dev/null +++ b/packages/tandem-designer/src/bug-reporting/index.ts @@ -0,0 +1,23 @@ +import * as React from "react"; +import * as ReactDOM from "react-dom"; +import { Main } from "./components/main/view.pc"; + +export const init = (dispatch: Function) => { + let triggered = false; + + const triggerError = (error) => { + console.error(error); + if (triggered) { + return; + } + + triggered = true; + + const div = document.createElement("div"); + document.body.appendChild(div); + ReactDOM.render(React.createElement(Main, { dispatch }), div); + }; + return { + triggerError, + }; +}; diff --git a/packages/tandem-designer/src/components/atoms/view.pc b/packages/tandem-designer/src/components/atoms/view.pc new file mode 100644 index 000000000..61c9eb342 --- /dev/null +++ b/packages/tandem-designer/src/components/atoms/view.pc @@ -0,0 +1,207 @@ +{ + "id": "6ceccc4089", + "version": "0.0.6", + "metadata": {}, + "name": "module", + "children": [ + { + "id": "33b5126b196", + "name": "style-mixin", + "label": "label font", + "style": { + "color": "rgba(136, 136, 136, 1)", + "font-size": "9px", + "display": "inline-block", + "opacity": "1", + "pointer": "default", + "user-select": "none", + "font-weight": "500", + "cursor": "default", + "letter-spacing": "0.08em" + }, + "value": "Label", + "targetType": "text", + "children": [], + "metadata": { + "bounds": { + "left": 606, + "top": 132, + "right": 663, + "bottom": 150 + } + }, + "styleMixins": { + "dc3b39eb1275": { + "priority": 0 + } + } + }, + { + "id": "dc3b39eb1275", + "name": "style-mixin", + "label": "Base font", + "style": { + "font-family": "Helvetica Neue, Helvetica", + "color": "rgba(136, 136, 136, 1)", + "font-size": "12px", + "letter-spacing": "0.05em", + "font-weight": "400" + }, + "value": "Base font", + "targetType": "text", + "children": [], + "metadata": { + "bounds": { + "left": 584, + "top": -40, + "right": 673, + "bottom": -15 + } + } + }, + { + "id": "dc3b39eb1627", + "name": "style-mixin", + "label": "Header font style", + "style": { + "text-transform": "uppercase", + "font-size": "10px", + "color": "var(--24ce1e4d482)", + "font-weight": "600", + "user-select": "none", + "cursor": "default" + }, + "value": "header", + "targetType": "text", + "children": [], + "metadata": { + "bounds": { + "left": 706, + "top": 94, + "right": 769, + "bottom": 119 + } + }, + "styleMixins": { + "dc3b39eb1275": { + "priority": 0 + } + } + }, + { + "id": "c29da5f4213993", + "label": "Default border", + "name": "style-mixin", + "style": { + "border-bottom-left-radius": "2px", + "border-top-left-radius": "2px", + "border-top-right-radius": "2px", + "border-bottom-right-radius": "2px", + "border-left": "1px none rgba(1, 0, 1, 0)", + "border-top": "1px none rgba(1, 0, 1, 0)", + "border-right": "1px none rgba(1, 0, 1, 0)", + "border-bottom": "1px none rgba(1, 0, 1, 0)", + "box-shadow": "inset 0px 0px 0px 1px var(--dd86347b1545)" + }, + "targetType": "element", + "children": [], + "metadata": { + "bounds": { + "left": 802, + "top": -80, + "right": 902, + "bottom": 20 + } + } + }, + { + "id": "61225017220906", + "name": "style-mixin", + "label": "Nowrap ellipsis", + "style": { + "overflow": "hidden", + "text-overflow": "ellipsis", + "white-space": "nowrap" + }, + "value": "Super long text that should be ellipsises", + "targetType": "text", + "children": [], + "metadata": { + "bounds": { + "left": 912, + "top": -139, + "right": 1012, + "bottom": -39 + } + } + }, + { + "id": "9cd522d52691", + "label": "Input background", + "name": "style-mixin", + "style": { + "box-sizing": "border-box", + "display": "block", + "border-bottom-left-radius": "2px", + "border-top-left-radius": "2px", + "border-top-right-radius": "2px", + "border-bottom-right-radius": "2px", + "background": "rgba(250, 250, 250, 1)" + }, + "targetType": "element", + "children": [], + "metadata": { + "bounds": { + "left": 1022, + "top": -271.5, + "right": 1122, + "bottom": -171.5 + } + } + }, + { + "id": "9798784b2419", + "name": "style-mixin", + "label": "Base font + nobreak", + "style": { + "white-space": "nowrap" + }, + "styleMixins": { + "dc3b39eb1275": { + "priority": 0 + } + }, + "value": "Base font + nobreak", + "targetType": "text", + "children": [], + "metadata": { + "bounds": { + "left": 565, + "top": -136, + "right": 665, + "bottom": -107 + } + } + }, + { + "id": "fb4d37ca18486", + "label": "Default shadow style", + "name": "style-mixin", + "style": { + "box-sizing": "border-box", + "display": "block", + "filter": "drop-shadow(4px 4px 2px rgba(0,0,0,0.1))" + }, + "targetType": "element", + "children": [], + "metadata": { + "bounds": { + "left": 1132, + "top": -312.25, + "right": 1232, + "bottom": -212.25 + } + } + } + ] +} \ No newline at end of file diff --git a/packages/tandem-designer/src/components/box-shadows-enhancer.tsx b/packages/tandem-designer/src/components/box-shadows-enhancer.tsx new file mode 100644 index 000000000..e69de29bb diff --git a/packages/tandem-designer/src/components/component-picker/all.pc b/packages/tandem-designer/src/components/component-picker/all.pc new file mode 100644 index 000000000..10a1f9d15 --- /dev/null +++ b/packages/tandem-designer/src/components/component-picker/all.pc @@ -0,0 +1,149 @@ +{ + "id": "a5bde25030259", + "version": "0.0.6", + "metadata": {}, + "name": "module", + "children": [ + { + "id": "839a748a3", + "variant": {}, + "is": "97a34b151010442", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [ + { + "id": "839a748a5", + "propertyName": "text", + "targetIdPath": [ + "97a34b151010439" + ], + "value": " ", + "name": "override", + "children": [] + }, + { + "id": "839a748a6", + "propertyName": "text", + "targetIdPath": [ + "97a34b151010441" + ], + "value": "TODO: component picker should be part of quick search HUD instead", + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": 101, + "top": 551, + "right": 394.6542270494879, + "bottom": 751.7213373757045 + } + }, + "label": "NOTICE" + }, + { + "id": "dcd2c13f1346802", + "label": "Preview", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "box-sizing": "border-box" + }, + "children": [ + { + "id": "dcd2c13f1369180", + "variant": {}, + "is": "dcd2c13f1117488", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": { + "bounds": { + "left": -2, + "top": 1030, + "right": 1058.745578674279, + "bottom": 1794.10984700987 + } + } + } + ], + "metadata": { + "bounds": { + "left": 1193, + "top": 617, + "right": 2930.5222022067624, + "bottom": 1615.7550017858953 + } + } + }, + { + "id": "a5bde25030262", + "variant": {}, + "is": "dcd2c13f1453155", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": { + "bounds": { + "left": 721, + "top": 621, + "right": 821, + "bottom": 721 + } + } + }, + { + "id": "9399e92d567", + "variant": {}, + "is": "dcd2c13f21458", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [ + { + "id": "9399e92d568", + "propertyName": "style", + "targetIdPath": [ + "33949bb8180402" + ], + "value": {}, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": 99, + "top": 895, + "right": 1030.5520794519923, + "bottom": 1431.962079966811 + } + } + }, + { + "id": "5a5fe4fa441", + "label": "Element", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "display": "block" + }, + "children": [], + "metadata": { + "bounds": { + "left": 993.377287724091, + "top": 231.97628021865143, + "right": 1093.377287724091, + "bottom": 331.9762802186514 + } + } + } + ] +} \ No newline at end of file diff --git a/packages/tandem-designer/src/components/component-picker/cell-controller.tsx b/packages/tandem-designer/src/components/component-picker/cell-controller.tsx new file mode 100644 index 000000000..47705bba0 --- /dev/null +++ b/packages/tandem-designer/src/components/component-picker/cell-controller.tsx @@ -0,0 +1,11 @@ +import * as React from "react"; +import { BaseComponentOptionProps } from "./cell.pc"; + +export type Props = BaseComponentOptionProps; + +export default (Base: React.ComponentClass) => + class CellController extends React.PureComponent { + render() { + return ; + } + }; diff --git a/packages/tandem-designer/src/components/component-picker/cell.pc b/packages/tandem-designer/src/components/component-picker/cell.pc new file mode 100644 index 000000000..a7c632c15 --- /dev/null +++ b/packages/tandem-designer/src/components/component-picker/cell.pc @@ -0,0 +1,87 @@ +{ + "id": "a5bde25012342", + "version": "0.0.6", + "metadata": {}, + "name": "module", + "children": [ + { + "label": "Component Option", + "is": "div", + "style": { + "box-sizing": "border-box", + "width": "33.333%", + "height": "100px", + "display": "inline-block", + "padding": "8px", + "color": "var(--24ce1e4d482)" + }, + "attributes": {}, + "id": "dcd2c13f1453155", + "name": "component", + "children": [ + { + "id": "33949bb8539851", + "label": "inner", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "border": "1px solid var(--d8f6340b1442)", + "width": "100%", + "height": "100%", + "border-radius": "2px", + "position": "relative", + "cursor": "pointer" + }, + "children": [ + { + "id": "c9f2b12511904", + "label": "center", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "left": "50%", + "top": "50%", + "transform": "translate(-50%, -50%)", + "position": "absolute", + "user-select": "none" + }, + "children": [ + { + "id": "1d3c2e8470", + "name": "text", + "label": "Text", + "value": "Component\n", + "style": {}, + "children": [], + "metadata": {}, + "styleMixins": { + "dc3b39eb1275": { + "priority": 0 + } + } + } + ], + "metadata": {} + } + ], + "metadata": {} + } + ], + "metadata": { + "bounds": { + "left": 437, + "top": 305, + "right": 537, + "bottom": 405 + } + }, + "controllers": [ + "./cell-controller.tsx" + ], + "variant": {} + } + ] +} \ No newline at end of file diff --git a/packages/tandem-designer/src/components/component-picker/modal-controller.tsx b/packages/tandem-designer/src/components/component-picker/modal-controller.tsx new file mode 100644 index 000000000..a380aea17 --- /dev/null +++ b/packages/tandem-designer/src/components/component-picker/modal-controller.tsx @@ -0,0 +1,35 @@ +import * as React from "react"; +import { RootState, ToolType } from "../../state"; +import { Dispatch } from "redux"; +import { componentPickerBackgroundClick } from "../../actions"; +import { BaseModalProps } from "./modal.pc"; + +export type Props = { + root: RootState; + dispatch: Dispatch; +}; + +export default (Base: React.ComponentClass) => + class ModalController extends React.PureComponent { + onBackgroundClick = () => { + this.props.dispatch(componentPickerBackgroundClick()); + }; + render() { + const { root, dispatch } = this.props; + const { onBackgroundClick } = this; + // if (root.toolType === ToolType.COMPONENT && !root.selectedComponentId) { + // return ( + // + // ); + // } + return null; + } + }; diff --git a/packages/tandem-designer/src/components/component-picker/modal.pc b/packages/tandem-designer/src/components/component-picker/modal.pc new file mode 100644 index 000000000..5f01d279e --- /dev/null +++ b/packages/tandem-designer/src/components/component-picker/modal.pc @@ -0,0 +1,123 @@ +{ + "id": "a5bde25018988", + "version": "0.0.6", + "metadata": {}, + "name": "module", + "children": [ + { + "label": "Modal", + "is": "div", + "style": { + "box-sizing": "border-box" + }, + "attributes": {}, + "id": "dcd2c13f1117488", + "name": "component", + "children": [ + { + "id": "dcd2c13f1117486", + "label": "background", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "width": "100%", + "height": "100%", + "position": "absolute", + "left": "0px", + "top": "0px", + "background": "rgba(253, 253, 253, 0.47)" + }, + "children": [], + "metadata": { + "bounds": { + "left": -899.0356858130644, + "top": 976.3517232565041, + "right": -799.0356858130644, + "bottom": 1076.351723256504 + } + } + }, + { + "id": "dcd2c13f1117487", + "variant": {}, + "is": "dcd2c13f21458", + "name": "component-instance", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "width": "400px", + "height": "300px", + "padding": "8px", + "border-radius": "2px", + "left": "50%", + "top": "50%", + "position": "absolute", + "transform": "translate(-50%, -50%)" + }, + "children": [ + { + "id": "33949bb8371360", + "propertyName": "style", + "targetIdPath": [ + "33949bb8180402" + ], + "value": { + "width": "33.333%", + "padding": "8px" + }, + "name": "override", + "children": [] + }, + { + "id": "33949bb81080620", + "propertyName": "attributes", + "targetIdPath": [ + "dcd2c13f709198" + ], + "value": { + "placeholder": "Filter" + }, + "name": "override", + "children": [] + }, + { + "id": "33949bb81131300", + "propertyName": "style", + "targetIdPath": [ + "dcd2c13f709198" + ], + "value": { + "opacity": 0.862 + }, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": -483, + "top": 15, + "right": 448.5520794519923, + "bottom": 551.9620799668112 + } + }, + "label": "picker" + } + ], + "metadata": { + "bounds": { + "left": 340, + "top": 336, + "right": 1400.745578674279, + "bottom": 1100.10984700987 + } + }, + "controllers": [ + "./modal-controller.tsx" + ], + "variant": {} + } + ] +} \ No newline at end of file diff --git a/packages/tandem-designer/src/components/component-picker/picker-controller.tsx b/packages/tandem-designer/src/components/component-picker/picker-controller.tsx new file mode 100644 index 000000000..a3be1958b --- /dev/null +++ b/packages/tandem-designer/src/components/component-picker/picker-controller.tsx @@ -0,0 +1,74 @@ +import * as React from "react"; +import { Dispatch } from "redux"; +import { RootState } from "../../state"; +import { ComponentOption } from "./cell.pc"; +import { getAllPCComponents } from "paperclip"; +import { componentPickerItemClick } from "../../actions"; +import { BasePickerProps } from "./picker.pc"; + +export type Props = { + root: RootState; + dispatch: Dispatch; +}; + +type State = { + filter: string[]; +}; + +export default (Base: React.ComponentClass) => { + return class PickerController extends React.PureComponent { + state = { + filter: [], + }; + onFilterChange = (value) => { + this.setState({ + ...this.state, + filter: String(value || "") + .toLowerCase() + .trim() + .split(/\s+/g), + }); + }; + onClickComponent = (component) => { + this.props.dispatch(componentPickerItemClick(component)); + }; + render() { + const { onFilterChange, onClickComponent } = this; + const { filter } = this.state; + const { root } = this.props; + + const componentNodes = getAllPCComponents(root.graph); + + // TODO - filter private + const options = componentNodes + .filter((component) => { + const label = (component.label || "").toLowerCase(); + for (const part of filter) { + if (label.indexOf(part) === -1) { + return false; + } + } + + return true; + }) + .map((component) => { + return ( + onClickComponent(component)} + centerProps={{ children: component.label }} + /> + ); + }); + + return ( + + ); + } + }; +}; diff --git a/packages/tandem-designer/src/components/component-picker/picker.pc b/packages/tandem-designer/src/components/component-picker/picker.pc new file mode 100644 index 000000000..7d8bf18bd --- /dev/null +++ b/packages/tandem-designer/src/components/component-picker/picker.pc @@ -0,0 +1,943 @@ +{ + "id": "a5bde25041538", + "version": "0.0.6", + "metadata": {}, + "name": "module", + "children": [ + { + "label": "Picker", + "is": "div", + "style": { + "box-sizing": "border-box", + "width": "400px", + "height": "300px", + "background": "var(--bc891e755312)", + "padding": "8px", + "border-radius": "2px", + "display": "flex", + "flex-direction": "column", + "border": "1px solid rgba(0,0,0,0.1)" + }, + "attributes": {}, + "id": "dcd2c13f21458", + "name": "component", + "children": [ + { + "id": "33949bb81531103", + "variant": {}, + "is": "33949bb81531102", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": {}, + "label": "filter input" + }, + { + "id": "dcd2c13f1458755", + "label": "options", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "height": "100%", + "width": "100%", + "overflow": "scroll" + }, + "children": [ + { + "id": "33949bb8981", + "variant": {}, + "is": "dcd2c13f1453155", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": {} + }, + { + "id": "33949bb8180402", + "variant": {}, + "is": "dcd2c13f1453155", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [ + { + "id": "bf98e93e231", + "propertyName": "style", + "targetIdPath": [], + "value": {}, + "name": "override", + "children": [] + } + ], + "metadata": {} + }, + { + "id": "33949bb8186010", + "variant": {}, + "is": "dcd2c13f1453155", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": {} + }, + { + "id": "33949bb8191621", + "variant": {}, + "is": "dcd2c13f1453155", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": {} + }, + { + "id": "33949bb8197235", + "variant": {}, + "is": "dcd2c13f1453155", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [ + { + "id": "321339dc647", + "variantId": null, + "propertyName": "text", + "targetIdPath": [ + "1d3c2e8470" + ], + "value": "Box", + "name": "override", + "children": [] + } + ], + "metadata": {} + }, + { + "id": "29ae594c90", + "variant": {}, + "is": "dcd2c13f1453155", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": {} + }, + { + "id": "29ae594c6062", + "variant": {}, + "is": "dcd2c13f1453155", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": {} + }, + { + "id": "29ae594c11978", + "variant": {}, + "is": "dcd2c13f1453155", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": {} + }, + { + "id": "29ae594c17906", + "variant": {}, + "is": "dcd2c13f1453155", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": {} + }, + { + "id": "29ae594c23846", + "variant": {}, + "is": "dcd2c13f1453155", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": {} + }, + { + "id": "29ae594c29798", + "variant": {}, + "is": "dcd2c13f1453155", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": {} + }, + { + "id": "29ae594c35762", + "variant": {}, + "is": "dcd2c13f1453155", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": {} + }, + { + "id": "29ae594c41738", + "variant": {}, + "is": "dcd2c13f1453155", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": {} + }, + { + "id": "29ae594c47726", + "variant": {}, + "is": "dcd2c13f1453155", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": {} + }, + { + "id": "29ae594c53726", + "variant": {}, + "is": "dcd2c13f1453155", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": {} + }, + { + "id": "29ae594c59738", + "variant": {}, + "is": "dcd2c13f1453155", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": {} + }, + { + "id": "29ae594c65762", + "variant": {}, + "is": "dcd2c13f1453155", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": {} + }, + { + "id": "29ae594c71798", + "variant": {}, + "is": "dcd2c13f1453155", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": {} + }, + { + "id": "29ae594c77846", + "variant": {}, + "is": "dcd2c13f1453155", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": {} + }, + { + "id": "29ae594c83906", + "variant": {}, + "is": "dcd2c13f1453155", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": {} + } + ], + "metadata": {} + } + ], + "metadata": { + "bounds": { + "left": 516, + "top": 579, + "right": 1447.5520794519925, + "bottom": 1115.962079966811 + } + }, + "controllers": [ + "./picker-controller.tsx" + ], + "variant": {} + }, + { + "label": "filter", + "is": "7149f8199122", + "style": { + "width": "100%", + "padding": "4px 8px", + "border-radius": "2px", + "box-sizing": "border-box", + "margin-bottom": "8px", + "border-left": "0px none", + "border-top": "0px none", + "border-right": "0px none", + "border-bottom": "0px none" + }, + "attributes": {}, + "id": "33949bb81531102", + "name": "component", + "children": [], + "metadata": { + "bounds": { + "left": 519, + "top": 438, + "right": 1433, + "bottom": 461 + } + }, + "controllers": [ + "../focus/controller.tsx" + ], + "variant": {} + }, + { + "label": "Component Popdown Picker", + "is": "div", + "style": { + "box-sizing": "border-box", + "display": "block", + "width": "200px", + "position": "relative", + "transform": "translateX(-50%)" + }, + "attributes": {}, + "id": "936f29271359", + "name": "component", + "children": [ + { + "id": "936f29271341", + "is": "936f2927707", + "label": "Tooltip", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [ + { + "slotId": "936f2927716", + "id": "936f29271342", + "children": [ + { + "id": "936f29271343", + "label": "content", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "display": "flex", + "width": "100%", + "height": "100%", + "flex-direction": "column" + }, + "children": [ + { + "id": "936f29271344", + "label": "Header", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "padding-left": "12px", + "padding-top": "12px", + "padding-right": "12px", + "padding-bottom": "12px", + "flex-shrink": "0" + }, + "children": [ + { + "id": "936f29271345", + "is": "7149f8199122", + "label": "filter", + "name": "component-instance", + "attributes": { + "placeholder": "filter" + }, + "style": {}, + "children": [], + "metadata": { + "bounds": { + "left": 384, + "top": 298, + "right": 484, + "bottom": 327.0358087589019 + } + }, + "variant": {} + } + ], + "metadata": {} + }, + { + "id": "936f29271346", + "label": "Items", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "display": "block", + "height": "100%", + "max-height": "200px", + "overflow-y": "scroll" + }, + "children": [ + { + "id": "d7d55938491", + "children": [ + { + "id": "936f29271354", + "is": "936f29271179", + "label": "item", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": {}, + "variant": { + "936f29271227": false + } + }, + { + "id": "936f29271353", + "is": "936f29271179", + "label": "item", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": {}, + "variant": {} + }, + { + "id": "936f29271352", + "is": "936f29271179", + "label": "item", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": {}, + "variant": { + "936f29271227": false, + "39f5a1891084": true + } + }, + { + "id": "936f29271351", + "is": "936f29271179", + "label": "item", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": {}, + "variant": {} + }, + { + "id": "936f29271350", + "is": "936f29271179", + "label": "item", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": {}, + "variant": { + "936f29271227": false + } + }, + { + "id": "936f29271349", + "is": "936f29271179", + "label": "item", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": {}, + "variant": {} + }, + { + "id": "417f19f2468", + "is": "936f29271179", + "label": "item", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": {}, + "variant": { + "936f29271227": false + } + }, + { + "id": "417f19f2498", + "is": "936f29271179", + "label": "item", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": {}, + "variant": { + "936f29271227": false + } + }, + { + "id": "417f19f2513", + "is": "936f29271179", + "label": "item", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": {}, + "variant": { + "936f29271227": false + } + }, + { + "id": "417f19f2483", + "is": "936f29271179", + "label": "item", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": {}, + "variant": { + "936f29271227": true + } + }, + { + "id": "417f19f2453", + "is": "936f29271179", + "label": "item", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": {}, + "variant": { + "936f29271227": false + } + }, + { + "id": "936f29271348", + "is": "936f29271179", + "label": "item", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": {}, + "variant": { + "936f29271227": true + } + }, + { + "id": "936f29271347", + "is": "936f29271179", + "label": "item", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": {}, + "variant": {} + } + ], + "metadata": {}, + "name": "slot", + "label": "items" + } + ], + "metadata": {} + }, + { + "id": "e42d628f659", + "label": "no components", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "display": "none" + }, + "children": [ + { + "id": "e42d628f666", + "name": "text", + "label": "None found", + "value": "No components found.", + "style": { + "text-align": "left", + "display": "block", + "font-weight": "600", + "margin-bottom": "12px" + }, + "children": [], + "metadata": {}, + "styleMixins": { + "dc3b39eb1275": { + "priority": 0 + } + } + }, + { + "id": "e42d628f669", + "name": "text", + "label": "desc", + "value": "To create one, right click a layer and click ", + "style": { + "text-align": "left", + "display": "inline" + }, + "children": [], + "metadata": {}, + "styleMixins": { + "dc3b39eb1275": { + "priority": 0 + } + } + }, + { + "id": "e42d628f672", + "name": "text", + "label": "ctra", + "value": "\"Convert to Component\"", + "style": { + "text-align": "left", + "display": "inline", + "font-weight": "600" + }, + "children": [], + "metadata": {}, + "styleMixins": { + "dc3b39eb1275": { + "priority": 0 + } + } + }, + { + "id": "e42d628f663", + "name": "text", + "label": "period", + "value": ".\n", + "style": { + "text-align": "left", + "display": "inline-block" + }, + "children": [], + "metadata": {}, + "styleMixins": { + "dc3b39eb1275": { + "priority": 0 + } + } + } + ], + "metadata": {} + } + ], + "metadata": {} + } + ], + "metadata": {}, + "name": "plug" + }, + { + "id": "936f29271358", + "propertyName": "style", + "targetIdPath": [ + "936f2927712" + ], + "value": { + "padding-left": "0px", + "padding-top": "0px", + "padding-right": "0px", + "padding-bottom": "0px" + }, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": 1847.651101951617, + "top": 547.0324588855084, + "right": 2182.651101951617, + "bottom": 760.0324588855083 + } + }, + "variant": {} + }, + { + "id": "e42d628f657", + "name": "variant", + "label": "no components", + "isDefault": true, + "children": [], + "metadata": {} + }, + { + "id": "e42d628f658", + "variantId": "e42d628f657", + "propertyName": "style", + "targetIdPath": [ + "936f29271346" + ], + "value": { + "display": "none" + }, + "name": "override", + "children": [] + }, + { + "id": "e42d628f662", + "variantId": "e42d628f657", + "propertyName": "style", + "targetIdPath": [ + "e42d628f659" + ], + "value": { + "display": "block", + "padding-left": "12px", + "padding-top": "0px", + "padding-right": "12px", + "padding-bottom": "12px" + }, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": 1675, + "top": 597, + "right": 2480, + "bottom": 1146 + } + }, + "variant": {}, + "controllers": [ + "./picker2-controller.tsx" + ], + "styleMixins": { + "fb4d37ca18486": { + "priority": 0 + } + } + }, + { + "label": "Component picker popdown item", + "is": "div", + "style": { + "box-sizing": "border-box", + "display": "flex", + "padding-left": "12px", + "padding-top": "6px", + "padding-right": "12px", + "padding-bottom": "6px", + "align-items": "center", + "cursor": "pointer" + }, + "attributes": {}, + "id": "936f29271179", + "name": "component", + "children": [ + { + "id": "936f29271234", + "is": "724c3c9e7", + "label": "Component Icon", + "name": "component-instance", + "attributes": {}, + "style": { + "color": "var(--24ce1e4d482)", + "display": "block", + "height": "12px" + }, + "children": [], + "metadata": { + "bounds": { + "left": -1837, + "top": -318, + "right": -1437, + "bottom": -18 + } + }, + "variant": {} + }, + { + "id": "936f29271184", + "name": "text", + "label": "component name", + "value": "Item", + "style": { + "margin-left": "6px", + "display": "block", + "width": "100%", + "cursor": "inherit" + }, + "children": [], + "metadata": {}, + "styleMixins": { + "dc3b39eb1275": { + "priority": 0 + }, + "61225017220906": { + "priority": 1 + } + } + }, + { + "id": "936f29271227", + "name": "variant", + "label": "alt", + "isDefault": true, + "children": [], + "metadata": {} + }, + { + "id": "936f29271228", + "variantId": "936f29271227", + "propertyName": "style", + "targetIdPath": [], + "value": { + "background-image": "linear-gradient(var(--1934368810788), var(--1934368810788))", + "display": "flex", + "align-items": "center" + }, + "name": "override", + "children": [] + }, + { + "id": "936f29271283", + "variantId": "936f29271227", + "propertyName": "style", + "targetIdPath": [ + "936f29271234" + ], + "value": { + "color": "var(--24ce1e4d482)" + }, + "name": "override", + "children": [] + }, + { + "id": "936f29271284", + "variantId": "936f29271227", + "propertyName": "style", + "targetIdPath": [ + "936f29271184" + ], + "value": {}, + "name": "override", + "children": [] + }, + { + "id": "39f5a1891084", + "name": "variant", + "label": "hover", + "isDefault": true, + "children": [], + "metadata": {} + }, + { + "id": "39f5a1891085", + "variantId": "39f5a1891084", + "propertyName": "style", + "targetIdPath": [], + "value": { + "background-image": "linear-gradient(var(--1934368810788), var(--1934368810788))" + }, + "name": "override", + "children": [] + }, + { + "id": "98f82cb7850", + "name": "variant-trigger", + "targetVariantId": "39f5a1891084", + "source": { + "type": 1, + "state": "hover" + }, + "children": [], + "metadata": {} + }, + { + "id": "47744854653", + "name": "variant", + "label": "preselected", + "isDefault": true, + "children": [], + "metadata": {} + }, + { + "id": "47744854654", + "variantId": "47744854653", + "propertyName": "style", + "targetIdPath": [], + "value": { + "background-image": "linear-gradient(var(--32c1eebd7630), var(--32c1eebd7630))" + }, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": 2519, + "top": 644, + "right": 3298, + "bottom": 694 + } + }, + "variant": {} + }, + { + "id": "5c5f499e426", + "label": "Element", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "display": "block" + }, + "children": [], + "metadata": { + "bounds": { + "left": 72, + "top": 308, + "right": 172, + "bottom": 408 + } + } + } + ] +} \ No newline at end of file diff --git a/packages/tandem-designer/src/components/component-picker/picker2-controller.tsx b/packages/tandem-designer/src/components/component-picker/picker2-controller.tsx new file mode 100644 index 000000000..c73b886ef --- /dev/null +++ b/packages/tandem-designer/src/components/component-picker/picker2-controller.tsx @@ -0,0 +1,129 @@ +import * as React from "react"; +import * as ReactDOM from "react-dom"; +import cx from "classnames"; +import { Dispatch } from "redux"; +import { + BaseComponentPopdownPickerProps, + ComponentPickerPopdownItem as BaseComponentPickerPopdownItem, + BaseComponentPickerPopdownItemProps, +} from "./picker.pc"; +import { PCComponent, DependencyGraph, getAllPCComponents } from "paperclip"; +import { componentPickerItemClick } from "../../actions"; +import scrollIntoView from "scroll-into-view-if-needed"; + +export type Props = { + graph: DependencyGraph; + dispatch: Dispatch; +}; + +type State = { + filter: string[]; + preselectIndex: number; +}; + +type ComponentPickerPopdownItemProps = { + preselected: boolean; +} & BaseComponentPickerPopdownItemProps; + +class ComponentPickerPopdownItem extends React.PureComponent { + componentDidUpdate(prevProps: ComponentPickerPopdownItemProps) { + if (this.props.preselected && !prevProps.preselected) { + scrollIntoView(ReactDOM.findDOMNode(this) as HTMLDivElement, { + scrollMode: "if-needed", + }); + } + } + render() { + const { preselected, ...rest } = this.props; + return ( + + ); + } +} + +export default (Base: React.ComponentClass) => + class Picker2Controller extends React.PureComponent { + state = { + filter: [], + preselectIndex: 0, + }; + + onFilterChange = (value) => { + this.setState({ + ...this.state, + preselectIndex: 0, + filter: String(value || "") + .toLowerCase() + .trim() + .split(/\s+/g), + }); + }; + onClickComponent = (component) => { + this.props.dispatch(componentPickerItemClick(component)); + }; + onFilterKeyDown = (event: React.KeyboardEvent) => { + let preselectIndex = this.state.preselectIndex; + const filteredComponents = this.getFilteredComponents(); + + if (event.key === "ArrowDown") { + preselectIndex++; + } else if (event.key === "ArrowUp") { + preselectIndex--; + } else if (event.key === "Enter") { + this.props.dispatch( + componentPickerItemClick(filteredComponents[preselectIndex]) + ); + } + + this.setState({ + ...this.state, + preselectIndex: Math.max( + 0, + Math.min(preselectIndex, filteredComponents.length - 1) + ), + }); + }; + getFilteredComponents() { + const { graph } = this.props; + const { filter } = this.state; + const components = getAllPCComponents(graph); + return components.filter((component) => { + const label = (component.label || "").toLowerCase(); + for (const part of filter) { + if (label.indexOf(part) === -1) { + return false; + } + } + + return true; + }); + } + render() { + const { onClickComponent, onFilterChange, onFilterKeyDown } = this; + const { preselectIndex } = this.state; + const items = this.getFilteredComponents().map((component, i) => { + return ( + onClickComponent(component)} + componentNameProps={{ text: component.label }} + preselected={i === preselectIndex} + /> + ); + }); + return ( + + ); + } + }; diff --git a/packages/tandem-designer/src/components/configure-build/controller.tsx b/packages/tandem-designer/src/components/configure-build/controller.tsx new file mode 100644 index 000000000..3ec656925 --- /dev/null +++ b/packages/tandem-designer/src/components/configure-build/controller.tsx @@ -0,0 +1,59 @@ +import * as React from "react"; +import { BaseConfigureBuildModalProps } from "./view.pc"; +import { Dispatch } from "redux"; +import { + configureBuildModalXClicked, + configureBuildModalBackgroundClicked, + openAppScriptConfigChanged, + buildScriptConfigChanged, +} from "../../actions"; +import { ProjectInfo } from "../../state"; +export type Props = { + projectInfo: ProjectInfo; + dispatch: Dispatch; +}; +export default (Base: React.ComponentClass) => + class ConfigureBuildController extends React.PureComponent { + onCloseButtonClick = () => { + this.props.dispatch(configureBuildModalXClicked()); + }; + onBackgroundClick = () => { + this.props.dispatch(configureBuildModalBackgroundClicked()); + }; + onOpenCommandChangeComplete = (value: string) => { + this.props.dispatch(openAppScriptConfigChanged(value)); + }; + onBuildCommandChangeComplete = (value: string) => { + this.props.dispatch(buildScriptConfigChanged(value)); + }; + render() { + const { + onCloseButtonClick, + onBackgroundClick, + onBuildCommandChangeComplete, + onOpenCommandChangeComplete, + } = this; + const { projectInfo, dispatch, ...rest } = this.props; + return ( + + ); + } + }; diff --git a/packages/tandem-designer/src/components/configure-build/view.pc b/packages/tandem-designer/src/components/configure-build/view.pc new file mode 100644 index 000000000..f6fc2af30 --- /dev/null +++ b/packages/tandem-designer/src/components/configure-build/view.pc @@ -0,0 +1,306 @@ +{ + "id": "a8ea458088", + "name": "module", + "version": "0.0.6", + "children": [ + { + "label": "Configure build modal", + "is": "div", + "style": { + "box-sizing": "border-box", + "display": "block", + "position": "fixed", + "top": "0px", + "width": "100%", + "height": "100%", + "z-index": "1024", + "left": "0px" + }, + "attributes": {}, + "id": "18a9cfc32689", + "name": "component", + "children": [ + { + "id": "7b302ae817522", + "label": "background", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "display": "block", + "width": "100%", + "height": "100%", + "position": "absolute", + "background-image": "linear-gradient(var(--dd86347b1545), var(--dd86347b1545))" + }, + "children": [], + "metadata": {} + }, + { + "id": "18a9cfc32804", + "label": "Element", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "display": "block", + "width": "400px", + "background-image": "linear-gradient(var(--bc891e755312), var(--bc891e755312))", + "border-top-left-radius": "2px", + "border-top-right-radius": "2px", + "border-bottom-left-radius": "2px", + "border-bottom-right-radius": "2px", + "left": "50%", + "top": "30%", + "transform": "translate(-50%, -50%)", + "position": "absolute", + "padding-left": "12px", + "padding-top": "12px", + "padding-right": "12px", + "padding-bottom": "12px", + "border-left": "1px solid var(--30f4693267675)", + "border-top": "1px solid var(--30f4693267675)", + "border-right": "1px solid var(--30f4693267675)", + "border-bottom": "1px solid var(--30f4693267675)" + }, + "children": [ + { + "id": "18a9cfc32809", + "label": "header", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "display": "flex", + "align-items": "center", + "justify-content": "space-between" + }, + "children": [ + { + "id": "18a9cfc32807", + "name": "text", + "label": "Text", + "value": "Configure Build", + "style": {}, + "children": [], + "metadata": {}, + "styleMixins": { + "dc3b39eb1627": { + "priority": 0 + } + } + }, + { + "id": "18a9cfc32946", + "name": "text", + "label": "close button", + "value": "×\n", + "style": { + "cursor": "pointer", + "display": "inline-block" + }, + "children": [], + "metadata": {}, + "styleMixins": { + "dc3b39eb1275": { + "priority": 0 + } + } + } + ], + "metadata": {} + }, + { + "id": "18a9cfc32960", + "label": "Content", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "display": "block", + "padding-top": "12px" + }, + "children": [ + { + "id": "7b302ae8213", + "is": "7149f8192509", + "label": "Build Script", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [ + { + "id": "7b302ae8214", + "variantId": null, + "propertyName": "text", + "targetIdPath": [ + "7149f8192506" + ], + "value": "Build Command\n", + "name": "override", + "children": [] + }, + { + "slotId": "e73029b416045", + "id": "7b302ae8215", + "children": [ + { + "id": "7b302ae8216", + "is": "7149f8199122", + "label": "build command input", + "name": "component-instance", + "attributes": { + "placeholder": "webpack --watch" + }, + "style": {}, + "children": [], + "metadata": { + "bounds": { + "left": 384, + "top": 298, + "right": 484, + "bottom": 327.0358087589019 + } + }, + "variant": {} + } + ], + "metadata": {}, + "name": "plug" + } + ], + "metadata": { + "bounds": { + "left": 486, + "top": 306, + "right": 586, + "bottom": 353.5832678332798 + } + }, + "variant": {} + }, + { + "id": "18a9cfc32962", + "is": "7149f8192509", + "label": "Build Script", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [ + { + "id": "7b302ae8207", + "variantId": null, + "propertyName": "text", + "targetIdPath": [ + "7149f8192506" + ], + "value": "Open Application Command", + "name": "override", + "children": [] + }, + { + "slotId": "e73029b416045", + "id": "7b302ae8209", + "children": [ + { + "id": "7b302ae8208", + "is": "7149f8199122", + "label": "open command input", + "name": "component-instance", + "attributes": { + "placeholder": "open http://localhost:8080/" + }, + "style": {}, + "children": [], + "metadata": { + "bounds": { + "left": 384, + "top": 298, + "right": 484, + "bottom": 327.0358087589019 + } + }, + "variant": {} + } + ], + "metadata": {}, + "name": "plug" + } + ], + "metadata": { + "bounds": { + "left": 486, + "top": 306, + "right": 586, + "bottom": 353.5832678332798 + } + }, + "variant": {} + } + ], + "metadata": {} + } + ], + "metadata": {}, + "styleMixins": {} + } + ], + "metadata": { + "bounds": { + "left": 240, + "top": 248, + "right": 1555, + "bottom": 1216 + } + }, + "variant": {}, + "controllers": [ + "./controller.tsx" + ] + }, + { + "id": "7b302ae8231", + "label": "Element", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "display": "block" + }, + "children": [ + { + "id": "7b302ae817488", + "is": "18a9cfc32689", + "label": "Configure build modal", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": { + "bounds": { + "left": 240, + "top": 248, + "right": 1555, + "bottom": 1216 + } + }, + "variant": {} + } + ], + "metadata": { + "bounds": { + "left": -2210, + "top": 0, + "right": -592, + "bottom": 1379 + } + } + } + ], + "metadata": {} +} \ No newline at end of file diff --git a/packages/tandem-designer/src/components/context-menu/controller.tsx b/packages/tandem-designer/src/components/context-menu/controller.tsx new file mode 100644 index 000000000..dea7d72e6 --- /dev/null +++ b/packages/tandem-designer/src/components/context-menu/controller.tsx @@ -0,0 +1,19 @@ +import * as React from "react"; +import { BaseContextMenuProps } from "./view.pc"; +import { Point } from "tandem-common"; +import { ContextMenuOption } from "../../state"; + +export type Props = { + anchor: Point; + options: ContextMenuOption[]; +} & BaseContextMenuProps; + +export const ContextMenuContext = React.createContext({}); + +export default (Base: React.ComponentClass) => + class ContextMenuController extends React.PureComponent { + render() { + const { anchor, options, ...rest } = this.props; + return ; + } + }; diff --git a/packages/tandem-designer/src/components/context-menu/view.pc b/packages/tandem-designer/src/components/context-menu/view.pc new file mode 100644 index 000000000..830aa5db3 --- /dev/null +++ b/packages/tandem-designer/src/components/context-menu/view.pc @@ -0,0 +1,239 @@ +{ + "id": "8c06472158661", + "version": "0.0.5", + "metadata": {}, + "name": "module", + "children": [ + { + "label": "Context Menu", + "is": "div", + "style": { + "min-width": "150px", + "background": "var(--bc891e755312)", + "position": "fixed", + "border-radius": "2px", + "box-shadow": "2px 2px 4px 0px rgba(0, 0, 0, 0.23)", + "color": "var(--24ce1e4d482)", + "width": "unset", + "left": "0px", + "top": "0px", + "z-index": "9999" + }, + "attributes": {}, + "id": "8c06472162847", + "name": "component", + "children": [ + { + "id": "8c064721397692", + "variant": {}, + "is": "8c064721397691", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": {}, + "styleMixins": { + "1542269404878": { + "priority": 0 + } + } + }, + { + "id": "8c064721502470", + "variant": { + "e549f686984": true + }, + "is": "8c064721397691", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": {} + }, + { + "id": "8c064721506666", + "variant": {}, + "is": "8c064721397691", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": {} + }, + { + "id": "8c0647211201683", + "variant": {}, + "is": "8c0647211142703", + "name": "component-instance", + "attributes": {}, + "style": { + "width": "100%", + "height": "2px" + }, + "children": [], + "metadata": {} + }, + { + "id": "8c064721510866", + "variant": {}, + "is": "8c064721397691", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": {} + }, + { + "id": "8c064721515070", + "variant": {}, + "is": "8c064721397691", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": {} + }, + { + "id": "8c064721519278", + "variant": {}, + "is": "8c064721397691", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": {} + } + ], + "metadata": { + "bounds": { + "left": 2627, + "top": 137, + "right": 2863, + "bottom": 388 + } + }, + "variant": {}, + "controllers": [ + "./controller.tsx" + ] + }, + { + "id": "8c06472192134", + "label": "Preview", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "background": "rgba(86, 86, 86, 1)" + }, + "children": [ + { + "id": "8c06472183765", + "variant": {}, + "is": "8c06472162847", + "name": "component-instance", + "attributes": {}, + "style": { + "background": "rgba(238, 238, 238, 1)", + "position": "absolute", + "left": "50%", + "top": "50%", + "transform": "translate(-50%, -50%)" + }, + "children": [], + "metadata": { + "bounds": { + "left": 1940, + "top": -64, + "right": 2040, + "bottom": 36 + } + } + } + ], + "metadata": { + "bounds": { + "left": 1849.9357023832233, + "top": 69.46301729203338, + "right": 2417.951653305937, + "bottom": 392.48866899527604 + } + } + }, + { + "label": "Context Menu item", + "is": "div", + "style": { + "padding": "8px", + "text-align": "left" + }, + "attributes": {}, + "id": "8c064721397691", + "name": "component", + "children": [ + { + "id": "8c064721397690", + "name": "text", + "label": "Text", + "value": "Menu Item", + "style": {}, + "children": [], + "metadata": {}, + "styleMixins": { + "dc3b39eb1275": { + "priority": 0 + } + } + }, + { + "id": "e549f686984", + "name": "variant", + "label": "selected", + "isDefault": true, + "children": [], + "metadata": {} + }, + { + "id": "e549f6861033", + "variantId": "e549f686984", + "propertyName": "style", + "targetIdPath": [], + "value": { + "background": "var(--d8f6340b1442)" + }, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": 2479, + "top": 77, + "right": 2617.377917434091, + "bottom": 115.1989039126796 + } + }, + "variant": {} + }, + { + "label": "Divider", + "is": "div", + "style": { + "background": "var(--d8f6340b1442)" + }, + "attributes": {}, + "id": "8c0647211142703", + "name": "component", + "children": [], + "metadata": { + "bounds": { + "left": 2515.1662068012306, + "top": 292.34499325373525, + "right": 2615.1662068012306, + "bottom": 392.34499325373525 + } + }, + "variant": {} + } + ] +} \ No newline at end of file diff --git a/packages/tandem-designer/src/components/contexts/index.ts b/packages/tandem-designer/src/components/contexts/index.ts new file mode 100644 index 000000000..ba57f82c3 --- /dev/null +++ b/packages/tandem-designer/src/components/contexts/index.ts @@ -0,0 +1,14 @@ +import * as React from "react"; + +export type FileOpenerOptions = { + name: string; + extensions?: string[]; +}; + +export type FileOpener = (options: FileOpenerOptions) => Promise; + +export type FrontEndContextOptions = { + openFile: FileOpener; +}; + +export const OpenFileContext = React.createContext(null); diff --git a/packages/tandem-designer/src/components/dev/comments.pc b/packages/tandem-designer/src/components/dev/comments.pc new file mode 100644 index 000000000..939028bea --- /dev/null +++ b/packages/tandem-designer/src/components/dev/comments.pc @@ -0,0 +1,161 @@ +{ + "id": "97a34b159010", + "version": "0.0.5", + "metadata": {}, + "name": "module", + "children": [ + { + "label": "TODO", + "is": "97a34b151010442", + "style": {}, + "attributes": {}, + "id": "d6261ad5198", + "name": "component", + "children": [ + { + "slotId": "88156175335", + "id": "d6261ad5194", + "children": [ + { + "id": "d6261ad5195", + "label": "Element", + "is": "ul", + "name": "element", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "margin-left": "0px", + "margin-top": "0px", + "margin-right": "0px", + "margin-bottom": "0px" + }, + "children": [ + { + "id": "d6261ad5196", + "label": "Element", + "is": "li", + "name": "element", + "attributes": {}, + "style": { + "box-sizing": "border-box" + }, + "children": [ + { + "id": "d6261ad5197", + "name": "text", + "label": "Text", + "value": "TODO\n", + "style": {}, + "children": [], + "metadata": {} + } + ], + "metadata": { + "bounds": { + "left": -82.02623104308414, + "top": 119.13820878685686, + "right": 17.973768956915862, + "bottom": 219.13820878685686 + } + } + } + ], + "metadata": {} + } + ], + "metadata": {}, + "name": "plug" + } + ], + "metadata": { + "bounds": { + "left": 20, + "top": 103, + "right": 403.1708291271775, + "bottom": 303.7213373757045 + } + }, + "variant": {} + }, + { + "label": "Comment", + "is": "div", + "style": { + "background": "yellow", + "overflow": "none", + "padding": "8px", + "font-family": "Helvetica", + "font-size": "12px", + "display": "flex", + "flex-direction": "column" + }, + "attributes": {}, + "id": "97a34b151010442", + "name": "component", + "children": [ + { + "id": "97a34b151010438", + "label": "Element", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "background": "rgba(0,0,0,0.07)", + "width": "20px", + "height": "20px", + "position": "absolute", + "right": "0", + "transform": "translate(50%, -50%)", + "top": "0" + }, + "children": [], + "metadata": {} + }, + { + "id": "97a34b151010440", + "label": "Element", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "height": "100%", + "width": "100%", + "margin-top": "8px" + }, + "children": [ + { + "exportName": null, + "id": "88156175335", + "children": [ + { + "id": "97a34b151010441", + "name": "text", + "label": "Text", + "value": "comment text here", + "style": { + "color": "#444", + "opacity": "0.8" + }, + "children": [], + "metadata": {} + } + ], + "metadata": {}, + "name": "slot" + } + ], + "metadata": {} + } + ], + "metadata": { + "bounds": { + "left": 509.1992294346617, + "top": 118.07285735609861, + "right": 892.3700585618392, + "bottom": 318.7941947318031 + } + }, + "variant": {} + } + ] +} \ No newline at end of file diff --git a/packages/tandem-designer/src/components/draggable/index.tsx b/packages/tandem-designer/src/components/draggable/index.tsx new file mode 100644 index 000000000..642bdf9ef --- /dev/null +++ b/packages/tandem-designer/src/components/draggable/index.tsx @@ -0,0 +1,51 @@ +import * as React from "react"; +import * as ReactDOM from "react-dom"; + +export type DraggableProps = { + onDrag: (ops: { + px: number; + py: number; + width: number; + height: number; + }) => any; + onDragStop?: () => any; + children: any; +}; + +export class DraggableComponent extends React.Component { + private _element: HTMLElement; + componentDidMount() {} + onMouseDown = (event: React.MouseEvent) => { + this._element = ReactDOM.findDOMNode(this) as HTMLElement; + document.body.addEventListener("mouseup", this.onMouseUp); + document.body.addEventListener("mousemove", this.onMouseMove); + }; + onMouseMove = (event: MouseEvent) => { + const element = this._element; + const prect = element.getBoundingClientRect(); + const rx = Math.min( + prect.right - prect.left, + Math.max(0, event.clientX - prect.left) + ); + const ry = Math.min( + prect.bottom - prect.top, + Math.max(0, event.clientY - prect.top) + ); + this.props.onDrag({ + px: rx / prect.width, + py: ry / prect.height, + width: prect.width, + height: prect.height, + }); + }; + onMouseUp = (event: MouseEvent) => { + document.body.removeEventListener("mouseup", this.onMouseUp); + document.body.removeEventListener("mousemove", this.onMouseMove); + if (this.props.onDragStop) { + this.props.onDragStop(); + } + }; + render() { + return {this.props.children}; + } +} diff --git a/packages/tandem-designer/src/components/focus/controller.tsx b/packages/tandem-designer/src/components/focus/controller.tsx new file mode 100644 index 000000000..65fa05ed0 --- /dev/null +++ b/packages/tandem-designer/src/components/focus/controller.tsx @@ -0,0 +1,15 @@ +import * as React from "react"; +import { FocusComponent } from "./index"; + +export type Props = any; + +export default (Base: React.ComponentClass) => + class FocusController extends React.PureComponent { + render() { + return ( + + + + ); + } + }; diff --git a/packages/tandem-designer/src/components/focus/index.tsx b/packages/tandem-designer/src/components/focus/index.tsx new file mode 100644 index 000000000..acd6e576f --- /dev/null +++ b/packages/tandem-designer/src/components/focus/index.tsx @@ -0,0 +1,33 @@ +import * as React from "react"; +import * as ReactDOM from "react-dom"; + +export type FocusProps = { + children?: any; + focus?: boolean; +}; + +export class FocusComponent extends React.Component { + componentDidMount() { + if (this.props.focus !== false) { + this.focus(); + } + } + componentWillReceiveProps({ focus }: FocusProps, context) { + if (this.props.focus !== focus && focus) { + this.focus(); + } + } + focus() { + setTimeout(() => { + const self = ReactDOM.findDOMNode(this) as HTMLElement; + const input = + self.tagName === "INPUT" + ? (self as HTMLInputElement) + : self.querySelector("input"); + input.select(); + }, 10); + } + render() { + return this.props.children; + } +} diff --git a/packages/tandem-designer/src/components/gutter/index.scss b/packages/tandem-designer/src/components/gutter/index.scss new file mode 100644 index 000000000..f996e0f74 --- /dev/null +++ b/packages/tandem-designer/src/components/gutter/index.scss @@ -0,0 +1,7 @@ +.m-gutter { + background: var(--background-3); + min-width: 200px; + // height: 100%; + display: flex; + flex-direction: column; +} diff --git a/packages/tandem-designer/src/components/gutter/index.tsx b/packages/tandem-designer/src/components/gutter/index.tsx new file mode 100644 index 000000000..b58307d89 --- /dev/null +++ b/packages/tandem-designer/src/components/gutter/index.tsx @@ -0,0 +1,12 @@ +import "./index.scss"; +import * as React from "react"; + +export type GutterComponentInnerProps = { + children: any; +}; + +const BaseGutterComponent = ({ children }: GutterComponentInnerProps) => ( +
{children}
+); + +export const GutterComponent = BaseGutterComponent; diff --git a/packages/tandem-designer/src/components/inputs/atoms.pc b/packages/tandem-designer/src/components/inputs/atoms.pc new file mode 100644 index 000000000..2959618cc --- /dev/null +++ b/packages/tandem-designer/src/components/inputs/atoms.pc @@ -0,0 +1,50 @@ +{ + "id": "76b155a0869608", + "version": "0.0.5", + "metadata": {}, + "name": "module", + "children": [ + { + "label": "Input Row", + "is": "div", + "style": { + "display": "flex", + "align-items": "center" + }, + "attributes": {}, + "id": "2657ec412855", + "name": "component", + "children": [], + "metadata": { + "bounds": { + "left": 1305, + "top": 1327, + "right": 1590, + "bottom": 1386.471217980185 + } + }, + "variant": {} + }, + { + "label": "Input Row Item", + "is": "div", + "style": { + "margin-right": "8px", + "box-sizing": "border-box" + }, + "attributes": {}, + "id": "bcda9fb551452", + "name": "component", + "children": [], + "metadata": { + "bounds": { + "left": 1321, + "top": 1474, + "right": 1549, + "bottom": 1538.1275206975329 + } + }, + "variant": {} + } + ] +} \ No newline at end of file diff --git a/packages/tandem-designer/src/components/inputs/button-bar/controller.tsx b/packages/tandem-designer/src/components/inputs/button-bar/controller.tsx new file mode 100644 index 000000000..3d4852a7f --- /dev/null +++ b/packages/tandem-designer/src/components/inputs/button-bar/controller.tsx @@ -0,0 +1,39 @@ +import * as React from "react"; +import cx from "classnames"; +import { EMPTY_ARRAY } from "tandem-common"; +import { BaseButtonBarProps } from "./view.pc"; +import { ButtonBarItem as ButtonBarItemComponent } from "./item.pc"; + +export type ButtonBarOption = { + icon: any; + value: any; +}; + +export type Props = { + options: ButtonBarOption[]; + value: any; + onChangeComplete: any; +}; + +export default (Base: React.ComponentClass) => + class ButtonBarController extends React.PureComponent { + render() { + const { options, value, onChangeComplete } = this.props; + const items = (options || EMPTY_ARRAY).map((item, i) => { + return ( + onChangeComplete(item.value))} + /> + ); + }); + + return ; + } + }; diff --git a/packages/tandem-designer/src/components/inputs/button-bar/item.pc b/packages/tandem-designer/src/components/inputs/button-bar/item.pc new file mode 100644 index 000000000..333b26924 --- /dev/null +++ b/packages/tandem-designer/src/components/inputs/button-bar/item.pc @@ -0,0 +1,129 @@ +{ + "id": "70ef61a6213", + "version": "0.0.6", + "metadata": {}, + "name": "module", + "children": [ + { + "label": "Button Bar Item", + "is": "div", + "style": { + "background": "var(--f63574de434)", + "box-sizing": "border-box", + "width": "100%", + "text-align": "center", + "position": "relative", + "height": "20px", + "border-right": "1px solid var(--d8f6340b1442)", + "color": "rgba(123, 123, 123, 1)", + "padding-left": "6px", + "padding-top": "4px", + "padding-right": "6px", + "padding-bottom": "7px" + }, + "attributes": {}, + "id": "6489655782851", + "name": "component", + "children": [ + { + "label": "icon", + "id": "e42107633", + "children": [ + { + "id": "41cb1f8590628", + "variant": {}, + "is": "38fc2a472503", + "name": "component-instance", + "attributes": {}, + "style": { + "height": "100%", + "color": "var(--24ce1e4d482)" + }, + "children": [], + "metadata": {}, + "label": "icon" + } + ], + "metadata": {}, + "name": "slot" + }, + { + "id": "15d6c81f3", + "name": "variant", + "label": "last", + "isDefault": true, + "children": [], + "metadata": {} + }, + { + "id": "15d6c81f4", + "variantId": "15d6c81f3", + "propertyName": "style", + "targetIdPath": [], + "value": { + "border-right": "none", + "border-top-right-radius": "1px", + "border-bottom-right-radius": "1px" + }, + "name": "override", + "children": [] + }, + { + "id": "15d6c81f5", + "name": "variant", + "label": "selected", + "isDefault": false, + "children": [], + "metadata": {} + }, + { + "id": "15d6c81f6", + "variantId": "15d6c81f5", + "propertyName": "style", + "targetIdPath": [], + "value": { + "background": "#00B5FF", + "color": "rgba(255, 255, 255, 1)" + }, + "name": "override", + "children": [] + }, + { + "id": "af62926b2035", + "name": "variant", + "label": "first", + "isDefault": false, + "children": [], + "metadata": {} + }, + { + "id": "af62926b2036", + "variantId": "af62926b2035", + "propertyName": "style", + "targetIdPath": [], + "value": { + "text-align": "center", + "border-bottom-left-radius": "1px", + "border-top-left-radius": "1px" + }, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": 454, + "top": 415, + "right": 554, + "bottom": 441 + } + }, + "variant": {}, + "styleMixins": { + "dc3b39eb1275": { + "priority": 0 + } + } + } + ] +} \ No newline at end of file diff --git a/packages/tandem-designer/src/components/inputs/button-bar/view.pc b/packages/tandem-designer/src/components/inputs/button-bar/view.pc new file mode 100644 index 000000000..ef5280e8b --- /dev/null +++ b/packages/tandem-designer/src/components/inputs/button-bar/view.pc @@ -0,0 +1,275 @@ +{ + "id": "76b155a0877453", + "version": "0.0.6", + "metadata": {}, + "name": "module", + "children": [ + { + "label": "Button Bar", + "is": "div", + "style": { + "display": "flex", + "align-content": "center", + "border-bottom-left-radius": "2px", + "border-top-left-radius": "2px", + "border-top-right-radius": "2px", + "border-bottom-right-radius": "2px", + "position": "relative", + "padding-left": "1px", + "padding-top": "1px", + "padding-right": "1px", + "padding-bottom": "1px", + "box-sizing": "border-box", + "height": "22px" + }, + "attributes": {}, + "id": "6489655782833", + "name": "component", + "children": [ + { + "label": "items", + "id": "a282a90069", + "children": [ + { + "id": "6489655782852", + "variant": {}, + "is": "6489655782851", + "name": "component-instance", + "attributes": {}, + "style": { + "padding": "4px 8px", + "box-sizing": "border-box", + "width": "100%", + "text-align": "center", + "position": "relative", + "border-top-left-radius": "2px", + "border-bottom-left-radius": "2px" + }, + "children": [ + { + "id": "e5a8a3332761", + "variant": {}, + "is": "38fc2a4713564", + "name": "component-instance", + "attributes": {}, + "style": { + "height": "100%" + }, + "children": [], + "metadata": {} + }, + { + "id": "d789e7004", + "variantId": null, + "propertyName": "isDefault", + "targetIdPath": [ + "15d6c81f3" + ], + "value": false, + "name": "override", + "children": [] + }, + { + "id": "d789e7005", + "variantId": null, + "propertyName": "isDefault", + "targetIdPath": [ + "15d6c81f5" + ], + "value": false, + "name": "override", + "children": [] + } + ], + "metadata": {} + }, + { + "id": "9bb8b8487882", + "variant": {}, + "is": "6489655782851", + "name": "component-instance", + "attributes": {}, + "style": { + "padding": "4px 8px", + "box-sizing": "border-box", + "width": "100%", + "text-align": "center", + "position": "relative" + }, + "children": [ + { + "id": "9bb8b8487883", + "variant": {}, + "is": "38fc2a471274", + "name": "component-instance", + "attributes": {}, + "style": { + "height": "100%" + }, + "children": [], + "metadata": {} + }, + { + "id": "9bb8b8487884", + "variantId": null, + "propertyName": "isDefault", + "targetIdPath": [ + "15d6c81f3" + ], + "value": false, + "name": "override", + "children": [] + }, + { + "id": "9bb8b8487885", + "variantId": null, + "propertyName": "isDefault", + "targetIdPath": [ + "15d6c81f5" + ], + "value": true, + "name": "override", + "children": [] + } + ], + "metadata": {} + }, + { + "id": "6489655782886", + "variant": {}, + "is": "6489655782851", + "name": "component-instance", + "attributes": {}, + "style": { + "padding": "4px 8px", + "box-sizing": "border-box", + "width": "100%", + "text-align": "center", + "position": "relative" + }, + "children": [ + { + "id": "e5a8a33339544", + "variant": {}, + "is": "38fc2a471274", + "name": "component-instance", + "attributes": {}, + "style": { + "height": "100%" + }, + "children": [], + "metadata": {} + }, + { + "id": "d789e7006", + "variantId": null, + "propertyName": "isDefault", + "targetIdPath": [ + "15d6c81f3" + ], + "value": false, + "name": "override", + "children": [] + }, + { + "id": "ddf283f44", + "variantId": null, + "propertyName": "isDefault", + "targetIdPath": [ + "15d6c81f5" + ], + "value": true, + "name": "override", + "children": [] + } + ], + "metadata": {} + }, + { + "id": "6489655797375", + "variant": { + "15d6c81f3": true + }, + "is": "6489655782851", + "name": "component-instance", + "attributes": {}, + "style": { + "padding": "4px 8px", + "box-sizing": "border-box", + "width": "100%", + "border-top-right-radius": "2px", + "border-bottom-right-radius": "2px", + "height": "22px" + }, + "children": [ + { + "id": "e5a8a33342298", + "variant": {}, + "is": "38fc2a4717251", + "name": "component-instance", + "attributes": {}, + "style": { + "height": "100%" + }, + "children": [], + "metadata": {} + }, + { + "id": "ddf283f43", + "variantId": null, + "propertyName": "isDefault", + "targetIdPath": [ + "15d6c81f3" + ], + "value": true, + "name": "override", + "children": [] + } + ], + "metadata": {} + } + ], + "metadata": {}, + "name": "slot" + }, + { + "id": "37f5ce877863", + "label": "border", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "display": "block", + "pointer-events": "none", + "width": "100%", + "position": "absolute", + "left": "0px", + "top": "0px", + "height": "100%" + }, + "children": [], + "metadata": {}, + "styleMixins": { + "c29da5f4213993": { + "priority": 0 + } + } + } + ], + "metadata": { + "bounds": { + "left": 455, + "top": 310, + "right": 688, + "bottom": 352 + } + }, + "controllers": [ + "./controller.tsx" + ], + "variant": {}, + "styleMixins": {} + } + ] +} \ No newline at end of file diff --git a/packages/tandem-designer/src/components/inputs/button-group/index.scss b/packages/tandem-designer/src/components/inputs/button-group/index.scss new file mode 100644 index 000000000..e69de29bb diff --git a/packages/tandem-designer/src/components/inputs/button-group/index.tsx b/packages/tandem-designer/src/components/inputs/button-group/index.tsx new file mode 100644 index 000000000..e69de29bb diff --git a/packages/tandem-designer/src/components/inputs/button/index.scss b/packages/tandem-designer/src/components/inputs/button/index.scss new file mode 100644 index 000000000..e69de29bb diff --git a/packages/tandem-designer/src/components/inputs/button/index.tsx b/packages/tandem-designer/src/components/inputs/button/index.tsx new file mode 100644 index 000000000..e69de29bb diff --git a/packages/tandem-designer/src/components/inputs/button/view.pc b/packages/tandem-designer/src/components/inputs/button/view.pc new file mode 100644 index 000000000..f340178f8 --- /dev/null +++ b/packages/tandem-designer/src/components/inputs/button/view.pc @@ -0,0 +1,99 @@ +{ + "id": "9f364d2139376", + "version": "0.0.6", + "metadata": {}, + "name": "module", + "children": [ + { + "label": "Button", + "is": "div", + "style": { + "box-sizing": "border-box", + "color": "#777", + "cursor": "pointer", + "display": "inline-block", + "padding-left": "8px", + "padding-top": "4px", + "padding-right": "8px", + "padding-bottom": "4px", + "background": "rgba(214, 213, 213, 1)", + "border-bottom-left-radius": "2px", + "border-top-left-radius": "2px", + "border-top-right-radius": "2px", + "border-bottom-right-radius": "2px", + "user-select": "none" + }, + "attributes": {}, + "id": "9f364d2139415", + "name": "component", + "children": [ + { + "id": "9f364d2139650", + "name": "text", + "label": "Text", + "value": "Label", + "style": { + "font-weight": "500", + "user-select": "none" + }, + "children": [], + "metadata": {}, + "styleMixins": { + "dc3b39eb1275": { + "priority": 0 + } + } + }, + { + "id": "38b32d581121", + "name": "variant", + "label": "secondary", + "isDefault": false, + "children": [], + "metadata": {} + }, + { + "id": "38b32d581284", + "variantId": "38b32d581121", + "propertyName": "style", + "targetIdPath": [], + "value": { + "background": "rgba(227, 227, 227, 1)", + "color": "var(--24ce1e4d482)" + }, + "name": "override", + "children": [] + }, + { + "id": "c6acc7ee1385", + "name": "variant", + "label": "disabled", + "isDefault": true, + "children": [], + "metadata": {} + }, + { + "id": "c6acc7ee1386", + "variantId": "c6acc7ee1385", + "propertyName": "style", + "targetIdPath": [], + "value": { + "cursor": "default", + "opacity": 0.253 + }, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": 300, + "top": 120, + "right": 400, + "bottom": 220 + } + }, + "variant": {} + } + ] +} \ No newline at end of file diff --git a/packages/tandem-designer/src/components/inputs/checkbox/controller.tsx b/packages/tandem-designer/src/components/inputs/checkbox/controller.tsx new file mode 100644 index 000000000..450d52dd4 --- /dev/null +++ b/packages/tandem-designer/src/components/inputs/checkbox/controller.tsx @@ -0,0 +1,27 @@ +import * as React from "react"; + +export type Props = { + value: boolean; + onChange?: (value: boolean) => any; + onChangeComplete?: (value: boolean) => any; +}; + +export default (Base: React.ComponentClass) => { + return class CheckboxController extends React.PureComponent { + onClick = (event) => { + const { value, onChange, onChangeComplete } = this.props; + + event.stopPropagation(); + if (onChange) { + onChange(value); + } + if (onChangeComplete) { + onChangeComplete(!value); + } + }; + + render() { + return ; + } + }; +}; diff --git a/packages/tandem-designer/src/components/inputs/checkbox/index.scss b/packages/tandem-designer/src/components/inputs/checkbox/index.scss new file mode 100644 index 000000000..e69de29bb diff --git a/packages/tandem-designer/src/components/inputs/color/canvas-controller.tsx b/packages/tandem-designer/src/components/inputs/color/canvas-controller.tsx new file mode 100644 index 000000000..3c069225e --- /dev/null +++ b/packages/tandem-designer/src/components/inputs/color/canvas-controller.tsx @@ -0,0 +1,145 @@ +import * as React from "react"; +import { noop } from "lodash"; +import { startDOMDrag, Point } from "tandem-common"; +import { compose, pure, withHandlers, withState, lifecycle } from "recompose"; +import { BasePickerProps } from "./picker.pc"; + +export enum GrabberAxis { + X = 1, + Y = X << 1, +} + +export type Props = { + grabberAxis: any; + draw: any; + onChange: any; + onChangeComplete: any; + getGraggerPoint: any; + value: any; +}; + +type InnerProps = { + canvas: HTMLCanvasElement; + setCanvas: any; + grabberPoint: Point; + setGrabberPoint: any; +} & Props; + +export default compose( + pure, + withState(`canvas`, `setCanvas`, null), + withState(`grabberPoint`, `setGrabberPoint`, null), + withHandlers(() => { + let _canvas: HTMLCanvasElement; + return { + onCanvas: + ({ setCanvas, draw = noop }: InnerProps) => + (canvas: HTMLCanvasElement) => { + setCanvas((_canvas = canvas)); + if (canvas) { + // need to set immediate to ensure that canvas is actually mounted + setImmediate(() => { + const { width, height } = + canvas.parentElement.getBoundingClientRect(); + draw(canvas, width || 100, height || 100); + }); + } + }, + onMouseDown: + ({ + grabberAxis, + setGrabberPoint, + onChange, + onChangeComplete, + }: InnerProps) => + (event) => { + const rect = _canvas.getBoundingClientRect(); + + const handleChange = (callback) => (event) => { + const point = { + left: + grabberAxis & GrabberAxis.X + ? Math.max( + 0, + Math.min(rect.width - 1, event.clientX - rect.left) + ) + : 0, + top: + grabberAxis & GrabberAxis.Y + ? Math.max( + 0, + Math.min(rect.height - 1, event.clientY - rect.top) + ) + : 0, + }; + if (callback) { + const imageData = _canvas + .getContext("2d") + .getImageData(point.left, point.top, 1, 1).data; + + callback(imageData); + } + + setGrabberPoint(point); + }; + + startDOMDrag( + event, + noop, + handleChange(onChange), + handleChange(onChangeComplete) + ); + }, + }; + }), + lifecycle({ + componentDidUpdate({ + setGrabberPoint, + getGraggerPoint, + draw, + canvas, + value, + }: InnerProps) { + if (canvas && this.props.draw !== draw && this.props.draw) { + setImmediate(() => { + const { width, height } = + canvas.parentElement.getBoundingClientRect(); + this.props.draw(canvas, width, height); + }); + } + + if (canvas && this.props.value !== value) { + setImmediate(() => { + const { width, height } = + canvas.parentElement.getBoundingClientRect(); + setGrabberPoint(getGraggerPoint(this.props.value, width, height)); + }); + } + }, + }), + (Base: React.ComponentClass) => + ({ + onMouseDown, + onCanvas, + grabberAxis, + draw, + onChange, + onChangeComplete, + canvas, + grabberPoint, + ...rest + }) => { + return ( + + ); + } +); diff --git a/packages/tandem-designer/src/components/inputs/color/color-input-controller.tsx b/packages/tandem-designer/src/components/inputs/color/color-input-controller.tsx new file mode 100644 index 000000000..12f30a765 --- /dev/null +++ b/packages/tandem-designer/src/components/inputs/color/color-input-controller.tsx @@ -0,0 +1,88 @@ +import * as React from "react"; +import { EMPTY_ARRAY } from "tandem-common"; +import { BaseColorInputProps, ElementProps } from "./view.pc"; +import { ColorPicker } from "./picker.pc"; +import { + maybeConvertSwatchValueToColor, + ColorSwatchGroup, +} from "./color-swatch-controller"; + +export type ColorPickerProps = { + value: string; + onChange: any; + onChangeComplete: any; + swatchOptionGroups: ColorSwatchGroup[]; +}; + +export type Props = { + value: string; + onChange: any; + onChangeComplete: any; + swatchOptionGroups: ColorSwatchGroup[]; + renderColorPicker?: (props: ColorPickerProps) => any; +} & ElementProps; + +export default (Base: React.ComponentClass) => + class ColorInputController extends React.PureComponent { + state = { open: false }; + onButtonClick = () => { + this.setState({ ...this.state, open: !this.state.open }); + }; + onShouldClose = () => { + this.setState({ ...this.state, open: false }); + }; + render() { + let popdownChildren: any = EMPTY_ARRAY; + const { open } = this.state; + + const { + value, + onChange, + swatchOptionGroups, + onChangeComplete, + renderColorPicker, + ...rest + } = this.props; + const { onButtonClick, onShouldClose } = this; + + if (open) { + popdownChildren = renderColorPicker ? ( + renderColorPicker({ + value: value || "#FF0000", + onChange, + onChangeComplete, + swatchOptionGroups, + }) + ) : ( + + ); + } + + return ( + + ); + } + }; diff --git a/packages/tandem-designer/src/components/inputs/color/color-swatch-controller.tsx b/packages/tandem-designer/src/components/inputs/color/color-swatch-controller.tsx new file mode 100644 index 000000000..6b4f237e6 --- /dev/null +++ b/packages/tandem-designer/src/components/inputs/color/color-swatch-controller.tsx @@ -0,0 +1,157 @@ +import * as React from "react"; +import cx from "classnames"; +import { BaseColorSwatchesProps, ColorSwatchItem } from "./picker.pc"; +import { EMPTY_ARRAY, memoize } from "tandem-common"; +import { DropdownMenuOption } from "../dropdown/controller"; + +export const maybeConvertSwatchValueToColor = ( + value: string, + swatchOptionGroups: ColorSwatchGroup[] = [] +) => { + for (const group of swatchOptionGroups) { + const option = group.options.find((option) => option.value === value); + if (option) { + return option.color; + } + } + return value; +}; + +export type ColorSwatchGroup = { + label: string; + options: ColorSwatchOption[]; +}; + +export type ColorSwatchOption = { + value: string; + color: string; +}; + +export const mapValueToColorSwatch = (value: string): ColorSwatchOption => ({ + value, + color: value, +}); + +export const getColorSwatchOptionsFromValues = memoize((value: string[]) => + value.map(mapValueToColorSwatch) +); + +export type Props = { + onChange: (value: string) => any; + value: string; + optionGroups: ColorSwatchGroup[]; +}; + +export type State = { + selectedGroupIndex: number; + value: string; +}; + +const getColorSwatchGroupFromValue = ( + value: string, + groups: ColorSwatchGroup[] +) => { + if (!groups.length) { + return 0; + } + for (const group of groups) { + const option = group.options.find((option) => option.value === value); + if (option) { + return group; + } + } + return groups[0]; +}; + +export default (Base: React.ComponentClass) => + class ColorSwatchesController extends React.PureComponent { + state = { + selectedGroupIndex: 0, + value: null, + }; + static getDerivedStateFromProps(nextProps: Props, prevState: State): State { + if ( + nextProps.value !== prevState.value && + nextProps.optionGroups.length + ) { + const selectedGroup = getColorSwatchGroupFromValue( + nextProps.value, + nextProps.optionGroups + ); + return { + selectedGroupIndex: selectedGroup + ? nextProps.optionGroups.indexOf(selectedGroup) + : 0, + value: nextProps.value, + }; + } + return null; + } + onGroupChange = (group: ColorSwatchGroup) => { + this.setState({ + ...this.state, + selectedGroupIndex: this.props.optionGroups.indexOf(group), + }); + }; + render() { + const { + value: selectedValue, + optionGroups = EMPTY_ARRAY, + onChange, + ...rest + } = this.props; + const { onGroupChange } = this; + const { selectedGroupIndex } = this.state; + + if (!optionGroups.length) { + return null; + } + + const selectedGroup = + optionGroups[Math.min(selectedGroupIndex, optionGroups.length - 1)]; + + const content = selectedGroup.options.map( + ({ color, value, label }, i) => { + return ( + onChange(value)} + pillProps={{ + style: { + background: color, + }, + }} + /> + ); + } + ); + + return ( + 1, + })} + swatchSourceInputProps={{ + value: selectedGroup, + options: mapColorSwatchGroupsToDropdownOptions(optionGroups), + onChangeComplete: onGroupChange, + }} + content={content} + /> + ); + } + }; + +const mapColorSwatchGroupsToDropdownOptions = memoize( + (groups: ColorSwatchGroup[]): DropdownMenuOption[] => { + return groups.map((group) => ({ + label: group.label, + value: group, + })); + } +); diff --git a/packages/tandem-designer/src/components/inputs/color/hex-input-controller.tsx b/packages/tandem-designer/src/components/inputs/color/hex-input-controller.tsx new file mode 100644 index 000000000..e8bfec19e --- /dev/null +++ b/packages/tandem-designer/src/components/inputs/color/hex-input-controller.tsx @@ -0,0 +1,11 @@ +import * as React from "react"; +import { BaseHexInputProps } from "./picker.pc"; + +export type Props = BaseHexInputProps; + +export default (Base: React.ComponentClass) => + class HexInputController extends React.PureComponent { + render() { + return ; + } + }; diff --git a/packages/tandem-designer/src/components/inputs/color/index.scss b/packages/tandem-designer/src/components/inputs/color/index.scss new file mode 100644 index 000000000..34fcd5f56 --- /dev/null +++ b/packages/tandem-designer/src/components/inputs/color/index.scss @@ -0,0 +1,48 @@ +.m-color-picker { + width: 300px; + background: var(--background-3); + border-radius: 4px; + box-shadow: 0 0 0 1px var(--boundary-color-1); + .content { + padding: 4px; + } + .settings { + width: 100%; + } + canvas { + vertical-align: bottom; + } + .knob { + position: absolute; + top: 0; + left: 0; + cursor: pointer; + background: transparent; + border: 1px solid var(--boundary-color-1); + box-shadow: inset 0px 0px 0px 1px white; + } + .palette { + position: relative; + margin-bottom: 4px; + } + .hsl { + .knob { + border-radius: 50%; + width: 15px; + height: 15px; + transform: translate(-50%, -50%); + } + } + .spectrum, + .opacity { + .knob { + height: 100%; + width: 15px; + border-radius: 2px; + transform: translateX(-50%); + } + } + + .presets { + } +} diff --git a/packages/tandem-designer/src/components/inputs/color/login-form-controller.tsx b/packages/tandem-designer/src/components/inputs/color/login-form-controller.tsx new file mode 100644 index 000000000..e69de29bb diff --git a/packages/tandem-designer/src/components/inputs/color/picker-controller.tsx b/packages/tandem-designer/src/components/inputs/color/picker-controller.tsx new file mode 100644 index 000000000..a2261ee50 --- /dev/null +++ b/packages/tandem-designer/src/components/inputs/color/picker-controller.tsx @@ -0,0 +1,378 @@ +import * as React from "react"; +import cx from "classnames"; +import { pure, compose, lifecycle, withState, withHandlers } from "recompose"; +import { memoize, EMPTY_ARRAY } from "tandem-common"; +import { GrabberAxis } from "./canvas-controller"; +import { throttle, identity } from "lodash"; +import { BasePickerProps, BaseColorPickerProps } from "./picker.pc"; +import { + ColorSwatchOption, + maybeConvertSwatchValueToColor, + ColorSwatchGroup, +} from "./color-swatch-controller"; + +const CHANGE_THROTTLE_MS = 1000 / 20; + +type RGBA = [number, number, number, number]; +type HSLA = [number, number, number, number]; + +export type Props = { + value: string; + onChange?: any; + onChangeComplete?: any; + swatchOptionGroups: ColorSwatchGroup[]; +}; + +type InnerProps = { + hsla: any; + setHSLA: any; + selectedSwatchGroupIndex: number; + onColorSwatchChange: any; + onRGBAInputChange: any; + onRGBAInputChangeComplete: any; + onHSLChange: any; + onHSLChangeComplete: any; + onSpectrumChange: any; + onSpectrumChangeComplete: any; + onOpacityChange: any; + onOpacityChangeComplete: any; +} & Props; + +export default compose( + pure, + withState( + `hsla`, + `setHSLA`, + ({ value = "#000", swatchOptionGroups = EMPTY_ARRAY }: Props) => { + value = maybeConvertSwatchValueToColor(value, swatchOptionGroups); + const rgba = parseRGBA(value); + return rgbaToHsla(rgba); + } + ), + lifecycle({ + componentWillUpdate(props: InnerProps) { + if (this.props.value !== props.value) { + const rgba = parseRGBA( + maybeConvertSwatchValueToColor(props.value, props.swatchOptionGroups) + ); + const hsla = rgbaToHsla(rgba); + if (hsla.join("") !== props.hsla.join("")) { + this.props.setHSLA(hsla); + } + } + }, + }), + withHandlers(() => { + const colorChangeCallback = + (updater) => + ({ onChange, hsla, setHSLA }: InnerProps) => + throttle((rgba) => { + setHSLA((hsla = updater(rgba, hsla))); + if (onChange) { + onChange(stringifyRgba(hslaToRgba(hsla))); + } + }, CHANGE_THROTTLE_MS); + + const colorChangeCompleteCallback = + (updater) => + ({ onChangeComplete, hsla, setHSLA }) => + (rgba) => { + setHSLA((hsla = updater(rgba, hsla))); + if (onChangeComplete) { + setTimeout( + onChangeComplete, + CHANGE_THROTTLE_MS * 2, + stringifyRgba(hslaToRgba(hsla)) + ); + } + }; + + return { + onHSLChange: colorChangeCallback(updateHSLA), + onHSLChangeComplete: colorChangeCompleteCallback(updateHSLA), + onSpectrumChange: colorChangeCallback(updateHue), + onSpectrumChangeComplete: colorChangeCompleteCallback(updateHue), + onOpacityChange: colorChangeCallback(updateOpacity), + onOpacityChangeComplete: colorChangeCompleteCallback(updateOpacity), + onRGBAInputChange: colorChangeCallback(rgbaToHsla), + onRGBAInputChangeComplete: colorChangeCompleteCallback(rgbaToHsla), + onColorSwatchChange: + ({ onChange, onChangeComplete }) => + (value) => { + if (onChange) { + onChange(value); + } + + if (onChangeComplete) { + onChangeComplete(value); + } + }, + }; + }), + (Base: React.ComponentClass) => + ({ + value, + hsla, + onChange, + onChangeComplete, + onRGBAInputChange, + onRGBAInputChangeComplete, + onColorSwatchChange, + onHSLChange, + onHSLChangeComplete, + onSpectrumChange, + onSpectrumChangeComplete, + swatchOptionGroups = EMPTY_ARRAY, + onOpacityChange, + onOpacityChangeComplete, + ...rest + }: InnerProps) => { + const rgba = hslaToRgba(hsla); + return ( + + ); + } +); + +const stringifyRgba = ([r, g, b, a]: RGBA) => `rgba(${r}, ${g}, ${b}, ${a})`; + +const hslDrawer = memoize( + (h: number) => + (canvas: HTMLCanvasElement, width: number = 100, height: number = 100) => { + const hv = h * 360; + const ctx = canvas.getContext("2d"); + canvas.width = width; + canvas.height = height; + + for (let row = 0; row <= height; row++) { + let grad = ctx.createLinearGradient(0, 0, width, 0); + grad.addColorStop( + 1, + `hsl(${hv}, 0%, ${((height - row) / height) * 100}%)` + ); + grad.addColorStop( + 0, + `hsl(${hv}, 100%, ${((height - row) / height) * 50}%)` + ); + ctx.fillStyle = grad; + ctx.fillRect(0, row, width, 1); + } + } +); + +const hslPointer = (hsl: HSLA, width: number, height: number) => { + const [h, s, v] = hslToHsv(hsl); + return { + left: width * (1 - s), + top: height * (1 - v), + }; +}; + +const opacityPointer = ([h, s, l, a]: HSLA, width: number, height: number) => { + return { + left: width * a, + }; +}; + +const huePointer = ([h]: HSLA, width: number, height: number) => { + return { + left: (width * (h * 360)) / 360, + }; +}; + +const hueDrawer = ( + canvas: HTMLCanvasElement, + width: number, + height: number +) => { + const ctx = canvas.getContext("2d"); + canvas.width = width; + canvas.height = height; + + for (let row = 0; row <= width; row++) { + ctx.fillStyle = `hsl(${((row - width) / width) * 360}, 100%, 50%)`; + ctx.fillRect(row, 0, 1, height); + } +}; + +const opacityDrawer = memoize( + (h: number) => (canvas: HTMLCanvasElement, width: number, height: number) => { + let ctx = canvas.getContext("2d"); + const hv = h * 360; + canvas.width = width; + canvas.height = height; + for (let row = 0; row <= width; row++) { + ctx.fillStyle = `hsl(${hv}, 100%, ${((width - row) / width) * 50 + 50}%)`; + ctx.fillRect(row, 0, 1, height); + } + } +); + +const updateOpacity = (rgba: RGBA, [h, s, l]: HSLA) => { + const l2 = rgbaToHsla(rgba)[2]; + return [h, s, l, lToA(l2)]; +}; + +const lToA = (l) => + Number((1 - Math.min(0.5, Math.max(0, l - 0.5)) / 0.5).toFixed(2)); + +const updateHue = (rgba: RGBA, [, s, l, a]: HSLA) => [ + rgbaToHsla(rgba)[0], + s, + l, + a, +]; +const updateHSLA = (rgba: RGBA, [h, , , a]: HSLA) => { + const [, s, l] = rgbaToHsla(rgba); + return [h, s, l, a]; +}; + +const rgbaToHsla = ([r, g, b, a]: RGBA) => { + (r /= 255), (g /= 255), (b /= 255); + let max = Math.max(r, g, b), + min = Math.min(r, g, b); + let h, + s, + l = (max + min) / 2; + if (max == min) { + h = s = 0; // achromatic + } else { + let d = max - min; + s = l > 0.5 ? d / (2 - max - min) : d / (max + min); + switch (max) { + case r: + h = (g - b) / d + (g < b ? 6 : 0); + break; + case g: + h = (b - r) / d + 2; + break; + case b: + h = (r - g) / d + 4; + break; + } + h /= 6; + } + + return [h, s, l, a]; +}; + +const hueToRgb = (p, q, t) => { + if (t < 0) t += 1; + if (t > 1) t -= 1; + if (t < 1 / 6) return p + (q - p) * 6 * t; + if (t < 1 / 2) return q; + if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; + return p; +}; + +const hslaToRgba = ([h, s, l, a]: HSLA): RGBA => { + let r, g, b; + + if (s == 0) { + r = g = b = l; + } else { + let q = l < 0.5 ? l * (1 + s) : l + s - l * s; + let p = 2 * l - q; + r = hueToRgb(p, q, h + 1 / 3); + g = hueToRgb(p, q, h); + b = hueToRgb(p, q, h - 1 / 3); + } + + return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255), a]; +}; + +const rgbToHsv = ([r, g, b]: RGBA) => { + (r /= 255), (g /= 255), (b /= 255); + + var max = Math.max(r, g, b), + min = Math.min(r, g, b); + var h, + s, + v = max; + + var d = max - min; + s = max == 0 ? 0 : d / max; + + if (max == min) { + h = 0; // achromatic + } else { + switch (max) { + case r: + h = (g - b) / d + (g < b ? 6 : 0); + break; + case g: + h = (b - r) / d + 2; + break; + case b: + h = (r - g) / d + 4; + break; + } + + h /= 6; + } + + return [h, s, v]; +}; + +const hslToHsv = (hsl: HSLA) => rgbToHsv(hslaToRgba(hsl)); + +const parseRGBA = memoize((value: string): RGBA => { + if (value.indexOf("rgba") !== -1) { + return ((value.match(/[\d\.]+/g) as any) || [0, 0, 0, 1]).map(Number) as [ + number, + number, + number, + number + ]; + } + let result = + /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(value) || + /^#?([a-f\d]{1})([a-f\d]{1})([a-f\d]{1})$/i.exec(value); + return result + ? [ + parseInt(result[1], 16), + parseInt(result[2], 16), + parseInt(result[3], 16), + 1, + ] + : [0, 0, 0, 1]; +}); diff --git a/packages/tandem-designer/src/components/inputs/color/picker.pc b/packages/tandem-designer/src/components/inputs/color/picker.pc new file mode 100644 index 000000000..4e2e40fc3 --- /dev/null +++ b/packages/tandem-designer/src/components/inputs/color/picker.pc @@ -0,0 +1,1320 @@ +{ + "id": "b5f797ed34250", + "version": "0.0.6", + "metadata": {}, + "name": "module", + "children": [ + { + "label": "Color Picker", + "is": "div", + "style": { + "box-sizing": "border-box", + "background": "var(--bc891e755312)", + "display": "inline-block", + "flex-direction": "column", + "position": "relative", + "opacity": "1", + "text-align": "left", + "border-top-left-radius": "2px", + "border-top-right-radius": "2px", + "border-bottom-left-radius": "2px", + "border-bottom-right-radius": "2px", + "border-left": "1px solid rgba(230, 230, 230, 1)", + "border-top": "1px solid rgba(230, 230, 230, 1)", + "border-right": "1px solid rgba(230, 230, 230, 1)", + "border-bottom": "1px solid rgba(230, 230, 230, 1)", + "width": "250px" + }, + "attributes": {}, + "id": "67e386c762", + "name": "component", + "children": [ + { + "id": "e879c5401", + "label": "inputs", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "display": "block", + "padding-left": "12px", + "padding-top": "12px", + "padding-right": "12px", + "padding-bottom": "12px" + }, + "children": [ + { + "id": "41979411451593", + "variant": {}, + "is": "41979411419193", + "name": "component-instance", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "position": "relative", + "height": "120px", + "width": "100%", + "opacity": "0.991", + "border": "0px rgba(230, 230, 230, 1)" + }, + "children": [], + "metadata": {}, + "label": "HSL" + }, + { + "id": "41979411464689", + "variant": {}, + "is": "41979411419193", + "name": "component-instance", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "position": "relative", + "height": "12px", + "width": "100%", + "margin-top": "12px", + "border": "0px var(--d8f6340b1442)", + "opacity": "0.991" + }, + "children": [ + { + "id": "41979411527242", + "propertyName": "style", + "targetIdPath": [ + "41979411425672" + ], + "value": { + "height": "100%", + "transform": "translateX(-50%)", + "border-radius": "2px", + "left": "20%", + "top": "0", + "border": "1px solid var(--24ce1e4d482)", + "width": "12px" + }, + "name": "override", + "children": [] + }, + { + "id": "43fa80869887", + "variantId": "43fa80867728", + "propertyName": "style", + "targetIdPath": [ + "41979411425672" + ], + "value": { + "border-top-left-radius": "2px", + "border-top-right-radius": "2px", + "border-bottom-left-radius": "2px", + "border-bottom-right-radius": "2px" + }, + "name": "override", + "children": [] + } + ], + "metadata": {}, + "label": "Spectrum" + }, + { + "id": "41979411490970", + "variant": {}, + "is": "41979411419193", + "name": "component-instance", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "position": "relative", + "height": "12px", + "width": "100%", + "margin-top": "12px", + "border": "0px var(--d8f6340b1442)", + "opacity": "0.991" + }, + "children": [ + { + "id": "41979411514101", + "propertyName": "style", + "targetIdPath": [ + "41979411425672" + ], + "value": { + "height": "100%", + "transform": "translateX(-50%)", + "border-radius": "2px", + "left": "50%", + "border": "1px solid var(--24ce1e4d482)", + "width": "12px" + }, + "name": "override", + "children": [] + }, + { + "id": "43fa80869888", + "variantId": "43fa80867728", + "propertyName": "style", + "targetIdPath": [ + "41979411425672" + ], + "value": { + "border-top-left-radius": "2px", + "border-top-right-radius": "2px", + "border-bottom-left-radius": "2px", + "border-bottom-right-radius": "2px" + }, + "name": "override", + "children": [] + } + ], + "metadata": {}, + "label": "Opacity" + }, + { + "id": "d227ff68422144", + "variant": {}, + "is": "d227ff68422143", + "name": "component-instance", + "attributes": {}, + "style": { + "flex-shrink": "0", + "margin-top": "12px", + "display": "flex", + "align-items": "center", + "width": "100%" + }, + "children": [], + "metadata": {}, + "label": "RGBA Input" + } + ], + "metadata": {} + }, + { + "id": "db9643831", + "is": "dc9a302c2", + "name": "component-instance", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "display": "block", + "padding-left": "4px", + "border-top": "1px solid var(--d8f6340b1442)" + }, + "children": [ + { + "id": "d7ae73f2333", + "variantId": "d7ae73f2167", + "propertyName": "style", + "targetIdPath": [ + "db9643831" + ], + "value": { + "display": "none" + }, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": -624.4534349901305, + "top": 1316.2966411360896, + "right": -184.86213781856583, + "bottom": 1416.2966411360896 + } + }, + "label": "Color Swatches" + }, + { + "id": "d7ae73f2167", + "name": "variant", + "label": "no-swatches", + "isDefault": false, + "children": [], + "metadata": {} + }, + { + "id": "43fa80867728", + "name": "variant", + "label": "gradient", + "isDefault": true, + "children": [], + "metadata": {} + }, + { + "id": "43fa80867750", + "name": "variant", + "label": "no tabs", + "isDefault": false, + "children": [], + "metadata": {} + }, + { + "id": "43fa80867751", + "variantId": "43fa80867750", + "propertyName": "style", + "targetIdPath": [ + "43fa80867729" + ], + "value": { + "display": "none" + }, + "name": "override", + "children": [] + }, + { + "id": "43fa80867772", + "variantId": "43fa80867728", + "propertyName": "style", + "targetIdPath": [ + "43fa80867752" + ], + "value": { + "display": "block", + "padding-top": "6px", + "padding-bottom": "6px", + "border-top": "0px solid var(--d8f6340b1442)", + "border-bottom": "1px solid var(--d8f6340b1442)" + }, + "name": "override", + "children": [] + }, + { + "id": "43fa80869884", + "variantId": "43fa80867728", + "propertyName": "style", + "targetIdPath": [ + "41979411464689" + ], + "value": { + "height": "20px" + }, + "name": "override", + "children": [] + }, + { + "id": "43fa80869885", + "variantId": "43fa80867728", + "propertyName": "style", + "targetIdPath": [ + "43fa80869788" + ], + "value": { + "height": "20px" + }, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": -528, + "top": 367, + "right": -98, + "bottom": 910 + }, + "mode": "preview" + }, + "controllers": [ + "./picker-controller.tsx" + ], + "variant": {}, + "export": { + "name": "ColorPicker" + }, + "styleMixins": { + "fb4d37ca18486": { + "priority": 0 + } + } + }, + { + "label": "RGBA Input", + "is": "div", + "style": { + "flex-shrink": "0", + "margin-top": "10px", + "display": "flex", + "align-items": "center" + }, + "attributes": {}, + "id": "d227ff68422143", + "name": "component", + "children": [ + { + "id": "d227ff68422138", + "name": "text", + "label": "Label", + "value": "RGBA", + "style": { + "font-size": "0.8em", + "margin-right": "8px" + }, + "children": [], + "metadata": {}, + "styleMixins": { + "dc3b39eb1275": { + "priority": 0 + } + } + }, + { + "id": "d227ff68422139", + "variant": {}, + "is": "7149f8199122", + "name": "component-instance", + "attributes": {}, + "style": { + "width": "100%", + "padding": "4px 8px", + "border-radius": "2px", + "box-sizing": "border-box", + "margin-right": "8px", + "flex": "1" + }, + "children": [], + "metadata": {}, + "label": "R Input" + }, + { + "id": "d227ff68422140", + "variant": {}, + "is": "7149f8199122", + "name": "component-instance", + "attributes": {}, + "style": { + "width": "100%", + "padding": "4px 8px", + "border-radius": "2px", + "box-sizing": "border-box", + "margin-right": "8px", + "flex": "1" + }, + "children": [], + "metadata": {}, + "label": "G Input" + }, + { + "id": "d227ff68422141", + "variant": {}, + "is": "7149f8199122", + "name": "component-instance", + "attributes": {}, + "style": { + "width": "100%", + "padding": "4px 8px", + "border-radius": "2px", + "box-sizing": "border-box", + "margin-right": "8px", + "flex": "1" + }, + "children": [], + "metadata": {}, + "label": "B Input" + }, + { + "id": "d227ff68422142", + "variant": {}, + "is": "7149f8199122", + "name": "component-instance", + "attributes": {}, + "style": { + "width": "100%", + "padding": "4px 8px", + "border-radius": "2px", + "box-sizing": "border-box", + "flex": "1" + }, + "children": [], + "metadata": {}, + "label": "A Input" + } + ], + "metadata": { + "bounds": { + "left": 409, + "top": 539, + "right": 727.4505475827968, + "bottom": 611.4821398220452 + } + }, + "controllers": [ + "./rgba-input-controller.tsx" + ], + "variant": {} + }, + { + "label": "HSL Input", + "is": "div", + "style": { + "flex-shrink": "0", + "margin-top": "10px", + "display": "flex", + "align-items": "center" + }, + "attributes": {}, + "id": "d227ff68507402", + "name": "component", + "children": [ + { + "id": "d227ff68507398", + "name": "text", + "label": "Label", + "value": "HSLA", + "style": { + "margin-right": "8px" + }, + "children": [], + "metadata": {}, + "styleMixins": { + "dc3b39eb1275": { + "priority": 0 + } + } + }, + { + "id": "d227ff68507399", + "variant": {}, + "is": "7149f8199122", + "name": "component-instance", + "attributes": {}, + "style": { + "width": "100%", + "padding": "4px 8px", + "border-radius": "2px", + "box-sizing": "border-box", + "margin-right": "8px", + "flex": "1" + }, + "children": [], + "metadata": { + "bounds": { + "left": 354.28125, + "top": 91.5, + "right": 416.71875, + "bottom": 114.5 + } + }, + "label": "R Input" + }, + { + "id": "d227ff68507400", + "variant": {}, + "is": "7149f8199122", + "name": "component-instance", + "attributes": {}, + "style": { + "width": "100%", + "padding": "4px 8px", + "border-radius": "2px", + "box-sizing": "border-box", + "margin-right": "8px", + "flex": "1" + }, + "children": [], + "metadata": {}, + "label": "G Input" + }, + { + "id": "d227ff68507401", + "variant": {}, + "is": "7149f8199122", + "name": "component-instance", + "attributes": {}, + "style": { + "width": "100%", + "padding": "4px 8px", + "border-radius": "2px", + "box-sizing": "border-box", + "flex": "1", + "margin-right": "8px" + }, + "children": [], + "metadata": {}, + "label": "A Input" + }, + { + "id": "d227ff68557441", + "variant": {}, + "is": "7149f8199122", + "name": "component-instance", + "attributes": {}, + "style": { + "width": "100%", + "padding": "4px 8px", + "border-radius": "2px", + "box-sizing": "border-box", + "flex": "1" + }, + "children": [], + "metadata": {}, + "label": "A Input" + } + ], + "metadata": { + "bounds": { + "left": 409, + "top": 700, + "right": 712.974934087616, + "bottom": 800 + } + }, + "variant": {} + }, + { + "label": "Hex Input", + "is": "div", + "style": { + "flex-shrink": "0", + "margin-top": "10px", + "display": "flex", + "align-items": "center" + }, + "attributes": {}, + "id": "d227ff68554496", + "name": "component", + "children": [ + { + "id": "d227ff68554494", + "name": "text", + "label": "Label", + "value": "HEX", + "style": { + "margin-right": "8px" + }, + "children": [], + "metadata": { + "bounds": { + "left": 302, + "top": 230.5, + "right": 326.90625, + "bottom": 245.5 + } + }, + "styleMixins": { + "dc3b39eb1275": { + "priority": 0 + } + } + }, + { + "id": "d227ff68554495", + "variant": {}, + "is": "7149f8199122", + "name": "component-instance", + "attributes": {}, + "style": { + "width": "100%", + "padding": "4px 8px", + "border-radius": "2px", + "box-sizing": "border-box", + "margin-right": "8px", + "flex": "1" + }, + "children": [], + "metadata": { + "bounds": { + "left": 354.28125, + "top": 91.5, + "right": 416.71875, + "bottom": 114.5 + } + }, + "label": "R Input" + } + ], + "metadata": { + "bounds": { + "left": 411, + "top": 376, + "right": 729.7131272135463, + "bottom": 476 + } + }, + "controllers": [ + "./hex-input-controller.tsx" + ], + "variant": {} + }, + { + "label": "Grabber", + "is": "div", + "style": { + "border": "1px solid rgba(0,0,0,0.5)", + "width": "10px", + "height": "10px", + "position": "absolute", + "box-sizing": "border-box", + "background": "transparent", + "transform": "translate(-50%, -50%)" + }, + "attributes": {}, + "id": "5c08964d24625", + "name": "component", + "children": [], + "metadata": { + "bounds": { + "left": 987, + "top": 409, + "right": 1029, + "bottom": 459 + } + }, + "variant": {} + }, + { + "label": "Slider", + "is": "5c08964d24625", + "style": { + "border": "1px solid rgba(0,0,0,0.5)", + "width": "10px", + "height": "100%", + "position": "absolute", + "box-sizing": "border-box", + "background": "transparent", + "transform": "translateX(-50%)", + "border-radius": "2px" + }, + "attributes": {}, + "id": "5c08964d900983", + "name": "component", + "children": [], + "metadata": { + "bounds": { + "left": 1105, + "top": 418, + "right": 1168.3510347837232, + "bottom": 453.34755795148203 + } + }, + "variant": {} + }, + { + "id": "236ecf1a47759", + "label": "Preview", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "opacity": "1", + "background-image": "linear-gradient(rgba(241, 240, 240, 1), rgba(241, 240, 240, 1))" + }, + "children": [ + { + "id": "236ecf1a44568", + "variant": { + "43fa80867728": true, + "43fa80867750": true + }, + "is": "67e386c762", + "name": "component-instance", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "background": "white", + "border-radius": "2px", + "border": "1px solid rgba(200, 200, 200, 1)", + "display": "inline-block", + "flex-direction": "column", + "position": "relative", + "top": "100px", + "left": "100px" + }, + "children": [ + { + "id": "f4c968d148331", + "propertyName": "style", + "targetIdPath": [ + "f4c968d135444" + ], + "value": {}, + "name": "override", + "children": [] + }, + { + "id": "4197941155264", + "propertyName": "style", + "targetIdPath": [ + "4197941151996" + ], + "value": {}, + "name": "override", + "children": [] + }, + { + "id": "2477db583351", + "propertyName": "style", + "targetIdPath": [ + "41979411451593" + ], + "value": { + "position": "relative" + }, + "name": "override", + "children": [] + }, + { + "id": "24ce1e4d13225", + "propertyName": "style", + "targetIdPath": [ + "db9643831", + "b9d1103b8" + ], + "value": { + "background": "var(--24ce1e4d13456)" + }, + "name": "override", + "children": [] + }, + { + "id": "af5ebdc666", + "propertyName": "style", + "targetIdPath": [ + "41979411464689" + ], + "value": { + "opacity": "0.991", + "height": "10px" + }, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": 81, + "top": 365, + "right": 370.0470628523325, + "bottom": 613.3866802446275 + } + } + } + ], + "metadata": { + "bounds": { + "left": -55, + "top": 885, + "right": 619.3156420694501, + "bottom": 1459.8171978505472 + } + } + }, + { + "label": "Picker", + "is": "div", + "style": { + "box-sizing": "border-box", + "position": "relative", + "height": "100px", + "opacity": "0.991", + "background": "var(--f63574de434)", + "width": "100%" + }, + "attributes": {}, + "id": "41979411419193", + "name": "component", + "children": [ + { + "id": "f3a25ab6666", + "label": "canvas container", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "width": "100%", + "height": "100%", + "position": "absolute", + "top": "0", + "left": "0", + "overflow": "hidden", + "border-radius": "2px" + }, + "children": [ + { + "id": "41979411419192", + "label": "canvas", + "is": "canvas", + "name": "element", + "attributes": {}, + "style": { + "width": "100%", + "height": "100%", + "position": "absolute", + "left": "0px" + }, + "children": [], + "metadata": {}, + "styleMixins": { + "c29da5f4213993": { + "priority": 0 + } + } + } + ], + "metadata": {} + }, + { + "id": "41979411425672", + "variant": {}, + "is": "5c08964d24625", + "name": "component-instance", + "attributes": {}, + "style": { + "border": "1px solid var(--24ce1e4d482)", + "width": "10px", + "height": "10px", + "position": "absolute", + "box-sizing": "border-box", + "background": "transparent", + "transform": "translate(-50%, -50%)", + "top": "0px", + "border-top-left-radius": "10px", + "border-top-right-radius": "10px", + "border-bottom-left-radius": "10px", + "border-bottom-right-radius": "10px" + }, + "children": [], + "metadata": {}, + "label": "grabber" + } + ], + "metadata": { + "bounds": { + "left": 530, + "top": 160, + "right": 630, + "bottom": 260 + } + }, + "controllers": [ + "./canvas-controller.tsx" + ], + "variant": {}, + "styleMixins": {} + }, + { + "label": "Color Swatches", + "is": "div", + "style": { + "box-sizing": "border-box", + "display": "block", + "padding-left": "4px", + "padding-top": "4px", + "padding-right": "5px", + "padding-bottom": "4px" + }, + "attributes": {}, + "id": "dc9a302c2", + "name": "component", + "children": [ + { + "id": "52771059438", + "is": "50e32bec2591", + "label": "swatch source input", + "name": "component-instance", + "attributes": {}, + "style": { + "margin-bottom": "8px", + "margin-top": "4px", + "display": "none" + }, + "children": [ + { + "id": "527710593085", + "variantId": null, + "propertyName": "text", + "targetIdPath": [ + "67e386c7935" + ], + "value": "Global colors", + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": 133, + "top": 279, + "right": 334, + "bottom": 521.2360321797468 + } + }, + "variant": {} + }, + { + "id": "b9d1103b3", + "label": "Element", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "display": "inline-block", + "padding-left": "2px", + "padding-top": "2px", + "padding-right": "2px", + "padding-bottom": "2px" + }, + "children": [ + { + "id": "d8f6340b5790", + "children": [ + { + "id": "b9d1103b6", + "is": "b9d1103b2", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [ + { + "id": "db9643836", + "propertyName": "style", + "targetIdPath": [ + "b9d1103b11" + ], + "value": { + "background": "rgba(159, 198, 234, 1)" + }, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": -596.7791311476066, + "top": 1575.897643431201, + "right": -496.77913114760656, + "bottom": 1675.897643431201 + } + } + }, + { + "id": "b9d1103b7", + "is": "b9d1103b2", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [ + { + "id": "db9643835", + "propertyName": "style", + "targetIdPath": [ + "b9d1103b11" + ], + "value": { + "background": "rgba(244, 244, 58, 1)" + }, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": -596.7791311476066, + "top": 1575.897643431201, + "right": -496.77913114760656, + "bottom": 1675.897643431201 + } + } + }, + { + "id": "b9d1103b10", + "is": "b9d1103b2", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [ + { + "id": "db9643834", + "propertyName": "style", + "targetIdPath": [ + "b9d1103b11" + ], + "value": { + "background": "rgba(95, 88, 227, 1)" + }, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": -596.7791311476066, + "top": 1575.897643431201, + "right": -496.77913114760656, + "bottom": 1675.897643431201 + } + } + }, + { + "id": "b9d1103b9", + "is": "b9d1103b2", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [ + { + "id": "db9643833", + "propertyName": "style", + "targetIdPath": [ + "b9d1103b11" + ], + "value": { + "background": "rgba(38, 226, 110, 1)" + }, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": -596.7791311476066, + "top": 1575.897643431201, + "right": -496.77913114760656, + "bottom": 1675.897643431201 + } + } + }, + { + "id": "b9d1103b8", + "is": "b9d1103b2", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [ + { + "id": "db9643832", + "propertyName": "style", + "targetIdPath": [ + "b9d1103b11" + ], + "value": { + "background": "rgba(246, 33, 33, 1)" + }, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": -596.7791311476066, + "top": 1575.897643431201, + "right": -496.77913114760656, + "bottom": 1675.897643431201 + } + }, + "variant": { + "a5ab78791": true + } + }, + { + "id": "b9d1103b4", + "is": "b9d1103b2", + "name": "component-instance", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "display": "inline-block", + "width": "16px", + "height": "16px", + "border-radius": "2px", + "position": "relative" + }, + "children": [ + { + "id": "b9d1103b12", + "propertyName": "style", + "targetIdPath": [ + "b9d1103b11" + ], + "value": {}, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": -596.7791311476066, + "top": 1575.897643431201, + "right": -496.77913114760656, + "bottom": 1675.897643431201 + } + } + } + ], + "metadata": {}, + "name": "slot", + "label": "content" + } + ], + "metadata": {} + }, + { + "id": "a5ab78793", + "propertyName": "isDefault", + "targetIdPath": [ + "a5ab78791" + ], + "value": true, + "name": "override", + "children": [] + }, + { + "id": "c7da0a1d39133", + "label": "Element", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "display": "inline-flex", + "align-items": "center" + }, + "children": [], + "metadata": {} + }, + { + "id": "596b7f9f679", + "name": "variant", + "label": "has multiple groups", + "isDefault": true, + "children": [], + "metadata": {} + }, + { + "id": "596b7f9f2196", + "variantId": "596b7f9f679", + "propertyName": "style", + "targetIdPath": [ + "52771059438" + ], + "value": { + "display": "block" + }, + "name": "override", + "children": [] + }, + { + "id": "4ad8e384673", + "variantId": "596b7f9f679", + "propertyName": "style", + "targetIdPath": [], + "value": { + "padding-top": "12px", + "padding-right": "12px", + "padding-bottom": "12px", + "padding-left": "12px" + }, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": -588, + "top": 1123, + "right": -148.40870282843525, + "bottom": 1223 + } + }, + "variant": {}, + "controllers": [ + "./color-swatch-controller.tsx" + ] + }, + { + "label": "Color swatch item", + "is": "div", + "style": { + "box-sizing": "border-box", + "display": "inline-block", + "width": "16px", + "height": "16px", + "border-radius": "2px", + "margin-right": "4px", + "padding-left": "2px", + "padding-top": "2px", + "padding-right": "2px", + "padding-bottom": "2px", + "position": "relative" + }, + "attributes": {}, + "id": "b9d1103b2", + "name": "component", + "children": [ + { + "id": "b9d1103b11", + "label": "pill", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "display": "block", + "border-radius": "2px", + "background": "var(--d8f6340b1442)", + "width": "100%", + "height": "100%", + "cursor": "pointer" + }, + "children": [], + "metadata": {} + }, + { + "id": "a5ab78791", + "name": "variant", + "label": "selected", + "isDefault": true, + "children": [], + "metadata": {} + }, + { + "id": "a5ab78792", + "variantId": "a5ab78791", + "propertyName": "style", + "targetIdPath": [], + "value": { + "background": "var(--24ce1e4d13456)", + "margin-right": "4px", + "padding-left": "2px", + "padding-top": "2px", + "padding-right": "2px", + "padding-bottom": "2px" + }, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": -587, + "top": 1324, + "right": -487, + "bottom": 1424 + } + }, + "variant": {} + }, + { + "id": "ff88947b672", + "label": "Element", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "display": "block", + "background": "rgba(200, 200, 200, 1)" + }, + "children": [], + "metadata": { + "bounds": { + "left": 264.235120608077, + "top": 184.8840820577259, + "right": 364.235120608077, + "bottom": 284.8840820577259 + } + } + } + ] +} \ No newline at end of file diff --git a/packages/tandem-designer/src/components/inputs/color/presets/index.scss b/packages/tandem-designer/src/components/inputs/color/presets/index.scss new file mode 100644 index 000000000..b24c73390 --- /dev/null +++ b/packages/tandem-designer/src/components/inputs/color/presets/index.scss @@ -0,0 +1,5 @@ +.m-presets { + border-top: 1px solid var(--boundary-color-1); + margin-top: 4px; + margin-bottom: 4px; +} diff --git a/packages/tandem-designer/src/components/inputs/color/presets/index.tsx b/packages/tandem-designer/src/components/inputs/color/presets/index.tsx new file mode 100644 index 000000000..1d3b23b41 --- /dev/null +++ b/packages/tandem-designer/src/components/inputs/color/presets/index.tsx @@ -0,0 +1,21 @@ +import "./index.scss"; +import * as React from "react"; + +export type PresetOption = { + name: string; + value: string; +}; + +export type PresetComponentOuterProps = { + values: PresetOption[]; +}; + +export class PresetComponent extends React.PureComponent { + render() { + return ( +
+
TODO
+
+ ); + } +} diff --git a/packages/tandem-designer/src/components/inputs/color/raw-input/index.scss b/packages/tandem-designer/src/components/inputs/color/raw-input/index.scss new file mode 100644 index 000000000..bb3068670 --- /dev/null +++ b/packages/tandem-designer/src/components/inputs/color/raw-input/index.scss @@ -0,0 +1,34 @@ +.m-raw-color-input { + margin-top: 16px; + display: flex; + flex-direction: row; + .switcher { + display: flex; + cursor: pointer; + background: transparent; + flex-direction: column; + i { + height: 8px; + } + } + .field { + flex-direction: column; + display: flex; + flex: 1; + align-items: center; + padding-right: 4px; + label { + text-transform: uppercase; + } + + input { + width: 100%; + text-align: center; + } + } + .fields { + width: 100%; + display: flex; + flex-direction: row; + } +} diff --git a/packages/tandem-designer/src/components/inputs/color/raw-input/index.tsx b/packages/tandem-designer/src/components/inputs/color/raw-input/index.tsx new file mode 100644 index 000000000..f6d23f3d7 --- /dev/null +++ b/packages/tandem-designer/src/components/inputs/color/raw-input/index.tsx @@ -0,0 +1,78 @@ +import "./index.scss"; +import * as React from "react"; +import { compose, pure, withState, withHandlers } from "recompose"; + +type InputComponentProps = { + value: any; + onChange?: () => any; +}; + +type LabeledInputComponentProps = { + label: string; +} & InputComponentProps; + +export type RawColorInputOuterProps = {} & InputComponentProps; + +export type RawColorInputInputProps = { + currentInputIndex: number; + onSwitcherClick: () => any; +} & RawColorInputOuterProps; + +const InputComponent = ({ + value, + label, + onChange, +}: LabeledInputComponentProps) => { + return ( +
+ {/* + */} +
+ ); +}; + +const HexInputComponent = ({ value }: InputComponentProps) => { + return ( +
+ +
+ ); +}; + +const RGBAInputComponent = ({ value }: InputComponentProps) => { + return ( +
+ + + + +
+ ); +}; + +const OPTIONS = [RGBAInputComponent, HexInputComponent]; + +const BaseRawColorInputComponent = ({ + value, + onSwitcherClick, +}: RawColorInputInputProps) => { + return ( +
+ +
+ + +
+
+ ); +}; + +const enhance = compose( + pure, + withState("currentInputIndex", "setCurrentInputIndex", 0), + withHandlers({ + onSwitcherClick: () => () => {}, + }) +); + +export const RawColorInputComponent = enhance(BaseRawColorInputComponent); diff --git a/packages/tandem-designer/src/components/inputs/color/rgba-input-controller.tsx b/packages/tandem-designer/src/components/inputs/color/rgba-input-controller.tsx new file mode 100644 index 000000000..5e6d8b046 --- /dev/null +++ b/packages/tandem-designer/src/components/inputs/color/rgba-input-controller.tsx @@ -0,0 +1,53 @@ +import * as React from "react"; +import { arraySplice } from "tandem-common"; +import { clamp, noop } from "lodash"; +import { BaseRgbaInputProps } from "./picker.pc"; + +export type Props = { + onChange?: any; + onChangeComplete?: any; + value?: [number, number, number, number]; +}; + +export default (Base: React.ComponentClass) => + class RGBAInputController extends React.PureComponent { + render() { + const { + onChange = noop, + onChangeComplete = noop, + value: [r, g, b, a] = [0, 0, 0, 0], + } = this.props; + const changeCallback = (index) => (value) => + onChange( + arraySplice([r, g, b, a], index, 1, clamp(Number(value), 0, 255)) + ); + const changeCompleteCallback = (index) => (value) => + onChangeComplete( + arraySplice([r, g, b, a], index, 1, clamp(Number(value), 0, 255)) + ); + return ( + + ); + } + }; diff --git a/packages/tandem-designer/src/components/inputs/color/utils.ts b/packages/tandem-designer/src/components/inputs/color/utils.ts new file mode 100644 index 000000000..e69de29bb diff --git a/packages/tandem-designer/src/components/inputs/color/view.pc b/packages/tandem-designer/src/components/inputs/color/view.pc new file mode 100644 index 000000000..cca4da156 --- /dev/null +++ b/packages/tandem-designer/src/components/inputs/color/view.pc @@ -0,0 +1,267 @@ +{ + "id": "808486bb69", + "version": "0.0.6", + "metadata": {}, + "name": "module", + "children": [ + { + "label": "Color Input", + "is": "div", + "style": { + "position": "relative" + }, + "attributes": {}, + "id": "d227ff68826768", + "name": "component", + "children": [ + { + "id": "ff4f91e03148", + "variant": {}, + "is": "9b7b527f175442", + "name": "component-instance", + "attributes": {}, + "style": { + "position": "absolute" + }, + "children": [ + { + "id": "ddec6a12145779", + "propertyName": "style", + "targetIdPath": [ + "ddec6a12139578" + ], + "value": { + "çheight": "100px" + }, + "name": "override", + "children": [] + }, + { + "slotId": "c00d8561361", + "id": "7057aee112046", + "children": [ + { + "id": "d227ff68826765", + "label": "button", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "padding": "4px 8px", + "border-radius": "2px", + "box-sizing": "border-box", + "background": "red", + "width": "100%", + "height": "22px", + "cursor": "pointer", + "display": "block" + }, + "children": [], + "metadata": {}, + "styleMixins": { + "c29da5f4213993": { + "priority": 0 + } + } + } + ], + "metadata": {}, + "name": "plug" + }, + { + "slotId": "e6638364254", + "id": "7057aee112557", + "children": [ + { + "id": "6a8da795139", + "children": [ + { + "id": "ddec6a12260453", + "variant": {}, + "is": "67e386c762", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": { + "bounds": { + "left": 135, + "top": 356, + "right": 442.7928111413887, + "bottom": 604.3866802446275 + } + } + } + ], + "metadata": {}, + "name": "slot", + "label": "content" + } + ], + "metadata": {}, + "name": "plug" + }, + { + "id": "e68983c8240615", + "propertyName": "style", + "targetIdPath": [ + "d227ff68826765" + ], + "value": {}, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": 237, + "top": 371, + "right": 337, + "bottom": 471 + } + }, + "label": "Popover" + }, + { + "id": "d227ff68826766", + "label": "popdown", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "position": "absolute", + "top": "20px", + "right": "0", + "z-index": "1024", + "display": "none" + }, + "children": [], + "metadata": { + "bounds": { + "left": -397, + "top": 169, + "right": 3, + "bottom": 469 + } + } + } + ], + "metadata": { + "bounds": { + "left": -195, + "top": -203, + "right": 224.3481137442551, + "bottom": 125.74445685348837 + } + }, + "controllers": [ + "./color-input-controller.tsx" + ], + "variant": {} + }, + { + "id": "d227ff68920365", + "label": "Preview", + "is": "div", + "name": "element", + "attributes": {}, + "style": {}, + "children": [ + { + "id": "d227ff68923389", + "variant": {}, + "is": "d227ff68826768", + "name": "component-instance", + "attributes": {}, + "style": { + "width": "100px", + "top": "100px", + "left": "200px" + }, + "children": [ + { + "id": "d227ff681275565", + "propertyName": "style", + "targetIdPath": [ + "d227ff68826766" + ], + "value": { + "top": "20px", + "right": "0", + "z-index": "1024", + "display": "block" + }, + "name": "override", + "children": [] + }, + { + "id": "d227ff681524518", + "propertyName": "style", + "targetIdPath": [ + "d227ff68826767" + ], + "value": {}, + "name": "override", + "children": [] + }, + { + "id": "d227ff681706679", + "propertyName": "style", + "targetIdPath": [ + "d227ff68826765" + ], + "value": { + "width": "100px", + "position": "relative" + }, + "name": "override", + "children": [] + }, + { + "id": "ff4f91e0111532", + "propertyName": "style", + "targetIdPath": [ + "ff4f91e03148", + "46686eab9332" + ], + "value": { + "display": "block" + }, + "name": "override", + "children": [] + }, + { + "id": "ddec6a12142679", + "propertyName": "style", + "targetIdPath": [ + "ff4f91e03148", + "ddec6a12139578" + ], + "value": { + "çheight": "100px" + }, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": -499, + "top": -15, + "right": -393.12369537938656, + "bottom": 33.792202591797206 + } + } + } + ], + "metadata": { + "bounds": { + "left": -678, + "top": 215, + "right": -211.46457284746373, + "bottom": 645.3124627985359 + } + } + } + ] +} \ No newline at end of file diff --git a/packages/tandem-designer/src/components/inputs/dropdown/controller.tsx b/packages/tandem-designer/src/components/inputs/dropdown/controller.tsx new file mode 100644 index 000000000..e0f70e08b --- /dev/null +++ b/packages/tandem-designer/src/components/inputs/dropdown/controller.tsx @@ -0,0 +1,170 @@ +import * as React from "react"; +import cx from "classnames"; +import { DropdownMenuItem } from "./menu.pc"; +import { EMPTY_ARRAY, memoize } from "tandem-common"; +import { BaseDropdownProps, ElementProps } from "./view.pc"; +import { PCVariable } from "paperclip"; + +export type DropdownMenuOption = { + label: string; + value: any; + special?: boolean; +}; + +export const NO_OPTION: DropdownMenuOption = { + label: "--", + value: undefined, +}; + +export const dropdownMenuOptionFromValue = ( + value: string +): DropdownMenuOption => ({ label: value || "--", value }); + +export const mapVariablesToDropdownOptions = memoize( + (variables: PCVariable[]): DropdownMenuOption[] => { + return variables.map((variable) => ({ + value: variable, + label: variable.label, + special: true, + })); + } +); + +export type Props = { + value?: any; + filterable?: boolean; + options: DropdownMenuOption[]; + onChange?: (value: any) => any; + onChangeComplete?: (value: any) => any; +} & ElementProps; + +type DropdownState = { + open: boolean; + filter: string; +}; + +export default (Base: React.ComponentClass) => { + return class DropdownController extends React.PureComponent< + Props, + DropdownState + > { + constructor(props) { + super(props); + this.state = { + open: false, + filter: null, + }; + } + onMouseDown = (event) => { + // only open if _not_ opened yet. The popover will call onShouldClose if already open + // since the button is technically out of the popover scope. + if (!this.state.open) { + this.setState({ ...this.state, open: true }); + } + + if (this.props.onMouseDown) { + this.props.onMouseDown(event); + } + }; + onFilterChange = (value) => { + this.setState({ + ...this.state, + filter: value ? String(value).toLowerCase() : null, + }); + }; + componentWillUpdate(props) { + if (this.props.value !== props.value && this.state.filter) { + this.setState({ ...this.state, filter: null, open: false }); + } + } + onItemClick = (item, event) => { + const { onChange, onChangeComplete } = this.props; + this.setState({ ...this.state, open: false }); + if (onChange) { + onChange(item.value); + } + if (onChangeComplete) { + onChangeComplete(item.value); + } + }; + onKeyDown = (event) => { + if (event.key === "Enter") { + this.setState({ ...this.state, open: true }); + } + }; + onShouldClose = () => { + this.setState({ ...this.state, open: false }); + }; + + render() { + const { + value, + options = EMPTY_ARRAY, + filterable, + onMouseDown, + onChange, + onChangeComplete, + ...rest + } = this.props; + const { open, filter } = this.state; + + const menuItems = open + ? options + .filter( + ({ label }) => + !filter || String(label).toLowerCase().indexOf(filter) !== -1 + ) + .map((item, i) => { + return ( + this.onItemClick(item, event)} + > + {item.label} + + ); + }) + : EMPTY_ARRAY; + + const selectedItem: DropdownMenuOption = options.find( + (item) => item.value === value + ); + const showFilter = open && filterable !== false; + + return ( + + ); + } + }; +}; diff --git a/packages/tandem-designer/src/components/inputs/dropdown/index.scss b/packages/tandem-designer/src/components/inputs/dropdown/index.scss new file mode 100644 index 000000000..e69de29bb diff --git a/packages/tandem-designer/src/components/inputs/dropdown/menu.pc b/packages/tandem-designer/src/components/inputs/dropdown/menu.pc new file mode 100644 index 000000000..61ede03c2 --- /dev/null +++ b/packages/tandem-designer/src/components/inputs/dropdown/menu.pc @@ -0,0 +1,88 @@ +{ + "id": "5d6bd01099", + "version": "0.0.5", + "metadata": {}, + "name": "module", + "children": [ + { + "label": "Dropdown Menu Item", + "is": "div", + "style": { + "padding": "4px", + "border-bottom": "1px rgba(0,0,0,0.05)", + "user-select": "none", + "cursor": "default", + "background": "var(--bc891e755312)" + }, + "attributes": {}, + "id": "8b8bbe2c859177", + "name": "component", + "children": [ + { + "id": "8b8bbe2c859176", + "name": "text", + "label": "Text", + "value": "menu item 1", + "style": { + "padding": "8px" + }, + "children": [], + "metadata": {} + }, + { + "id": "cd433e9f899", + "name": "variant", + "label": "alt", + "isDefault": false, + "children": [], + "metadata": {} + }, + { + "id": "cd433e9f1196", + "variantId": "cd433e9f899", + "propertyName": "style", + "targetIdPath": [], + "value": { + "background": "var(--f63574de434)", + "border-bottom": "0px rgba(0,0,0,0.05)" + }, + "name": "override", + "children": [] + }, + { + "id": "cd433e9f6531", + "name": "variant", + "label": "special", + "isDefault": false, + "children": [], + "metadata": {} + }, + { + "id": "cd433e9f6828", + "variantId": "cd433e9f6531", + "propertyName": "style", + "targetIdPath": [], + "value": { + "color": "rgba(223, 18, 233, 1)" + }, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": 395, + "top": 346, + "right": 596, + "bottom": 380 + } + }, + "variant": {}, + "styleMixins": { + "dc3b39eb1275": { + "priority": 0 + } + } + } + ] +} \ No newline at end of file diff --git a/packages/tandem-designer/src/components/inputs/dropdown/view.pc b/packages/tandem-designer/src/components/inputs/dropdown/view.pc new file mode 100644 index 000000000..7fee63b61 --- /dev/null +++ b/packages/tandem-designer/src/components/inputs/dropdown/view.pc @@ -0,0 +1,923 @@ +{ + "id": "76b155a0893154", + "version": "0.0.6", + "metadata": {}, + "name": "module", + "children": [ + { + "id": "5c9686b875966", + "is": "50e32bec2591", + "label": "Dropdown", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [ + { + "id": "5c9686b876903", + "variantId": null, + "propertyName": "text", + "targetIdPath": [ + "67e386c7935" + ], + "value": "super long label that should ellipsis if it overflows", + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": 357, + "top": 282, + "right": 558, + "bottom": 524.2360321797468 + } + }, + "variant": {} + }, + { + "id": "f89d0ee73352", + "is": "50e32bec2591", + "label": "Filtering", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": { + "bounds": { + "left": 132, + "top": 580, + "right": 333, + "bottom": 822.2360321797469 + } + }, + "variant": { + "69c680a12": true + } + }, + { + "label": "Dropdown", + "is": "div", + "style": { + "width": "100%", + "position": "relative", + "outline": "none" + }, + "attributes": {}, + "id": "50e32bec2591", + "name": "component", + "children": [ + { + "id": "782254018619", + "variant": {}, + "is": "9b7b527f175442", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [ + { + "id": "69c680a14", + "variantId": "69c680a12", + "propertyName": "style", + "targetIdPath": [ + "67e386c7935" + ], + "value": { + "display": "block", + "cursor": "default" + }, + "name": "override", + "children": [] + }, + { + "slotId": "c00d8561361", + "id": "ebe8eef3202", + "children": [ + { + "id": "87568a7232485", + "children": [ + { + "id": "8b8bbe2c232831", + "label": "button", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "display": "flex", + "align-items": "center", + "user-select": "none", + "background": "rgba(255, 255, 255, 1)", + "cursor": "default", + "padding-left": "6px", + "padding-top": "4px", + "padding-right": "6px", + "padding-bottom": "4px" + }, + "children": [ + { + "id": "69c680a11", + "is": "7149f8199122", + "name": "component-instance", + "attributes": { + "placeholder": "filter" + }, + "style": { + "width": "100%", + "padding": "4px 8px", + "border-radius": "0px", + "border": "none", + "box-sizing": "border-box", + "display": "none", + "padding-top": "0px", + "padding-right": "0px", + "padding-bottom": "0px", + "padding-left": "0px", + "box-shadow": "unset" + }, + "children": [ + { + "id": "69c680a13", + "variantId": "69c680a12", + "propertyName": "style", + "targetIdPath": [], + "value": { + "border-radius": "0px", + "border": "none", + "display": "block" + }, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": 435.5632830380766, + "top": 172.7598749633466, + "right": 535.5632830380766, + "bottom": 201.7956837222485 + } + }, + "label": "filter input" + }, + { + "id": "67e386c7935", + "name": "text", + "label": "Label", + "value": "Label", + "style": { + "display": "inline-block", + "width": "100%" + }, + "children": [], + "metadata": {}, + "styleMixins": { + "dc3b39eb1275": { + "priority": 0 + }, + "61225017220906": { + "priority": 1 + } + } + }, + { + "id": "628c465922", + "variant": {}, + "is": "e186b96e4079", + "name": "component-instance", + "attributes": {}, + "style": { + "height": "10px", + "position": "relative", + "opacity": "0.4", + "top": "1px" + }, + "children": [], + "metadata": {} + } + ], + "metadata": {}, + "styleMixins": { + "c29da5f4213993": { + "priority": 0 + } + } + } + ], + "metadata": {}, + "name": "slot", + "label": "button" + } + ], + "metadata": {}, + "name": "plug" + }, + { + "slotId": "e6638364254", + "id": "e6638364407", + "children": [ + { + "id": "806ffd0684", + "label": "Menu", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "display": "block", + "max-height": "200px", + "margin-top": "8px", + "border-bottom-left-radius": "2px", + "border-top-left-radius": "2px", + "border-top-right-radius": "2px", + "border-bottom-right-radius": "2px", + "border": "1px solid rgba(238, 238, 238, 1)", + "overflow-y": "scroll" + }, + "children": [ + { + "label": "options", + "id": "806ffd06590", + "children": [ + { + "id": "9c4dcc9c484", + "is": "8b8bbe2c859177", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": { + "bounds": { + "left": 341, + "top": 451.64745698660715, + "right": 542, + "bottom": 485.64745698660715 + } + } + }, + { + "id": "9c4dcc9c578", + "is": "8b8bbe2c859177", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": { + "bounds": { + "left": 341, + "top": 451.64745698660715, + "right": 542, + "bottom": 485.64745698660715 + } + }, + "variant": { + "cd433e9f899": true + } + }, + { + "id": "9c4dcc9c678", + "is": "8b8bbe2c859177", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": { + "bounds": { + "left": 341, + "top": 451.64745698660715, + "right": 542, + "bottom": 485.64745698660715 + } + } + }, + { + "id": "9c4dcc9c784", + "is": "8b8bbe2c859177", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": { + "bounds": { + "left": 341, + "top": 451.64745698660715, + "right": 542, + "bottom": 485.64745698660715 + } + }, + "variant": { + "cd433e9f899": true + } + }, + { + "id": "9c4dcc9c896", + "is": "8b8bbe2c859177", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": { + "bounds": { + "left": 341, + "top": 451.64745698660715, + "right": 542, + "bottom": 485.64745698660715 + } + } + }, + { + "id": "9c4dcc9c1014", + "is": "8b8bbe2c859177", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": { + "bounds": { + "left": 341, + "top": 451.64745698660715, + "right": 542, + "bottom": 485.64745698660715 + } + }, + "variant": { + "cd433e9f899": true + } + }, + { + "id": "9c4dcc9c1138", + "is": "8b8bbe2c859177", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": { + "bounds": { + "left": 341, + "top": 451.64745698660715, + "right": 542, + "bottom": 485.64745698660715 + } + } + }, + { + "id": "9c4dcc9c1268", + "is": "8b8bbe2c859177", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": { + "bounds": { + "left": 341, + "top": 451.64745698660715, + "right": 542, + "bottom": 485.64745698660715 + } + }, + "variant": { + "cd433e9f899": true + } + }, + { + "id": "9c4dcc9c1404", + "is": "8b8bbe2c859177", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": { + "bounds": { + "left": 341, + "top": 451.64745698660715, + "right": 542, + "bottom": 485.64745698660715 + } + } + }, + { + "id": "e6638364329", + "is": "8b8bbe2c859177", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": { + "bounds": { + "left": 341, + "top": 451.64745698660715, + "right": 542, + "bottom": 485.64745698660715 + } + }, + "variant": { + "cd433e9f899": true + } + }, + { + "id": "d5b0b72c121", + "is": "8b8bbe2c859177", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": { + "bounds": { + "left": 341, + "top": 451.64745698660715, + "right": 542, + "bottom": 485.64745698660715 + } + } + }, + { + "id": "d5b0b72c343", + "is": "8b8bbe2c859177", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": { + "bounds": { + "left": 341, + "top": 451.64745698660715, + "right": 542, + "bottom": 485.64745698660715 + } + }, + "variant": { + "cd433e9f899": true + } + }, + { + "id": "d5b0b72c263", + "is": "8b8bbe2c859177", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": { + "bounds": { + "left": 341, + "top": 451.64745698660715, + "right": 542, + "bottom": 485.64745698660715 + } + } + }, + { + "id": "d5b0b72c189", + "is": "8b8bbe2c859177", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": { + "bounds": { + "left": 341, + "top": 451.64745698660715, + "right": 542, + "bottom": 485.64745698660715 + } + }, + "variant": { + "cd433e9f899": true + } + } + ], + "metadata": {}, + "name": "slot" + } + ], + "metadata": { + "bounds": { + "left": 382.50305721861076, + "top": 371.29600643511884, + "right": 482.50305721861076, + "bottom": 471.29600643511884 + } + }, + "styleMixins": { + "fb4d37ca18486": { + "priority": 0 + } + } + } + ], + "metadata": {}, + "name": "plug" + }, + { + "id": "22702c5f14240", + "variantId": "22702c5f2706", + "propertyName": "style", + "targetIdPath": [ + "67e386c7935" + ], + "value": { + "color": "rgba(223, 18, 233, 1)" + }, + "name": "override", + "children": [] + }, + { + "id": "c29da5f4830054", + "propertyName": "styleMixins", + "targetIdPath": [ + "67e386c7935" + ], + "value": { + "1538744319106": { + "priority": 0 + }, + "1538744322303": { + "priority": 0 + }, + "1538744324123": { + "priority": 0 + }, + "1538744362709": { + "priority": 0 + }, + "1538744363813": { + "priority": 0 + }, + "1538744381364": { + "priority": 0 + } + }, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": 237, + "top": 371, + "right": 337, + "bottom": 471 + } + }, + "label": "Popover" + }, + { + "id": "69c680a12", + "name": "variant", + "label": "filterable", + "isDefault": false, + "children": [], + "metadata": {} + }, + { + "id": "be1fb4991", + "variantId": "69c680a12", + "propertyName": "style", + "targetIdPath": [ + "67e386c7935" + ], + "value": { + "display": "none" + }, + "name": "override", + "children": [] + }, + { + "id": "be1fb4992", + "variantId": null, + "propertyName": "style", + "targetIdPath": [], + "value": { + "font-size": "11px" + }, + "name": "override", + "children": [] + }, + { + "id": "be1fb4994", + "variantId": "69c680a12", + "propertyName": "style", + "targetIdPath": [ + "69c680a11" + ], + "value": { + "display": "block" + }, + "name": "override", + "children": [] + }, + { + "id": "22702c5f2706", + "name": "variant", + "label": "special", + "isDefault": true, + "children": [], + "metadata": {} + }, + { + "id": "22702c5f3079", + "variantId": "22702c5f2706", + "propertyName": "style", + "targetIdPath": [], + "value": {}, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": 133, + "top": 279, + "right": 334, + "bottom": 521.2360321797468 + } + }, + "controllers": [ + "./controller.tsx" + ], + "variant": {} + }, + { + "id": "83d6aa885923", + "variant": {}, + "is": "50e32bec2591", + "name": "component-instance", + "attributes": {}, + "style": { + "background": "rgba(105, 105, 105, 1)" + }, + "children": [ + { + "id": "83d6aa8811798", + "propertyName": "style", + "targetIdPath": [ + "8b8bbe2c432477" + ], + "value": { + "display": "block" + }, + "name": "override", + "children": [] + }, + { + "id": "83d6aa8833337", + "propertyName": "style", + "targetIdPath": [ + "8b8bbe2c237350" + ], + "value": { + "background": "rgba(250, 250, 250, 250)", + "border": "1px solid rgba(0,0,0,0.08)", + "box-sizing": "border-box", + "max-height": "200px", + "overflow": "scroll" + }, + "name": "override", + "children": [] + }, + { + "id": "83d6aa8868582", + "propertyName": "style", + "targetIdPath": [ + "8b8bbe2c859178" + ], + "value": {}, + "name": "override", + "children": [] + }, + { + "id": "83d6aa88244809", + "propertyName": "style", + "targetIdPath": [ + "8b8bbe2c882925" + ], + "value": { + "border-bottom": "none" + }, + "name": "override", + "children": [] + }, + { + "id": "93b595c642", + "propertyName": "style", + "targetIdPath": [ + "67e386c7935" + ], + "value": { + "use-select": "none" + }, + "name": "override", + "children": [] + }, + { + "id": "7822540130313", + "propertyName": "style", + "targetIdPath": [ + "782254018619", + "ddec6a12139578" + ], + "value": { + "display": "block", + "width": "100%" + }, + "name": "override", + "children": [] + }, + { + "id": "3041a301150368", + "propertyName": "style", + "targetIdPath": [ + "782254018619", + "ddec6a12139578", + "8b8bbe2c237350" + ], + "value": {}, + "name": "override", + "children": [] + }, + { + "id": "cd433e9f2973", + "propertyName": "variant", + "targetIdPath": [ + "9c4dcc9c578" + ], + "value": { + "cd433e9f899": true, + "cd433e9f6531": true + }, + "name": "override", + "children": [] + }, + { + "id": "cd433e9f3270", + "propertyName": "variant", + "targetIdPath": [ + "9c4dcc9c784" + ], + "value": { + "cd433e9f899": true + }, + "name": "override", + "children": [] + }, + { + "id": "cd433e9f3567", + "propertyName": "variant", + "targetIdPath": [ + "9c4dcc9c1014" + ], + "value": { + "cd433e9f899": true + }, + "name": "override", + "children": [] + }, + { + "id": "cd433e9f3864", + "propertyName": "variant", + "targetIdPath": [ + "9c4dcc9c1268" + ], + "value": { + "cd433e9f899": true + }, + "name": "override", + "children": [] + }, + { + "id": "cd433e9f4161", + "propertyName": "variant", + "targetIdPath": [ + "9c4dcc9c1404" + ], + "value": { + "cd433e9f899": true + }, + "name": "override", + "children": [] + }, + { + "id": "cd433e9f4458", + "propertyName": "variant", + "targetIdPath": [ + "e6638364329" + ], + "value": { + "cd433e9f899": false + }, + "name": "override", + "children": [] + }, + { + "id": "cd433e9f8013", + "propertyName": "variant", + "targetIdPath": [ + "9c4dcc9c484" + ], + "value": { + "cd433e9f6531": true + }, + "name": "override", + "children": [] + }, + { + "id": "cd433e9f8606", + "variantId": null, + "propertyName": "text", + "targetIdPath": [ + "9c4dcc9c484", + "8b8bbe2c859176" + ], + "value": "variable 1", + "name": "override", + "children": [] + }, + { + "id": "cd433e9f11567", + "variantId": null, + "propertyName": "text", + "targetIdPath": [ + "9c4dcc9c578", + "8b8bbe2c859176" + ], + "value": "variable 2", + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": 636, + "top": 284, + "right": 838, + "bottom": 763.2949139732143 + } + }, + "label": "Dropdown open" + }, + { + "id": "75283639905", + "label": "Element", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "display": "block" + }, + "children": [ + { + "id": "752836391500", + "is": "50e32bec2591", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [ + { + "id": "752836392602", + "propertyName": "variant", + "targetIdPath": [ + "782254018619" + ], + "value": { + "e691a1d98281": true + }, + "name": "override", + "children": [] + }, + { + "id": "752836392970", + "propertyName": "style", + "targetIdPath": [ + "782254018619", + "ddec6a12139578" + ], + "value": { + "display": "block" + }, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": 133, + "top": 279, + "right": 334, + "bottom": 521.2360321797468 + } + }, + "variant": { + "69c680a12": false + } + } + ], + "metadata": { + "bounds": { + "left": 1118.8702518954262, + "top": 290.5348726353282, + "right": 1642.978560762243, + "bottom": 622.236217096113 + } + } + } + ] +} \ No newline at end of file diff --git a/packages/tandem-designer/src/components/inputs/file-picker/controller.tsx b/packages/tandem-designer/src/components/inputs/file-picker/controller.tsx new file mode 100644 index 000000000..5f2061b1e --- /dev/null +++ b/packages/tandem-designer/src/components/inputs/file-picker/controller.tsx @@ -0,0 +1,88 @@ +import * as React from "react"; +import * as path from "path"; +import { BaseFileInputProps } from "./view.pc"; +import { OpenFileContext, FileOpener } from "../../contexts"; + +export type Props = { + cwd: string; + value: string; + onChangeComplete?: (value: string) => void; +}; + +export type State = { + _value: string; + value: string; +}; + +export default (Base: React.ComponentClass) => + class FileInputController extends React.PureComponent { + state = { + _value: this.props.value, + value: this.props.value, + }; + private _openFile: FileOpener; + onBrowseButtonClick = async () => { + const filePath = await this._openFile({ + name: "Open Image", + extensions: ["jpg", "png", "svg", "gif", "jpeg"], + }); + + const modulePath = filePath.replace(this.props.cwd, "").substr(1); + this.onFileUriChange(modulePath); + }; + + static getDerivedStateFromProps(nextProps: Props, prevState: State): State { + let state = prevState; + + if (nextProps.value != prevState._value) { + state = { + ...state, + _value: nextProps.value, + value: nextProps.value, + }; + } + + return state === prevState ? null : state; + } + + onFilePathInputChange = (fileUri) => { + this.onFileUriChange(fileUri); + }; + + onFileUriChange = (fileUri: string) => { + this.setState( + { + value: fileUri, + }, + () => { + if (this.props.onChangeComplete) { + this.props.onChangeComplete(fileUri); + } + } + ); + }; + render() { + const { value } = this.state; + const { onBrowseButtonClick, onFilePathInputChange } = this; + const { onChangeComplete, ...rest } = this.props; + return ( + + {(openFile) => { + this._openFile = openFile; + return ( + + ); + }} + + ); + } + }; diff --git a/packages/tandem-designer/src/components/inputs/file-picker/view.pc b/packages/tandem-designer/src/components/inputs/file-picker/view.pc new file mode 100644 index 000000000..f22ac77c3 --- /dev/null +++ b/packages/tandem-designer/src/components/inputs/file-picker/view.pc @@ -0,0 +1,98 @@ +{ + "id": "1173728894", + "name": "module", + "version": "0.0.6", + "children": [ + { + "label": "file input", + "is": "div", + "style": { + "box-sizing": "border-box", + "display": "flex" + }, + "attributes": {}, + "id": "9fb9afea1357", + "name": "component", + "children": [ + { + "id": "9fb9afea1354", + "is": "7149f8199122", + "label": "file path input", + "name": "component-instance", + "attributes": {}, + "style": { + "margin-right": "6px" + }, + "children": [], + "metadata": { + "bounds": { + "left": 384, + "top": 298, + "right": 484, + "bottom": 327.0358087589019 + } + }, + "variant": {} + }, + { + "id": "6fc47e06486", + "label": "Element", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "display": "flex", + "position": "relative" + }, + "children": [ + { + "id": "9fb9afea1355", + "is": "9f364d2139415", + "label": "browse button", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [ + { + "id": "9fb9afea1356", + "variantId": null, + "propertyName": "text", + "targetIdPath": [ + "9f364d2139650" + ], + "value": "browse", + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": 300, + "top": 120, + "right": 400, + "bottom": 220 + } + }, + "variant": {} + } + ], + "metadata": {} + } + ], + "metadata": { + "bounds": { + "left": 193, + "top": 21, + "right": 531, + "bottom": 121 + } + }, + "variant": {}, + "controllers": [ + "./controller.tsx" + ] + } + ], + "metadata": {} +} \ No newline at end of file diff --git a/packages/tandem-designer/src/components/inputs/molecules.pc b/packages/tandem-designer/src/components/inputs/molecules.pc new file mode 100644 index 000000000..f3ad62f46 --- /dev/null +++ b/packages/tandem-designer/src/components/inputs/molecules.pc @@ -0,0 +1,362 @@ +{ + "id": "76b155a0889212", + "version": "0.0.6", + "metadata": {}, + "name": "module", + "children": [ + { + "label": "Labeled Input", + "is": "div", + "style": { + "width": "100%", + "flex": "1" + }, + "attributes": {}, + "id": "7149f8192509", + "name": "component", + "children": [ + { + "id": "38fc2a4724622", + "label": "Element", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "margin-bottom": "2px" + }, + "children": [ + { + "label": "label", + "id": "ba94dac93878", + "children": [ + { + "id": "7149f8192506", + "name": "text", + "label": "Text", + "value": "Label", + "style": { + "margin-left": "2px", + "margin-bottom": "0px" + }, + "children": [], + "metadata": {}, + "styleMixins": { + "33b5126b196": { + "priority": 0 + } + } + } + ], + "metadata": {}, + "name": "slot" + } + ], + "metadata": {} + }, + { + "id": "7149f81937818", + "label": "Input", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "margin-bottom": "6px" + }, + "children": [ + { + "label": "input", + "id": "e73029b416045", + "children": [ + { + "id": "7149f8199969", + "variant": {}, + "is": "7149f8199122", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [ + { + "id": "80b0b6e7408", + "variantId": null, + "propertyName": "attributes", + "targetIdPath": [], + "value": {}, + "name": "override", + "children": [] + } + ], + "metadata": {}, + "label": "project name input", + "bind": { + "properties": [ + { + "from": "value", + "to": "value" + } + ] + } + } + ], + "metadata": {}, + "name": "slot" + } + ], + "metadata": {}, + "bind": { + "properties": [] + } + } + ], + "metadata": { + "bounds": { + "left": 486, + "top": 306, + "right": 586, + "bottom": 353.5832678332798 + } + }, + "variant": {} + }, + { + "label": "Tooltip", + "is": "div", + "style": { + "box-sizing": "border-box", + "display": "flex", + "flex-direction": "column", + "filter": "drop-shadow(4px 4px 2px rgba(0,0,0,0.1))", + "position": "relative" + }, + "attributes": {}, + "id": "936f2927707", + "name": "component", + "children": [ + { + "id": "936f2927704", + "label": "arrow container", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "display": "block", + "width": "100%", + "height": "12px", + "flex-shrink": "0" + }, + "children": [ + { + "id": "936f2927705", + "label": "arrow", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "display": "block", + "border-top": "12px solid rgba(255, 0, 0, 0)", + "border-right": "12px solid rgba(255, 0, 0, 0)", + "border-bottom": "12px solid var(--bc891e755312)", + "border-left": "12px solid rgba(255, 0, 0, 0)", + "box-sizing": "border-box", + "left": "50%", + "position": "absolute", + "filter": "drop-shadow(0px -1px 0px var(--30f4693267675))", + "transform": "translate(-50%, calc(-50% + 1px))", + "top": "1px" + }, + "children": [], + "metadata": {} + } + ], + "metadata": {} + }, + { + "id": "936f2927706", + "label": "Card", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "background-image": "linear-gradient(var(--bc891e755312), var(--bc891e755312))", + "display": "flex", + "width": "100%", + "height": "100%", + "border-left": "1px solid var(--30f4693267675)", + "border-top": "1px solid var(--30f4693267675)", + "border-right": "1px solid var(--30f4693267675)", + "border-bottom": "1px solid var(--30f4693267675)", + "box-sizing": "border-box", + "border-top-left-radius": "2px", + "border-top-right-radius": "2px", + "border-bottom-left-radius": "2px", + "border-bottom-right-radius": "2px" + }, + "children": [ + { + "id": "936f2927712", + "label": "Content Wrapper", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "display": "block", + "padding-left": "12px", + "padding-top": "12px", + "padding-right": "12px", + "padding-bottom": "12px", + "width": "100%", + "height": "100%", + "position": "relative" + }, + "children": [ + { + "id": "936f2927716", + "children": [ + { + "id": "936f2927714", + "name": "text", + "label": "Text", + "value": "Some content", + "style": {}, + "children": [], + "metadata": {}, + "styleMixins": { + "dc3b39eb1275": { + "priority": 0 + } + } + } + ], + "metadata": {}, + "name": "slot", + "label": "content" + } + ], + "metadata": {} + } + ], + "metadata": {} + }, + { + "id": "368712de18492", + "name": "variant", + "label": "right", + "isDefault": true, + "children": [], + "metadata": {} + }, + { + "id": "368712de18493", + "variantId": "368712de18492", + "propertyName": "style", + "targetIdPath": [ + "936f2927705" + ], + "value": { + "left": "calc(100% - 30px)" + }, + "name": "override", + "children": [] + }, + { + "id": "4496ba59214", + "variantId": "368712de18492", + "propertyName": "style", + "targetIdPath": [], + "value": { + "transform": "translate(-70%, 0px)" + }, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": 58, + "top": 295, + "right": 393, + "bottom": 508 + } + }, + "variant": {}, + "styleMixins": { + "fb4d37ca18486": { + "priority": 0 + } + } + }, + { + "id": "4496ba59215", + "label": "Element", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "display": "block" + }, + "children": [ + { + "id": "4496ba59221", + "label": "Element", + "is": "div", + "name": "element", + "attributes": {}, + "style": {}, + "children": [ + { + "id": "4496ba59217", + "is": "9f364d2139415", + "label": "Button", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": { + "bounds": { + "left": 300, + "top": 120, + "right": 400, + "bottom": 220 + } + }, + "variant": {} + }, + { + "id": "4496ba59226", + "is": "936f2927707", + "label": "Tooltip", + "name": "component-instance", + "attributes": {}, + "style": { + "position": "absolute" + }, + "children": [], + "metadata": { + "bounds": { + "left": 58, + "top": 297, + "right": 393, + "bottom": 510 + } + }, + "variant": { + "368712de18492": true + } + } + ], + "metadata": {} + } + ], + "metadata": { + "bounds": { + "left": 620, + "top": 437, + "right": 1215, + "bottom": 804 + } + } + } + ] +} \ No newline at end of file diff --git a/packages/tandem-designer/src/components/inputs/slider/controller.tsx b/packages/tandem-designer/src/components/inputs/slider/controller.tsx new file mode 100644 index 000000000..af05d0c45 --- /dev/null +++ b/packages/tandem-designer/src/components/inputs/slider/controller.tsx @@ -0,0 +1,95 @@ +import { clamp } from "lodash"; +import * as React from "react"; +import { startDOMDrag } from "tandem-common"; +import { compose, pure, withHandlers, withState } from "recompose"; +import { BaseSliderProps } from "./view.pc"; + +const DEFAULT_MIN = 0; +const DEFAULT_MAX = 100; + +export type Props = { + value?: number; + onChange: any; + onChangeComplete: any; + min?: number; + max?: number; +}; + +type State = { + percent: number; +}; + +const getPercent = ({ min = DEFAULT_MIN, max = DEFAULT_MAX, value }: Props) => { + return clamp((value || 0) / (max - min), 0, 1); +}; + +export default (Base: React.ComponentClass) => + class SliderController extends React.PureComponent { + private _slider: HTMLDivElement; + constructor(props: Props) { + super(props); + this.state = { + percent: getPercent(props), + }; + } + private setPercent = (value: number) => { + this.setState({ ...this.state, percent: value }); + }; + private setSlider = (slider: HTMLDivElement) => { + this._slider = slider; + }; + + private onMouseDown = (event) => { + const { + min = DEFAULT_MIN, + max = DEFAULT_MAX, + onChange, + onChangeComplete, + } = this.props; + const changeCallback = (callback) => { + return (event: MouseEvent) => { + const sliderRect = this._slider.getBoundingClientRect(); + const relativeLeft = event.clientX - sliderRect.left; + let percent = relativeLeft / sliderRect.width; + const change = max - min; + percent = clamp( + ((relativeLeft / sliderRect.width) * change) / change, + 0, + 1 + ); + percent = Number(percent.toFixed(3)); + this.setPercent(percent); + if (callback) { + callback(percent); + } + }; + }; + + startDOMDrag( + event, + () => {}, + changeCallback(onChange), + changeCallback(onChangeComplete) + ); + }; + + componentWillUpdate(props: Props) { + if (props.value !== this.props.value) { + this.setPercent(getPercent(props)); + } + } + + render() { + const { percent } = this.state; + const { setSlider, onMouseDown } = this; + + return ( + + + + ); + } + }; diff --git a/packages/tandem-designer/src/components/inputs/slider/index.scss b/packages/tandem-designer/src/components/inputs/slider/index.scss new file mode 100644 index 000000000..e69de29bb diff --git a/packages/tandem-designer/src/components/inputs/slider/view.pc b/packages/tandem-designer/src/components/inputs/slider/view.pc new file mode 100644 index 000000000..8cf924ad7 --- /dev/null +++ b/packages/tandem-designer/src/components/inputs/slider/view.pc @@ -0,0 +1,75 @@ +{ + "id": "76b155a0891181", + "version": "0.0.6", + "metadata": {}, + "name": "module", + "children": [ + { + "label": "Slider", + "is": "div", + "style": { + "height": "11px", + "position": "relative", + "box-sizing": "border-box" + }, + "attributes": {}, + "id": "956880c910105", + "name": "component", + "children": [ + { + "id": "956880c910103", + "label": "track", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "width": "calc(100% - 8px)", + "height": "4px", + "background": "var(--d8f6340b1442)", + "position": "absolute", + "transform": "translateY(-50%)", + "top": "50%", + "margin-left": "4px", + "border-top-left-radius": "2px", + "border-top-right-radius": "2px", + "border-bottom-left-radius": "2px", + "border-bottom-right-radius": "2px" + }, + "children": [], + "metadata": {} + }, + { + "id": "956880c910104", + "label": "grabber", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "width": "8px", + "height": "8px", + "border-radius": "8px", + "background": "var(--24ce1e4d482)", + "position": "absolute", + "transform": "translate(-50%, -50%)", + "left": "50%", + "top": "50%" + }, + "children": [], + "metadata": {} + } + ], + "metadata": { + "bounds": { + "left": 560, + "top": 290, + "right": 748, + "bottom": 296.4870090036885 + } + }, + "controllers": [ + "./controller.tsx" + ], + "variant": {} + } + ] +} \ No newline at end of file diff --git a/packages/tandem-designer/src/components/inputs/switch/controller.tsx b/packages/tandem-designer/src/components/inputs/switch/controller.tsx new file mode 100644 index 000000000..735ad57d5 --- /dev/null +++ b/packages/tandem-designer/src/components/inputs/switch/controller.tsx @@ -0,0 +1,18 @@ +import * as React from "react"; +import { compose } from "recompose"; +import cx from "classnames"; +import { + default as checkboxController, + Props as CheckboxProps, +} from "../checkbox/controller"; +import { BaseSwitchProps } from "./view.pc"; + +export type Props = CheckboxProps; + +export default compose( + checkboxController, + (Base: React.ComponentClass) => + ({ value, onChange, onChangeComplete, ...rest }) => { + return ; + } +); diff --git a/packages/tandem-designer/src/components/inputs/switch/view.pc b/packages/tandem-designer/src/components/inputs/switch/view.pc new file mode 100644 index 000000000..155907196 --- /dev/null +++ b/packages/tandem-designer/src/components/inputs/switch/view.pc @@ -0,0 +1,128 @@ +{ + "id": "eb4cfb9719", + "version": "0.0.6", + "metadata": {}, + "name": "module", + "children": [ + { + "id": "3f6ce4151973", + "is": "6f30576e8", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": { + "bounds": { + "left": 453, + "top": 274, + "right": 541.5386591971022, + "bottom": 293.77061437971554 + } + }, + "variant": { + "246c305d8": true + }, + "label": "On preview" + }, + { + "label": "Switch", + "is": "div", + "style": { + "box-sizing": "border-box", + "cursor": "pointer" + }, + "attributes": {}, + "id": "6f30576e8", + "name": "component", + "children": [ + { + "id": "6f30576e6", + "label": "track", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "width": "20px", + "height": "10px", + "border-radius": "10px", + "background": "rgba(200, 200, 200, 1)", + "position": "relative" + }, + "children": [ + { + "id": "6f30576e7", + "label": "dot", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "width": "10px", + "height": "10px", + "background": "#333", + "border-radius": "10px", + "position": "relative", + "opacity": "0.4", + "top": "r" + }, + "children": [], + "metadata": {} + } + ], + "metadata": {} + }, + { + "id": "246c305d8", + "name": "variant", + "label": "on", + "isDefault": true, + "children": [], + "metadata": {} + }, + { + "id": "456e01df3", + "variantId": "246c305d8", + "propertyName": "style", + "targetIdPath": [ + "6f30576e6" + ], + "value": { + "background": "var(--24ce1e4d13456)", + "position": "relative" + }, + "name": "override", + "children": [] + }, + { + "id": "40d03f593", + "variantId": "246c305d8", + "propertyName": "style", + "targetIdPath": [ + "6f30576e7" + ], + "value": { + "left": "100%", + "transform": "translateX(-100%)", + "background": "rgba(1, 1, 1, 1)", + "opacity": 0.284 + }, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": 318, + "top": 271, + "right": 418, + "bottom": 371 + } + }, + "controllers": [ + "./controller.tsx" + ], + "variant": {} + } + ] +} \ No newline at end of file diff --git a/packages/tandem-designer/src/components/inputs/table/view.pc b/packages/tandem-designer/src/components/inputs/table/view.pc new file mode 100644 index 000000000..6106f262d --- /dev/null +++ b/packages/tandem-designer/src/components/inputs/table/view.pc @@ -0,0 +1,605 @@ +{ + "id": "651e07640", + "version": "0.0.6", + "metadata": {}, + "name": "module", + "children": [ + { + "label": "Table Cell", + "is": "div", + "style": { + "box-sizing": "border-box", + "flex-grow": "1", + "text-align": "center", + "border-right": "1px solid var(--d8f6340b1442)", + "padding-top": "4px", + "padding-bottom": "4px", + "display": "block", + "width": "100%", + "padding-left": "16px", + "padding-right": "16px" + }, + "attributes": {}, + "id": "c389e38219", + "name": "component", + "children": [ + { + "id": "4b46931a125", + "children": [ + { + "id": "c389e38220", + "name": "text", + "label": "Text", + "value": "Cell\n", + "style": { + "padding-left": "8", + "padding-top": "6", + "padding-right": "8", + "padding-bottom": "6", + "box-sizing": "border-box", + "display": "block", + "text-align": "left" + }, + "children": [], + "metadata": {}, + "styleMixins": { + "dc3b39eb1275": { + "priority": 0 + } + } + } + ], + "metadata": {}, + "name": "slot", + "label": "content" + }, + { + "id": "c389e38235", + "variantId": "c389e38229", + "propertyName": "style", + "targetIdPath": [], + "value": { + "text-align": "center" + }, + "name": "override", + "children": [] + }, + { + "id": "c389e38236", + "variantId": "c389e38229", + "propertyName": "style", + "targetIdPath": [ + "c389e38220" + ], + "value": {}, + "name": "override", + "children": [] + }, + { + "id": "4cc76c5b32", + "name": "variant", + "label": "last", + "isDefault": false, + "children": [], + "metadata": {} + }, + { + "id": "4cc76c5b33", + "variantId": "4cc76c5b32", + "propertyName": "style", + "targetIdPath": [], + "value": { + "border-right": "none" + }, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": 401, + "top": 292, + "right": 501, + "bottom": 392 + } + }, + "variant": {} + }, + { + "label": "Table Row", + "is": "div", + "style": { + "box-sizing": "border-box", + "display": "flex" + }, + "attributes": {}, + "id": "c389e38216", + "name": "component", + "children": [ + { + "id": "cc878eb5469042", + "children": [ + { + "id": "c389e38226", + "is": "c389e38219", + "name": "component-instance", + "attributes": {}, + "style": { + "flex-grow": "1", + "flex-shrink": "1", + "display": "block", + "font-family": "unset" + }, + "children": [], + "metadata": { + "bounds": { + "left": -311, + "top": 877, + "right": -211, + "bottom": 977 + } + }, + "styleMixins": { + "1542269649351": { + "priority": 0 + } + } + }, + { + "id": "c389e38224", + "is": "c389e38219", + "name": "component-instance", + "attributes": {}, + "style": { + "flex-shrink": "1" + }, + "children": [ + { + "id": "4cc76c5b34", + "propertyName": "isDefault", + "targetIdPath": [ + "4cc76c5b32" + ], + "value": true, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": -311, + "top": 877, + "right": -211, + "bottom": 977 + } + }, + "variant": { + "4cc76c5b32": true + } + } + ], + "metadata": {}, + "name": "slot", + "label": "content" + }, + { + "id": "c389e38227", + "name": "variant", + "label": "header", + "isDefault": true, + "children": [], + "metadata": {} + }, + { + "id": "c389e38228", + "variantId": "c389e38227", + "propertyName": "style", + "targetIdPath": [], + "value": { + "font-weight": "600", + "background": "var(--d8f6340b1442)", + "color": "var(--24ce1e4d482)" + }, + "name": "override", + "children": [] + }, + { + "id": "c389e38229", + "name": "variant", + "label": "alt", + "isDefault": false, + "children": [], + "metadata": {} + }, + { + "id": "c389e38230", + "variantId": "c389e38229", + "propertyName": "style", + "targetIdPath": [], + "value": { + "background": "rgba(250, 250, 250, 1)" + }, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": 647, + "top": 145, + "right": 936.685857777165, + "bottom": 263.0653197883014 + } + }, + "variant": {} + }, + { + "label": "Table", + "is": "div", + "style": { + "box-sizing": "border-box", + "display": "flex", + "flex-direction": "column", + "font-size": "10px", + "color": "var(--24ce1e4d482)" + }, + "attributes": {}, + "id": "c389e3829", + "name": "component", + "children": [ + { + "id": "cc878eb5233262", + "children": [ + { + "id": "c389e38234", + "is": "c389e38216", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [ + { + "id": "4cc76c5b4", + "variantId": null, + "propertyName": "isDefault", + "targetIdPath": [ + "c389e38229" + ], + "value": true, + "name": "override", + "children": [] + }, + { + "id": "2842a72d7", + "variantId": null, + "propertyName": "isDefault", + "targetIdPath": [ + "c389e38227" + ], + "value": false, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": -309, + "top": 723, + "right": -19.31414222283513, + "bottom": 841.0653197883014 + } + }, + "variant": { + "c389e38227": true + }, + "label": "header" + }, + { + "id": "4cc76c5b7", + "is": "c389e38216", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [ + { + "id": "4cc76c5b8", + "variantId": null, + "propertyName": "isDefault", + "targetIdPath": [ + "c389e38229" + ], + "value": false, + "name": "override", + "children": [] + }, + { + "id": "2842a72d6", + "variantId": null, + "propertyName": "isDefault", + "targetIdPath": [ + "c389e38227" + ], + "value": false, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": -309, + "top": 723, + "right": -19.31414222283513, + "bottom": 841.0653197883014 + } + } + }, + { + "id": "cc878eb5324099", + "is": "c389e38216", + "name": "component-instance", + "attributes": {}, + "style": { + "display": "flex" + }, + "children": [ + { + "id": "cc878eb5324100", + "variantId": null, + "propertyName": "isDefault", + "targetIdPath": [ + "c389e38229" + ], + "value": true, + "name": "override", + "children": [] + }, + { + "id": "cc878eb5324101", + "variantId": null, + "propertyName": "isDefault", + "targetIdPath": [ + "c389e38227" + ], + "value": false, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": -309, + "top": 723, + "right": -19.31414222283513, + "bottom": 841.0653197883014 + } + }, + "variant": { + "c389e38229": true + } + }, + { + "id": "cc878eb5337197", + "is": "c389e38216", + "name": "component-instance", + "attributes": {}, + "style": { + "display": "flex" + }, + "children": [ + { + "id": "cc878eb5337198", + "variantId": null, + "propertyName": "isDefault", + "targetIdPath": [ + "c389e38229" + ], + "value": true, + "name": "override", + "children": [] + }, + { + "id": "cc878eb5337199", + "variantId": null, + "propertyName": "isDefault", + "targetIdPath": [ + "c389e38227" + ], + "value": false, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": -309, + "top": 723, + "right": -19.31414222283513, + "bottom": 841.0653197883014 + } + } + }, + { + "id": "cc878eb5311065", + "is": "c389e38216", + "name": "component-instance", + "attributes": {}, + "style": { + "display": "flex" + }, + "children": [ + { + "id": "cc878eb5311066", + "variantId": null, + "propertyName": "isDefault", + "targetIdPath": [ + "c389e38229" + ], + "value": true, + "name": "override", + "children": [] + }, + { + "id": "cc878eb5311067", + "variantId": null, + "propertyName": "isDefault", + "targetIdPath": [ + "c389e38227" + ], + "value": false, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": -309, + "top": 723, + "right": -19.31414222283513, + "bottom": 841.0653197883014 + } + }, + "variant": { + "c389e38229": true + } + }, + { + "id": "4cc76c5b9", + "is": "c389e38216", + "name": "component-instance", + "attributes": {}, + "style": { + "display": "flex" + }, + "children": [ + { + "id": "4cc76c5b10", + "variantId": null, + "propertyName": "isDefault", + "targetIdPath": [ + "c389e38229" + ], + "value": true, + "name": "override", + "children": [] + }, + { + "id": "2842a72d5", + "variantId": null, + "propertyName": "isDefault", + "targetIdPath": [ + "c389e38227" + ], + "value": false, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": -309, + "top": 723, + "right": -19.31414222283513, + "bottom": 841.0653197883014 + } + } + }, + { + "id": "c389e38233", + "is": "c389e38216", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [ + { + "id": "2842a72d3", + "variantId": null, + "propertyName": "isDefault", + "targetIdPath": [ + "c389e38227" + ], + "value": false, + "name": "override", + "children": [] + }, + { + "id": "2842a72d4", + "variantId": null, + "propertyName": "isDefault", + "targetIdPath": [ + "c389e38229" + ], + "value": false, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": -309, + "top": 723, + "right": -19.31414222283513, + "bottom": 841.0653197883014 + } + }, + "variant": { + "c389e38229": true + } + } + ], + "metadata": {}, + "name": "slot", + "label": "content" + }, + { + "id": "fa0a27ce2156", + "name": "variant", + "label": "no header", + "isDefault": true, + "children": [], + "metadata": {} + }, + { + "id": "fa0a27ce2157", + "variantId": "fa0a27ce2156", + "propertyName": "style", + "targetIdPath": [ + "c389e38234" + ], + "value": { + "display": "none" + }, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": -21, + "top": 94, + "right": 308.50795530191954, + "bottom": 418.6425584867711 + } + }, + "variant": {} + }, + { + "id": "fa0a27ce2154", + "label": "Element", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "display": "block" + }, + "children": [], + "metadata": { + "bounds": { + "left": -294, + "top": 100, + "right": -194, + "bottom": 200 + } + } + } + ] +} \ No newline at end of file diff --git a/packages/tandem-designer/src/components/inputs/text/auto-complete-controller.tsx b/packages/tandem-designer/src/components/inputs/text/auto-complete-controller.tsx new file mode 100644 index 000000000..7608fe92c --- /dev/null +++ b/packages/tandem-designer/src/components/inputs/text/auto-complete-controller.tsx @@ -0,0 +1,92 @@ +import * as React from "react"; +import { noop } from "lodash"; +import cx from "classnames"; +import { compose } from "recompose"; +import { BaseAutoComleteTextInputProps } from "./view.pc"; +import { withPureInputHandlers, WithInputHandlersProps } from "./controller"; +import { DropdownMenuOption } from "../dropdown/controller"; +import { DropdownMenuItem } from "../dropdown/menu.pc"; +import { EMPTY_ARRAY } from "tandem-common"; + +export type Props = { + value?: any; + onChange?: any; + onChangeComplete?: any; + autoCompleteOptions: DropdownMenuOption[]; +} & BaseAutoComleteTextInputProps; + +export default compose( + (Base: React.ComponentClass) => + class AutoCompleteController extends React.PureComponent { + state = { + openPopover: false, + value: this.props.value, + prevValue: this.props.value, + }; + + onShouldClosePopover = () => { + this.setState({ ...this.state, openPopover: false }); + }; + onBlur = (event) => { + this.setState({ ...this.state, openPopover: false }); + this.props.onBlur && this.props.onBlur(event); + }; + onFocus = () => { + this.setState({ ...this.state, openPopover: true }); + }; + componentWillUpdate(props, state) { + if (props.value !== state.prevValue) { + this.setState({ value: props.value, prevValue: props.value }); + } + } + onChange = (value) => { + this.setState({ value, prevValue: this.props.value }); + if (this.props.onChange) { + this.props.onChange(value); + } + }; + render() { + const { + onKeyDown, + autoCompleteOptions, + onChangeComplete = noop, + ...rest + } = this.props; + const { onShouldClosePopover, onFocus, onBlur, onChange } = this; + const { openPopover, value } = this.state; + const open = openPopover && !value; + + const menuItems = open + ? autoCompleteOptions.map((option, i) => { + return ( + onChangeComplete(option.value)} + > + {option.label} + + ); + }) + : EMPTY_ARRAY; + + return ( + + ); + } + } +); diff --git a/packages/tandem-designer/src/components/inputs/text/controller.tsx b/packages/tandem-designer/src/components/inputs/text/controller.tsx new file mode 100644 index 000000000..e28509d90 --- /dev/null +++ b/packages/tandem-designer/src/components/inputs/text/controller.tsx @@ -0,0 +1,115 @@ +import * as React from "react"; +import * as ReactDOM from "react-dom"; +import { compose } from "recompose"; +import { FocusComponent, FocusProps } from "../../focus"; +import { BaseTextInputProps } from "./view.pc"; + +export type WithInputHandlersProps = { + value?: any; + onChange?: any; + onChangeComplete?: any; + disabled?: boolean; +} & BaseTextInputProps; + +type State = { + value: string; + _value: string; +}; + +export const withPureInputHandlers = + () => (Base: React.ComponentClass) => { + return class InputHandlersWrapper extends React.PureComponent< + WithInputHandlersProps, + State + > { + // needed so that sub components get updates value if source doesn't change. + state = { + value: this.props.value, + _value: this.props.value, + }; + + static getDerivedStateFromProps( + props: WithInputHandlersProps, + state: State + ) { + let newState = state; + if (props.value !== state._value) { + newState = { + ...newState, + _value: props.value, + value: props.value, + }; + } + + return newState === state ? null : newState; + } + + onKeyDown = (event) => { + const { onKeyDown, onChange, onChangeComplete } = this.props; + + if (onKeyDown) { + onKeyDown(event); + } + const nativeEvent = event.nativeEvent; + + setTimeout(() => { + const { + key, + target: { value: newValue }, + } = nativeEvent; + + const oldState = this.state; + + this.setState( + { + ...oldState, + value: newValue, + }, + () => { + if (onChange && oldState.value !== newValue) { + onChange(newValue || undefined); + } + + if (key === "Enter" && onChangeComplete) { + onChangeComplete(newValue || undefined); + } + } + ); + }); + }; + onBlur = (event) => { + const { onChangeComplete } = this.props; + if (onChangeComplete) { + onChangeComplete(event.target.value || undefined); + } + }; + componentDidUpdate(props) { + if (props.value !== this.props.value) { + const input = ReactDOM.findDOMNode( + this as any + ) as HTMLTextAreaElement; + if (document.activeElement !== input) { + input.value = this.props.value == null ? "" : this.props.value; + } + } + } + render() { + const { onKeyDown, onBlur } = this; + return ; + } + }; + }; + +export type Props = WithInputHandlersProps & FocusProps; + +export default compose( + withPureInputHandlers(), + (Base: React.ComponentClass) => + ({ value, focus, onChange, onChangeComplete, ...rest }) => { + return ( + + + + ); + } +); diff --git a/packages/tandem-designer/src/components/inputs/text/index.scss b/packages/tandem-designer/src/components/inputs/text/index.scss new file mode 100644 index 000000000..27f908574 --- /dev/null +++ b/packages/tandem-designer/src/components/inputs/text/index.scss @@ -0,0 +1,3 @@ +.m-text-input { + display: inline-block; +} diff --git a/packages/tandem-designer/src/components/inputs/text/view.pc b/packages/tandem-designer/src/components/inputs/text/view.pc new file mode 100644 index 000000000..fad712e46 --- /dev/null +++ b/packages/tandem-designer/src/components/inputs/text/view.pc @@ -0,0 +1,411 @@ +{ + "id": "76b155a0907062", + "version": "0.0.6", + "metadata": {}, + "name": "module", + "children": [ + { + "label": "Text Input", + "is": "input", + "style": { + "width": "100%", + "box-sizing": "border-box", + "padding-left": "6px", + "padding-bottom": "4px", + "padding-top": "4px", + "padding-right": "6px" + }, + "attributes": {}, + "id": "7149f8199122", + "name": "component", + "children": [ + { + "id": "6507b7e31381", + "name": "variant", + "label": "focus", + "isDefault": false, + "children": [], + "metadata": {} + }, + { + "id": "6507b7e31382", + "variantId": "6507b7e31381", + "propertyName": "style", + "targetIdPath": [], + "value": { + "box-shadow": "inset 0px 0px 0px 1px var(--24ce1e4d13456)" + }, + "name": "override", + "children": [] + }, + { + "id": "e87522711522", + "name": "variant", + "label": "disabled", + "isDefault": true, + "children": [], + "metadata": {} + }, + { + "id": "e87522711523", + "variantId": "e87522711522", + "propertyName": "style", + "targetIdPath": [], + "value": { + "background-image": "linear-gradient(var(--bc891e755312), var(--bc891e755312))", + "box-shadow": "inset 0px 0px 0px 1px var(--1934368810788)", + "opacity": "1" + }, + "name": "override", + "children": [] + }, + { + "id": "19887e89364", + "name": "variant-trigger", + "targetVariantId": "6507b7e31381", + "source": { + "type": 1, + "state": "focus" + }, + "children": [], + "metadata": {} + } + ], + "metadata": { + "bounds": { + "left": 384, + "top": 298, + "right": 484, + "bottom": 327.0358087589019 + } + }, + "controllers": [ + "./controller.tsx" + ], + "variant": {}, + "styleMixins": { + "c29da5f4213993": { + "priority": 0 + }, + "dc3b39eb1275": { + "priority": 1 + } + } + }, + { + "id": "2c83e997767", + "is": "2c83e997743", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [ + { + "id": "2c83e997858", + "propertyName": "style", + "targetIdPath": [ + "2c83e997737", + "ddec6a12139578" + ], + "value": { + "display": "block" + }, + "name": "override", + "children": [] + }, + { + "id": "bc891e75527", + "propertyName": "style", + "targetIdPath": [ + "2c83e997741" + ], + "value": { + "border": "1px solid var(--d8f6340b1442)" + }, + "name": "override", + "children": [] + }, + { + "id": "bc891e755219", + "propertyName": "style", + "targetIdPath": [ + "2c83e997956" + ], + "value": {}, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": 831, + "top": 359, + "right": 1038.9668420825287, + "bottom": 619.7055454883794 + } + }, + "variant": {} + }, + { + "label": "Auto comlete text input", + "is": "div", + "style": { + "box-sizing": "border-box", + "display": "block" + }, + "attributes": {}, + "id": "2c83e997743", + "name": "component", + "children": [ + { + "id": "2c83e997737", + "is": "9b7b527f175442", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [ + { + "slotId": "c00d8561361", + "id": "2c83e997738", + "children": [ + { + "id": "2c83e997739", + "is": "7149f8199122", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": { + "bounds": { + "left": 384, + "top": 298, + "right": 484, + "bottom": 327.0358087589019 + } + }, + "variant": {}, + "label": "text input" + } + ], + "metadata": {}, + "name": "plug" + }, + { + "slotId": "e6638364254", + "id": "2c83e997740", + "children": [ + { + "id": "2c83e997741", + "label": "menu outer", + "is": "div", + "name": "element", + "attributes": {}, + "style": { + "box-sizing": "border-box", + "display": "block", + "margin-top": "4px", + "border-bottom-left-radius": "2px", + "border-top-left-radius": "2px", + "border-top-right-radius": "2px", + "border-bottom-right-radius": "2px", + "border": "1px solid var(--d8f6340b1442)", + "overflow": "scroll" + }, + "children": [ + { + "id": "4200e313386", + "children": [ + { + "id": "2c83e997904", + "is": "8b8bbe2c859177", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [ + { + "id": "2c83e9973980", + "variantId": null, + "propertyName": "text", + "targetIdPath": [ + "8b8bbe2c859176" + ], + "value": "Padding 4", + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": 395, + "top": 347, + "right": 596, + "bottom": 381 + } + }, + "variant": { + "cd433e9f899": false + } + }, + { + "id": "2c83e9971078", + "is": "8b8bbe2c859177", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [ + { + "id": "2c83e9974740", + "variantId": null, + "propertyName": "text", + "targetIdPath": [ + "8b8bbe2c859176" + ], + "value": "Padding 3", + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": 395, + "top": 347, + "right": 596, + "bottom": 381 + } + }, + "variant": { + "cd433e9f899": true + } + }, + { + "id": "2c83e9971014", + "is": "8b8bbe2c859177", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [ + { + "id": "2c83e9973358", + "variantId": null, + "propertyName": "text", + "targetIdPath": [ + "8b8bbe2c859176" + ], + "value": "Padding 2", + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": 395, + "top": 347, + "right": 596, + "bottom": 381 + } + }, + "variant": { + "cd433e9f899": false + } + }, + { + "id": "2c83e997956", + "is": "8b8bbe2c859177", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [ + { + "id": "2c83e9972667", + "variantId": null, + "propertyName": "text", + "targetIdPath": [ + "8b8bbe2c859176" + ], + "value": "Padding 1", + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": 395, + "top": 347, + "right": 596, + "bottom": 381 + } + }, + "variant": { + "cd433e9f899": true + } + }, + { + "id": "2c83e997742", + "is": "8b8bbe2c859177", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [ + { + "id": "2c83e9975362", + "variantId": null, + "propertyName": "text", + "targetIdPath": [ + "8b8bbe2c859176" + ], + "value": "Padding 5", + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": 395, + "top": 347, + "right": 596, + "bottom": 381 + } + }, + "variant": {} + } + ], + "metadata": {}, + "name": "slot", + "label": "menu" + } + ], + "metadata": {} + } + ], + "metadata": {}, + "name": "plug" + } + ], + "metadata": { + "bounds": { + "left": 227, + "top": 361, + "right": 327, + "bottom": 461 + } + }, + "variant": { + "e691a1d98281": false + }, + "label": "popover" + } + ], + "metadata": { + "bounds": { + "left": 535, + "top": 296, + "right": 742.9668420825287, + "bottom": 396 + } + }, + "variant": {}, + "controllers": [ + "./auto-complete-controller.tsx" + ] + } + ] +} \ No newline at end of file diff --git a/packages/tandem-designer/src/components/inputs/textarea/controller.tsx b/packages/tandem-designer/src/components/inputs/textarea/controller.tsx new file mode 100644 index 000000000..12871b8fb --- /dev/null +++ b/packages/tandem-designer/src/components/inputs/textarea/controller.tsx @@ -0,0 +1,18 @@ +import * as React from "react"; +import { compose, pure } from "recompose"; +import { + withPureInputHandlers, + WithInputHandlersProps, +} from "../text/controller"; +import { BaseTextareaProps } from "./view.pc"; + +export type Props = WithInputHandlersProps; + +export default compose( + pure, + withPureInputHandlers(), + (Base: React.ComponentClass) => + ({ value, onKeyDown }) => { + return ; + } +); diff --git a/packages/tandem-designer/src/components/inputs/textarea/view.pc b/packages/tandem-designer/src/components/inputs/textarea/view.pc new file mode 100644 index 000000000..cf5f4e76b --- /dev/null +++ b/packages/tandem-designer/src/components/inputs/textarea/view.pc @@ -0,0 +1,74 @@ +{ + "id": "d65d17fd64", + "version": "0.0.6", + "metadata": {}, + "name": "module", + "children": [ + { + "label": "Textarea", + "is": "textarea", + "style": { + "width": "100%", + "height": "150px", + "border-radius": "2px", + "box-sizing": "border-box", + "border-left": "0px none rgba(1, 0, 1, 0)", + "border-top": "0px none rgba(1, 0, 1, 0)", + "border-right": "0px none rgba(1, 0, 1, 0)", + "border-bottom": "0px none rgba(1, 0, 1, 0)" + }, + "attributes": {}, + "id": "d65d17fd4015", + "name": "component", + "children": [ + { + "id": "c475e80b836", + "name": "variant", + "label": "focus", + "isDefault": true, + "children": [], + "metadata": {} + }, + { + "id": "c475e80b837", + "name": "variant-trigger", + "targetVariantId": "c475e80b836", + "source": { + "type": 1, + "state": "focus" + }, + "children": [], + "metadata": {} + }, + { + "id": "c475e80b1644", + "variantId": "c475e80b836", + "propertyName": "style", + "targetIdPath": [], + "value": { + "box-shadow": "inset 0px 0px 0px 1px var(--24ce1e4d13456)" + }, + "name": "override", + "children": [] + } + ], + "metadata": { + "bounds": { + "left": 681, + "top": 263.5, + "right": 781, + "bottom": 363.5 + } + }, + "controllers": [ + "./controller.tsx" + ], + "variant": {}, + "styleMixins": { + "c29da5f4213993": { + "priority": 0 + } + } + } + ] +} \ No newline at end of file diff --git a/packages/tandem-designer/src/components/inputs/view.pc b/packages/tandem-designer/src/components/inputs/view.pc new file mode 100644 index 000000000..14cb0fa50 --- /dev/null +++ b/packages/tandem-designer/src/components/inputs/view.pc @@ -0,0 +1,127 @@ +{ + "id": "b78f10d2499", + "version": "0.0.5", + "metadata": {}, + "name": "module", + "children": [ + { + "id": "76b155a0873548", + "variant": {}, + "is": "2657ec412855", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": { + "bounds": { + "left": 424, + "top": 399, + "right": 709, + "bottom": 458.471217980185 + } + } + }, + { + "id": "76b155a0875499", + "variant": {}, + "is": "bcda9fb551452", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": { + "bounds": { + "left": 422, + "top": 552, + "right": 650, + "bottom": 616.1275206975329 + } + } + }, + { + "id": "76b155a0883315", + "variant": {}, + "is": "6489655782833", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": { + "bounds": { + "left": 441, + "top": 174, + "right": 674.4524790701034, + "bottom": 236 + } + } + }, + { + "id": "76b155a0897094", + "variant": {}, + "is": "50e32bec2591", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": { + "bounds": { + "left": 403, + "top": 290, + "right": 604, + "bottom": 318.23603217974676 + } + } + }, + { + "id": "76b155a0903070", + "variant": {}, + "is": "67e386c762", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": { + "bounds": { + "left": 829, + "top": 80, + "right": 1041.7928111413887, + "bottom": 261.38668024462754 + } + } + }, + { + "id": "76b155a0915058", + "variant": {}, + "is": "7149f8199122", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": { + "bounds": { + "left": 795, + "top": 320, + "right": 895, + "bottom": 349.0358087589019 + } + } + }, + { + "id": "76b155a0919057", + "variant": {}, + "is": "956880c910105", + "name": "component-instance", + "attributes": {}, + "style": {}, + "children": [], + "metadata": { + "bounds": { + "left": 529, + "top": 258, + "right": 717, + "bottom": 264.4870090036885 + } + } + } + ] +} \ No newline at end of file diff --git a/packages/tandem-designer/src/components/isolated/index.tsx b/packages/tandem-designer/src/components/isolated/index.tsx new file mode 100644 index 000000000..a5f945580 --- /dev/null +++ b/packages/tandem-designer/src/components/isolated/index.tsx @@ -0,0 +1,169 @@ +import React from "react"; +import ReactDOM from "react-dom"; +import { bubbleHTMLIframeEvents, Point } from "tandem-common"; +import { Consumer } from "react-dnd/lib/DragDropContext"; + +export class Isolate extends React.Component< + { + inheritCSS?: boolean; + onMouseDown?: any; + onKeyDown?: any; + onLoad?: any; + scrollPosition?: Point; + children: any; + ignoreInputEvents?: boolean; + translateMousePositions?: boolean; + onScroll?: any; + scrolling?: boolean; + style?: any; + onWheel?: any; + onDragOver?: any; + className?: string; + onDrop?: any; + }, + any +> { + private _mountElement: any; + private _iframe: HTMLIFrameElement; + private _dragDropManager: any; + + componentDidMount() { + if (window["$synthetic"]) { + return; + } + + this._dragDropManager.getBackend().addEventListeners(this.window); + + if (this.props.inheritCSS) { + const head = this.head; + + const tags = [ + ...Array.prototype.slice.call( + document.getElementsByTagName("style"), + 0 + ), + ...Array.prototype.slice.call(document.getElementsByTagName("link"), 0), + ]; + + Array.prototype.forEach.call(tags, function (style) { + head.appendChild(style.cloneNode(true)); + }); + } + + this.body.appendChild((this._mountElement = document.createElement("div"))); + + if (this.props.onMouseDown) { + this.body.addEventListener("mousedown", this.props.onMouseDown); + } + + if (this.props.onKeyDown) { + this.body.addEventListener("keydown", this.props.onKeyDown); + } + + this._render(); + + this._addListeners(); + } + + componentWillUnmount() { + if (this._dragDropManager) { + this._dragDropManager.getBackend().removeEventListeners(this.window); + } + } + + componentDidUpdate() { + this._render(); + const scrollPosition = this.props.scrollPosition as Point; + + if (this.window && scrollPosition) { + if ( + scrollPosition.left !== this.window.scrollX || + scrollPosition.top !== this.window.scrollY + ) { + this.window.scrollTo(scrollPosition.left, scrollPosition.top); + } + } + } + + get window(): Window { + return this._iframe && this._iframe.contentWindow; + } + + get head() { + return this.window.document.head; + } + + get body() { + return this.window.document.body; + } + + onLoad = () => { + if (this.props.onLoad) this.props.onLoad(); + }; + + _render() { + if (window["$synthetic"]) return; + if (this.props.children && this._mountElement) { + ReactDOM.render(this.props.children, this._mountElement); + } + } + + _addListeners() { + bubbleHTMLIframeEvents(this._iframe, { + ignoreInputEvents: this.props.ignoreInputEvents, + translateMousePositions: this.props.translateMousePositions, + }); + } + + onWheel = (event) => { + this.props.onWheel(event); + }; + + onScroll = (event) => { + if (this.props.onScroll) this.props.onScroll(event); + if (this.props.scrolling === false) { + const db = this._iframe.contentDocument; + db.body.scrollLeft = db.body.scrollTop = 0; + } + }; + + setIframe = (iframe: HTMLIFrameElement) => { + this._iframe = iframe; + }; + receiveDragDropManager(manager: any) { + if (this._dragDropManager) { + return; + } + this._dragDropManager = manager; + } + + onTouchMove = () => {}; + + render() { + // TODO - eventually want to use iframes. Currently not supported though. + if (window["$synthetic"]) { + return {this.props.children}; + } + + return ( + + {({ dragDropManager }) => { + this.receiveDragDropManager(dragDropManager); + return ( +