Skip to content

Storybook gallery for Core UI, published on FN infrastructure - #315

Open
caseylocker wants to merge 3 commits into
mainfrom
feature/storybook-config-core-stories
Open

Storybook gallery for Core UI, published on FN infrastructure#315
caseylocker wants to merge 3 commits into
mainfrom
feature/storybook-config-core-stories

Conversation

@caseylocker

@caseylocker caseylocker commented Aug 14, 2026

Copy link
Copy Markdown

ref: https://app.clickup.com/t/86bbdtyjc

Why these changes

The Core UI library has no browsable documentation. Anyone building an FN application has to read the source to find out which components exist, what they look like, and how they behave. This adds a Storybook gallery so there is one URL where every component is rendered with its variants.

It has to live somewhere permanent and rebuild itself. The preview to date has run on a personal Cloudflare account with its config in a temp directory, which cannot be the arrangement for a team asset, and a gallery that does not rebuild becomes a stale snapshot of whatever main looked like on the day it was built.

No src/ files are touched. Nothing here changes the library itself or what consuming apps install.

What this adds

  • Storybook 10 configuration (.storybook/) with autodocs and the redux decorators
  • 110 stories: 35 for the non-MUI Core UI components under stories/core/, 75 for the MUI set, plus the shared stories/_helpers.jsx and stories/_form-item-fixture.js
  • wrangler.jsonc, an assets only Cloudflare Worker named ftn-core-ui-storybook

The propTypes half of #314 is a separate PR, #316. That one is what fills in the props tables the autodocs pages render.

Why a separate Worker

The docs site pipeline is mkdocs build running in Cloudflare Workers Builds. It has no Node and no Core UI checkout, so it cannot build a Storybook bundle. The alternative considered was committing built output into guides/, which would make the gallery a snapshot that goes stale rather than a live view of main.

A second Worker keeps the rebuild automatic and leaves the docs site pipeline untouched.

Packaging

package.json has no files field and .npmignore is a short denylist, so left alone this change would publish 112 story files, .storybook/, wrangler.jsonc and any dist/ output into the tarball that every consuming app installs. .npmignore now excludes all four, and .gitignore gains dist.

Verified with npm pack --dry-run --json: no story file, config file or build output appears in the tarball.

Deployment shape

The bundle builds into dist/core-ui/ so the directory structure mirrors the URL path. Cloudflare Workers static assets match on pathname, so a flat storybook-static/ would 404 under /core-ui/. The build-storybook script is pointed at the same path, so the script and the Worker config cannot drift apart.

Once merged, the gallery is served at https://docs.foxtrotnov.app/core-ui/ and rebuilt by Cloudflare Workers Builds on every merge to main.

Verification

  • yarn build-storybook exits 0, and the built story index contains 304 entries
  • yarn test passes 113/113 suites and 916/916 tests, unchanged from main
  • Asset references in the built index.html are all relative, with zero root absolute references
  • Stories were scanned for real email addresses, internal hostnames and credentials before this goes to a public URL: clean, all fixture addresses are example.com

Known limitation

Storybook's preview navigator mode (?navigator=true) calls fetch("/index.json") with a root absolute path, which does not resolve under a subpath. Normal gallery browsing is unaffected, since the manager loads its index relatively. If that mode is wanted later, the options are to serve a copy of index.json at the docs site root or to move the gallery to a subdomain.

caseylocker and others added 3 commits August 14, 2026 09:22
…nfig

Splits the config and non-MUI stories out of the original combined branch so
each PR clears CodeRabbit's 100-file review limit.

Co-Authored-By: Claude <noreply@anthropic.com>
The bare `storybook build` script wrote to storybook-static/, while
wrangler.jsonc serves ./dist. Aligning the script means the deploy config and
the build command share one source of truth, so a bare `yarn build-storybook`
in CI can no longer publish an empty assets directory.

Co-Authored-By: Claude <noreply@anthropic.com>
Completes the Storybook coverage for the component library, pairing the MUI
components with the Core UI stories already on this branch.

Co-Authored-By: Claude <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 14, 2026

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 119 files, which is 19 over the limit of 100.

To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch.

Upgrade to a paid plan to raise the limit.

This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 6096b90e-f12d-46b6-a04a-032447c8c9b1

📥 Commits

