146
docs/en/00-what-is-sunmao-ui.md
Normal file
@ -0,0 +1,146 @@
|
||||
# sunmao-ui: A truly extensible low-code UI framework
|
||||
|
||||
Although more and more people are becoming interested in low-code development, they still have some reservations.
|
||||
|
||||
The most common concerns about low-code are a lack of flexibility and vendor lock-in.
|
||||
|
||||
That is reasonable because no user wants to be told that they cannot implement certain features in their application or that they must rewrite the application when moving it off of a vendor's platform.
|
||||
|
||||
Some products, wisely, limit the use of low-code to specific areas, such as internal tools and landing pages, where users value productivity over flexibility. It works until developers want to boost their productivity in more general scenarios.
|
||||
|
||||
That's why we started working on sunmao-ui, an open-source low-code UI framework with a focus on extensibility.
|
||||
|
||||
## Design principles
|
||||
|
||||
Sunmao is a Chinese phrase '榫卯' that refers to one of the oldest and most durable wooden architectural techniques used in Chinese history. We love this name because it represents how we put together building blocks and make solid applications in sunmao-ui.
|
||||
|
||||
Several design principles are followed while developing sunmao-ui to ensure proper abstraction.
|
||||
|
||||
### 1. Clarify the jobs of different roles
|
||||
|
||||
Sunmao-ui's aha moment came when we learned that persons who develop applications are normally separated into two groups: component developers and application builders.
|
||||
|
||||
Component developers are concerned with code quality, performance, and user experience when creating reusable components. After creating a component in their favourite way, they can wrap it as a sunmao-ui component and register it to the platform.
|
||||
|
||||
Application builders pick reusable components and incorporate business logic into them. They can complete this task quickly and effectively in sunmao-ui with much less code.
|
||||
|
||||
Applications are made every hour, but components are created significantly less frequently. With sunmao-roles ui's division, users may delegate component creation to senior frontend developers while junior frontend developers, backend developers, and even non-coders build and iterate apps.
|
||||
|
||||
### 2. Leverage the power of coding, not limit
|
||||
|
||||
As previously stated, sunmao-ui will not compel users to create applications only with simple components like buttons and inputs. Instead, component developers may register sophisticated, domain-specific components that meet your requirements and follow your design system.
|
||||
|
||||
We also put a lot of effort to ensure that sunmao-ui's implementation does not impose any limit on users. For example, many low-code tools' GUI editors offer highlight when you hover over or select a component. Some of them implement this by wrapping the component with a `<div>` element and styling it.
|
||||
|
||||
However, this is unsatisfactory for sunmao-ui because it increases the number of DOM nodes, changes the hirarchy of DOM nodes, and prevents components from having inline layout.
|
||||
|
||||
Although It took us longer to develop a solution that overcames all of the drawbacks, but we believe it was worthwhile because it does not limit the power of coding.
|
||||
|
||||
### 3. Extensible in every aspect
|
||||
|
||||
Sunmao-ui contains three layers: the core spec, the runtime, and the editor.
|
||||
|
||||
The schema of a component or an application is described in the core spec. Aside from the usual fields, users can add annotations and use them later in the runtime or editor.
|
||||
|
||||
We've already discussed how components functions for the runtime, and all of them are customizable. Later on, we'll talk about trait, which is another approach to expand the runtime.
|
||||
|
||||
Users can also change how a component's property is inputted and displayed in the editor.
|
||||
|
||||
### 4. Concentration rather than divergence
|
||||
|
||||
Instead of creating a full-stack low-code solution, we concentrate on the UI part, and sunmao-ui is currently just available on the web.
|
||||
|
||||
Since we believe that backend technologies are fast improving these days ,creating a UI-only solution that can be utilized with any type of backend service would provide our users with the most flexibility.
|
||||
|
||||
## How does it work
|
||||
|
||||
We believe that web UI development is already quite mature, and sunmao-ui just adds a few necessary primitives for the low-code scenario, namely:
|
||||
|
||||
- reactive
|
||||
- events and methods
|
||||
- slots and style slots
|
||||
- types
|
||||
- traits
|
||||
- GUI editor
|
||||
|
||||
### Respond to the latest state
|
||||
|
||||
Reactive means when a state changes, all the UIs that depend on it will re-render automatically. Sunmao-ui creates a performant, reactive state store in which all components expose their state and can access the state of others.
|
||||
|
||||
For example, we can access demo input's value state in the demo text component:
|
||||
|
||||
<img src="../images/00/reactive.png" width="500px" />
|
||||
|
||||
And it just work!
|
||||
|
||||
<img src="../images/00/reactive.gif" width="500px" />
|
||||
|
||||
### Connect the components
|
||||
|
||||
Modern UI frameworks emphasize state-driven and declarative concepts, which are not friendly to the low-code scenario.
|
||||
|
||||
If you want to switch to the dark theme when you click the theme button, all you need is an `onClick` event and a `changeTheme` method.
|
||||
|
||||
Sunmao-ui's spec lets every component declare the events they will dispatch and a set of immersive methods for interacting with itself from any other components.
|
||||
|
||||
To add an event handler as follows:
|
||||
|
||||
<img src="../images/00/event.png" width="500px" />
|
||||
|
||||
### Layout and style
|
||||
|
||||
When we develop an application, we usually end up with a hierarchical structure of components, such as a DOM tree.
|
||||
|
||||
Sunmao-ui's schema on the other hand, is straightforward to store and modify because we utilize an array to contain all the components without nesting. As a result, we introduce slots to aid in the organization of the hierarchy.
|
||||
|
||||
To declare and implement slots in a component as follows:
|
||||
|
||||
<img src="../images/00/slot1.png" width="500px" />
|
||||
|
||||
To insert a component into a slot of another component:
|
||||
|
||||
<img src="../images/00/slot2.png" width="500px" />
|
||||
|
||||
Another fascinating aspect is customizing the style of a component. If component developers can offer the ability to style a component, it will dramatically increase reusability.
|
||||
|
||||
That is why style slots were created. It enables the application builder to pass CSS styles to components.
|
||||
|
||||
To declare and implement style slots in a component as follows:
|
||||
|
||||
<img src="../images/00/style1.png" width="500px" />
|
||||
|
||||
To insert customized styles to a style slot:
|
||||
|
||||
<img src="../images/00/style2.png" width="500px" />
|
||||
|
||||
### Live in a type-safe world
|
||||
|
||||
We at sunmao-ui feel that type-safe will increase DX and efficiency for component developers as well as application builders. As a result, typescript and JSON schema are heavily used in our implementation.
|
||||
|
||||
If you use typescript to create a component, we will infer types from the JSON schema, which will help you write safe code.
|
||||
|
||||

