Differences from React

Where @chelone/vue departs from the React pages, so you know which code does not carry over.

Most pages in these docs show React code. @chelone/vue has the same components, controllers and hooks, so a page still describes the behaviour. This page lists where the Vue code is written differently. Setup is on the Vue setup page.

The general mapping:

  • Props are kebab-case in templates: :data-provider, :query-client.
  • A React callback prop such as onConfirm is an emitted event: @confirm.
  • A ReactNode prop is a slot: #layout, #dashboard, #error.
  • A component prop takes the component itself, not a render function: :list="PostList".
  • A composable returns Refs where the React hook returns plain values.

A component page's props table follows the React and Vue switch on the page. Set to Vue, it lists the props, emitted events and slots @chelone/vue declares for that component, which is not always the React list with the names changed.

The admin

ReactVueReact page
<Admin router={...}> swaps the router adapter.There is no router prop and no router swap. <Admin> uses the vue-router the app installs.Swapping the router
The children can be a function that receives permissions.The default slot takes no arguments.Auth, basename and permissions
<Admin.Title> and the title prop set the admin title.There is no <Admin.Title> and no title slot.Admin
With no layout given, <Admin> renders the routes with no layout.A default layout renders when no #layout slot is given.The layout slot
The Zod registry prop is resources.The Zod registry prop is registry. resources is an array of view definitions, the way to register a resource without a <Resource> child.The resources prop
<CustomRoutes> children add routes.customRoutes is an array prop, read once.Custom Routes
The error fallback receives { error, errorInfo, resetErrorBoundary }.The #error slot receives { error, info, reset }. info is Vue's description of where the error was thrown.Error
ResourceDefinition takes options, so resources group in the menu and carry a label override.ResourceDefinition has no options: the menu is one flat group, and a resource label comes from the translation key or the humanized name.Resource

The full prop list for <Admin> and <Resource> is on the Vue setup page.

Forms and hooks

ReactVueReact page
<TabbedForm.Tab> and <WizardForm.Step> are statics on the form.TabbedFormTab and WizardFormStep are separate components, imported from @chelone/vue.Tabbed Form, Wizard Form
useStoreItem(key, default) returns [value, setter] and follows a changing key.useStoreItem returns [Ref, setter]. The key and default are read once, in setup.None
A field or input label is a ReactNode.label is a string, or false to hide it. An input takes no label markup. <FieldLabelText> renders its default slot as the label, for a label you build yourself.Text Input
<FilterForm> selects the displayed filters with alwaysOn and a remove control per input.<FilterForm> shows the inputs slotted into it. There is no alwaysOn and no displayed-filter selection.Filter Form

Components

