node build fixed
This commit is contained in:
280
seanime-2.9.10/internal/plugin/ui/components.go
Normal file
280
seanime-2.9.10/internal/plugin/ui/components.go
Normal file
@@ -0,0 +1,280 @@
|
||||
package plugin_ui
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/dop251/goja"
|
||||
"github.com/goccy/go-json"
|
||||
)
|
||||
|
||||
const (
|
||||
MAX_FIELD_REFS = 100
|
||||
)
|
||||
|
||||
// ComponentManager is used to register components.
|
||||
// Any higher-order UI system must use this to register components. (Tray)
|
||||
type ComponentManager struct {
|
||||
ctx *Context
|
||||
|
||||
// Last rendered components
|
||||
lastRenderedComponents interface{}
|
||||
}
|
||||
|
||||
// jsDiv
|
||||
//
|
||||
// Example:
|
||||
// const div = tray.div({
|
||||
// items: [
|
||||
// tray.text("Some text"),
|
||||
// ]
|
||||
// })
|
||||
func (c *ComponentManager) jsDiv(call goja.FunctionCall) goja.Value {
|
||||
return defineComponent(c.ctx.vm, call, "div", []ComponentProp{
|
||||
{Name: "items", Type: "array", Required: false, OptionalFirstArg: true},
|
||||
{Name: "style", Type: "object", Required: false, Validate: validateType("object")},
|
||||
{Name: "className", Type: "string", Required: false, Validate: validateType("string")},
|
||||
})
|
||||
}
|
||||
|
||||
// jsFlex
|
||||
//
|
||||
// Example:
|
||||
// const flex = tray.flex({
|
||||
// items: [
|
||||
// tray.button({ label: "A button", onClick: "my-action" }),
|
||||
// true ? tray.text("Some text") : null,
|
||||
// ]
|
||||
// })
|
||||
// tray.render(() => flex)
|
||||
func (c *ComponentManager) jsFlex(call goja.FunctionCall) goja.Value {
|
||||
return defineComponent(c.ctx.vm, call, "flex", []ComponentProp{
|
||||
{Name: "items", Type: "array", Required: false, OptionalFirstArg: true},
|
||||
{Name: "style", Type: "object", Required: false, Validate: validateType("object")},
|
||||
{Name: "gap", Type: "number", Required: false, Default: 2, Validate: validateType("number")},
|
||||
{Name: "direction", Type: "string", Required: false, Default: "row", Validate: validateType("string")},
|
||||
{Name: "className", Type: "string", Required: false, Validate: validateType("string")},
|
||||
})
|
||||
}
|
||||
|
||||
// jsStack
|
||||
//
|
||||
// Example:
|
||||
// const stack = tray.stack({
|
||||
// items: [
|
||||
// tray.text("Some text"),
|
||||
// ]
|
||||
// })
|
||||
func (c *ComponentManager) jsStack(call goja.FunctionCall) goja.Value {
|
||||
return defineComponent(c.ctx.vm, call, "stack", []ComponentProp{
|
||||
{Name: "items", Type: "array", Required: false, OptionalFirstArg: true},
|
||||
{Name: "style", Type: "object", Required: false, Validate: validateType("object")},
|
||||
{Name: "gap", Type: "number", Required: false, Default: 2, Validate: validateType("number")},
|
||||
{Name: "className", Type: "string", Required: false, Validate: validateType("string")},
|
||||
})
|
||||
}
|
||||
|
||||
// jsText
|
||||
//
|
||||
// Example:
|
||||
// const text = tray.text("Some text")
|
||||
// // or
|
||||
// const text = tray.text({ text: "Some text" })
|
||||
func (c *ComponentManager) jsText(call goja.FunctionCall) goja.Value {
|
||||
return defineComponent(c.ctx.vm, call, "text", []ComponentProp{
|
||||
{Name: "text", Type: "string", Required: true, OptionalFirstArg: true, Validate: validateType("string")},
|
||||
{Name: "style", Type: "object", Required: false, Validate: validateType("object")},
|
||||
{Name: "className", Type: "string", Required: false, Validate: validateType("string")},
|
||||
})
|
||||
}
|
||||
|
||||
// jsButton
|
||||
//
|
||||
// Example:
|
||||
// const button = tray.button("Click me")
|
||||
// // or
|
||||
// const button = tray.button({ label: "Click me", onClick: "my-action" })
|
||||
func (c *ComponentManager) jsButton(call goja.FunctionCall) goja.Value {
|
||||
return defineComponent(c.ctx.vm, call, "button", []ComponentProp{
|
||||
{Name: "label", Type: "string", Required: true, OptionalFirstArg: true, Validate: validateType("string")},
|
||||
{Name: "onClick", Type: "string", Required: false, Validate: validateType("string")},
|
||||
{Name: "style", Type: "object", Required: false, Validate: validateType("object")},
|
||||
{Name: "intent", Type: "string", Required: false, Validate: validateType("string")},
|
||||
{Name: "disabled", Type: "boolean", Required: false, Default: false, Validate: validateType("boolean")},
|
||||
{Name: "loading", Type: "boolean", Required: false, Default: false, Validate: validateType("boolean")},
|
||||
{Name: "size", Type: "string", Required: false, Validate: validateType("string")},
|
||||
{Name: "className", Type: "string", Required: false, Validate: validateType("string")},
|
||||
})
|
||||
}
|
||||
|
||||
// jsAnchor
|
||||
//
|
||||
// Example:
|
||||
// const anchor = tray.anchor("Click here", { href: "https://example.com" })
|
||||
// // or
|
||||
// const anchor = tray.anchor({ text: "Click here", href: "https://example.com" })
|
||||
func (c *ComponentManager) jsAnchor(call goja.FunctionCall) goja.Value {
|
||||
return defineComponent(c.ctx.vm, call, "anchor", []ComponentProp{
|
||||
{Name: "text", Type: "string", Required: true, OptionalFirstArg: true, Validate: validateType("string")},
|
||||
{Name: "href", Type: "string", Required: true, Validate: validateType("string")},
|
||||
{Name: "target", Type: "string", Required: false, Default: "_blank", Validate: validateType("string")},
|
||||
{Name: "onClick", Type: "string", Required: false, Validate: validateType("string")},
|
||||
{Name: "style", Type: "object", Required: false, Validate: validateType("object")},
|
||||
{Name: "className", Type: "string", Required: false, Validate: validateType("string")},
|
||||
})
|
||||
}
|
||||
|
||||
////////////////////////////////////////////
|
||||
// Fields
|
||||
////////////////////////////////////////////
|
||||
|
||||
// jsInput
|
||||
//
|
||||
// Example:
|
||||
// const input = tray.input("Enter your name") // placeholder as shorthand
|
||||
// // or
|
||||
// const input = tray.input({
|
||||
// placeholder: "Enter your name",
|
||||
// value: "John",
|
||||
// onChange: "input-changed"
|
||||
// })
|
||||
func (c *ComponentManager) jsInput(call goja.FunctionCall) goja.Value {
|
||||
return defineComponent(c.ctx.vm, call, "input", []ComponentProp{
|
||||
{Name: "label", Type: "string", Required: false, OptionalFirstArg: true, Validate: validateType("string")},
|
||||
{Name: "placeholder", Type: "string", Required: false, Validate: validateType("string")},
|
||||
{Name: "value", Type: "string", Required: false, Default: "", Validate: validateType("string")},
|
||||
{Name: "onChange", Type: "string", Required: false, Validate: validateType("string")},
|
||||
{Name: "onSelect", Type: "string", Required: false, Validate: validateType("string")},
|
||||
{Name: "fieldRef", Type: "object", Required: false, Validate: validateType("object")},
|
||||
{Name: "style", Type: "object", Required: false, Validate: validateType("object")},
|
||||
{Name: "disabled", Type: "boolean", Required: false, Default: false, Validate: validateType("boolean")},
|
||||
{Name: "textarea", Type: "boolean", Required: false, Default: false, Validate: validateType("boolean")},
|
||||
{Name: "size", Type: "string", Required: false, Validate: validateType("string")},
|
||||
{Name: "className", Type: "string", Required: false, Validate: validateType("string")},
|
||||
})
|
||||
}
|
||||
|
||||
func validateOptions(v interface{}) error {
|
||||
if v == nil {
|
||||
return errors.New("options must be an array of objects")
|
||||
}
|
||||
marshaled, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var arr []map[string]interface{}
|
||||
if err := json.Unmarshal(marshaled, &arr); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(arr) == 0 {
|
||||
return nil
|
||||
}
|
||||
for _, option := range arr {
|
||||
if _, ok := option["label"]; !ok {
|
||||
return errors.New("options must be an array of objects with a label property")
|
||||
}
|
||||
if _, ok := option["value"]; !ok {
|
||||
return errors.New("options must be an array of objects with a value property")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// jsSelect
|
||||
//
|
||||
// Example:
|
||||
// const select = tray.select("Select an item", {
|
||||
// options: [{ label: "Item 1", value: "item1" }, { label: "Item 2", value: "item2" }],
|
||||
// onChange: "select-changed"
|
||||
// })
|
||||
// // or
|
||||
// const select = tray.select({
|
||||
// placeholder: "Select an item",
|
||||
// options: [{ label: "Item 1", value: "item1" }, { label: "Item 2", value: "item2" }],
|
||||
// value: "Item 1",
|
||||
// onChange: "select-changed"
|
||||
// })
|
||||
func (c *ComponentManager) jsSelect(call goja.FunctionCall) goja.Value {
|
||||
return defineComponent(c.ctx.vm, call, "select", []ComponentProp{
|
||||
{Name: "label", Type: "string", Required: true, OptionalFirstArg: true, Validate: validateType("string")},
|
||||
{Name: "placeholder", Type: "string", Required: false, Validate: validateType("string")},
|
||||
{
|
||||
Name: "options",
|
||||
Type: "array",
|
||||
Required: true,
|
||||
Validate: validateOptions,
|
||||
},
|
||||
{Name: "value", Type: "string", Required: false, Default: "", Validate: validateType("string")},
|
||||
{Name: "onChange", Type: "string", Required: false, Validate: validateType("string")},
|
||||
{Name: "fieldRef", Type: "object", Required: false, Validate: validateType("object")},
|
||||
{Name: "style", Type: "object", Required: false, Validate: validateType("object")},
|
||||
{Name: "disabled", Type: "boolean", Required: false, Default: false, Validate: validateType("boolean")},
|
||||
{Name: "size", Type: "string", Required: false, Validate: validateType("string")},
|
||||
{Name: "className", Type: "string", Required: false, Validate: validateType("string")},
|
||||
})
|
||||
}
|
||||
|
||||
// jsCheckbox
|
||||
//
|
||||
// Example:
|
||||
// const checkbox = tray.checkbox("I agree to the terms and conditions")
|
||||
// // or
|
||||
// const checkbox = tray.checkbox({ label: "I agree to the terms and conditions", value: true })
|
||||
func (c *ComponentManager) jsCheckbox(call goja.FunctionCall) goja.Value {
|
||||
return defineComponent(c.ctx.vm, call, "checkbox", []ComponentProp{
|
||||
{Name: "label", Type: "string", Required: true, OptionalFirstArg: true, Validate: validateType("string")},
|
||||
{Name: "value", Type: "boolean", Required: false, Default: false, Validate: validateType("boolean")},
|
||||
{Name: "onChange", Type: "string", Required: false, Validate: validateType("string")},
|
||||
{Name: "fieldRef", Type: "object", Required: false, Validate: validateType("object")},
|
||||
{Name: "style", Type: "object", Required: false, Validate: validateType("object")},
|
||||
{Name: "disabled", Type: "boolean", Required: false, Default: false, Validate: validateType("boolean")},
|
||||
{Name: "size", Type: "string", Required: false, Validate: validateType("string")},
|
||||
{Name: "className", Type: "string", Required: false, Validate: validateType("string")},
|
||||
})
|
||||
}
|
||||
|
||||
// jsRadioGroup
|
||||
//
|
||||
// Example:
|
||||
// const radioGroup = tray.radioGroup({
|
||||
// options: [{ label: "Item 1", value: "item1" }, { label: "Item 2", value: "item2" }],
|
||||
// onChange: "radio-group-changed"
|
||||
// })
|
||||
func (c *ComponentManager) jsRadioGroup(call goja.FunctionCall) goja.Value {
|
||||
return defineComponent(c.ctx.vm, call, "radio-group", []ComponentProp{
|
||||
{Name: "label", Type: "string", Required: true, OptionalFirstArg: true, Validate: validateType("string")},
|
||||
{Name: "value", Type: "string", Required: false, Default: "", Validate: validateType("string")},
|
||||
{
|
||||
Name: "options",
|
||||
Type: "array",
|
||||
Required: true,
|
||||
Validate: validateOptions,
|
||||
},
|
||||
{Name: "onChange", Type: "string", Required: false, Validate: validateType("string")},
|
||||
{Name: "fieldRef", Type: "object", Required: false, Validate: validateType("object")},
|
||||
{Name: "style", Type: "object", Required: false, Validate: validateType("object")},
|
||||
{Name: "disabled", Type: "boolean", Required: false, Default: false, Validate: validateType("boolean")},
|
||||
{Name: "size", Type: "string", Required: false, Validate: validateType("string")},
|
||||
{Name: "className", Type: "string", Required: false, Validate: validateType("string")},
|
||||
})
|
||||
}
|
||||
|
||||
// jsSwitch
|
||||
//
|
||||
// Example:
|
||||
// const switch = tray.switch({
|
||||
// label: "Toggle me",
|
||||
// value: true
|
||||
// })
|
||||
func (c *ComponentManager) jsSwitch(call goja.FunctionCall) goja.Value {
|
||||
return defineComponent(c.ctx.vm, call, "switch", []ComponentProp{
|
||||
{Name: "label", Type: "string", Required: true, OptionalFirstArg: true, Validate: validateType("string")},
|
||||
{Name: "value", Type: "boolean", Required: false, Default: false, Validate: validateType("boolean")},
|
||||
{Name: "onChange", Type: "string", Required: false, Validate: validateType("string")},
|
||||
{Name: "fieldRef", Type: "object", Required: false, Validate: validateType("object")},
|
||||
{Name: "style", Type: "object", Required: false, Validate: validateType("object")},
|
||||
{Name: "disabled", Type: "boolean", Required: false, Default: false, Validate: validateType("boolean")},
|
||||
{Name: "size", Type: "string", Required: false, Validate: validateType("string")},
|
||||
{Name: "side", Type: "string", Required: false, Validate: validateType("string")},
|
||||
{Name: "className", Type: "string", Required: false, Validate: validateType("string")},
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user