|
||||
|
||||
Our type system also provides auto-complete and validation features for application builders.
|
||||
|
||||

|
||||
|
||||
### Ability sharing across components
|
||||
|
||||
The word 'trait' appears in the application schema in the previous examples. That is how we share common abilities across components, such as fetching data and throttling events.
|
||||
|
||||
We believe that providing props like `dataUrl`, `hidden`, or `handlers` to every component is redundant. The trait system is a good abstraction for keeping component implementation clean and simple.
|
||||
|
||||
### A extensible GUI editor
|
||||
|
||||
Sunmao-ui's GUI editor will read all of the components' specs and generate a form based on its JSON schema description.
|
||||
|
||||
If some of the form widgets require extensive customization, component developers can implement their own widgets and allow specific components to use them. A detailed design of the customized widgets can be found [here](https://github.com/webzard-io/sunmao-ui/issues/313).
|
||||
|
||||
## Sunmao-ui is open
|
||||
|
||||
Sunmao-ui is an open-source project from day 1. But when we say 'open,' we don't just mean open-sourcing the code under the MIT license.
|
||||
|
||||
Although sunmao-ui starts as an internal project from SmartX, we chose to place all the proposals, discussions, and design decisions into our public repo rather than any internal channels. Because we believe that 'be open' is the cornerstone of sunmao-ui, and that this project will shine as more developers construct their own low-code solution on top of sunmao-ui.
|
||||
|
||||
If you're interested in sunmao-ui, please visit our Github repository and join the slack channel to stay connected with the community.
|
BIN
docs/images/00/event.png
Normal file
After Width: | Height: | Size: 558 KiB |
BIN
docs/images/00/reactive.gif
Normal file
After Width: | Height: | Size: 117 KiB |
BIN
docs/images/00/reactive.png
Normal file
After Width: | Height: | Size: 389 KiB |
BIN
docs/images/00/slot1.png
Normal file
After Width: | Height: | Size: 378 KiB |
BIN
docs/images/00/slot2.png
Normal file
After Width: | Height: | Size: 470 KiB |
BIN
docs/images/00/style1.png
Normal file
After Width: | Height: | Size: 398 KiB |
BIN
docs/images/00/style2.png
Normal file
After Width: | Height: | Size: 305 KiB |
BIN
docs/images/00/type1-1.gif
Normal file
After Width: | Height: | Size: 5.9 MiB |
BIN
docs/images/00/type2.gif
Normal file
After Width: | Height: | Size: 700 KiB |
144
docs/zh/00-what-is-sunmao-ui.md
Normal file
@ -0,0 +1,144 @@
|
||||
# sunmao-ui:一个真正可扩展的低代码 UI 框架
|
||||
|
||||
尽管现在越来越多的人开始对低代码开发感兴趣,但已有低代码方案的一些局限性仍然让大家有所保留。其中最常见的担忧莫过于低代码缺乏灵活性以及容易被厂商锁定。
|
||||
|
||||
显然这样的担忧是合理的,因为大家都不希望在实现特定功能的时候才发现低代码平台无法支持,也不希望从某个厂商的低代码平台迁出时发现应用需要彻底的重写。
|
||||
|
||||
一些已有产品机智地将低代码的使用场景限定在了特定领域中,例如内部工具或者是官网,因为在这些场景中用户更关心开发效率而不是灵活性与定制能力。但当我们希望使用低代码在更多场景中提升效率时,这类产品就不能满足需求了。
|
||||
|
||||
因此,我们开始开发 sunmao-ui 这个项目,在开源开发的基础之上,我们专注于这个低代码 UI 框架的拓展性。
|
||||
|
||||
## 设计原则
|
||||
|
||||
sunmao-ui 的命名来源于中文榫卯,它是一种从古至今一直被使用的木结构技术,以精巧、稳固著称。我们非常喜欢这个名字,因为榫卯结构与我们将各类构建单元组合成一个稳固的应用的方式十分相似。
|
||||
|
||||
在开发的过程中,我们始终遵循以下设计原则,从而确保我们的抽象方式正确且一致。
|
||||
|
||||
### 1. 明确不同角色的职责
|
||||
|
||||
在开发 sunmao-ui 的过程中,我们首先将使用者划分为了组件开发者与应用构建者两个角色,角色的划分是我们后续设计中最重要的概念。
|
||||
|
||||
组件开发者应该更加关注代码质量、性能以及用户体验等部分,并以此为标准创造出可复用的组件。当组件开发者以他们趁手的方式开发了一个新的组件,他们就可以将该组件封装为一个 sunmao-ui 组件并注册到组件库中。
|
||||
|
||||
应用构建者则选用已有的组件,并实现应用相关的业务逻辑。结合组件与 sunmao-ui 的平台特性,应用构建者可以更高效地完成这一工作。
|
||||
|
||||
之所以将角色进行划分,是因为每时每刻都有应用被开发,但组件迭代的频率则低得多。所以在 sunmao-ui 的帮助下,用户可以将组件开发的任务交给少量高级前端工程师完成,而将应用搭建的工作交由初级前端工程师、后端工程师、甚至是无代码开发经验的人完成。
|
||||
|
||||
### 2. 发挥代码的威力,而不是限制
|
||||
|
||||
如之前所说,sunmao-ui 并不将用户局限于只能使用按钮、输入框等基础组件开发应用,而是可以由组件开发者注册各类复杂、适用于特定领域的组件,以此覆盖应用需求以及延续已有的视觉设计体系。
|
||||
|
||||
在开发 sunmao-ui 的过程中,我们也投入了大量的精力来保证我们的实现不会给用户的应用带来限制。
|
||||
|
||||
举个例子来说,许多低代码工具的可视化编辑器都提供了悬浮在组件上时进行高亮的效果。相当一部分编辑器在实现这个功能时都是通过在每个组件之外包裹一个 `<div>` 元素,并对该元素进行事件的监听与高亮样式的修改。但这样的实现方式有诸多弊端,例如增加了 DOM 节点数量、使组件无法被配置 inline 样式以及增加了隐式的嵌套关系,这些对于 sunmao-ui 来说都是不可接受的。
|
||||
|
||||
尽管我们花费了更多时间才找到一个避免以上所有缺陷的实现方式,但我们相信这样的付出是值得的。因为只有这样,我们才能做到发挥代码的威力,赢得开发者的认可。
|
||||
|
||||
### 3. 各个层面的可扩展性
|
||||
|
||||
sunmao-ui 包含三个层级,分别是核心规范、运行时以及编辑器。
|
||||
|
||||
组件与应用的 schema 都在核心规范中进行定义。除去常规的字段之外,用户还可以通过添加注解(annotations)的方式注入额外信息,并在运行时或编辑器中使用。
|
||||
|
||||
我们多次提到的组件本身也是可扩展的,组件开发者为组件可以定义各类参数以及与其他组件交互的行为。在下文中我们还会介绍另一种在组件间共享扩展能力的方式:trait。
|
||||
|
||||
在可视化的编辑器中,用户也可以配置每个组件参数在编辑器中的展示方式与输入方式。
|
||||
|
||||
### 4. 专注而不是发散
|
||||
|
||||
我们没有选择开发一个全栈的低代码解决方案,而是聚焦于 UI 部分,并且目前仅限 Web UI。
|
||||
|
||||
因为我们认为现如今的后端技术日新月异,一个 UI 低代码方案可以更灵活的与各类后端服务对接,这样才能够为使用者带来最大的灵活性。
|
||||
|
||||
## sunmao-ui 的工作原理
|
||||
|
||||
Web UI 开发已经相当成熟,所以 sunmao-ui 只是在此基础之上增加少量低代码场景中必备的能力,即:
|
||||
|
||||
- 响应式
|
||||
- 事件与方法
|
||||
- 插槽与样式插槽
|
||||
- 类型
|
||||
- trait
|
||||
- 可视化编辑器
|
||||
|
||||
### 响应最新的状态
|
||||
|
||||
响应式指的是当应用状态发生变化时,所有依赖该状态的 UI 都自动重写渲染。sunmao-ui 实现了一个高性能的响应式状态中心,所有组件都可以将自己的状态同步至其中以及从中访问其他组件的状态。
|
||||
|
||||
例如,当我们想让 demo 按钮渲染 demo 输入框中的值,只需要填写 `{{ input.value.length }}`:
|
||||
|
||||
<img src="../images/00/reactive.png" width="500px" />
|
||||
|
||||
按钮就能够响应输入框的变化实时渲染!
|
||||
|
||||
<img src="../images/00/reactive.gif" width="500px" />
|
||||
|
||||
### 组件间交互
|
||||
|
||||
现代 UI 框架往往强调状态驱动与声明式的概念,但在低代码场景中过份追求这两点可能适得其反。
|
||||
|
||||
例如当你希望实现点击一个主题按钮并切换至暗色主题的功能,最符合直觉的方式就是按钮提供一个 `onClick` 事件并触发主题组件的 `changeTheme` 方法。
|
||||
|
||||
在 sunmao-ui 中,你可以在组件的规范中声明它会对外发送的事件以及可以供外部调用的一组命令式方法。在此基础上,任意组件都可以通过事件与方法和其他组件进行交互。
|
||||
|
||||
以下是一个监听事件并执行方法的示例:
|
||||
|
||||
<img src="../images/00/event.png" width="500px" />
|
||||
|
||||
### 布局与样式
|
||||
|
||||
当我们开发应用时,最终通常都会将组件组合成一个嵌套结构,例如浏览器中的 DOM 树。
|
||||
|
||||
在 sunmao-ui 的应用 schema 中,我们采用的是一个扁平的数组结构记录所有的组件信息,这样使得修改与存储的时候可以更加高效。也因此,我们引入了插槽的概念来表示嵌套结构。
|
||||
|
||||
通过以下方式可以实现并声明一个组件有哪些插槽:
|
||||
|
||||
<img src="../images/00/slot1.png" width="500px" />
|
||||
|
||||
将一个组件放入另一个组件的插槽中:
|
||||
|
||||
<img src="../images/00/slot2.png" width="500px" />
|
||||
|
||||
另一个有极大想象空间的功能是自定义组件的样式。如果组件开发者能够将定义组件样式的能力对外暴露,组件的可复用性就将大大提升。
|
||||
|
||||
类似地,我们引入了样式插槽的概念实现自定义样式的功能。
|
||||
|
||||
通过以下方式可以实现并声明一个组件有哪些样式插槽:
|
||||
|
||||
<img src="../images/00/style1.png" width="500px" />
|
||||
|
||||
在样式插槽中自定义样式:
|
||||
|
||||
<img src="../images/00/style2.png" width="500px" />
|
||||
|
||||
### 类型安全
|
||||
|
||||
在低代码场景中,类型安全可以极大地提升开发体验与应用搭建速度。所以在 sunmao-ui 中我们重度使用 typescript 与 JSON schema 来实现极佳的类型系统。
|
||||
|
||||
如果组件开发者使用 typescript 进行开发,sunmao-ui 能够从组件的 JSON schema 定义中推断 typescript 的类型,从而帮助组件开发者编写类型安全的代码。
|
||||
|
||||

|
||||
|
||||
我们的类型系统也会在搭建应用的过程中提供自动补全与校验等功能。
|
||||
|
||||

|
||||
|
||||
### 在组件间复用代码
|
||||
|
||||
许多组件都需要获取数据、事件节流等通用能力,我们在上文中多次提到的 trait 就是为这一需求而设计的。
|
||||
|
||||
试想一下,如果每个组件都自行实现 `dataUrl(获取数据的 URL)`、`hidden(是否可见)`、`handlers(事件回调)` 等属性,显然是十分冗余的。对于这类需求,trait 系统提供了很好的抽象,帮助开发者将通用的能力以 trait 形式实现并复用于多个组件,从而保证组件实现的简洁。
|
||||
|
||||
### 可扩展的可视化编辑器
|
||||
|
||||
sunmao-ui 的可视化编辑器读取所有组件的规范并基于其定义的 JSON schema 自动生成表单。
|
||||
|
||||
如果一部分表单需要定制,组件开发者可以实现自定义的编辑器 widget。关于扩展可视化编辑器的设计可以进一步阅读这一[设计文档](https://github.com/webzard-io/sunmao-ui/issues/313)。
|
||||
|
||||
## 保持开放
|
||||
|
||||
从第一天起,sunmao-ui 就以开源的方式进行开发。但当我们说到“开放”时,我们并不仅仅局限于以 MIT 协议开放所有的源代码。
|
||||
|
||||
尽管 sunmao-ui 是从 SmartX 内部发起的项目,我们在开发过程中还是选择将所有的提案、讨论与设计决策放在公开的 Github 仓库中进行,而不是其他的内部频道。因为我们相信“保持开放”是 sunmao-ui 发展的基石,并且我们也视开发者使用 sunmao-ui 构建自己的低代码方案为最大的荣耀。
|
||||
|
||||
如果你对 sunamo-ui 感兴趣,欢迎访问我们的 Github 仓库或者加入我们 slack 频道,与社区保持联系。
|