ReactVueReact page
<Confirm> takes onConfirm and onClose, and a node as content.<Confirm> emits confirm and close, and takes a string as content. Its default slot holds a body that is not translated.Confirm
<BooleanField> takes TrueIcon and FalseIcon.<BooleanField> has no TrueIcon or FalseIcon props. It draws a built-in check or cross, styled through class.Boolean Field
<FileInput> and <ImageInput> use react-dropzone.They use native drag and drop. The value shape is the same: { rawFile, src, title } for a dropped file.File Input, Image Input
<Notification> renders through sonner.<Notification> is a dependency-free toaster, a stack at the bottom centre with its own close button.Notification
<ThemeModeToggle> opens a dropdown of modes.<ThemeModeToggle> is one button. Each click cycles light, dark, system.Theme Mode Toggle
<IconButtonWithTooltip> shows a styled tooltip.<IconButtonWithTooltip> shows the native title, because the Vue ui slice has no Tooltip. Its label is also the aria-label; a #label slot stands in for a non-string label.Icon Button With Tooltip
<SimpleList> takes function props such as primaryText.<SimpleList> takes scoped slots such as #primary-text, each given { record, id }.Simple List
<SimpleFormIterator> is a child of <ArrayInput>.There is no <SimpleFormIterator>. <ArrayInput> takes disableAdd, disableRemove, inline and the rest as props, with the #add-button, #remove-button and #reorder-buttons slots.Simple Form Iterator
<TabbedShowLayout>, <TranslatableInputs> and <TranslatableFields> draw their tabs with ui/tabs.They draw native buttons with role="tab". The tab child of <TabbedShowLayout> is TabbedShowLayoutTab, imported from @chelone/vue.Tabbed Show Layout, Translatable Inputs, Translatable Fields
<TranslatableInputs> and <TranslatableFields> take a selector element.They take a #selector slot.Translatable Inputs, Translatable Fields
<RefreshIconButton> shows a styled tooltip.<RefreshIconButton> shows the native title, and its label is also the aria-label.Refresh Icon Button
<BulkEditDrawer> opens a Sheet.<BulkEditDrawer> opens an inline panel that is not teleported.Bulk Edit Drawer
<FilterLiveSearch> builds on FilterLiveForm.<FilterLiveSearch> builds on <FilterForm>, because Vue has no FilterLiveForm.Filter Live Search
<ColumnsButton> opens a Popover.<ColumnsButton> shows its panel inside a DropdownMenu. The panel holds plain rows, so it stays open while you switch several columns.Columns Button
<TreeList> takes the onSelect, loading and empty props.<TreeList> emits select and takes the #loading and #empty slots. With no select listener a row navigates, as React does with no onSelect.Tree List
<PivotGrid> takes the loading and empty props.<PivotGrid> takes the #loading and #empty slots.Pivot Grid
<PivotGrid> takes a format that returns a node.<PivotGrid> takes a format that returns a string, so a cell is always text.Pivot Grid
<RecordTimeline> takes the loading and empty props.<RecordTimeline> takes the #loading and #empty slots.Record Timeline
<CalendarList> takes the onSelectEvent, onSelectSlot and onDrop props.<CalendarList> emits select-event, select-slot and drop. A drop listener makes month-view events draggable.Calendar List
<CalendarList> takes the eventRenderer and headerRenderer props.<CalendarList> takes the #event and #header slots.Calendar List
<KanbanBoard> takes an onSelectCard prop.<KanbanBoard> emits select-card. With no select-card listener a card navigates, as React does with no onSelectCard.Kanban Board
<KanbanBoard> takes a cardRenderer prop.<KanbanBoard> takes the #card slot, given { record }.Kanban Board
<ApprovalQueue> takes a rowExtra prop, a function of the record.<ApprovalQueue> takes the #extra slot, given { record }.Approval Queue
<StatusTransitionButton> takes an onTransition prop. <DualApprovalButton> takes only props.<StatusTransitionButton> emits a transition event with the same (from, to, record) arguments. <DualApprovalButton> takes the same props.Status Transition Button, Dual Approval Button
<CommandMenu> composes cmdk's Command with a teleported dialog.<CommandMenu> composes the native ui/command family with an inline dialog that is not teleported.Command Menu
<Assistant> confirms a tool in a Radix Dialog that shows the arguments in a <pre>.<Assistant> confirms a tool in the inline <Confirm>, which is not teleported. It passes the arguments in <Confirm>'s default slot, in a <pre>. Its icons are inline SVG. The props are the same.Assistant
<DiffViewer> takes formatters, a renderer per source that returns a node.<DiffViewer> takes the #value slot, given { source, value, side } with side either before or after.Diff Viewer
<DiffViewer> takes labels whose values can be nodes.<DiffViewer> takes labels whose values are strings.Diff Viewer
<PermissionMatrix> takes value and onChange.<PermissionMatrix> is a v-model: modelValue in and update:modelValue out with the whole next value. It takes class where React takes className.Permission Matrix
<InPlaceEditor> takes children for the shown value and editor for the input.<InPlaceEditor> takes the default slot for the shown value and the #editor slot for the input.In Place Editor
<InPlaceEditor> takes onSuccess and onError props.<InPlaceEditor> emits success with the saved record and error with the failure.In Place Editor
<Configurable> takes an editor node prop, and <InspectorButton> takes the shadcn button props with an onClick.<Configurable> takes the #editor slot, and <InspectorButton> takes label, class and disabled, has an #icon slot and emits click. Both take class where React takes className.Inspector
<OnboardingTour> takes an onComplete prop, called with "finished" or "skipped".<OnboardingTour> emits complete with the same two values.Onboarding Tour
<OnboardingTour> steps take a title and content that are nodes.A step's title and content are strings. A #step slot, given { step, index }, replaces both.Onboarding Tour
<TrendChart> and <BarChart> plot the row's xField value on the x axis.They plot the row index and label each tick with that row's xField, so any x value keeps its order. With more than 7 rows only every step-th tick is labelled.Trend Chart, Bar Chart
<TrendChart>'s xTickFormatter formats the x axis ticks.It formats the tooltip's row label too: the axis and the crosshair share one function.Trend Chart
<TrendChart> and <BarChart> show their tooltip through recharts' <ChartTooltip>.They show it through unovis' crosshair: VisCrosshair carries an HTML template and VisTooltip renders it.Trend Chart, Bar Chart
<DonutChart> shows its tooltip through recharts' <ChartTooltip> as well.It has no crosshair. VisTooltip takes a triggers map keyed on Donut.selectors.segment, so the tooltip follows the hovered segment.Donut Chart
<TrendChart>'s tooltipFormatter returns text recharts renders as a node.It returns text that goes into the crosshair's HTML string.Trend Chart
<DonutChart>'s height sizes the chart, and the ring is 30% of the radius whatever it is.height sizes the chart and the ring: the arc is 15% of height wide.Donut Chart
<TrendChart>, <BarChart>, <DonutChart> and <MetricCard> take className.They take class.Trend Chart, Bar Chart, Donut Chart, Metric Card
useGeoJsonSource(map, sourceId, data, style) takes plain values.useGeoJsonSource(sourceId, data, style) takes refs or getters and reads the map from the surrounding <MapCanvas>.None

