@thecb/components 2.2.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/.github/workflows/bump-version.yml +30 -0
  2. package/.github/workflows/create-release/build-body.sh +35 -0
  3. package/.github/workflows/create-release.yml +52 -0
  4. package/.github/workflows/publish-update.yml +73 -0
  5. package/README.md +68 -90
  6. package/dist/index.cjs.js +49122 -0
  7. package/package.json +17 -37
  8. package/rollup.config.js +43 -23
  9. package/src/components/atoms/button-with-action/ButtonWithAction.js +25 -4
  10. package/src/components/atoms/button-with-action/ButtonWithAction.theme.js +64 -234
  11. package/src/components/atoms/formatted-credit-card/FormattedCreditCard.js +53 -0
  12. package/src/components/atoms/formatted-credit-card/FormattedCreditCard.theme.js +9 -0
  13. package/src/components/atoms/formatted-credit-card/index.js +3 -0
  14. package/src/components/atoms/icons/AccountNumberImage.js +95 -0
  15. package/src/components/atoms/icons/BankIcon.js +82 -0
  16. package/src/components/atoms/icons/CheckmarkIcon.js +55 -0
  17. package/src/components/atoms/icons/GenericCard.js +39 -0
  18. package/src/components/atoms/icons/PaymentIcon.js +50 -0
  19. package/src/components/atoms/icons/RoutingNumberImage.js +95 -0
  20. package/src/components/atoms/icons/index.js +14 -1
  21. package/src/components/atoms/index.js +3 -0
  22. package/src/components/atoms/jumbo/Jumbo.js +76 -0
  23. package/src/components/atoms/jumbo/index.js +3 -0
  24. package/src/components/atoms/loading/Loading.js +17 -0
  25. package/src/components/atoms/loading/index.js +3 -0
  26. package/src/components/atoms/nav-header/NavHeader.js +1 -1
  27. package/src/components/index.js +1 -0
  28. package/src/components/molecules/account-and-routing-modal/AccountAndRoutingModal.js +75 -0
  29. package/src/components/molecules/account-and-routing-modal/AccountAndRoutingModal.theme.js +24 -0
  30. package/src/components/molecules/account-and-routing-modal/index.js +3 -0
  31. package/src/components/molecules/address-form/AddressForm.js +2 -1
  32. package/src/components/molecules/address-form/index.js +6 -6
  33. package/src/components/molecules/change-password-form/ChangePasswordForm.js +2 -1
  34. package/src/components/molecules/change-password-form/index.js +1 -1
  35. package/src/components/molecules/edit-name-form/EditNameForm.js +2 -1
  36. package/src/components/molecules/edit-name-form/index.js +1 -1
  37. package/src/components/molecules/editable-list/EditableList.js +139 -0
  38. package/src/components/molecules/editable-list/EditableList.styled.js +31 -0
  39. package/src/components/molecules/editable-list/index.js +3 -0
  40. package/src/components/molecules/editable-table/EditableTable.js +30 -0
  41. package/src/components/molecules/editable-table/EditableTable.styled.js +80 -0
  42. package/src/components/molecules/editable-table/TableListItem.js +64 -0
  43. package/src/components/molecules/editable-table/index.js +4 -0
  44. package/src/components/molecules/email-form/EmailForm.js +2 -1
  45. package/src/components/molecules/email-form/index.js +1 -1
  46. package/src/components/molecules/forgot-password-form/ForgotPasswordForm.js +2 -1
  47. package/src/components/molecules/forgot-password-form/index.js +1 -1
  48. package/src/components/molecules/index.js +5 -0
  49. package/src/components/molecules/login-form/LoginForm.js +2 -1
  50. package/src/components/molecules/login-form/index.js +1 -1
  51. package/src/components/molecules/module/Module.js +1 -3
  52. package/src/components/molecules/partial-amount-form/PartialAmountForm.js +73 -0
  53. package/src/components/molecules/partial-amount-form/PartialAmountForm.state.js +51 -0
  54. package/src/components/molecules/partial-amount-form/index.js +4 -0
  55. package/src/components/molecules/payment-form-ach/PaymentFormACH.js +189 -0
  56. package/src/components/molecules/payment-form-ach/PaymentFormACH.state.js +38 -0
  57. package/src/components/molecules/payment-form-ach/index.js +11 -0
  58. package/src/components/molecules/payment-form-card/PaymentFormCard.js +132 -0
  59. package/src/components/molecules/payment-form-card/PaymentFormCard.state.js +39 -0
  60. package/src/components/molecules/payment-form-card/index.js +11 -0
  61. package/src/components/molecules/phone-form/PhoneForm.js +2 -1
  62. package/src/components/molecules/phone-form/index.js +1 -1
  63. package/src/components/molecules/registration-form/RegistrationForm.js +2 -1
  64. package/src/components/molecules/registration-form/index.js +1 -1
  65. package/src/components/molecules/reset-password-form/ResetPasswordForm.js +3 -1
  66. package/src/components/molecules/reset-password-form/index.js +1 -1
  67. package/src/constants/index.js +4 -0
  68. package/src/index.js +3 -1
  69. package/src/util/formats.js +54 -2
  70. package/src/util/general.js +27 -4
  71. package/src/util/index.js +4 -0
  72. package/src/util/inputValidationUtils.js +0 -167
  73. package/.tool-versions +0 -1
  74. package/dist/cb-components.cjs.js +0 -77
  75. package/src/util/router-utils.js +0 -23