Reviewing files that changed from the base of the PR and between 848fc18 and 344c1a6.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (119)
  • .gitignore
  • .npmignore
  • .storybook/main.js
  • .storybook/preview-head.html
  • .storybook/preview.jsx
  • package.json
  • stories/AddonTypeSelect.stories.jsx
  • stories/AlertButton.stories.jsx
  • stories/AlertModal.stories.jsx
  • stories/AuthButton.stories.jsx
  • stories/BulkEditTable.stories.jsx
  • stories/CartButton.stories.jsx
  • stories/CheckboxList.stories.jsx
  • stories/ChipList.stories.jsx
  • stories/ChipNotify.stories.jsx
  • stories/ChipSelectInput.stories.jsx
  • stories/ConfirmDeleteDialog.stories.jsx
  • stories/ConfirmDialog.stories.jsx
  • stories/CustomAlert.stories.jsx
  • stories/CustomTablePagination.stories.jsx
  • stories/DndList.stories.jsx
  • stories/DownloadBtn.stories.jsx
  • stories/DragNDropList.stories.jsx
  • stories/Dropdown.stories.jsx
  • stories/DropdownCheckbox.stories.jsx
  • stories/EditableTable.stories.jsx
  • stories/ExtraRows.stories.jsx
  • stories/FormItemTable.stories.jsx
  • stories/FormikAdditionalInput.stories.jsx
  • stories/FormikAdditionalInputList.stories.jsx
  • stories/FormikAddonTypeSelect.stories.jsx
  • stories/FormikAsyncSelect.stories.jsx
  • stories/FormikCheckbox.stories.jsx
  • stories/FormikCheckboxGroup.stories.jsx
  • stories/FormikCompanyInput.stories.jsx
  • stories/FormikDatepicker.stories.jsx
  • stories/FormikDiscountField.stories.jsx
  • stories/FormikDropdownCheckbox.stories.jsx
  • stories/FormikDropdownRadio.stories.jsx
  • stories/FormikFileSizeField.stories.jsx
  • stories/FormikItemPriceTiers.stories.jsx
  • stories/FormikPriceField.stories.jsx
  • stories/FormikQuantityField.stories.jsx
  • stories/FormikRadioGroup.stories.jsx
  • stories/FormikSelect.stories.jsx
  • stories/FormikSelectGroup.stories.jsx
  • stories/FormikSelectV2.stories.jsx
  • stories/FormikSponsorInput.stories.jsx
  • stories/FormikSponsorshipInput.stories.jsx
  • stories/FormikSponsorshipSummitSelect.stories.jsx
  • stories/FormikSwitch.stories.jsx
  • stories/FormikTextEditor.stories.jsx
  • stories/FormikTextField.stories.jsx
  • stories/FormikTimepicker.stories.jsx
  • stories/FormikUpload.stories.jsx
  • stories/GridFilter.stories.jsx
  • stories/InfiniteTable.stories.jsx
  • stories/InfoNote.stories.jsx
  • stories/InlineCard.stories.jsx
  • stories/ItemSettingsModal.stories.jsx
  • stories/ListCard.stories.jsx
  • stories/LoadingOverlay.stories.jsx
  • stories/MenuButton.stories.jsx
  • stories/NavBar.stories.jsx
  • stories/NotesModal.stories.jsx
  • stories/OrderSummary.stories.jsx
  • stories/RoundButton.stories.jsx
  • stories/SearchInput.stories.jsx
  • stories/ShowConfirmDialog.stories.jsx
  • stories/SnackbarNotification.stories.jsx
  • stories/SortableTable.stories.jsx
  • stories/SponsorAddonSelect.stories.jsx
  • stories/SponsorOrderGrid.stories.jsx
  • stories/StatusChip.stories.jsx
  • stories/StripePayment.stories.jsx
  • stories/SummitsDropdown.stories.jsx
  • stories/Table.stories.jsx
  • stories/TableCard.stories.jsx
  • stories/ToggleButtons.stories.jsx
  • stories/UploadBtn.stories.jsx
  • stories/UploadDialog.stories.jsx
  • stories/_form-item-fixture.js
  • stories/_helpers.jsx
  • stories/core/ActionDropdown.stories.jsx
  • stories/core/AjaxLoader.stories.jsx
  • stories/core/AsyncEntityInputs.stories.jsx
  • stories/core/BulkActionsSelector.stories.jsx
  • stories/core/CheckboxList.stories.jsx
  • stories/core/CircleButton.stories.jsx
  • stories/core/Clock.stories.jsx
  • stories/core/DateTimePicker.stories.jsx
  • stories/core/Dropdown.stories.jsx
  • stories/core/EditableTable.stories.jsx
  • stories/core/Exclusive.stories.jsx
  • stories/core/FreeMultiTextInput.stories.jsx
  • stories/core/FreeTextSearch.stories.jsx
  • stories/core/GroupedDropdown.stories.jsx
  • stories/core/Panel.stories.jsx
  • stories/core/RadioList.stories.jsx
  • stories/core/RawHTML.stories.jsx
  • stories/core/RsvpForm.stories.jsx
  • stories/core/ScheduleBuilderView.stories.jsx
  • stories/core/SelectableTable.stories.jsx
  • stories/core/SimpleForm.stories.jsx
  • stories/core/SimpleLinkList.stories.jsx
  • stories/core/SortableTable.stories.jsx
  • stories/core/SteppedSelect.stories.jsx
  • stories/core/SummitDaysSelect.stories.jsx
  • stories/core/SummitDropdown.stories.jsx
  • stories/core/SummitVenuesSelect.stories.jsx
  • stories/core/Table.stories.jsx
  • stories/core/TextArea.stories.jsx
  • stories/core/TextEditor.stories.jsx
  • stories/core/TextInput.stories.jsx
  • stories/core/UploadInput.stories.jsx
  • stories/core/UploadInputV2.stories.jsx
  • stories/core/UploadInputV3.stories.jsx
  • stories/core/VideoStream.stories.jsx
  • wrangler.jsonc

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a Storybook-based component gallery for the Core UI library (without modifying src/), along with Cloudflare Workers static-assets configuration so the gallery can be published/rebuilt on FN infrastructure.

