Skip to content

Built-in Widgets

v3sf ships built-in widgets through adapters. Each UI library has its own set of widgets.

Vant Adapter Widgets

For mobile apps. Provided by @v3sf/vant.

Widget NameDescriptionUnderlying Vant Component
inputText inputvan-field
checkboxCheckbox groupvan-checkbox-group
switchToggle switchvan-switch
stepperSteppervan-stepper
numberNumber input (alias for stepper)van-stepper
radioRadio groupvan-radio-group
radioButtonButton-style radiovan-radio-group (button)
pickerScroll pickervan-picker
cascaderCascading selectorvan-cascader
dateDate pickervan-date-picker

Automatic type mapping:

typeDefault Widget
stringinput
booleanswitch
numberstepper
arraycheckbox
datedate

Element Plus Adapter Widgets

For desktop apps. Provided by @v3sf/element-plus.

Widget NameDescriptionUnderlying Element Plus Component
inputText inputel-input
numberNumber inputel-input-number
switchToggle switchel-switch
radioRadio groupel-radio-group
checkboxCheckbox groupel-checkbox-group
selectDropdown selectel-select
cascaderCascading selectorel-cascader
dateDate pickerel-date-picker
textareaMulti-line textel-input (type=textarea)

Passing Props to Underlying Components

Every widget supports forwarding extra props to the underlying UI component through the schema's props field.

json
{
  "quantity": {
    "type": "number",
    "title": "Quantity",
    "widget": "stepper",
    "props": {
      "min": 1,
      "max": 99,
      "step": 1
    }
  }
}

Any prop supported by the underlying component (e.g., van-stepper or el-input-number) can be passed this way.

Custom Widgets

When built-in widgets don't meet your needs, you can create custom ones. See the Custom Widgets guide for full details.

Quick Example with defineWidget

ts
import { defineWidget } from '@v3sf/core'
import MyColorPicker from './MyColorPicker.vue'

const colorPickerWidget = defineWidget({
  component: MyColorPicker,
  propsMap: {
    modelValue: 'value', // Map the standard modelValue to the component's value prop
    disabled: 'disabled',
  },
})

Registering to an Adapter

ts
import { defineAdapter } from '@v3sf/core'
import { vantAdapter } from '@v3sf/vant'
import MyRating from './MyRating.vue'

const customAdapter = defineAdapter({
  widgets: {
    ...vantAdapter.widgets,
    rating: { component: MyRating },
  },
  globalPropsMap: vantAdapter.globalPropsMap,
})

Then use it in a schema:

json
{
  "score": {
    "type": "number",
    "title": "Rating",
    "widget": "rating"
  }
}

Released under the MIT License.