├── .eslintrc.js ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── 1.bug_report.yml │ └── config.yml ├── actions │ └── setup-project │ │ └── action.yml ├── dependabot.yml ├── lock.yml ├── no-response.yml └── workflows │ ├── publish-cli.yml │ ├── publish-core-latest.yml │ ├── publish-core-rc.yml │ ├── publish-docs.yml │ ├── publish.yml │ ├── quality.yml │ └── test.yml ├── .gitignore ├── .prettierignore ├── .prettierrc ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── docs ├── .vuepress │ ├── components │ │ ├── Demo.vue │ │ ├── DemoBasicBlocks.vue │ │ ├── DemoCanvasOnly.vue │ │ ├── DemoCustomPanels.vue │ │ ├── DemoDevices.vue │ │ ├── DemoLayers.vue │ │ ├── DemoStyle.vue │ │ ├── DemoTheme.vue │ │ ├── DemoTraits.vue │ │ ├── DemoViewer.vue │ │ └── demos │ │ │ ├── DemoCanvasOnly.css │ │ │ ├── DemoCanvasOnly.html │ │ │ ├── DemoCanvasOnly.js │ │ │ ├── DemoLayers.css │ │ │ └── utils.js │ ├── config.js │ ├── enhanceApp.js │ ├── public │ │ ├── assets-builtin-modal.png │ │ ├── assets-empty-view.png │ │ ├── assets-full-dropzone.gif │ │ ├── assets-svg-view.png │ │ ├── assets-uploader.png │ │ ├── block-custom-render.jpg │ │ ├── block-custom-render2.jpg │ │ ├── blocks3.jpg │ │ ├── btn-clicked.png │ │ ├── canvas-panels.jpg │ │ ├── canvas-spot-hover.jpg │ │ ├── canvas-spot-resize.jpg │ │ ├── canvas-spot-select.jpg │ │ ├── canvas-spot-target.jpg │ │ ├── component-type-stack.svg │ │ ├── cssom-devtools.png │ │ ├── cssom-result.jpg │ │ ├── default-gjs.jpg │ │ ├── default-link-comp.jpg │ │ ├── default-sm.jpg │ │ ├── default-traits.png │ │ ├── demo-view.png │ │ ├── docs-init-link-trait.jpg │ │ ├── docs-link-trait-raw.jpg │ │ ├── empty-gjs.png │ │ ├── enabled-sm.jpg │ │ ├── grapes.min.js │ │ ├── input-custom-traits.png │ │ ├── layer-manager.png │ │ ├── logo-icon.png │ │ ├── logo.png │ │ ├── margin-strings.jpg │ │ ├── new-btn.png │ │ ├── new-panel.png │ │ ├── selector-manager.jpg │ │ ├── sm-base-type.jpg │ │ ├── sm-component-first.jpg │ │ ├── sm-disable-selector.jpg │ │ ├── sm-empty-state.jpg │ │ ├── sm-selected-component.jpg │ │ ├── sm-type-color.jpg │ │ ├── sm-type-composite.jpg │ │ ├── sm-type-number.jpg │ │ ├── sm-type-radio.jpg │ │ ├── sm-type-select.jpg │ │ ├── sm-type-slider.jpg │ │ ├── sm-type-stack.jpg │ │ ├── studio-banner.jpg │ │ ├── style-comp.jpg │ │ ├── style-manager.jpg │ │ ├── symbols-model.svg │ │ └── trait-categories.png │ ├── styles │ │ ├── index.styl │ │ └── palette.styl │ └── theme │ │ ├── index.js │ │ └── layouts │ │ ├── CarbonAds.vue │ │ ├── Layout.vue │ │ ├── StudioSdkBannerSidebar.vue │ │ └── utils.js ├── Home.md ├── README.md ├── api.mjs ├── api │ ├── README.md │ ├── asset.md │ ├── assets.md │ ├── block.md │ ├── block_manager.md │ ├── canvas.md │ ├── canvas_spot.md │ ├── commands.md │ ├── component.md │ ├── components.md │ ├── css_composer.md │ ├── css_rule.md │ ├── data_source_manager.md │ ├── datarecord.md │ ├── datasource.md │ ├── datasources.md │ ├── device.md │ ├── device_manager.md │ ├── editor.md │ ├── frame.md │ ├── i18n.md │ ├── keymaps.md │ ├── layer.md │ ├── layer_manager.md │ ├── modal_dialog.md │ ├── page.md │ ├── pages.md │ ├── panels.md │ ├── parser.md │ ├── property.md │ ├── property_composite.md │ ├── property_number.md │ ├── property_select.md │ ├── property_stack.md │ ├── rich_text_editor.md │ ├── sector.md │ ├── selector.md │ ├── selector_manager.md │ ├── state.md │ ├── storage_manager.md │ ├── style_manager.md │ ├── trait.md │ ├── trait_manager.md │ └── undo_manager.md ├── faq.md ├── getting-started.md ├── guides │ ├── Custom-CSS-parser.md │ ├── Replace-Rich-Text-Editor.md │ ├── Symbols.md │ └── Telemetry.md ├── modules │ ├── Assets.md │ ├── Blocks.md │ ├── Canvas.md │ ├── Commands.md │ ├── Components-js.md │ ├── Components.md │ ├── DataSources.md │ ├── I18n.md │ ├── Layers.md │ ├── Modal.md │ ├── Pages.md │ ├── Plugins.md │ ├── Selectors.md │ ├── Storage.md │ ├── Style-manager.md │ └── Traits.md └── package.json ├── package.json ├── packages ├── cli │ ├── README.md │ ├── babel.config.js │ ├── index.html │ ├── jest.config.ts │ ├── package.json │ ├── src │ │ ├── banner.txt │ │ ├── build.ts │ │ ├── cli.ts │ │ ├── init.ts │ │ ├── main.ts │ │ ├── serve.ts │ │ ├── template │ │ │ ├── .gitignore-t │ │ │ ├── .npmignore-t │ │ │ ├── README.md │ │ │ ├── package.json │ │ │ ├── src │ │ │ │ ├── blocks.js │ │ │ │ ├── components.js │ │ │ │ └── index.js │ │ │ └── tsconfig.json │ │ ├── utils.ts │ │ └── webpack.config.ts │ ├── test │ │ └── utils.spec.ts │ ├── tsconfig.json │ └── webpack.cli.ts └── core │ ├── .npmignore │ ├── .yarnrc │ ├── LICENSE │ ├── README.md │ ├── babel.config.js │ ├── index.html │ ├── jest.config.js │ ├── package.json │ ├── src │ ├── abstract │ │ ├── CollectionWithCategories.ts │ │ ├── Module.ts │ │ ├── ModuleCategories.ts │ │ ├── ModuleCategory.ts │ │ ├── ModuleCategoryView.ts │ │ ├── ModuleCollection.ts │ │ ├── ModuleDomainViews.ts │ │ ├── ModuleModel.ts │ │ ├── ModuleView.ts │ │ └── index.ts │ ├── asset_manager │ │ ├── config │ │ │ └── config.ts │ │ ├── index.ts │ │ ├── model │ │ │ ├── Asset.ts │ │ │ ├── AssetImage.ts │ │ │ └── Assets.ts │ │ ├── types.ts │ │ └── view │ │ │ ├── AssetImageView.ts │ │ │ ├── AssetView.ts │ │ │ ├── AssetsView.ts │ │ │ └── FileUploader.ts │ ├── block_manager │ │ ├── config │ │ │ └── config.ts │ │ ├── index.ts │ │ ├── model │ │ │ ├── Block.ts │ │ │ └── Blocks.ts │ │ ├── types.ts │ │ └── view │ │ │ ├── BlockView.ts │ │ │ └── BlocksView.ts │ ├── canvas │ │ ├── config │ │ │ └── config.ts │ │ ├── index.ts │ │ ├── model │ │ │ ├── Canvas.ts │ │ │ ├── CanvasSpot.ts │ │ │ ├── CanvasSpots.ts │ │ │ ├── Frame.ts │ │ │ └── Frames.ts │ │ ├── types.ts │ │ └── view │ │ │ ├── CanvasView.ts │ │ │ ├── FrameView.ts │ │ │ ├── FrameWrapView.ts │ │ │ └── FramesView.ts │ ├── code_manager │ │ ├── config │ │ │ └── config.ts │ │ ├── index.ts │ │ ├── model │ │ │ ├── CodeMirrorEditor.ts │ │ │ ├── CssGenerator.ts │ │ │ ├── HtmlGenerator.ts │ │ │ ├── JsGenerator.ts │ │ │ └── JsonGenerator.ts │ │ └── view │ │ │ └── EditorView.ts │ ├── commands │ │ ├── config │ │ │ └── config.ts │ │ ├── index.ts │ │ ├── types.ts │ │ └── view │ │ │ ├── CanvasClear.ts │ │ │ ├── CanvasMove.ts │ │ │ ├── CommandAbstract.ts │ │ │ ├── ComponentDelete.ts │ │ │ ├── ComponentDrag.ts │ │ │ ├── ComponentEnter.ts │ │ │ ├── ComponentExit.ts │ │ │ ├── ComponentNext.ts │ │ │ ├── ComponentPrev.ts │ │ │ ├── ComponentStyleClear.ts │ │ │ ├── CopyComponent.ts │ │ │ ├── ExportTemplate.ts │ │ │ ├── Fullscreen.ts │ │ │ ├── MoveComponent.ts │ │ │ ├── OpenAssets.ts │ │ │ ├── OpenBlocks.ts │ │ │ ├── OpenLayers.ts │ │ │ ├── OpenStyleManager.ts │ │ │ ├── OpenTraitManager.ts │ │ │ ├── PasteComponent.ts │ │ │ ├── Preview.ts │ │ │ ├── Resize.ts │ │ │ ├── SelectComponent.ts │ │ │ ├── SelectPosition.ts │ │ │ ├── ShowOffset.ts │ │ │ └── SwitchVisibility.ts │ ├── common │ │ └── index.ts │ ├── css_composer │ │ ├── config │ │ │ └── config.ts │ │ ├── index.ts │ │ ├── model │ │ │ ├── CssRule.ts │ │ │ └── CssRules.ts │ │ └── view │ │ │ ├── CssGroupRuleView.ts │ │ │ ├── CssRuleView.ts │ │ │ └── CssRulesView.ts │ ├── data_sources │ │ ├── index.ts │ │ ├── model │ │ │ ├── ComponentDataVariable.ts │ │ │ ├── ComponentWithDataResolver.ts │ │ │ ├── DataRecord.ts │ │ │ ├── DataRecords.ts │ │ │ ├── DataResolverListener.ts │ │ │ ├── DataSource.ts │ │ │ ├── DataSources.ts │ │ │ ├── DataVariable.ts │ │ │ ├── TraitDataVariable.ts │ │ │ ├── conditional_variables │ │ │ │ ├── ComponentDataCondition.ts │ │ │ │ ├── ComponentDataOutput.ts │ │ │ │ ├── ConditionStatement.ts │ │ │ │ ├── ConditionalOutputBase.ts │ │ │ │ ├── DataCondition.ts │ │ │ │ ├── DataConditionEvaluator.ts │ │ │ │ ├── LogicalGroupEvaluator.ts │ │ │ │ ├── constants.ts │ │ │ │ ├── operators │ │ │ │ │ ├── AnyTypeOperator.ts │ │ │ │ │ ├── BaseOperator.ts │ │ │ │ │ ├── BooleanOperator.ts │ │ │ │ │ ├── NumberOperator.ts │ │ │ │ │ └── StringOperator.ts │ │ │ │ └── types.ts │ │ │ └── data_collection │ │ │ │ ├── ComponentDataCollection.ts │ │ │ │ ├── constants.ts │ │ │ │ └── types.ts │ │ ├── types.ts │ │ ├── utils.ts │ │ └── view │ │ │ ├── ComponentDataCollectionView.ts │ │ │ ├── ComponentDataConditionView.ts │ │ │ └── ComponentDataVariableView.ts │ ├── device_manager │ │ ├── config │ │ │ └── config.ts │ │ ├── index.ts │ │ ├── model │ │ │ ├── Device.ts │ │ │ └── Devices.ts │ │ └── view │ │ │ └── DevicesView.ts │ ├── dom_components │ │ ├── config │ │ │ └── config.ts │ │ ├── index.ts │ │ ├── model │ │ │ ├── Component.ts │ │ │ ├── ComponentComment.ts │ │ │ ├── ComponentDataResolverWatchers.ts │ │ │ ├── ComponentFrame.ts │ │ │ ├── ComponentHead.ts │ │ │ ├── ComponentImage.ts │ │ │ ├── ComponentLabel.ts │ │ │ ├── ComponentLink.ts │ │ │ ├── ComponentMap.ts │ │ │ ├── ComponentResolverWatcher.ts │ │ │ ├── ComponentScript.ts │ │ │ ├── ComponentSvg.ts │ │ │ ├── ComponentSvgIn.ts │ │ │ ├── ComponentTable.ts │ │ │ ├── ComponentTableBody.ts │ │ │ ├── ComponentTableCell.ts │ │ │ ├── ComponentTableFoot.ts │ │ │ ├── ComponentTableHead.ts │ │ │ ├── ComponentTableRow.ts │ │ │ ├── ComponentText.ts │ │ │ ├── ComponentTextNode.ts │ │ │ ├── ComponentVideo.ts │ │ │ ├── ComponentWrapper.ts │ │ │ ├── Components.ts │ │ │ ├── SymbolUtils.ts │ │ │ ├── Symbols.ts │ │ │ ├── Toolbar.ts │ │ │ ├── ToolbarButton.ts │ │ │ └── types.ts │ │ ├── types.ts │ │ └── view │ │ │ ├── ComponentCommentView.ts │ │ │ ├── ComponentFrameView.ts │ │ │ ├── ComponentImageView.ts │ │ │ ├── ComponentLabelView.ts │ │ │ ├── ComponentLinkView.ts │ │ │ ├── ComponentMapView.ts │ │ │ ├── ComponentScriptView.ts │ │ │ ├── ComponentSvgView.ts │ │ │ ├── ComponentTableBodyView.ts │ │ │ ├── ComponentTableCellView.ts │ │ │ ├── ComponentTableFootView.ts │ │ │ ├── ComponentTableHeadView.ts │ │ │ ├── ComponentTableRowView.ts │ │ │ ├── ComponentTableView.ts │ │ │ ├── ComponentTextNodeView.ts │ │ │ ├── ComponentTextView.ts │ │ │ ├── ComponentVideoView.ts │ │ │ ├── ComponentView.ts │ │ │ ├── ComponentWrapperView.ts │ │ │ ├── ComponentsView.ts │ │ │ ├── ToolbarButtonView.ts │ │ │ └── ToolbarView.ts │ ├── domain_abstract │ │ ├── model │ │ │ ├── StyleableModel.ts │ │ │ └── TypeableCollection.ts │ │ ├── ui │ │ │ ├── Input.ts │ │ │ ├── InputColor.ts │ │ │ └── InputNumber.ts │ │ └── view │ │ │ └── DomainViews.ts │ ├── editor │ │ ├── config │ │ │ └── config.ts │ │ ├── index.ts │ │ ├── model │ │ │ ├── Editor.ts │ │ │ └── Selected.ts │ │ ├── types.ts │ │ └── view │ │ │ └── EditorView.ts │ ├── i18n │ │ ├── config.ts │ │ ├── index.ts │ │ ├── locale │ │ │ ├── ar.js │ │ │ ├── bs.js │ │ │ ├── ca.js │ │ │ ├── de.js │ │ │ ├── el.js │ │ │ ├── en.js │ │ │ ├── es.js │ │ │ ├── fa.js │ │ │ ├── fr.js │ │ │ ├── he.js │ │ │ ├── id.js │ │ │ ├── it.js │ │ │ ├── ko.js │ │ │ ├── nb.js │ │ │ ├── nl.js │ │ │ ├── pl.js │ │ │ ├── pt.js │ │ │ ├── ru.js │ │ │ ├── se.js │ │ │ ├── tr.js │ │ │ ├── vi.js │ │ │ └── zh.js │ │ └── types.ts │ ├── index.ts │ ├── keymaps │ │ ├── config.ts │ │ └── index.ts │ ├── modal_dialog │ │ ├── config │ │ │ └── config.ts │ │ ├── index.ts │ │ ├── model │ │ │ └── Modal.ts │ │ └── view │ │ │ └── ModalView.ts │ ├── navigator │ │ ├── config │ │ │ └── config.ts │ │ ├── index.ts │ │ └── view │ │ │ ├── ItemView.ts │ │ │ └── ItemsView.ts │ ├── pages │ │ ├── index.ts │ │ ├── model │ │ │ ├── Page.ts │ │ │ └── Pages.ts │ │ └── types.ts │ ├── panels │ │ ├── config │ │ │ └── config.ts │ │ ├── index.ts │ │ ├── model │ │ │ ├── Button.ts │ │ │ ├── Buttons.ts │ │ │ ├── Panel.ts │ │ │ └── Panels.ts │ │ └── view │ │ │ ├── ButtonView.ts │ │ │ ├── ButtonsView.ts │ │ │ ├── PanelView.ts │ │ │ └── PanelsView.ts │ ├── parser │ │ ├── config │ │ │ └── config.ts │ │ ├── index.ts │ │ ├── model │ │ │ ├── BrowserParserCss.ts │ │ │ ├── BrowserParserHtml.ts │ │ │ ├── ParserCss.ts │ │ │ └── ParserHtml.ts │ │ └── types.ts │ ├── plugin_manager │ │ └── index.ts │ ├── rich_text_editor │ │ ├── config │ │ │ └── config.ts │ │ ├── index.ts │ │ └── model │ │ │ └── RichTextEditor.ts │ ├── selector_manager │ │ ├── config │ │ │ └── config.ts │ │ ├── index.ts │ │ ├── model │ │ │ ├── Selector.ts │ │ │ ├── Selectors.ts │ │ │ └── State.ts │ │ └── view │ │ │ ├── ClassTagView.ts │ │ │ └── ClassTagsView.ts │ ├── storage_manager │ │ ├── config │ │ │ └── config.ts │ │ ├── index.ts │ │ ├── model │ │ │ ├── IStorage.ts │ │ │ ├── LocalStorage.ts │ │ │ └── RemoteStorage.ts │ │ └── types.ts │ ├── style_manager │ │ ├── config │ │ │ └── config.ts │ │ ├── index.ts │ │ ├── model │ │ │ ├── Layer.ts │ │ │ ├── Layers.ts │ │ │ ├── Properties.ts │ │ │ ├── Property.ts │ │ │ ├── PropertyComposite.ts │ │ │ ├── PropertyFactory.ts │ │ │ ├── PropertyNumber.ts │ │ │ ├── PropertyRadio.ts │ │ │ ├── PropertySelect.ts │ │ │ ├── PropertySlider.ts │ │ │ ├── PropertyStack.ts │ │ │ ├── Sector.ts │ │ │ └── Sectors.ts │ │ └── view │ │ │ ├── LayerView.ts │ │ │ ├── LayersView.ts │ │ │ ├── PropertiesView.ts │ │ │ ├── PropertyColorView.ts │ │ │ ├── PropertyCompositeView.ts │ │ │ ├── PropertyFileView.ts │ │ │ ├── PropertyNumberView.ts │ │ │ ├── PropertyRadioView.ts │ │ │ ├── PropertySelectView.ts │ │ │ ├── PropertySliderView.ts │ │ │ ├── PropertyStackView.ts │ │ │ ├── PropertyView.ts │ │ │ ├── SectorView.ts │ │ │ └── SectorsView.ts │ ├── styles │ │ └── scss │ │ │ ├── _gjs_assets.scss │ │ │ ├── _gjs_blocks.scss │ │ │ ├── _gjs_canvas.scss │ │ │ ├── _gjs_category_general.scss │ │ │ ├── _gjs_code_manager.scss │ │ │ ├── _gjs_commands.scss │ │ │ ├── _gjs_devices.scss │ │ │ ├── _gjs_file_uploader.scss │ │ │ ├── _gjs_inputs.scss │ │ │ ├── _gjs_layers.scss │ │ │ ├── _gjs_main_mixins.scss │ │ │ ├── _gjs_modal.scss │ │ │ ├── _gjs_panels.scss │ │ │ ├── _gjs_root.scss │ │ │ ├── _gjs_rte.scss │ │ │ ├── _gjs_selectors.scss │ │ │ ├── _gjs_spectrum.scss │ │ │ ├── _gjs_status.scss │ │ │ ├── _gjs_style_manager.scss │ │ │ ├── _gjs_traits.scss │ │ │ ├── _gjs_vars.scss │ │ │ ├── main.scss │ │ │ └── spectrum.scss │ ├── trait_manager │ │ ├── config │ │ │ └── config.ts │ │ ├── index.ts │ │ ├── model │ │ │ ├── Trait.ts │ │ │ ├── TraitFactory.ts │ │ │ └── Traits.ts │ │ ├── types.ts │ │ └── view │ │ │ ├── TraitButtonView.ts │ │ │ ├── TraitCheckboxView.ts │ │ │ ├── TraitColorView.ts │ │ │ ├── TraitNumberView.ts │ │ │ ├── TraitSelectView.ts │ │ │ ├── TraitView.ts │ │ │ └── TraitsView.ts │ ├── undo_manager │ │ ├── config.ts │ │ └── index.ts │ └── utils │ │ ├── AutoScroller.ts │ │ ├── ColorPicker.ts │ │ ├── Dragger.ts │ │ ├── Droppable.ts │ │ ├── Resizer.ts │ │ ├── cash-dom.ts │ │ ├── dom.ts │ │ ├── extender.ts │ │ ├── fetch.ts │ │ ├── host-name.ts │ │ ├── html.ts │ │ ├── index.ts │ │ ├── keymaster.ts │ │ ├── mixins.ts │ │ ├── polyfills.ts │ │ ├── promise-polyfill.d.ts │ │ └── sorter │ │ ├── BaseComponentNode.ts │ │ ├── CanvasComponentNode.ts │ │ ├── CanvasNewComponentNode.ts │ │ ├── ComponentSorter.ts │ │ ├── Dimension.ts │ │ ├── DropLocationDeterminer.ts │ │ ├── LayerNode.ts │ │ ├── LayersComponentNode.ts │ │ ├── PlaceholderClass.ts │ │ ├── RateLimiter.ts │ │ ├── SortableTreeNode.ts │ │ ├── Sorter.ts │ │ ├── SorterUtils.ts │ │ ├── StyleManagerSorter.ts │ │ └── types.ts │ ├── test │ ├── common.ts │ ├── setup.js │ ├── specs │ │ ├── asset_manager │ │ │ ├── index.ts │ │ │ ├── model │ │ │ │ ├── Asset.ts │ │ │ │ ├── AssetImage.ts │ │ │ │ └── Assets.ts │ │ │ └── view │ │ │ │ ├── AssetImageView.ts │ │ │ │ ├── AssetView.ts │ │ │ │ ├── AssetsView.ts │ │ │ │ └── FileUploader.ts │ │ ├── block_manager │ │ │ ├── index.ts │ │ │ └── view │ │ │ │ └── BlocksView.ts │ │ ├── canvas │ │ │ └── index.ts │ │ ├── code_manager │ │ │ ├── index.js │ │ │ └── model │ │ │ │ └── CodeModels.js │ │ ├── commands │ │ │ ├── index.ts │ │ │ └── view │ │ │ │ ├── CommandAbstract.ts │ │ │ │ ├── Preview.ts │ │ │ │ └── SwitchVisibility.ts │ │ ├── css_composer │ │ │ ├── e2e │ │ │ │ └── CssComposer.ts │ │ │ ├── index.ts │ │ │ ├── model │ │ │ │ └── CssModels.ts │ │ │ └── view │ │ │ │ ├── CssRuleView.ts │ │ │ │ └── CssRulesView.ts │ │ ├── data_sources │ │ │ ├── __snapshots__ │ │ │ │ ├── jsonplaceholder.ts.snap │ │ │ │ ├── serialization.ts.snap │ │ │ │ └── storage.ts.snap │ │ │ ├── dynamic_values │ │ │ │ ├── attributes.ts │ │ │ │ └── props.ts │ │ │ ├── index.ts │ │ │ ├── jsonplaceholder.ts │ │ │ ├── model │ │ │ │ ├── ComponentDataVariable.getters-setters.ts │ │ │ │ ├── ComponentDataVariable.ts │ │ │ │ ├── StyleDataVariable.ts │ │ │ │ ├── TraitDataVariable.ts │ │ │ │ ├── conditional_variables │ │ │ │ │ ├── ComponentDataCondition.getters-setters.ts │ │ │ │ │ ├── ComponentDataCondition.ts │ │ │ │ │ ├── ConditionalStyles.ts │ │ │ │ │ ├── ConditionalTraits.ts │ │ │ │ │ ├── DataCondition.ts │ │ │ │ │ └── operators │ │ │ │ │ │ ├── AnyTypeOperator.ts │ │ │ │ │ │ ├── BooleanOperator.ts │ │ │ │ │ │ ├── NumberOperator.ts │ │ │ │ │ │ └── StringOperator.ts │ │ │ │ └── data_collection │ │ │ │ │ ├── ComponentDataCollection.getters-setters.ts │ │ │ │ │ ├── ComponentDataCollection.ts │ │ │ │ │ ├── ComponentDataCollectionWithDataVariable.ts │ │ │ │ │ ├── __snapshots__ │ │ │ │ │ ├── ComponentDataCollection.ts.snap │ │ │ │ │ ├── ComponentDataCollectionWithDataVariable.ts.snap │ │ │ │ │ └── nestedComponentDataCollections.ts.snap │ │ │ │ │ └── nestedComponentDataCollections.ts │ │ │ ├── mutable.ts │ │ │ ├── serialization.ts │ │ │ ├── storage.ts │ │ │ └── transformers.ts │ │ ├── device_manager │ │ │ ├── index.js │ │ │ └── view │ │ │ │ └── DevicesView.js │ │ ├── dom_components │ │ │ ├── index.ts │ │ │ ├── model │ │ │ │ ├── Component.ts │ │ │ │ ├── ComponentImage.ts │ │ │ │ ├── ComponentTypes.ts │ │ │ │ ├── ComponentWrapper.ts │ │ │ │ └── Symbols.ts │ │ │ └── view │ │ │ │ ├── ComponentImageView.ts │ │ │ │ ├── ComponentTextView.ts │ │ │ │ ├── ComponentView.ts │ │ │ │ └── ComponentsView.ts │ │ ├── editor │ │ │ ├── index.ts │ │ │ └── telemetry.ts │ │ ├── grapesjs │ │ │ ├── headless.ts │ │ │ └── index.ts │ │ ├── i18n │ │ │ └── index.ts │ │ ├── issue_replications │ │ │ └── checkbox-not-working.ts │ │ ├── keymaps │ │ │ └── index.js │ │ ├── modal │ │ │ ├── index.js │ │ │ └── view │ │ │ │ └── ModalView.js │ │ ├── navigator │ │ │ └── view │ │ │ │ └── ItemView.ts │ │ ├── pages │ │ │ └── index.ts │ │ ├── panels │ │ │ ├── e2e │ │ │ │ └── PanelsE2e.js │ │ │ ├── index.ts │ │ │ ├── model │ │ │ │ └── PanelModels.js │ │ │ └── view │ │ │ │ ├── ButtonView.ts │ │ │ │ ├── ButtonsView.ts │ │ │ │ ├── PanelView.ts │ │ │ │ └── PanelsView.ts │ │ ├── parser │ │ │ └── model │ │ │ │ ├── ParserCss.ts │ │ │ │ └── ParserHtml.ts │ │ ├── plugin_manager │ │ │ └── index.js │ │ ├── selector_manager │ │ │ ├── e2e │ │ │ │ └── ClassManager.ts │ │ │ ├── index.ts │ │ │ ├── model │ │ │ │ └── SelectorModels.ts │ │ │ └── view │ │ │ │ ├── ClassTagView.ts │ │ │ │ └── ClassTagsView.ts │ │ ├── storage_manager │ │ │ ├── index.ts │ │ │ └── model │ │ │ │ └── Models.js │ │ ├── style_manager │ │ │ ├── index.ts │ │ │ ├── model │ │ │ │ ├── Models.ts │ │ │ │ ├── Properties.ts │ │ │ │ ├── PropertyFactory.ts │ │ │ │ └── Sectors.ts │ │ │ └── view │ │ │ │ ├── PropertyColorView.ts │ │ │ │ ├── PropertyCompositeView.ts │ │ │ │ ├── PropertyIntegerView.ts │ │ │ │ ├── PropertyRadioView.ts │ │ │ │ ├── PropertySelectView.ts │ │ │ │ ├── PropertyStackView.ts │ │ │ │ ├── PropertyView.ts │ │ │ │ ├── SectorView.ts │ │ │ │ └── SectorsView.ts │ │ ├── trait_manager │ │ │ ├── index.ts │ │ │ ├── model │ │ │ │ └── TraitsModel.ts │ │ │ └── view │ │ │ │ └── TraitsView.ts │ │ └── utils │ │ │ ├── Mixins.ts │ │ │ └── Sorter.ts │ └── test_utils.js │ ├── tsconfig.json │ └── webpack.config.js ├── pnpm-lock.yaml ├── pnpm-workspace.yaml └── scripts ├── common.ts ├── releaseCli.ts ├── releaseCore.ts └── releaseDocs.ts /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # Shows a funding button via Open Collective 2 | 3 | open_collective: grapesjs 4 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: 🚀 Feature Request 4 | url: https://github.com/artf/grapesjs/discussions/new?category=ideas 5 | about: 'Suggest any ideas you have using our discussion forums.' 6 | - name: 🙏 Help 7 | url: https://github.com/artf/grapesjs/discussions/new?category=q-a 8 | about: 'If you have a question or need help, ask a question on the discussion forums.' 9 | - name: 📢 Show and tell 10 | url: https://github.com/artf/grapesjs/discussions/new?category=show-and-tell 11 | about: "Have something nice to say or share about GrapesJS? We'd love to hear it!" 12 | -------------------------------------------------------------------------------- /.github/actions/setup-project/action.yml: -------------------------------------------------------------------------------- 1 | name: Setup Project 2 | description: 'Sets up the project by installing dependencies and building the project.' 3 | 4 | inputs: 5 | pnpm-version: 6 | description: 'The version of pnpm to use for installing dependencies.' 7 | required: false 8 | default: 9.10.0 9 | node-version: 10 | description: 'The version of Node.js to use for building the project.' 11 | required: false 12 | default: '20.16.0' 13 | 14 | runs: 15 | using: composite 16 | steps: 17 | - uses: pnpm/action-setup@v4 18 | with: 19 | version: ${{ inputs.pnpm-version }} 20 | - uses: actions/setup-node@v4 21 | with: 22 | node-version: ${{ inputs.node-version }} 23 | cache: 'pnpm' 24 | - name: Install dependencies 25 | run: pnpm install 26 | shell: bash 27 | - name: Build project 28 | run: pnpm build 29 | shell: bash 30 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | updates: 4 | - package-ecosystem: 'npm' 5 | directory: '/' 6 | open-pull-requests-limit: 0 7 | schedule: 8 | interval: 'weekly' 9 | -------------------------------------------------------------------------------- /.github/lock.yml: -------------------------------------------------------------------------------- 1 | # Configuration for Lock Threads - https://github.com/dessant/lock-threads 2 | 3 | # Number of days of inactivity before a closed issue or pull request is locked 4 | daysUntilLock: 365 5 | 6 | # Skip issues and pull requests created before a given timestamp. Timestamp must 7 | # follow ISO 8601 (`YYYY-MM-DD`). Set to `false` to disable 8 | skipCreatedBefore: false 9 | 10 | # Issues and pull requests with these labels will be ignored. Set to `[]` to disable 11 | exemptLabels: 12 | - no-locking 13 | - help-wanted 14 | 15 | # Label to add before locking, such as `outdated`. Set to `false` to disable 16 | lockLabel: outdated 17 | 18 | # Comment to post before locking. Set to `false` to disable 19 | lockComment: > 20 | This thread has been automatically locked since there has not been 21 | any recent activity after it was closed. Please open a new issue for 22 | related bugs. 23 | 24 | # Assign `resolved` as the reason for locking. Set to `false` to disable 25 | setLockReason: true 26 | # Limit to only `issues` or `pulls` 27 | # only: issues 28 | 29 | # Optionally, specify configuration settings just for `issues` or `pulls` 30 | # issues: 31 | # exemptLabels: 32 | # - help-wanted 33 | # lockLabel: outdated 34 | 35 | # pulls: 36 | # daysUntilLock: 30 37 | 38 | # Repository to extend settings from 39 | # _extends: repo 40 | -------------------------------------------------------------------------------- /.github/no-response.yml: -------------------------------------------------------------------------------- 1 | # Configuration for probot-no-response - https://github.com/probot/no-response 2 | 3 | # Number of days of inactivity before an Issue is closed for lack of response 4 | daysUntilClose: 10 5 | # Label requiring a response 6 | responseRequiredLabel: more-information-needed 7 | # Comment to post when closing an Issue for lack of response. Set to `false` to disable 8 | closeComment: > 9 | This issue has been automatically closed because there has been no response 10 | to our request for more information from the original author. With only the 11 | information that is currently in the issue, we don't have enough information 12 | to take action. Please reach out if you have or find the answers we need so 13 | that we can investigate further. 14 | -------------------------------------------------------------------------------- /.github/workflows/publish-cli.yml: -------------------------------------------------------------------------------- 1 | name: Publish GrapesJS CLI 2 | on: 3 | push: 4 | branches: [dev] 5 | paths: 6 | - 'packages/cli/**' 7 | 8 | jobs: 9 | publish: 10 | if: "contains(github.event.head_commit.message, 'Release GrapesJS cli:')" 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v4 14 | - uses: ./.github/actions/setup-project 15 | - name: Publish Core 16 | run: pnpm publish --access public 17 | working-directory: ./packages/cli 18 | -------------------------------------------------------------------------------- /.github/workflows/publish-core-latest.yml: -------------------------------------------------------------------------------- 1 | name: Publish GrapesJS core latest 2 | on: 3 | push: 4 | branches: [dev] 5 | paths: 6 | - 'packages/core/**' 7 | 8 | jobs: 9 | publish: 10 | if: "contains(github.event.head_commit.message, 'Release GrapesJS core latest:')" 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v4 14 | - uses: ./.github/actions/setup-project 15 | - name: Build cli 16 | run: pnpm run build:cli 17 | - name: Build core 18 | run: pnpm run build:core 19 | - name: Check core TS 20 | run: pnpm run ts:check 21 | - name: Publish to npm 22 | env: 23 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 24 | run: | 25 | echo "//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}" >> ./packages/core/.npmrc 26 | pnpm publish:core:latest 27 | -------------------------------------------------------------------------------- /.github/workflows/publish-core-rc.yml: -------------------------------------------------------------------------------- 1 | name: Publish GrapesJS core rc 2 | on: 3 | push: 4 | branches: [dev] 5 | paths: 6 | - 'packages/core/**' 7 | 8 | jobs: 9 | publish: 10 | if: "contains(github.event.head_commit.message, 'Release GrapesJS core rc:')" 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v4 14 | - uses: ./.github/actions/setup-project 15 | - name: Build cli 16 | run: pnpm run build:cli 17 | - name: Build core 18 | run: pnpm run build:core 19 | - name: Check core TS 20 | run: pnpm run ts:check 21 | - name: Publish to npm 22 | env: 23 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 24 | run: | 25 | echo "//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}" >> ./packages/core/.npmrc 26 | pnpm publish:core:rc 27 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish package 2 | 3 | on: 4 | release: 5 | types: [created] 6 | 7 | jobs: 8 | publish: 9 | if: ${{ false }} 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v4 13 | - uses: actions/setup-node@v4 14 | with: 15 | node-version: '20.x' 16 | registry-url: 'https://registry.npmjs.org' 17 | cache: 'yarn' 18 | - run: yarn --frozen-lockfile 19 | - run: yarn build 20 | - run: npm publish 21 | env: 22 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 23 | -------------------------------------------------------------------------------- /.github/workflows/quality.yml: -------------------------------------------------------------------------------- 1 | name: GrapesJS Qualty Checks 2 | on: 3 | push: 4 | branches: [dev] 5 | pull_request: 6 | branches: [dev] 7 | 8 | jobs: 9 | quality-checks: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v4 13 | - uses: ./.github/actions/setup-project 14 | - name: TS Check 15 | run: pnpm ts:check 16 | - name: Lint 17 | run: pnpm lint 18 | - name: Format Check 19 | run: pnpm format:check 20 | - name: Docs 21 | run: pnpm docs:api 22 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: GrapesJS Tests 2 | on: 3 | push: 4 | branches: [dev] 5 | pull_request: 6 | branches: [dev] 7 | 8 | jobs: 9 | test-core: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v4 13 | - uses: ./.github/actions/setup-project 14 | - name: Core Tests 15 | run: pnpm test 16 | working-directory: ./packages/core 17 | test-cli: 18 | runs-on: ubuntu-latest 19 | steps: 20 | - uses: actions/checkout@v4 21 | - uses: ./.github/actions/setup-project 22 | - name: CLI Tests 23 | run: pnpm test 24 | working-directory: ./packages/cli 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .settings/ 3 | .sass-cache/ 4 | .project 5 | .idea 6 | npm-debug.log* 7 | yarn-error.log 8 | package-lock.json 9 | style/.sass-cache/ 10 | stats.json 11 | .npmrc 12 | 13 | img/ 14 | images/ 15 | private/ 16 | vendor/ 17 | coverage/ 18 | locale/ 19 | node_modules/ 20 | bower_components/ 21 | grapesjs-*.tgz 22 | _index.html 23 | docs/.vuepress/dist 24 | dist/ -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | docs/**/*.md 2 | dist/ 3 | pnpm-lock.yaml 4 | packages/cli/src/template/**/*.* 5 | **/locale/** 6 | stats.json -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "endOfLine": "lf", 3 | "insertPragma": false, 4 | "requirePragma": false, 5 | "trailingComma": "all", 6 | "tabWidth": 2, 7 | "useTabs": false, 8 | "singleQuote": true, 9 | "printWidth": 120 10 | } 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | ./packages/core/LICENSE -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ./packages/core/README.md 2 | -------------------------------------------------------------------------------- /docs/.vuepress/components/Demo.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 15 | -------------------------------------------------------------------------------- /docs/.vuepress/components/DemoBasicBlocks.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 19 | 20 | 31 | -------------------------------------------------------------------------------- /docs/.vuepress/components/DemoCanvasOnly.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /docs/.vuepress/components/DemoCustomPanels.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 33 | 34 | 53 | -------------------------------------------------------------------------------- /docs/.vuepress/components/DemoLayers.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /docs/.vuepress/components/DemoStyle.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 54 | 55 | 60 | -------------------------------------------------------------------------------- /docs/.vuepress/components/DemoTraits.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | 55 | 56 | 61 | -------------------------------------------------------------------------------- /docs/.vuepress/components/DemoViewer.vue: -------------------------------------------------------------------------------- 1 |