@thecb/components
v12.3.12
Published
Common lib for CityBase react components
Maintainers
Keywords
Readme
CityBase Components
This library contains CityBase React components for use across all current and future CB applications (NFE, RMD, POS).
See CONTRIBUTING.md for PR guidelines, dev tasks checklist, integration testing, and deployment/versioning.
Development setup
- Install Node.js with asdf by running
asdf install brew install yarn && yarn
The following statement will inheritly be called with yarn, but you can run it with this command to not try to fetch new dependencies
yarn run build
Component styles
All component molecules and atoms are constructed from the layout primitive atoms (Box, Cover, Stack, etc...). For most atoms and molecules, styling is handled via passing props to the layout atoms. Layout atoms have their own
.styled.jsfiles where props are incorporated into standard styled-components styling.When creating new atoms/molecules, please make sure to use the layout primtiives to construct your component and follow the styling practices of already existing atoms/molecules
All components are also themed via integration with Frontend Configuration Service. Components have a
.theme.jsfile within their directory which specifies what style properties of the component are available to be themed and which provides fallback default values. These default values will be used if no override is specified in thetheme.jsonfile that comes back from FCS, or if thetheme.jsonfile is missing due to a request failure.When creating new components, please follow the theme conventions of existing atoms and molecules. Hardcoding style properties is acceptable if those style properties will not change from client to client. (E.g., the ButtonWithAction atom hardcodes its border radius to a value of "2px", while properties such as background color are themeable values specified in the
.theme.jsfile.Both atoms and molecules can make use of the "variants" ability to specify different types of components. For example, the ButtonWithAction component comes with "primary," "secondary," and "danger" variants, among others. When using a component within an application, the specific variant is specified by passing the string name as the value of the
variantprop.
Storybook
This repo uses React Storybook v8 for interactive component display.
Please include new component stories as this library will also be a sandbox.
yarn storybook- open browser to localhost:9001
Storybook addons
The repo uses all of the standard addons that come with Storybook v8, including the box model visualizer, measuring tool, and themes. The themes are currently static themes derived from FCS output. For the time being, when changes are made to themes in FCS, those changes need to be replicated inside of the .storybook/themes/ directory in order for component stories to pick up on them. Ideally in the future a script will dynamically pull FCS themes from UAT.
Storybook deployment
Storybook is deployed to GitHub Pages via a workflow action. This action will run on pushes to the master branch. When new PRs are merged to master the action should run on the merge commit and update the deployed version of Storybook. The deployed version lives here: GH Pages Storybook. The code for this action lives in .github/workflows/deploy-github-pages.yml.
Adding new components
New components may be added to this library via pull request. Only components that are currently used in, or expected to be used in, more than one CB frontend should be present in this library. Very niche application specific components should be kept in the
components/atomsandcomponents/moleculesdirectory of their parent application.Almost all components in this library, and almost all newly added components, should be as "dumb" as possible. Ideally avoid introducing components that have tight integrations with application state. Forms and form components that make use of redux-freeform are an exception to this rule.
If a non-form component contains integration with application state, or business logic specific to a particular application, breaking the component up into styled/layout atoms and an application specific molecule that consumes them is the best practice. An example of this can be observed with the
HeaderandFootermolecules in Navigate Frontend. Both of these molcules make use of component library atoms such asNavHeaderto layout out content. NFE then hasHeaderandFootermolecules which live in the NFE components directory and use NFE specific business logic to provide content to these atoms, resulting in a completeHeaderandFooter.
Adding Typescript declarations
Any components used in a Typescript app need a declaration file.
- Create a
index.d.tsfile in the directory for that component that exports the typed component constant. Use theExpandinterface found in./src/util/expandso the full props will appear on hover in VSCode. ExtendReact.HTMLAttributes<HTMLElement>>to add all html props and event handlers. e.g.:
import React from "react";
import Expand from "../../../util/expand";
export interface ButtonWithActionProps {
action?: React.SyntheticEvent;
variant?: string;
text?: string;
textWrap?: boolean;
isLoading?: boolean;
textExtraStyles?: string;
contentOverride?: boolean;
extraStyles?: string;
tabIndex?: number;
}
export const ButtonWithAction: React.FC<Expand<ButtonWithActionProps> &
React.HTMLAttributes<HTMLElement>>;- Export the component from the
index.d.tsin the top-level directory for your component, i.e.src/components/atoms/index.d.ts. e.g:
...
export * from "./button-with-action";
...Version bumping and publishing
Versioning and publishing to NPM is fully automated. When a PR is merged to master, the CI pipeline will automatically:
- Build the package
- Determine the version bump type from commit messages
- Bump the version in
package.json - Publish to NPM
- Create a git tag and GitHub Release with auto-generated changelog
Developers do not need to manually bump versions or publish. The version is determined by keywords in your commit messages.
Commit message keywords
Include these keywords anywhere in your commit message to control the version bump:
- No keyword → Patch bump (e.g.,
12.0.4→12.0.5)- Example:
fix button alignment
- Example:
[minor]→ Minor bump (e.g.,12.0.4→12.1.0)- Example:
add new dropdown component [minor]
- Example:
[major]→ Major bump (e.g.,12.0.4→13.0.0)- Example:
redesign form system [major]
- Example:
[skip release]→ No release (no version bump, no publish)- Example:
update README [skip release]
- Example:
Keywords are case-insensitive and can be placed anywhere in the message.
PR labels
Reviewers can also control the version bump by adding labels to the PR:
skiplabel → No release (no version bump, no publish)minorlabel → Minor bumpmajorlabel → Major bump- No label → Patch bump (default)
PR labels and commit keywords both work. The highest priority wins (skip > major > minor > patch).
How it works
The pipeline uses semantic-release with a custom commit analyzer (release-always-patch.js). The configuration is in .releaserc.json.
Semantic versioning
CB Components follows semantic versioning practices, which divides version upgrades into three categories: "Patch" (e.g.,
6.0.1->6.0.2), "Minor" (e.g.,6.0.2->6.1.0), and "Major" (e.g.,6.1.0->7.0.0)Patch — small, non-breaking changes: bug fixes, style tweaks, story updates, new HTML attributes on existing components
Minor — moderate, non-breaking additions: new components, new dependencies, changes to theme files, significant tooling changes, new tests
Major — breaking changes: removing components, breaking API/prop changes, removing dependencies, new peer dependencies. These should be rare and require notifying other frontend engineers at CB who own applications such as Navigate Frontend (NFE), Revenue Management Dashboard (RMD), or Point of Sale Frontend (POS-Frontend), or any future applications which consume CB Components in advance of the change being merged to master
Consuming in your application
Adding to existing application
- Run
yarn add @thecb/components. - To verify it installed successfully, make sure it is in the applicaton's
package.jsonfile.
Testing changes locally
See TESTING.md for a complete guide to testing your changes. In short, you have three options:
- Storybook (
yarn storybook) — fastest, for self-contained component changes - Live Sync (
yarn sync <path-to-project>) — test inside a real running app without publishing - Beta Publish (
yarn publish-beta) — publish to npm for CI/CD, QA, or sharing with teammates
Importing and using components
To use components, you need to import the desired components inside the file you’d like them in. For example, to import the <ButtonWithAction /> component into a file
import { ButtonWithAction } from"``@thecb/components``"``;
You can alias the component by
import { ButtonWithAction as MyButton } from "@thecb/components";
To import multiple components
import { ButtonWithAction, LoginForm, Box, Stack, Cluster } from "@thecb/components";
AI Documentation (ai-docs/)
The ai-docs/ directory contains documentation specifically tailored for AI assistants:
- Architecture Overview (
architecture.md): System design patterns, atomic design principles, theming architecture, and build system information - Component Structure (
components.md): Component hierarchy, layout primitives, form components, and usage patterns - Coding Conventions (
conventions.md): Development standards, naming conventions, and best practices for component development - Figma MCP Integration (
figma-mcp.md): Guidelines for using Figma MCP tools to generate components from designs - Integration Guidelines (
integration-guidelines.md): Step-by-step process for implementing @thecb/components in applications, including required examination of source code, TypeScript definitions, and usage patterns
Publishing Storybook to GitHub Pages
This is a test to see if the GH Actions publishing workflow is functional.