Changes:

  • Introduces Storybook 10 configuration under .storybook/ (autodocs + Redux/Theme decorators + style pipeline for less/scss).
  • Adds a large set of Storybook stories covering both Core and MUI component sets plus shared story helpers/fixtures.
  • Adds a Cloudflare Wrangler config for an assets-only Worker and updates packaging ignores to keep stories/config/build output out of the published npm tarball.

Reviewed changes

Copilot reviewed 118 out of 120 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
wrangler.jsonc Assets-only Cloudflare Worker config to serve the built Storybook bundle from ./dist.
package.json Adds Storybook scripts and Storybook-related devDependencies.
.storybook/main.js Storybook framework/addons plus webpack rules for less/scss (modules + globals).
.storybook/preview.jsx Global Storybook decorators (Redux store + MUI theme) and autodocs tag.
.storybook/preview-head.html Injects bootstrap CSS into the preview iframe for legacy component styling.
.npmignore Excludes stories, Storybook config, Wrangler config, and dist/ from npm package output.
.gitignore Ignores Storybook build outputs (storybook-static, dist).
stories/_helpers.jsx Shared decorators/fixtures for stories (Formik host, table host, sample rows/cols, NEEDS_API note).
stories/_form-item-fixture.js Shared fixture data for FormItemTable stories (lifted from tests).
stories/UploadDialog.stories.jsx Story coverage for MUI UploadDialog.
stories/UploadBtn.stories.jsx Story coverage for MUI UploadBtn.
stories/ToggleButtons.stories.jsx Story coverage for MUI ToggleButtons.
stories/TableCard.stories.jsx Story coverage for MUI TableCard.
stories/Table.stories.jsx Story coverage for MUI Table (default/paginated/sorted/empty).
stories/SummitsDropdown.stories.jsx Story coverage for MUI SummitsDropdown (fetch-path vs provided-data).
stories/StripePayment.stories.jsx Story coverage for MUI StripePayment with credential guidance.
stories/StatusChip.stories.jsx Story coverage for MUI StatusChip variants.
stories/SponsorOrderGrid.stories.jsx Story coverage for MUI SponsorOrderGrid.
stories/SponsorAddonSelect.stories.jsx Story coverage for MUI SponsorAddonSelect (API-backed).
stories/SortableTable.stories.jsx Story coverage for MUI SortableTable (drag-to-reorder).
stories/SnackbarNotification.stories.jsx Story coverage for MUI SnackbarNotification via hook and redux-state trigger paths.
stories/ShowConfirmDialog.stories.jsx Story coverage for MUI showConfirmDialog + GlobalConfirmDialog.
stories/SearchInput.stories.jsx Story coverage for MUI SearchInput (default/with-term/debounced).
stories/RoundButton.stories.jsx Story coverage for MUI RoundButton variants.
stories/OrderSummary.stories.jsx Story coverage for MUI OrderSummary.
stories/NotesModal.stories.jsx Story coverage for MUI NotesModal (Formik decorator).
stories/NavBar.stories.jsx Story coverage for MUI NavBar (logged out/in).
stories/MenuButton.stories.jsx Story coverage for MUI MenuButton (default + badge).
stories/LoadingOverlay.stories.jsx Story coverage for MUI LoadingOverlay (loading vs idle).
stories/ListCard.stories.jsx Story coverage for MUI ListCard.
stories/ItemSettingsModal.stories.jsx Story coverage for MUI ItemSettingsModal.
stories/InlineCard.stories.jsx Story coverage for MUI InlineCard.
stories/InfoNote.stories.jsx Story coverage for MUI InfoNote.
stories/InfiniteTable.stories.jsx Story coverage for MUI InfiniteTable (default/empty).
stories/GridFilter.stories.jsx Story coverage for MUI GridFilter with sample criteria and story isolation notes.
stories/FormItemTable.stories.jsx Story coverage for MUI FormItemTable with a real useFormik host + test-derived fixture.
stories/FormikUpload.stories.jsx Story coverage for MUI Formik Upload input.
stories/FormikTimepicker.stories.jsx Story coverage for MUI Formik Timepicker.
stories/FormikTextField.stories.jsx Story coverage for MUI Formik TextField.
stories/FormikTextEditor.stories.jsx Story coverage for MUI Formik TextEditor.
stories/FormikSwitch.stories.jsx Story coverage for MUI Formik Switch.
stories/FormikSponsorshipSummitSelect.stories.jsx Story coverage for MUI Formik SponsorshipSummitSelect (API-backed).
stories/FormikSponsorshipInput.stories.jsx Story coverage for MUI Formik SponsorshipInput (API-backed).
stories/FormikSponsorInput.stories.jsx Story coverage for MUI Formik SponsorInput (API-backed).
stories/FormikSelectV2.stories.jsx Story coverage for MUI Formik Select v2.
stories/FormikSelectGroup.stories.jsx Story coverage for MUI Formik SelectGroup with stubbed queryFunction.
stories/FormikSelect.stories.jsx Story coverage for MUI Formik Select with MenuItem children.
stories/FormikRadioGroup.stories.jsx Story coverage for MUI Formik RadioGroup.
stories/FormikQuantityField.stories.jsx Story coverage for MUI Formik QuantityField.
stories/FormikPriceField.stories.jsx Story coverage for MUI Formik PriceField.
stories/FormikItemPriceTiers.stories.jsx Story coverage for MUI Formik ItemPriceTiers.
stories/FormikFileSizeField.stories.jsx Story coverage for MUI Formik FileSizeField.
stories/FormikDropdownRadio.stories.jsx Story coverage for MUI Formik DropdownRadio.
stories/FormikDropdownCheckbox.stories.jsx Story coverage for MUI Formik DropdownCheckbox.
stories/FormikDiscountField.stories.jsx Story coverage for MUI Formik DiscountField.
stories/FormikDatepicker.stories.jsx Story coverage for MUI Formik Datepicker.
stories/FormikCompanyInput.stories.jsx Story coverage for MUI Formik CompanyInput (API-backed).
stories/FormikCheckboxGroup.stories.jsx Story coverage for MUI Formik CheckboxGroup.
stories/FormikCheckbox.stories.jsx Story coverage for MUI Formik Checkbox.
stories/FormikAsyncSelect.stories.jsx Story coverage for MUI Formik AsyncSelect with local stubbed queryFunction.
stories/FormikAddonTypeSelect.stories.jsx Story coverage for MUI Formik AddonTypeSelect (API-backed).
stories/FormikAdditionalInputList.stories.jsx Story coverage for MUI Formik AdditionalInputList.
stories/FormikAdditionalInput.stories.jsx Story coverage for MUI Formik AdditionalInput.
stories/ExtraRows.stories.jsx Story coverage for MUI table extra-rows rendered in a table context.
stories/EditableTable.stories.jsx Story coverage for MUI EditableTable.
stories/DropdownCheckbox.stories.jsx Story coverage for MUI DropdownCheckbox.
stories/Dropdown.stories.jsx Story coverage for MUI Dropdown.
stories/DragNDropList.stories.jsx Story coverage for MUI DragNDropList (dnd-kit).
stories/DownloadBtn.stories.jsx Story coverage for MUI DownloadBtn.
stories/DndList.stories.jsx Story coverage for legacy MUI DndList (react-beautiful-dnd).
stories/CustomTablePagination.stories.jsx Story coverage for MUI CustomTablePagination.
stories/CustomAlert.stories.jsx Story coverage for MUI CustomAlert variants.
stories/ConfirmDialog.stories.jsx Story coverage for MUI ConfirmDialog (default/warning).
stories/ConfirmDeleteDialog.stories.jsx Story coverage for MUI ConfirmDeleteDialog.
stories/ChipSelectInput.stories.jsx Story coverage for MUI ChipSelectInput.
stories/ChipNotify.stories.jsx Story coverage for MUI ChipNotify variants.
stories/ChipList.stories.jsx Story coverage for MUI ChipList.
stories/CheckboxList.stories.jsx Story coverage for MUI CheckboxList (default/empty).
stories/CartButton.stories.jsx Story coverage for MUI CartButton variants.
stories/BulkEditTable.stories.jsx Story coverage for MUI BulkEditTable.
stories/AuthButton.stories.jsx Story coverage for MUI AuthButton (logged out/in).
stories/AlertModal.stories.jsx Story coverage for MUI AlertModal.
stories/AlertButton.stories.jsx Story coverage for MUI AlertButton.
stories/AddonTypeSelect.stories.jsx Story coverage for MUI AddonTypeSelect (API-backed).
stories/core/VideoStream.stories.jsx Story coverage for Core VideoStream.
stories/core/UploadInputV3.stories.jsx Story coverage for Core UploadInputV3 (API-backed posting).
stories/core/UploadInputV2.stories.jsx Story coverage for Core UploadInputV2 (API-backed posting).
stories/core/UploadInput.stories.jsx Story coverage for Core UploadInput.
stories/core/TextInput.stories.jsx Story coverage for Core text Input.
stories/core/TextEditor.stories.jsx Story coverage for Core TextEditor.
stories/core/TextArea.stories.jsx Story coverage for Core TextArea.
stories/core/Table.stories.jsx Story coverage for Core Table (default + actions).
stories/core/SummitVenuesSelect.stories.jsx Story coverage for Core SummitVenuesSelect.
stories/core/SummitDropdown.stories.jsx Story coverage for Core SummitDropdown.
stories/core/SummitDaysSelect.stories.jsx Story coverage for Core SummitDaysSelect.
stories/core/SteppedSelect.stories.jsx Story coverage for Core SteppedSelect.
stories/core/SortableTable.stories.jsx Story coverage for Core SortableTable.
stories/core/SimpleLinkList.stories.jsx Story coverage for Core SimpleLinkList with injected search action.
stories/core/SimpleForm.stories.jsx Story coverage for Core SimpleForm (default + error state).
stories/core/SelectableTable.stories.jsx Story coverage for Core SelectableTable (selection/actions).
stories/core/ScheduleBuilderView.stories.jsx Story coverage for Core ScheduleBuilderView with DnD provider decorator and fixture data.
stories/core/RsvpForm.stories.jsx Story coverage for Core RsvpForm.
stories/core/RawHTML.stories.jsx Story coverage for Core RawHTML (default + newline replacement).
stories/core/RadioList.stories.jsx Story coverage for Core RadioList (default + inline).
stories/core/Panel.stories.jsx Story coverage for Core Panel (open/collapsed).
stories/core/GroupedDropdown.stories.jsx Story coverage for Core GroupedDropdown.
stories/core/FreeTextSearch.stories.jsx Story coverage for Core FreeTextSearch.
stories/core/FreeMultiTextInput.stories.jsx Story coverage for Core FreeMultiTextInput.
stories/core/Exclusive.stories.jsx Story coverage for Core Exclusive wrapper (window.EXCLUSIVE_SECTIONS gated).
stories/core/EditableTable.stories.jsx Story coverage for Core EditableTable.
stories/core/Dropdown.stories.jsx Story coverage for Core Dropdown (single + multi).
stories/core/DateTimePicker.stories.jsx Story coverage for Core DateTimePicker (date+time vs date-only).
stories/core/Clock.stories.jsx Story coverage for Core Clock (API-backed note).
stories/core/CircleButton.stories.jsx Story coverage for Core CircleButton (live/future states).
stories/core/CheckboxList.stories.jsx Story coverage for Core CheckboxList (default + allowOther).
stories/core/BulkActionsSelector.stories.jsx Story coverage for Core BulkActionsSelector.
stories/core/AsyncEntityInputs.stories.jsx Story coverage for multiple Core async entity inputs consolidated into one file.
stories/core/AjaxLoader.stories.jsx Story coverage for Core AjaxLoader with constrained positioning decorator.
stories/core/ActionDropdown.stories.jsx Story coverage for Core ActionDropdown.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +1 to +13
import Exclusive from "../../src/components/exclusive-wrapper";

export default {
title: "Core/Display/Exclusive",
component: Exclusive,
// gated by window.EXCLUSIVE_SECTIONS — simulate the host app setting it
decorators: [
(Story) => {
window.EXCLUSIVE_SECTIONS = ["beta-feature"];
return <Story />;
}
]
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants