Roadmap โ
The component list is taken from Element Plus as a checklist of what an admin panel needs. Every component is implemented in-house; the library in brackets is what the behaviour leans on.
Legend: โ done ยท ๐ง in progress ยท โฌ planned
Wave 1 โ basics โ
Complete: every component below has a demo, tests and a page it is documented on โ the four typographic ones share Typography, since a page each would be four pages of the same paragraph.
| Component | Status |
|---|---|
| Button | โ |
| ButtonGroup | โ |
| Icon | โ |
| Input | โ |
| Textarea | โ |
| InputNumber | โ |
| Select (Reka Combobox) | โ |
| Checkbox, CheckboxGroup | โ |
| Radio, RadioGroup | โ |
| Switch | โ |
| Form, FormItem | โ |
| Card | โ |
| Tag (as Badge) | โ |
| TagsInput | โ |
| Badge (count: Indicator) | โ |
| Alert | โ |
| Divider | โ |
| Layout (Container, Header, Aside, Main, Footer) | โ |
| Grid (Row, Col) | โ |
| Space | โ |
| Tabs (Reka) | โ |
| Menu / Sidebar | โ |
| Breadcrumb | โ |
| Link | โ |
| Text, Heading, Prose | โ |
| Scrollbar | โ |
Wave 2 โ data and overlays โ
Complete. Two notes on where this list stopped matching the one it was copied from:
- Message and Notification are one component. The difference between them is a title and a corner, so both are Toast โ one queue, one
WxToaster, aplacement. - Upload is ours, rather than a wrapper around Uppy or FilePond. Those bring their own UI and their own theme, which is the one thing this library does not do; and since a component here never calls an API, there was no request logic to inherit either.
| Component | Status |
|---|---|
Table (Laravel Paginated) | โ |
| Pagination | โ |
| Dialog (Reka) | โ |
| Drawer (Reka) | โ |
| Dropdown (Reka) | โ |
| Tooltip | โ |
| Popover (Reka) | โ |
| Popconfirm | โ |
| Message (one line, Toast) | โ |
| Notification / Toast (Reka) | โ |
| Loading | โ |
| Skeleton | โ |
| Empty | โ |
| Result | โ |
| Progress | โ |
| Descriptions | โ |
| Avatar | โ |
| Image | โ |
| Upload (ours) | โ |
DatePicker, TimePicker, DateTimePicker (@vuepic/vue-datepicker) | โ |
| DateRangePicker | โ |
| Steps | โ |
| Collapse (as Accordion) | โ |
| Segmented | โ |
| Statistic, Countdown | โ |
| Backtop | โ |
| Affix | โ |
Wave 3 โ as needed โ
ColorPicker โ , Slider โ , Rate โ , Autocomplete โ , Cascader โ , Timeline โ and Transfer โ are done.
Tree โ
โ ours rather than he-tree-vue, because a drop is three zones on a row and a <mark> in a label, and neither survives being themed through somebody else's CSS. It brings the part most trees skip: Alt and the arrow keys move a node the same four ways a drag does, which is also the only way to rearrange one on a touch screen.
Table in tree mode โ
โ the same nesting inside WxTable: indentation and a disclosure in the first column, the rest of the row still columns. Not a second component โ both run on useTreeNodes, so a drop means the same thing in each. It is the screen a pages or categories module wants: the tree and the data in one pane, instead of a sidebar tree beside a list of the same records.
It is lazy by design โ data is the roots, load(row) is one level โ and it gives up the two things a table does to a flat list, because both destroy a structure: sorting and pagination. Holding a dragged row over a closed branch opens it, fetching it if need be, so a move across the tree is one drag. What it does not have is a keyboard equivalent for the drag, the way Tree does; for that, and for a move across a long distance, a row wants a Move action and a picker.
TreeSelect โ
โ the same tree as a form field, single or with checkboxes. It is the "parent category" field, so it reads a key and reports a key: parent_id is what the form sends, and the node comes along with the event for whatever the screen needs to show.
Still open: Carousel, Anchor, Splitter, Watermark, Marquee.
Some day, maybe โ wanted, but nothing is waiting on them:
- Mention โ the
@namepicker inside a text field.
Dropped, so that the list stays a list of things somebody is going to write:
- Calendar โ a month of boxes to pick a date out of is what DatePicker already does, and does with a keyboard. What a calendar would add is a month of events, which is a scheduler and a different component with a different name.
- Tour โ the step-by-step walk over a screen. An admin panel earns its explanations in the screen itself; when one truly needs a tour, that is a sign to go back to the screen.
CMS-specific (not in Element Plus) โ
RichText (Tiptap) โ
โ see RichText. It edits one language at a time under localized, its toolbar takes its words as props, and a picture it takes from a library carries that library's key into the document rather than an address that will not survive the next deployment. On a screen it is wx-rich-text, from module-admin โ see Screens. CodeEditor (CodeMirror 6) โ
โ the same field for code: JSON with a linter, HTML, CSS, PHP, YAML and the rest, see CodeEditor. The screens mechanism needs its patches written somewhere better than a textarea. IconPicker โ
โ the icon set, picked from rather than typed into, see IconPicker. A name the set does not have draws nothing and says nothing, so anywhere an editor names an icon โ a block type, a menu entry โ the name has to come out of the set rather than out of a keyboard. EntityCard โ
โ one record as a row, see EntityCard. Actions โ
โ the icon buttons at the end of a row, see Actions. ActionBar โ
โ the same screen's buttons along the bottom of it, see Layout. A panel's screens scroll natively, so the head goes with the scroll and takes the save button with it; the bar is where the button waits. Kanban โ
โ a board of columns cards are dragged between, see Kanban. ListDetail โ
โ filters, records, the open one, and the rule for when there is room for all three: see ListDetail. An inbox and an orders screen are the same furniture.
SelectionArea โ โ the rubber band over a grid or a list, see SelectionArea. A media library is unusable without it.
FileCard โ
โ one file in that library: a preview or a glyph, the name, and the few things that can be done to it, see FileCard. It does none of them โ renaming reports a name, deleting reports a wish โ so the same card sits in a library, in a picker and in a form field. The icon set gained a file-<extension> family to go with it, and an extension nobody has drawn gets the plain page with its own name written underneath.
ImageEditor โ
โ what the card's edit action asks for: a crop with the eight grips everybody knows, aspect ratios, quarter turns, mirrorings, an output size, and a blob at the end of it. See ImageEditor. It is deliberately not folded into the card, which is a tile and should stay one โ the card asks, openImageEditor() answers.
It uploads nothing, the way nothing here does: the answer is a blob, its measurements and the crop it was cut from, so the same editor crops an avatar before a form is submitted and re-cuts a file that is already in a library. Everything on screen is geometry, and the picture is drawn exactly once โ at the end, under one transform โ because a chain of canvases softens a photograph at every link.
SortableList โ โ a list whose order is the point, dragged by a grip or moved with the arrow keys: see SortableList.
Repeater โ
โ the same list once every row is a form: a set of fields, repeated, in an order that is part of the answer. See Repeater. It is SortableList underneath, with the two things a form needs on top โ rows that fold to a name taken from their own fields, and a key of its own per row, so writing a field, removing the row above or dragging one elsewhere never rebuilds the form under the caret. In a described screen it is wx-repeater, the one type whose model is nested.
Gantt โฌ โ the other way to look at the same work: a task per row, a bar across a timeline. Decided, not started. It will be ours rather than a wrapper around frappe-gantt or vis-timeline, because a Gantt is a header of dates and bars placed along it โ a CSS grid, in other words โ and a wrapper would mean styling somebody else's SVG through their theme instead of our tokens, which is the one thing this library does not do. The first pass reads: a sticky column of task names, a scale of days, weeks or months, bars with progress, a marker on today, and hovering or clicking a bar reported as an event. Dragging the dates and the arrows between dependent tasks come after that, once the first pass has been lived with.
MediaLibrary / Gallery โ
โ the library itself, and the fields that reach into it: wx-media for one picture, wx-gallery for a grid of them in an order somebody dragged them into, wx-file and wx-files for documents. See Media fields. Markdown, LinkPicker and BlockPicker are still open.
Not components โ
Two things here are reached from code rather than from a template, and are easy to miss in a list of components:
- Toast โ
toast.success('Saved')from anywhere, including an HTTP interceptor or a store, with oneWxToasteron the page to show them. - Dialogs from code โ
confirm(), andopenModal/createModalfor mounting any component and awaiting its answer. A picker reached asawait productBrowser().
Beyond components โ
@webx-ui/adapter-laravelโ paginator, 422 validation errors, sort/filter query parameters.- CMS building blocks on top of
core: the panel's sections, each a pair of packages โ the file manager, administrators, settings, SEO, the block constructor and, newest, pages โ the first entity that puts the tree, the address registry, the blocks, the drafts and the SEO card together on something real. Each of them is also a set of MCP tools, so an agent reaches the panel through the same doors an editor does. - An in-admin component editor: fields defined as JSON plus a Blade template and CSS, generated into files by Laravel.