https://github.com/wheels-dev/wheels-basecoat
Basecoat UI component helpers for Wheels. shadcn/ui-quality design using plain HTML + Tailwind CSS. No React required.
https://github.com/wheels-dev/wheels-basecoat
Last synced: about 1 month ago
JSON representation
Basecoat UI component helpers for Wheels. shadcn/ui-quality design using plain HTML + Tailwind CSS. No React required.
- Host: GitHub
- URL: https://github.com/wheels-dev/wheels-basecoat
- Owner: wheels-dev
- License: apache-2.0
- Created: 2026-04-23T19:53:09.000Z (about 1 month ago)
- Default Branch: main
- Last Pushed: 2026-04-24T16:37:24.000Z (about 1 month ago)
- Last Synced: 2026-04-24T18:25:28.796Z (about 1 month ago)
- Language: ColdFusion
- Homepage: https://wheels.dev/packages/wheels-basecoat
- Size: 42 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# wheels-basecoat
A Wheels package that ships CFML view helpers for [Basecoat UI](https://basecoatui.com) — shadcn/ui-quality components rendered as plain HTML + Tailwind CSS classes. No React, no build step. Works with or without [wheels-hotwire](../hotwire/README.md).
## Requirements
- Wheels 3.0+
- Lucee 5+ or Adobe ColdFusion 2018+
- Basecoat CSS (served from your app — see **Serving Basecoat CSS** below)
## Installation
```bash
# Activate the package
cp -r packages/basecoat vendor/basecoat
# Restart or reload your app
wheels reload
```
All `ui*` helpers become available in views and controllers via the package mixin system.
## Configuration
Basecoat has no `set()`-style application settings. Configuration is passed to helpers directly — the only helper with knobs is `basecoatIncludes()`:
```cfml
#basecoatIncludes(
alpine = true,
alpineVersion = "3",
basecoatCSSPath = "/plugins/basecoat/assets/basecoat/basecoat.min.css",
turboAware = true
)#
```
| Argument | Default | Description |
|---|---|---|
| `alpine` | `true` | Include the Alpine.js CDN script (needed for dropdowns, dialogs with transitions, tabs). |
| `alpineVersion` | `"3"` | Alpine.js major version. |
| `basecoatCSSPath` | `"/plugins/basecoat/assets/basecoat/basecoat.min.css"` | Path to the Basecoat CSS file your app serves. |
| `turboAware` | `true` | Emit the `` tag — safe default when paired with wheels-hotwire. |
### Serving Basecoat CSS
This package ships helpers, not CSS assets. Grab `basecoat.min.css` from the [Basecoat UI releases](https://basecoatui.com) and serve it from your app — for example under `public/assets/basecoat.min.css` — then point `basecoatCSSPath` at it.
## Usage
### 1. Include CSS + JS in your layout
```cfm
My App
#basecoatIncludes(basecoatCSSPath="/assets/basecoat.min.css")#
#includeContent()#
```
### 2. Render components in views
```cfm
#uiButton(text="Save", variant="primary")#
#uiButton(text="Cancel", variant="outline", href="/users")#
#uiButton(text="Delete", variant="destructive", turboConfirm="Are you sure?")#
#uiBadge(text="Active", variant="default")#
#uiBadge(text="Archived", variant="secondary")#
#uiAlert(title="Heads up", description="Your trial expires in 3 days.", variant="default")#
#uiCard()#
#uiCardHeader(title="Order ##1234", description="Placed 2 days ago")#
#uiCardContent()#
Order details go here.
#uiCardContentEnd()#
#uiCardFooter()#
#uiButton(text="View", href="/orders/1234")#
#uiCardFooterEnd()#
#uiCardEnd()#
#uiField(label="Email", name="user[email]", type="email", required=true)#
#uiField(label="Bio", name="user[bio]", type="textarea", rows=4)#
#uiField(label="Role", name="user[role]", type="select", options="admin:Admin,user:User")#
```
### 3. Component reference
All helpers live on `Basecoat.cfc` and are injected into the controller scope via the package mixin system; they surface in views because Wheels views execute in the controller's `variables` scope.
| Category | Helpers |
|---|---|
| Includes | `basecoatIncludes` |
| Buttons & icons | `uiButton`, `uiBadge`, `uiIcon`, `uiSpinner`, `uiSkeleton`, `uiProgress`, `uiSeparator` |
| Tooltip | `uiTooltip` / `uiTooltipEnd` |
| Alert | `uiAlert` |
| Card | `uiCard` / `uiCardHeader` / `uiCardContent` / `uiCardContentEnd` / `uiCardFooter` / `uiCardFooterEnd` / `uiCardEnd` |
| Dialog | `uiDialog` / `uiDialogFooter` / `uiDialogEnd` |
| Forms | `uiField` (text, email, textarea, select, checkbox, switch, …) |
| Table | `uiTable` / `uiTableHeader` / `uiTableBody` / `uiTableRow` / `uiTableHead` / `uiTableCell` + matching `*End` helpers |
| Tabs | `uiTabs` / `uiTabList` / `uiTabTrigger` / `uiTabContent` + matching `*End` helpers |
| Dropdown | `uiDropdown` / `uiDropdownItem` / `uiDropdownSeparator` / `uiDropdownEnd` |
| Pagination | `uiPagination` |
| Layout | `uiBreadcrumb` / `uiBreadcrumbItem` / `uiBreadcrumbSeparator` / `uiBreadcrumbEnd`, `uiSidebar` / `uiSidebarSection` / `uiSidebarItem` + matching `*End` helpers |
### Turbo-awareness
Basecoat does not depend on wheels-hotwire, but its helpers are Turbo-friendly:
- `uiButton()` accepts `turboConfirm` and `turboMethod` — emitted as `data-turbo-confirm` / `data-turbo-method` attributes and ignored when Turbo is absent.
- `uiButton(close=true)` closes the enclosing `` via the native `HTMLDialogElement.close()` API — no JS library required.
- All block components generate markup that renders correctly inside `` elements.
## Deactivating
```bash
rm -rf vendor/basecoat
wheels reload
```
## Reference
- `packages/basecoat/CLAUDE.md` — markup reference, naming conventions, component categories
- `packages/basecoat/.ai/ARCHITECTURE.md` — design principles, phased component inventory
- [Basecoat UI](https://basecoatui.com) — upstream CSS component library
## License
MIT