shadcn.io is not affiliated with official shadcn/ui
Marketing Campaign Kanban Block for Svelte
A four-column campaign planner of nine campaigns, each with a channel chip and a budget kept in whole cents that every column head adds up, where a wrapped campaign stays closed.
Installation
Overview
Plan campaigns and their budgets from one screen with this board for Svelte with Ark UI. A hairline frame with a plus mark on each corner holds four columns that share their lines (Planned, Live, Paused and Wrapped) and nine campaigns. Each card has a channel chip, a glyph and a word in an outline Badge for Email, Search, Social or Events, its dates, and its budget. Budgets are kept as whole cents, so every sum is exact: each column head adds up its campaigns, and the sentence under the heading gives the total and what is live, formatted from the cents at the edge. Two rules guard the board: a campaign can't be wrapped without having run, and a wrapped campaign is closed and can't be reopened; each refusal says so. A card moves by dragging its grip, from the keyboard, or from its Dropdown Menu under "Move to"; a polite status line in the foot reports each change and Reset puts the board back. The frame is ruled by Guides. For marketing plans, budget reviews and any board that totals money by stage.
FAQ
Why are budgets whole cents?
Adding decimal dollars drifts (0.1 plus 0.2 is not 0.3), so each budget is an integer number of cents, totalIn adds integers, and only moneyOf turns cents into "$12,450.50" for display. Each price is one left-to-right span, so it reads the same in right-to-left languages. If your API sends decimals, convert them to cents once, when you load them.
What are the two rules, and how do I change them?
The function refusalOf refuses a move out of Wrapped (a wrapped campaign is closed) and a move from Planned straight to Wrapped (it never ran). The drop, the keyboard steps and the menu all ask it, and the status line gives the reason. Edit it to suit your own process, for example to let a paused campaign be wrapped only with a note.
How do I move a card without a mouse?
Tab to the grip at the start of a card, named "Move" with the card's title. Press Space or Enter to pick it up, then ArrowUp and ArrowDown to change its place, ArrowLeft and ArrowRight to go to the neighbouring column (the arrows swap in right-to-left languages), Home and End for the first and last place, Space or Enter to drop it and Escape to put it back. Every step is announced in the status line, with the column and the position.
Why is there a menu as well as the grip?
Dragging needs a held pointer and a path, which not everyone has, so each card also has a "More actions" menu with a "Move to" choice for every column and the current one ticked. Choosing one moves the card, puts focus on the card in its new place and says so in the status line.
What stays in the demo, and how do I save the moves?
Everything: the moves live in the component's state, nothing is sent anywhere, and a reload or Reset brings back the starting board. To save for real, call your API from put, the one function every finished move goes through, and keep the budgets in cents on the server too. The names and figures are made up.
How does it work on a phone?
The board is a sideways scroll region with the next column showing, and each column scrolls up and down inside the board's fixed height, so the page never jumps. Touch drags from the grip only, so the rest of a card still scrolls the board; the menu is the other way to move a card. The status line is still read out to screen readers.