-
Notifications
You must be signed in to change notification settings - Fork 95
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: Custom Widget #313
Comments
@Yuyz0112 @tanbowensg @xzdry PTAL |
In this spec, |
@tanbowensg Yes, you are right. I have already changed the contents of this proposal now. |
@MrWindlike @tanbowensg I'm going to start with a simple proposal. If we has a implementation like this: import { Editor, Widget, kit } from '@sunmao-ui/editor-sdk';
import ReactQuill from 'react-quill';
import 'react-quill/dist/quill.snow.css';
// type Widget = React.FC<WidgetProps>
const RichTextEditor: Widget = (props) => {
const { value, onChange, schema } = props;
return (
<>
<kit.button>toolbar</kit.button>
<kit.SchemaField schema={schema.subField} />
<ReactQuill
value={value}
onChange={onChange}
/>
</>
);
}
Editor.registerWidget({
name: 'myRichText',
component: RichTextEditor,
}); In this example, we can import static functions from the SDK package, and get dynamic values from the props. This may have a more flexible usage when implementing a custom widget. Since developers may want to build a widget that has the same UI theme as same as other built-in widgets, they need things like And I think the widget mapping API is a shortcut, which developers can implement by themself like this: import { Editor, Widget, kit } from "@sunmao-ui/editor-sdk";
// type Widget = React.FC<WidgetProps>
const LayoutWidget: Widget = (props) => {
const { value, onChange } = props;
return (
<kit.Location
value={{
left: value.paddingLeft,
right: value.paddingRight,
top: value.paddingTop,
bottom: value.paddingBottom,
}}
onChange={(v) =>
onChange({
paddingLeft: v.left,
paddingRight: v.right,
paddingTop: v.top,
paddingBottom: v.bottom,
})
}
/>
);
};
Editor.registerWidget({
name: "myLayout",
component: LayoutWidget,
}); This helps us remove some learning curve of our customize mapping API, and keep the flexibility when developers need to do more complex transformations. So I think we can let developers do this in userland at this moment and maybe provide some helper functions in the future. |
OK. We would support some static functions, types, UI components exported from the SDK package.
Oh, you are right. We should register the widgets by the editor instead of the In addition, maybe we shouldn't export the
The widget mapping API is provided by the If the other widget developers want to do more complex transformations for their properties, they can also import the widget component and use it to develop a new widget.
Does it wrong in the second example? The |
Yes, updated.
Agree, it's just a simple example in my code.
Got it, sorry for the misunderstanding. |
OK. I'm starting to implement it and I will do these jobs:
|
Sounds good. @tanbowensg @xzdry please confirm the latest design before @MrWindlike starts to implement it. |
Demand Overview
We would allow component developers to customize the form widgets for the properties. And we may support these features for the widget:
Scheme Design
Registering Widgets
We should register the widgets like registering the components, traits, and so on. Thus we also define a spec for widgets to describe their information:
Widget Props
The interface of props which would pass to widget component:
Using Other Widgets In The Custom Widget
If component developers want to use other widgets for sub-properties, they can define the widgets in the sub-properties spec options and use
renderBySchema
function in the custom widget component.In The following, I will show you an example of implementing a custom widget for the
Table
component'scolumn
property.First of all, we should define the
column
property's spec.And then we should implement the widget component and call
renderBySchema
inside.Using One Widget To Config Multiple Properties
In some situations, some properties should be configured by the same widget is better.
For example, some components would have the location properties such as
left
,right
,top
,bottom
, which should be configured by a location widget.There are two ways that come to my mind. The first one is using
Type.Object
to wrap the properties which should configure by one widget. And another way is adding a new field likewidgetGroup
into property spec options to define a virtual group for properties.The spec examples of these two ways are following this:
Type.Object
Group
The
Type.Object
way is already implemented and it's easy to use. Although it makes the component developers need to unwrap the properties to take their values in the components, I think it's doesn't matter.The second way needs more additional editor implementation to support it, which would break the currently
onChange
logic.Thus I prefer the first way, which is to use
Type.Object
to define the properties group.Widget Options
The component developers may also want to pass some additional options to the widget component. We would provide the new field
widgetOptions
in properties spec options.In the above location widget example, we may want to pass a keymap to the widget component for key transformed. For example, if we have
paddingLeft
property instead ofleft
property, we should transform it.So, we can define the
map
in thewidgetOptions
to tell the custom widget how to transform the keys.And then we read the
widgetOptions
in the widget component and implement the transformed logic.The text was updated successfully, but these errors were encountered: