feat: v3.0.0 — the killer-feature release#13
Merged
Conversation
Comprehensive AI-coding-assistant docs bundle plus a mountable live
showcase. Goal: an AI assistant working in any Wheels-basecoat app
can find the right helper, write idiomatic code, and avoid the known
footguns without trial-and-error.
* CLAUDE.md rewritten as the master index. Read-order, package
architecture, full helper category overview, the 14 coding rules
every generated CFML must follow.
* .ai/HELPERS.md — formal signature reference for every public
helper, alphabetical-ish by category. Quick lookup for IDE/AI
parameter completion.
* .ai/EXAMPLES.md — scenario-driven recipes. "I want to build a
comment thread", "I want to build a settings page", etc. Each
scenario shows the full helper composition.
* .ai/SCAFFOLDS.md — copy-paste page templates for index / show /
new / edit / login / signup / dashboard / wizard / show + comment
thread.
* .ai/PATTERNS.md — when-to-use decision trees. "Single text input?
→ uiBoundField. Single boolean? → uiBoundCheckbox." etc.
* .ai/PITFALLS.md — 14 known footguns this session has surfaced,
each with symptom, cause, and fix. Includes:
- CFML's null-coalescing operator is ?: not ??
- Hash-escape unbalance inside <cfoutput>
- _form.cfm chrome-in-partial vs chrome-in-page
- Links inside turbo-frame need data-turbo-frame="_top"
- buttonTo kwargs land on the form, use inputClass=
- turboStreamHeader() is mandatory for stream responses
- super.config() needed for protectsFromForgery() inheritance
- Wheels DI services drop after idle
- Lucee cgi.http_accept may be empty
- The [email protected] CDN URL gets mangled
- Private package methods don't reach controller scope
- posts.comments.recordCount with include= doesn't work
- <input type="date"> value format mismatch
- Lucee stores datetimes wrapped in literal quotes
* .ai/ARCHITECTURE.md updated — design rationale, file layout,
conventions, naming, the PackageLoader mixin gotcha, CSP safety,
Hotwire integration patterns, version history.
* examples/showcase/ — drop-in controller + view + route snippet that
mounts a live `/basecoat-showcase` URL in the host app. Renders
every helper with real demo data (a fake post object, a fake errored
post object). Solves the "package's index.cfm runs in admin scope
where helpers aren't mixed in" limitation by running in the host
app's controller scope.
* INSTALL.md — three-step install guide referenced from box.json's
instructionsFile field. Covers asset publishing, layout wiring,
optional showcase mount, updating, and troubleshooting.
* box.json — repository URL fixed to point at wheels-dev/wheels-basecoat
(was pointing at the old monorepo URL); version aligned with the
package.json bump; expanded keywords (hotwire, turbo, dark-mode);
instructionsFile pointer added.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…resource conventions The remaining helper coverage. Three stages bundled into one commit to keep the diff scannable. Stage 2 — layout/display helpers: * uiCallout(title, body, variant) — boxed inline note. Variants: info, tip, warning, success. Lighter than uiAlert (page-level). * uiEmptyState(title, description, icon, actionText, actionHref) — centered placeholder for zero-data scenarios with optional CTA. * uiAccordion family — CSS-only via <details>/<summary>. Animated chevron, hover state. * uiTimeline family — vertical timeline with marker icons + line. * uiCodeBlock(content, language, filename, showCopy, escape) — styled code display with optional title bar + copy-to-clipboard button. Auto-escapes; escape=false for pre-highlighted markup. * uiTagInput + uiBoundTagInput — multi-value chip entry with optional <datalist> autocomplete. Enter/comma adds, Backspace removes, pill × removes individual. Hidden input(s) kept in sync by JS. Stage 3 — file upload + date picker: * uiFileUpload + uiBoundFile — drag-and-drop zone + native input. Files dropped onto the label are assigned to the underlying input. File list mirrors selection. * uiDatePicker — basecoat-styled <input type="date"> with auto- coercion of Lucee-quoted datetime values to ISO yyyy-mm-dd so edit forms pre-populate cleanly. Stage 4 — Wheels resource conventions: * uiPaginationFor(query, baseUrl) — pagination UI from a Wheels paginated query (`currentpage` + `totalpages`). Returns "" when total <= 1. * uiResourceTable(query, columns, editRoute, deleteRoute, showRoute, keyColumn) — auto-builds a basecoat table from a Wheels query. Picks columns, formats cells (booleans → ✓/—, dates → "Mmm D, YYYY"), renders Edit/Delete row actions with Turbo confirms. * uiResourceForm(model, submitRoute, submitMethod, excludeFields) — auto-builds a Wheels-bound form from a model's properties(). Reads enum() declarations, validatesPresenceOf, type metadata to pick input types per property. * Helper utilities: $formatCell, $inferInputType, $optionsFromEnum (public for PackageLoader reachability — see PITFALLS #11). Extras CSS extended: * .ui-callout (4 variants), .ui-empty-state, .ui-accordion + chev rotation, .ui-timeline, .ui-code-block, .ui-tag-input + pills, .ui-file-upload + drag-and-drop styling. UI shim JS extended: * data-ui-tag-remove (pill removal + hidden-input sync). * data-ui-code-copy (clipboard write + visual confirmation). * data-ui-file-upload dragover/dragleave/drop (assigns dropped files to the input + dispatches change). * File `change` handler (mirrors file list inside upload zone). * Tag input keyboard handlers (Enter/comma to add, Backspace to remove from empty entry). Four new icons: copy, upload, calendar, star (star carried from v2.4). tests/BasecoatV30Spec.cfc — snapshot-style coverage for callout variants + arg validation, empty state with/without CTA, accordion open/closed, timeline structure, code block escape modes, tag input pill rendering + JSON/CSV/array value resolution + CSV-vs- plural-hidden output, file upload drag-and-drop attributes + multi naming, date picker Lucee-datetime coercion, paginationFor empty- short-circuit, resource table columns + actions + cell formatting. Version bumped to 3.0.0-rc.1. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drop the -rc.1 suffix in package.json, box.json, and the CHANGELOG heading. Ready for merge + tag. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Replaces #12 (closed; merge conflict from #11's squash-merge). Cherry-picked just the three v3.0 commits onto current main:
CLAUDE.md+.ai/docs + showcase + INSTALL.mdFor the full release notes, see
CHANGELOG.md[3.0.0].🤖 Generated with Claude Code