Sunmao: A Truly Extensible Low-Code UI Framework
Although more and more people are now interested in low-code development, some of the limitations of existing low-code solutions still hold everyone back. Among the most common concerns are the inflexibility of low-code and its vulnerability to vendor lock-in.
Obviously, such concerns are reasonable, because everyone does not want to realize that a specific function is not supported by the low-code platform, nor do they want to find that the application needs to be completely rewritten when migrating from a low-code platform of a certain manufacturer.
Some existing products wisely limit the use of low-code to specific areas, such as internal tools or official websites, because in these scenarios, users are more concerned with development efficiency than flexibility and customization capabilities. But when we want to use low code to improve efficiency in more scenarios, such products cannot meet the needs.
Therefore, we started to develop the Sunmao project. On the basis of open source development, we focused on the extensibility of this low-code UI framework.
Design Principles
The name of Sunmao comes from the Chinese tenon and mortise, which is a wood structure technology that has been used since ancient times, and is known for its exquisiteness and stability. We like the name a lot because the tenon and mortise structure is very similar to the way we combine various building elements into a solid application.
During development, we have always followed the following design principles to ensure that our abstractions are correct and consistent.
1. Clarify the responsibilities of different roles
In the process of developing Sunmao, we first divided users into two roles, component developers and application builders. The division of roles is the most important concept in our subsequent design.
Component developers should pay more attention to parts such as code quality, performance, and user experience, and use this as a standard to create reusable components. When component developers develop a new component in their own way, they can encapsulate the component as a Sunmao component and register it in the component library.
Application builders use existing components and implement application-related business logic. Combining components with Sunmao's platform features, application builders can do this more efficiently.
The roles are divided because applications are being developed all the time, but components are iterated much less frequently. Therefore, with the help of Sunmao, users can hand over the task of component development to a small number of senior front-end engineers, and hand over the work of application building to junior front-end engineers, back-end engineers, or even people without code development experience.
2. Use the power of code, not the limit
As mentioned earlier, Sunmao does not limit users to developing applications using only basic components such as buttons and input boxes, but allows component developers to register various complex and domain-specific components to cover application requirements and Continue the existing visual design system.
During the development of Sunmao, we also put a lot of effort into ensuring that our implementation does not impose constraints on users' applications.
For example, the visual editors of many low-code tools provide a highlighting effect when hovering over a component. Quite a few editors implement this function by wrapping a <div>
element outside each component, and monitoring the event and modifying the highlight style of the element. But this implementation has many drawbacks, such as increasing the number of DOM nodes, making components unable to be configured with inline styles, and increasing implicit nesting relationships, which are all unacceptable to Sunmao.
Although it took us more time to find an implementation that avoided all of the above pitfalls, we believe the effort was worth it. Because only in this way can we achieve the power of code and win the approval of developers.
3. Scalability at all levels
Sunmao consists of three layers, core specification, runtime, and editor.
Component and application schemas are defined in the core specification. In addition to regular fields, users can inject additional information by adding annotations and use them at runtime or in the editor.
The components we have mentioned many times are also extensible, and component developers can define various parameters for components and behaviors that interact with other components. In the following sections we will introduce another way to share extensibility between components: traits.
In the visual editor, users can also configure the display and input methods of each component parameter in the editor.
4. Focus instead of divergence
Instead of developing a full-stack low-code solution, we focused on the UI part and are currently limited to the Web UI.
Because we believe that today's back-end technology is changing with each passing day, a UI low-code solution can be more flexibly connected to various back-end services, so as to bring maximum flexibility to users.
How Sunmao Works
Web UI development is quite mature, so Sunmao just adds a few necessary capabilities in low-code scenarios on top of this, namely:
- Responsive
- events and methods
- Slots vs Style Slots
- type
- trait
- Visual editor
Respond to the latest status
Reactive means that when the application state changes, all UIs that depend on that state automatically re-render. Sunmao implements a high-performance reactive state center, into which all components can synchronize their own state and access the state of other components from it.
For example, when we want the demo button to render the value in the demo input box, just fill in {{ input.value.length }}
:
The button can be rendered in real time in response to changes in the input box!
Interaction between components
Modern UI frameworks tend to emphasize the concepts of state-driven and declarative, but pursuing these two points too much in low-code scenarios can be counterproductive.
For example, when you want to click a theme button and switch to a dark theme, the most intuitive way is for the button to provide a onClick
event and trigger the changeTheme
method of the theme component.
In Sunmao, you can declare in the component's specification the events it will send externally and a set of imperative methods that can be called externally. Based on this, any component can interact with methods and other components through events.
Here is an example that listens for an event and executes a method:
Layout and Style
When we develop applications, we often end up combining components into a nested structure, such as a DOM tree in a browser.
In Sunmao's application schema, we use a flat array structure to record all component information, which makes modification and storage more efficient. Therefore, we introduce the concept of slots to represent nested structures.
You can implement and declare which slots a component has in the following ways:
Put one component into another component's slot:
Another feature that has great imagination is the style of custom components. If component developers can expose the ability to define component styles, the reusability of components will be greatly improved.
Similarly, we introduced the concept of style slots to implement custom styles.
You can implement and declare which style slots a component has in the following ways:
Customize styles in style slots:
type safety
In low-code scenarios, type safety can greatly improve the development experience and application building speed. So in Sunmao we heavily use typescript and JSON schema to achieve a great type system.
If the component developer uses typescript for development, Sunmao can infer the typescript type from the component's JSON schema definition, thereby helping the component developer to write type-safe code.
Our type system also provides features such as auto-completion and validation during application building.
Reuse code between components
Many components require common capabilities such as data acquisition and event throttling. The traits we mentioned many times above are designed for this requirement.
Imagine if each component implements its own properties such as dataUrl(获取数据的 URL)
, hidden(是否可见)
, handlers(事件回调)
and so on, it is obviously very redundant. For such requirements, the trait system provides a good abstraction to help developers implement common capabilities in the form of traits and reuse them for multiple components, thereby ensuring the simplicity of component implementation.
Extensible Visual Editor
Sunmao's visual editor reads all component specifications and automatically generates forms based on their defined JSON schema.
If a part of the form needs to be customized, the component developer can implement a custom editor widget. Further reading on the design of the extended visual editor can be found in this design document .
keep open
Sunmao has been developed in an open source manner since day one. But when we say "open", we're not limited to just opening up all source code under the Apache-2.0 license.
Although Sunmao is a project initiated from within SmartX, we chose to keep all proposals, discussions and design decisions in the public Github repository during development, rather than other internal channels. Because we believe "staying open" is the cornerstone of Sunmao's development, and we also see it as our greatest honor for developers to build their own low-code solutions with Sunmao.
If you are interested in sunamo-ui, please visit our Github repository or join our slack channel to stay connected with the community.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。