freon4dsl / Freon4dsl

Web Native language Workbench with Projectional Web Editor
https://www.freon4dsl.dev
MIT License
63 stars 9 forks source link

Adding support for custom HTML (Svelte) components #364

Closed annekekleppe closed 2 weeks ago

annekekleppe commented 1 month ago

During our latest discussion with users of Freon, a wish was expressed to add new HTML parts to the editor. I have been thinking about this and want to share these thoughts, in order to get the requirements on such an enhancement right. As I see it, there are three situations in which a custom component can be useful:

  1. A concept cannot be projected in a desired manner using the in-built Freon component/box combinations. For instance, a property of type Date could be projected in the form of a Date picker. In this case, the language developer should provide an external Box, and a Svelte Component or Svelte wrapper for a component. In this minimal approach, the concept itself must still be defined within Freon to have a supporting TypeScript implementation of the concept.
  2. An HTML/Svelte component, that does not interfere with any of the projections, should be added to one of the projections. For instance, one might want to add a button that triggers some action, in any of the projections. Because Freon always works with a box-component pair, the language developer needs to provide a box, as well as the component.
  3. A Freon projection should be wrapped inside a custom HTML/Svelte component. For instance, creating an accordion or carrousel filled with the projections of the elements in a list. The list itself is wrapped in the Accordion component, while each of the elements is wrapped in a AccordionItem component. Likewise with a carousel. In this case, the language developer needs to provide the component(s) only, not a box. However, the components need to have a where the Freon projection can be added. Syntax in .edit file For all three options there should be a manner to express this in the .edit file. I am thinking in this direction. Situation 1 / AST FILE / expression DateLiteral base Expression { day: string; month: Month; year: string; }

    / EDIT FILE / DateLiteral { [custom=”MyDate”] }

/ SOME IMPORT FILE (maybe a .json?) / import MyDateBox, MyDateComponent from "MyCustomPackage" as "MyDate";

Situation2 / AST FILE / concept CheckingRule base Rule { check: Expression; }

/ EDIT FILE / CheckingRule { [ Validation ${self.name}: ${self.check} [custom =”MyButton”] description: ${self.description}

]

} / IMPORT FILE / import MyButtonBox, MyButtonComponent from "MyCustomPackage" as "MyButton";

Situation 3 / AST FILE / modelunit Rules { name: identifier; reference forEntity: Entity; rules: Rule[]; file-extension = "rules"; }

/ EDIT FILE / Rules { [ Rules ${self.name} for entity ${self.forEntity}

[custom =”MyAccordion” 
    slot=${self.rules}
]

} Rule { [custom =”MyAccordionItem”] }

/ IMPORT FILE / import MyAccordionBox, MyAccordionComponent from "MyCustomPackage" as "MyAccordion"; import MyAccordionItemBox, MyAccordionItemComponent from "MyCustomPackage" as "MyAccordionItem";

Implementation The manner in which this could be implemented is by including a CustomComponent in “Freon/core-svelte”, which should have a slot for whatever component is to be included. There are a number of technical issues to be resolved, like how to include the imports for the external component. There is also the issue of how to instantiate the external Box implementation. But, before solving the technical issues, I would first like to be certain of the requirements for this enhancement. Any input/comments are appreciated.

annekekleppe commented 2 weeks ago

Support for external components is currently in the development branch.