Theme storage differs too: the Vue <ThemeProvider> always uses localStorage and useTheme() returns Refs. The note under Themes has the details.

Maps

The maps add-on has three entries: @chelone/vue/maps for map display, @chelone/vue/maps/draw for the shape inputs and @chelone/vue/maps/osm for geocoding and OpenStreetMap import. They export the names of the React subpaths. The Vue ui slice lacks some of the components the React inputs build on, so <GeocodingInput> is a native combobox, <SimplifyInput> uses a native range input with two buttons for its quality, and <DrawToolbar> draws inline SVG icons. See Maps for the guide.

Add-ons

The Monaco components are an add-on, imported from @chelone/vue/monaco or installed from the registry as @chelone/monaco. The Markdown components are another, imported from @chelone/vue/mdx-editor or installed as @chelone/mdx-editor. The charts are a third: <TrendChart>, <BarChart> and <DonutChart> come from @chelone/vue/charts and need @unovis/vue and @unovis/ts, where React has @chelone/react/charts and recharts. <MetricCard> is not part of it: it ships in both base packages and draws no chart. The rich text components are a fourth, imported from @chelone/vue/rich-text-input or installed as @chelone/rich-text-input. The block editor is a fifth: <BlockEditorInput>, <BlockDocField> and defineBlock come from @chelone/vue/block-editor and need the @tiptap/* packages, @dnd-kit/vue and @dnd-kit/dom for the block drag handle, and @unovis/vue and @unovis/ts for its chart block. That block draws with the /charts components of its own adapter: <TrendChart>, <BarChart> and <DonutChart> from @chelone/vue/charts here, and the same three from @chelone/react/charts in React, where the block needs recharts instead. <BlockEditor> emits change with the document, and <BlockDocField> takes a string empty with a #empty slot where React takes an empty node. The inspector is a sixth: <Inspector>, <InspectorButton>, <Configurable>, <ConfigurableInputs> and <SortableFieldsSelector> come from @chelone/vue/inspector and need @dnd-kit/vue, where React has @chelone/react/inspector and @dnd-kit/react.

ReactVueReact page
<MonacoJsonInput> and <MonacoJsonField> use @monaco-editor/react, and take className. The input also takes editorClassName.They use @guolao/vue-monaco-editor, and take class. The input also takes editor-class. <MonacoJsonInput> has no id, resource, isRequired, format, parse or alwaysOn prop and emits no events.Monaco Json Input, Monaco Json Field
<MdxInput> and <MdxField> use @mdxeditor/editor and the mdxeditor-dark class. <MdxInput> has a fixed toolbar and takes mdxProps, whose plugins replace the defaults. <MdxField> has no toolbar and takes plugins and the other editor props directly.They wrap Milkdown's Crepe editor, because MDXEditor is React only. The input's toolbar floats over a selection, crepeConfig replaces mdxProps and plugins on both components, and a theme file replaces the dark class. They take class, and <MdxInput> has no id, resource, isRequired, format, parse or alwaysOn prop.Mdx Input, Mdx Field
<RichTextInput> uses @tiptap/react and takes toolbar. <RichTextToolbar> reads the editor context. <RichTextField> accepts a node for empty.The input uses @tiptap/vue-3 and a #toolbar slot receiving { editor }. The toolbar takes an editor prop. The field takes a string for empty or a #empty slot. Both components use class.Rich Text Input, Rich Text Field
<BlockEditorInput> takes className, a node label and a node helperText, and <BlockDocField> takes a node as empty. <BlockEditor> takes onChange.They take class, a label that is a string or false, and a helper-text string. <BlockEditorInput> has no id, resource, isRequired, format, parse or alwaysOn prop. <BlockEditor> emits change with the document, and <BlockDocField> takes a string empty plus a #empty slot. Both entries ship the four default blocks and the three data blocks (dataBlocks), and both move a block with a drag handle; a chart block draws with unovis here and recharts in React.Block Editor Input, Block Doc Field

What this page leaves out

The list is the differences you write differently. Port details with no API effect, such as how a dropdown menu positions itself, are not listed.