@@ -0,0 +1,30 @@
1
+ name: Bump Package Version
2
+ on:
3
+ push:
4
+ branches:
5
+ - "master"
6
+
7
+ jobs:
8
+ bump-version:
9
+ name: Bump version on master
10
+ runs-on: ubuntu-latest
11
+
12
+ steps:
13
+ - name: Checkout source code
14
+ uses: actions/checkout@v2
15
+ with:
16
+ ref: ${{ github.ref }}
17
+ - name: "cat package.json"
18
+ run: cat ./package.json
19
+ - name: Setup Node.js
20
+ uses: actions/setup-node@v1
21
+ with:
22
+ node-version: 12
23
+ - name: Automated version bump
24
+ uses: phips28/gh-action-bump-version@master
25
+ with:
26
+ tag-prefix: ''
27
+ env:
28
+ GITHUB_TOKEN: ${{ secrets.REPO_ACCESS_TOKEN }}
29
+ - name: "cat package.json"
30
+ run: cat ./package.json
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # The output is a Markdown table with columns for the PR (with a link),
4
+ # a branch, and JIRA ticket with link (if available).
5
+ #
6
+ # If the branch name starts with an id for a JIRA ticket (e.g.,
7
+ # PLAT-123), then a link to the ticket is created. Otherwise this
8
+ # column is blank.
9
+ #
10
+ # A link to the branch isn't valuable because they are usually
11
+ # deleted after merging.
12
+
13
+ from_tag=${FROM_TAG}
14
+ to_tag=${TAG##*/}
15
+
16
+ echo "## Changes"
17
+ echo ""
18
+ echo "### PRs"
19
+ # all merge commits, only merge commits
20
+ git --no-pager log --merges --format='%s' ${from_tag}..${to_tag} | \
21
+ # only pull-request merges
22
+ grep "Merge pull request" | \
23
+ gawk 'BEGIN { print "| PR | Branch | Ticket |" ;
24
+ print "| -- | ------ | ------ |" }
25
+ {if (match($0,/(#[0-9]+).*CityBaseInc\/(([A-Z]+-[0-9]+)\S+)/,m))
26
+ printf "| %s | %s | [%s](https://citybase.atlassian.net/browse/%s) |\n", m[1], m[2], m[3], m[3] }
27
+ {if (match($0,/(#[0-9]+).*CityBaseInc\/([a-z]\S+)/,m))
28
+ print "|", m[1], "|", m[2], "|", "|"}'
29
+
30
+ echo ""
31
+ echo "### Code Diff"
32
+ echo "https://github.com/${REPO}/compare/${from_tag}..${to_tag}"
33
+ echo ""
34
+
35
+ git show ${to_tag} --format=short | grep Tagger
@@ -0,0 +1,52 @@
1
+ on:
2
+ push:
3
+ tags:
4
+ - '*'
5
+
6
+
7
+ name: Create Release
8
+
9
+ jobs:
10
+ build:
11
+ name: Create Release
12
+ runs-on: ubuntu-latest
13
+ env:
14
+ REPO: ${{ github.repository }}
15
+ TAG: ${{ github.ref }}
16
+ steps:
17
+ - uses: actions/checkout@v2
18
+ - name: Get latest release
19
+ id: get_latest
20
+ run: |
21
+ tag_name=$(curl --silent --request GET \
22
+ --url https://api.github.com/repos/${{ github.repository }}/releases/latest \
23
+ --header "authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
24
+ --header "content-type: applicatoin/json" | jq -r .tag_name)
25
+ echo "::set-output name=tag_name::$tag_name"
26
+ - name: Fetch branches
27
+ run: git fetch --all --prune --unshallow
28
+ - name: Fetch tags
29
+ run: git fetch --unshallow origin +refs/tags/*:refs/tags/*
30
+ - name: Checkout master
31
+ run: git checkout master
32
+ - name: Build body
33
+ id: build_body
34
+ env:
35
+ FROM_TAG: ${{ steps.get_latest.outpus.tag_name}}
36
+ run: |
37
+ body=$(sh ./.github/workflows/create-release/build-body.sh)
38
+ body="${body//'%'/'%25'}"
39
+ body="${body//$'\n'/'%0A'}"
40
+ body="${body//$'\r'/'%0D'}"
41
+ echo "::set-output name=body::$body"
42
+ - name: Create Release
43
+ id: create_release
44
+ uses: actions/create-release@4d1b6075ce7561b672b8552148edec2f27584fe9
45
+ env:
46
+ GITHUB_TOKEN: ${{ secrets.REPO_ACCESS_TOKEN }}
47
+ with:
48
+ tag_name: ${{ github.ref }}
49
+ release_name: Release ${{ github.ref }}
50
+ body: ${{ steps.build_body.outputs.body }}
51
+ draft: false
52
+ prerelease: false
@@ -0,0 +1,73 @@
1
+ name: Publish and Update
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ build:
9
+ name: Build
10
+ runs-on: ubuntu-latest
11
+
12
+ steps:
13
+ - name: Checkout repository
14
+ uses: actions/checkout@v2
15
+ with:
16
+ ref: master
17
+
18
+ - name: Set up Node.js
19
+ uses: actions/setup-node@v1.2.0
20
+ with:
21
+ node-version: '10.x'
22
+
23
+ - name: Install dependencies
24
+ run: yarn install --silent
25
+
26
+ - name: Compile build
27
+ run: yarn build --silent
28
+
29
+ - name: Commit changes
30
+ uses: EndBug/add-and-commit@v2.1.0
31
+ with:
32
+ author_name: CB Feeps
33
+ author_email: feeps@thecitybase.com
34
+ message: "[auto] Update dist"
35
+ path: dist
36
+ pattern: "*.*"
37
+ force: true
38
+ ref: deploy
39
+ env:
40
+ GITHUB_TOKEN: ${{ secrets.REPO_ACCESS_TOKEN }}
41
+
42
+ publish:
43
+ name: Publish to NPM Registry
44
+ runs-on: ubuntu-latest
45
+ needs: build
46
+
47
+ steps:
48
+ - name: Checkout repository
49
+ uses: actions/checkout@v2
50
+ with:
51
+ ref: deploy
52
+
53
+ - name: Set up Node.js for NPM
54
+ if: steps.check.outputs.changed == 'true'
55
+ uses: actions/setup-node@v1.2.0
56
+ with:
57
+ node-version: '10.x'
58
+ registry-url: 'https://registry.npmjs.org'
59
+ scope: '@thecb'
60
+
61
+ - name: Install dependencies
62
+ if: steps.check.outputs.changed == 'true'
63
+ run: yarn install
64
+
65
+ - name: Create build
66
+ if: steps.check.outputs.changed == 'true'
67
+ run: yarn build
68
+
69
+ - name: Publish package to NPM
70
+ if: steps.check.outputs.changed == 'true'
71
+ run: yarn publish
72
+ env:
73
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
package/README.md CHANGED
@@ -1,29 +1,25 @@
1
- # Citybase JS Components
1
+ # Citybase Components
2
2
 
3
- This should be used for basic components that can be reused across applications with a standardized set of functionality hooks and props and base styles.
3
+ This library contains Citybase React components for use across all current and future CB applications (NFE, RMD, Kiosk, POS).
4
4
 
5
5
  <!-- TOC -->
6
6
 
7
- - [Setup](#setup)
8
- - [Testing](#testing)
9
- - [Base Styles for components](#base-styles-for-components)
7
+ - [Development setup](#development-setup)
8
+ - [Component styles](#component-styles)
10
9
  - [Storybook](#storybook)
11
- - [Storybook QA Environment](#storybook-qa-environment)
12
10
  - [Storybook addons](#storybook-addons)
13
- - [Deploying new changes](#deploying-new-changes)
11
+ - [Adding new components](#adding-new-components)
12
+ - [Version bumping and publishing](#version-bumping-and-publishing)
13
+ - [Version bumping](#version-bumping)
14
+ - [Publishing new versions to NPM](#publishing-new-versions-to-npm)
14
15
  - [Consuming in your application](#consuming-in-your-application)
15
- - [Prod import](#prod-import)
16
- - [Local import](#local-import)
17
- - [Package.json updates](#packagejson-updates)
18
- - [Circle CI needed setup](#circle-ci-needed-setup)
19
- - [Using in your application](#using-in-your-application)
20
- - [Wikitext Component Markdown](#wikitext-component-markdown)
21
- - [Listview Component Table](#listview-component-table)
22
- - [ExternalRedirect link protection library](#externalredirect-link-protection-library)
23
-
16
+ - [Adding to existing application](#adding-to-existing-application)
17
+ - [Local import and development](#local-import-and-development)
18
+ - [Importing and using components](#importing-and-using-components)
19
+
24
20
  <!-- /TOC -->
25
21
 
26
- ## Setup
22
+ ## Development setup
27
23
 
28
24
  - Install Node.js with [asdf](https://citybase.atlassian.net/wiki/spaces/DEV/pages/49777332/First+Time+Environment+Setup) by running `asdf install`
29
25
  - `brew install yarn && yarn`
@@ -32,118 +28,100 @@ The following statement will inheritly be called with `yarn`, but you can run it
32
28
 
33
29
  - `yarn run build`
34
30
 
35
- ## Testing
36
-
37
- - All components are to have specs with coverage to 100%.
38
- - Specs are to be added to the `__tests__` folder with an extension of `.spec.js`
39
-
40
- ## Base Styles for components
31
+ ## Component styles
41
32
 
42
- - If a component needs base styles from the library to be exposed, please add to the root component folder with the extension of `.css`
43
- - This will be the current direction of including styles until [IMP-857](https://citybase.atlassian.net/browse/IMP-857) is fully fleshed out and implemented.
33
+ - 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.js` files where props are incorporated into standard styled-components styling.
44
34
 
45
- Example directory structure -
35
+ - 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
46
36
 
47
- ```
48
- citybase_js_components
49
- |- .storybook-stories
50
- |- component.js
51
- |- src
52
- |- component
53
- |- __tests__
54
- |- component.spec.js
55
- component.css
56
- component.js
57
- component.types.js
58
- index.js
59
- ```
37
+ - All components are also themed via integration with Frontend Configuration Service. Components have a `.theme.js` file 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 the `theme.json` file that comes back from FCS, or if the `theme.json` file is missing due to a request failure.
60
38
 
61
- CLI -
62
- Run all tests and produce a code coverage report.
39
+ - 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.js` file.
63
40
 
64
- - `yarn test`
65
- Run Jest in "watch mode" and do not produce a code coverage report. (Useful while writing new tests.)
66
- - `yarn run jest --watch --coverage=false`
41
+ - 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 `variant` prop.
67
42
 
68
43
  ## Storybook
69
44
 
70
45
  This repo uses [React Storybook](https://storybook.js.org/basics/guide-react/) for interactive component display.
71
46
 
72
- ### Storybook QA Environment
73
-
74
- [https://js-assets.qa.citybase.thecb.net/](https://js-assets.qa.citybase.thecb.net/)
75
-
76
47
  ### Storybook addons
77
48
 
78
49
  - [Actions](https://github.com/storybooks/storybook/tree/master/addons/actions)
79
50
  - [Knobs](https://github.com/storybooks/storybook/tree/master/addons/knobs)
80
51
 
81
- Please include new component stories as this library will also be a sandbox. **Please consider these as important as unit tests.**
52
+ Please include new component stories as this library will also be a sandbox.
82
53
 
83
54
  - `yarn storybook`
84
55
  - open browser to localhost:9001
85
56
 
86
- ## Deploying new changes
57
+ ## Adding new components
87
58
 
88
- After new changes are ready to be deployed:
59
+ - 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/atoms` and `components/molecules` directory of their parent application.
89
60
 
90
- - `yarn build`
91
- - [Tag off changes on Github](https://github.com/CityBaseInc/citybase_js_components/releases)
61
+ - 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.
92
62
 
93
- ## Consuming in your application
63
+ - 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 `Header` and `Footer` molecules in Navigate Frontend. Both of these molcules make use of component library atoms such as `NavHeader` to layout out content. NFE then has `Header` and `Footer` molecules which live in the NFE components directory and use NFE specific business logic to provide content to these atoms, resulting in a complete `Header` and `Footer`.
64
+
65
+ ## Version bumping and publishing
66
+
67
+ ### Version bumping
68
+
69
+ - The version of the package is automatically bumped via GitHub Action after a pull request is merged to the master branch.
94
70
 
95
- ### Prod import
71
+ - The auto version bump action analyzes commit messages in the PR to determine what value to increment the package by. Including the keyword `major` in a commit message will result in a major version bump (i.e., `2.3.0` -> `3.0.0`). Including the keyword `minor` will result in a minor version bump (i.e., `2.3.0` -> `2.4.0`). PRs that are merged with neither the `major` or `minor` keywords present in commit messages will result in a patch version bump (i.e., `2.3.0` -> `2.3.1`).
72
+
73
+ - Patch versions should consist of small, non-breaking changes to components, component stories, and development tooling or documentation; or bug fixes
74
+
75
+ - Minor versions consist of moderate, non-breaking changes and additions: alterations to existing component structure or theme files; addition of new components, stories, or dependencies; significant changes to development tooling or introduction of tests
76
+
77
+ - Major version relases should be reserved for breaking library changes: removal of in-use components; breaking changes to component layout or theme properties; addition or removal of crticial dependencies. These version increases should be rare.
78
+
79
+ ### Publishing new versions to NPM
80
+
81
+ - While GitHub will handle bumping the version of the library with every PR merge to master, publishing an update version of the library to NPM requires creating a release using the `release` script. This script triggers an action in the repo to create a release tagged with a publication date. After a new release is created, an action checks to see whether the library version differs from that on NPM. If the library version has changed, the action attempts to publish the new version to NPM.
82
+
83
+ - Once a new version of the library is published to NPM, you may either manually update your application's `package.json` to request that new version, or wait until the following morning when dependabot will pick up the change and create an update PR for you.
84
+
85
+ ## Consuming in your application
96
86
 
97
- - `npm i git+ssh://git@github.com:CityBaseInc/citybase_js_components.git#<commit-ish> --save`
98
- - I would suggest using a tagged version of the component library as the default (master branch) can be unstable.
99
- - Learn more about [Git urls as dependencies](https://docs.npmjs.com/files/package.json#git-urls-as-dependencies)
87
+ ### Adding to existing application
100
88
 
101
- ### Local import
89
+ - Run `yarn add @thecb/components`.
90
+ - To verify it installed successfully, make sure it is in the applicaton's `package.json` file.
102
91
 
103
- - `npm i ../local/path/to/citybase_js_components --save`
104
- - This should persist changes up through the consuming application so that you don't have to rebuild and re `npm install` on every change.
92
+ ### Local import and development
105
93
 
106
- ### Package.json updates
94
+ If you are developing locally, you can add or make changes to components in the `@thecb/components` package and see those changes in the application running locally by linking the `@thecb/components` package to your application.
95
+ Open the `@thecb/components`, and in the command line
107
96
 
108
- As the citybase_js_components is not built and delivered from a package manager, when the package is imported, it will serve up raw source files. You will likely need to update your package.json file to include any `citybase` labelled node_module package to use your babel processor.
97
+ - Run `yarn build`
98
+ - Run `yarn link`
109
99
 
110
- ```javascript
111
- // in package.json
112
- {
113
- test: /\.jsx?$/,
114
- exclude: /node_modules\/(?!citybase).*/,
115
- use: ['babel-loader'],
116
- },
117
- ```
100
+ You should see a success message, and directions on how to link this package into an application. In the application you’d like the components, navigate to that application and in the command line
118
101
 
119
- ### Circle CI needed setup
102
+ - Run `yarn link @thecb/components`
120
103
 
121
- Please follow
122
- [this step by step document](https://citybase.atlassian.net/wiki/spaces/DEV/pages/276267015/How+to+set+up+CircleCI+to+have+permissions+from+multiple+repos) on how to allow CircleCI to reference multiple repositories
104
+ Now the package is linked locally and you can make changes to the `@thecb/components` and you’ll see the changes in the application running `@thecb/components`. To unlink the package, in the application running `@thecb/components` and in the command line
123
105
 
124
- ## Using in your application
106
+ - Run `yarn unlink @thecb/components`
107
+ - Run `yarn install` `--``force`
125
108
 
126
- - `import { Button } from 'citybase_js_components';`
127
- - or alias the component:
128
- - `import { Button as CBButton } from 'citybase_js_components';`
109
+ Next go to the `@thecb/components` and in the command line
129
110
 
130
- ## Wikitext Component Markdown
111
+ - Run `yarn unlink`
131
112
 
132
- The wikitext uses showdownjs to render markdown to html.
113
+ Now the package is unlinked, and you’re using the version on NPM.
133
114
 
134
- - Syntax docs can be found here: https://github.com/showdownjs/showdown/wiki/Showdown's-Markdown-syntax
135
- - Live editor: http://demo.showdownjs.com/
136
- - Showdownjs documentation: https://github.com/showdownjs/showdown/wiki
115
+ ### Importing and using components
137
116
 
138
- ## Listview Component Table
117
+ 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
139
118
 
140
- The listview component uses React-Table as the brains of the table.
119
+ - `import { ButtonWithAction } from` `"``@thecb/components``"``;`
141
120
 
142
- - Live table: https://react-table.js.org/
143
- - Documentation: https://github.com/react-tools/react-table
121
+ You can alias the component by
144
122
 
145
- ## ExternalRedirect link protection library
123
+ - `import { ButtonWithAction as MyButton } from "@thecb/components";`
146
124
 
147
- This lib helps prevent against reverse tabnabbing.
125
+ To import multiple components
148
126
 
149
- - Blankshield: https://github.com/danielstjules/blankshield
127
+ - `import { ButtonWithAction, LoginForm, Box, Stack, Cluster } from "@thecb/components";`