Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 45 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,58 @@ CR-CL has a dependency of Styled-components.
$ yarn add @comicrelief/component-library
```

#### Wrap your app with the ThemeProvider and crTheme
#### Theming

Wrap your app with `ThemeProvider` and `crTheme`. For the smallest dependency graph, import from the `theme` entry (see [Subpath entrypoints](#subpath-entrypoints) below) instead of the package root.

```
import { ThemeProvider, crTheme } from '@comicrelief/component-library/theme';
```

The root import is still valid and exposes the same tokens:

```
import { ThemeProvider, crTheme } from '@comicrelief/component-library';
```

#### Import components
#### Subpath entrypoints

The package exposes named entrypoints so you can import only the slice you need. Prefer these over the root barrel when you care about bundle size.

- **`@comicrelief/component-library/theme`** — `ThemeProvider`, `crTheme`, and theme tokens (`zIndex`, `allBreakpoints`, `spacing`, `containers`, `hideVisually`, `allowListed`, `animations`, …).

- **`@comicrelief/component-library/atoms`** — This is split into these sub-categories: **`atoms/form`**, **`atoms/actions`**, **`atoms/text`**, **`atoms/media`**, **`atoms/brand`**, **`atoms/navigation`**, **`atoms/icons`**, **`atoms/effects`**.

- **`@comicrelief/component-library/molecules`** — This is split into these sub-categories: **`molecules/search-lookup`**, **`molecules/cards-ctas`**, **`molecules/banners-heroes`**, **`molecules/engagement`**, **`molecules/footer`** , **`molecules/icons`**

- **`@comicrelief/component-library/organisms`** — This is split into these sub-categories: **`organisms/headers`**, **`organisms/footers`**, **`organisms/compliance`**, **`organisms/donation`**, **`organisms/email-contact`**, **`organisms/media`**.

If desired you can import the whole sections (`/atoms`, `/molecules`, `/organisms`) which re-export the same set of names as the subpaths combined.

Example: atoms + theme in a small app or route:

```
import { crTheme, ThemeProvider } from '@comicrelief/component-library/theme';
import { Text, Link, Button } from '@comicrelief/component-library/atoms';
```

Example: a molecule and an organism in separate features:

```
import { HeroBanner } from '@comicrelief/component-library/molecules';
import { WYMDCarousel } from '@comicrelief/component-library/organisms';
```

The root entry re-exports everything; use it when you want a single import path and are not optimizing for chunk size.

```
import { HeroBanner } from '@comicrelief/component-library';
import { crTheme, ThemeProvider, Text, DynamicGallery } from '@comicrelief/component-library';
```

#### Tree shaking hint 'sideEffects'

`package.json` sets `sideEffects` so Webpack 4+ and similar tools can treat most of the published JavaScript as free of import time side effects, while still keeping anything that is: all `*.css` files inside this package, and a few modules that pull in CSS files from dependencies (like `lazysizes` on `Picture`, carousel CSS from `pure-react-carousel`, and the range-slider stylesheet from `react-range-slider-input` on the ImpactSlider).

### Develop

To install CR-CL locally, run:
Expand Down
27 changes: 25 additions & 2 deletions babel.config.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,36 @@
// eslint-disable-next-line func-names
module.exports = function (api) {
api.cache(true);
const format = process.env.MODULE_FORMAT;

api.cache.using(() => `${format || 'node'}:${process.env.NODE_ENV || 'development'}`);

const presets = [['react-app', { absoluteRuntime: false }]];
const plugins = [
['babel-plugin-styled-components'],
['import', { libraryName: 'lodash', libraryDirectory: '', camel2DashComponentName: false }]
];

const presetEnvOptions = { bugfixes: true };

if (format === 'esm') {
presetEnvOptions.modules = false;
} else {
presetEnvOptions.modules = 'commonjs';
if (!format) {
presetEnvOptions.targets = { node: 'current' };
}
}

const presets = [
['@babel/preset-env', presetEnvOptions],
[
'@babel/preset-react',
{
runtime: 'classic',
development: process.env.NODE_ENV === 'test' || process.env.NODE_ENV === 'development'
}
]
];

return {
presets,
plugins
Expand Down
167 changes: 161 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,155 @@
"name": "@comicrelief/component-library",
"author": "Comic Relief Engineering Team",
"version": "0.0.0-see.readme.for.semantic.release.process",
"main": "dist/index.js",
"main": "dist/cjs/index.js",
"sideEffects": [
"**/*.css",
"**/components/Atoms/Picture/Picture.js",
"**/components/Organisms/WYMDCarousel/WYMDCarousel.js",
"**/components/Organisms/RichtextCarousel/RichtextCarousel.js",
"**/components/Organisms/ImpactSlider/_Slider.js"
],
"exports": {
".": {
"import": "./dist/esm/index.js",
"require": "./dist/cjs/index.js",
"default": "./dist/esm/index.js"
},
"./theme": {
"import": "./dist/esm/theme.js",
"require": "./dist/cjs/theme.js",
"default": "./dist/esm/theme.js"
},
"./atoms": {
"import": "./dist/esm/atoms.js",
"require": "./dist/cjs/atoms.js",
"default": "./dist/esm/atoms.js"
},
"./molecules": {
"import": "./dist/esm/molecules.js",
"require": "./dist/cjs/molecules.js",
"default": "./dist/esm/molecules.js"
},
"./organisms": {
"import": "./dist/esm/organisms.js",
"require": "./dist/cjs/organisms.js",
"default": "./dist/esm/organisms.js"
},
"./atoms/form": {
"import": "./dist/esm/atoms-form.js",
"require": "./dist/cjs/atoms-form.js",
"default": "./dist/esm/atoms-form.js"
},
"./atoms/actions": {
"import": "./dist/esm/atoms-actions.js",
"require": "./dist/cjs/atoms-actions.js",
"default": "./dist/esm/atoms-actions.js"
},
"./atoms/text": {
"import": "./dist/esm/atoms-text.js",
"require": "./dist/cjs/atoms-text.js",
"default": "./dist/esm/atoms-text.js"
},
"./atoms/media": {
"import": "./dist/esm/atoms-media.js",
"require": "./dist/cjs/atoms-media.js",
"default": "./dist/esm/atoms-media.js"
},
"./atoms/brand": {
"import": "./dist/esm/atoms-brand.js",
"require": "./dist/cjs/atoms-brand.js",
"default": "./dist/esm/atoms-brand.js"
},
"./atoms/navigation": {
"import": "./dist/esm/atoms-navigation.js",
"require": "./dist/cjs/atoms-navigation.js",
"default": "./dist/esm/atoms-navigation.js"
},
"./atoms/icons": {
"import": "./dist/esm/atoms-icons.js",
"require": "./dist/cjs/atoms-icons.js",
"default": "./dist/esm/atoms-icons.js"
},
"./atoms/effects": {
"import": "./dist/esm/atoms-effects.js",
"require": "./dist/cjs/atoms-effects.js",
"default": "./dist/esm/atoms-effects.js"
},
"./molecules/search-lookup": {
"import": "./dist/esm/molecules-search-lookup.js",
"require": "./dist/cjs/molecules-search-lookup.js",
"default": "./dist/esm/molecules-search-lookup.js"
},
"./molecules/cards-ctas": {
"import": "./dist/esm/molecules-cards-ctas.js",
"require": "./dist/cjs/molecules-cards-ctas.js",
"default": "./dist/esm/molecules-cards-ctas.js"
},
"./molecules/banners-heroes": {
"import": "./dist/esm/molecules-banners-heroes.js",
"require": "./dist/cjs/molecules-banners-heroes.js",
"default": "./dist/esm/molecules-banners-heroes.js"
},
"./molecules/engagement": {
"import": "./dist/esm/molecules-engagement.js",
"require": "./dist/cjs/molecules-engagement.js",
"default": "./dist/esm/molecules-engagement.js"
},
"./molecules/cards-initiatives": {
"import": "./dist/esm/molecules-cards-ctas.js",
"require": "./dist/cjs/molecules-cards-ctas.js",
"default": "./dist/esm/molecules-cards-ctas.js"
},
"./molecules/footer": {
"import": "./dist/esm/molecules-footer.js",
"require": "./dist/cjs/molecules-footer.js",
"default": "./dist/esm/molecules-footer.js"
},
"./molecules/footer-email": {
"import": "./dist/esm/molecules-footer.js",
"require": "./dist/cjs/molecules-footer.js",
"default": "./dist/esm/molecules-footer.js"
},
"./molecules/icons": {
"import": "./dist/esm/molecules-icons.js",
"require": "./dist/cjs/molecules-icons.js",
"default": "./dist/esm/molecules-icons.js"
},
"./organisms/headers": {
"import": "./dist/esm/organisms-headers.js",
"require": "./dist/cjs/organisms-headers.js",
"default": "./dist/esm/organisms-headers.js"
},
"./organisms/footers": {
"import": "./dist/esm/organisms-footers.js",
"require": "./dist/cjs/organisms-footers.js",
"default": "./dist/esm/organisms-footers.js"
},
"./organisms/compliance": {
"import": "./dist/esm/organisms-compliance.js",
"require": "./dist/cjs/organisms-compliance.js",
"default": "./dist/esm/organisms-compliance.js"
},
"./organisms/donation": {
"import": "./dist/esm/organisms-donation.js",
"require": "./dist/cjs/organisms-donation.js",
"default": "./dist/esm/organisms-donation.js"
},
"./organisms/email-contact": {
"import": "./dist/esm/organisms-email-contact.js",
"require": "./dist/cjs/organisms-email-contact.js",
"default": "./dist/esm/organisms-email-contact.js"
},
"./organisms/media": {
"import": "./dist/esm/organisms-media.js",
"require": "./dist/cjs/organisms-media.js",
"default": "./dist/esm/organisms-media.js"
},
"./dist/cjs/*": "./dist/cjs/*",
"./dist/esm/*": "./dist/esm/*",
"./src/*": "./src/*",
"./package.json": "./package.json"
},
"license": "ISC",
"jest": {
"verbose": true,
Expand All @@ -16,17 +164,22 @@
"^axios$": "axios/dist/node/axios.cjs"
}
},
"module": "dist/index.js",
"module": "dist/esm/index.js",
"repository": {
"type": "git",
"url": "https://github.com/comicrelief/component-library.git"
},
"dependencies": {
"@babel/cli": "^7.21.5",
"@babel/core": "^7.26.0",
"@babel/preset-env": "^7.26.0",
"@babel/preset-react": "^7.26.3",
"@hookform/resolvers": "^3.9.0",
"@splidejs/react-splide": "^0.7.12",
"axios": "^1.7.2",
"babel-plugin-import": "^1.13.8",
"babel-plugin-styled-components": "^2.1.4",
"cross-env": "^7.0.3",
"lazysizes": "^5.3.2",
"lodash": "^4.17.11",
"moment": "^2.29.4",
Expand Down Expand Up @@ -59,7 +212,9 @@
"nth-check": "2.0.1"
},
"scripts": {
"build": "rm -rf dist && NODE_ENV=production babel src --out-dir dist --copy-files --ignore __tests__,spec.js,test.js",
"build": "rm -rf dist && yarn build:cjs && yarn build:esm",
"build:cjs": "cross-env MODULE_FORMAT=cjs NODE_ENV=production babel src --out-dir dist/cjs --copy-files --ignore __tests__,spec.js,test.js",
"build:esm": "cross-env MODULE_FORMAT=esm NODE_ENV=production babel src --out-dir dist/esm --copy-files --ignore __tests__,spec.js,test.js && node scripts/write-esm-package-json.js",
"test:unit": "yarn run jest",
"test:unit:update": "yarn jest -u",
"styleguide": "cross-env FAST_REFRESH=false styleguidist server",
Expand All @@ -70,7 +225,9 @@
"test:e2e:local": "export NODE_ENV=development; start-server-and-test styleguide http://localhost:6060 test:e2e",
"lint": "eslint src",
"lint-fix": "yarn lint --fix",
"build-pr": "rm -rf dist && NODE_ENV=development BABEL_ENV=development yarn babel src --out-dir dist --copy-files --ignore __tests__,spec.js,test.js",
"build-pr": "rm -rf dist && yarn build-pr:cjs && yarn build-pr:esm",
"build-pr:cjs": "cross-env MODULE_FORMAT=cjs NODE_ENV=development BABEL_ENV=development babel src --out-dir dist/cjs --copy-files --ignore __tests__,spec.js,test.js",
"build-pr:esm": "cross-env MODULE_FORMAT=esm NODE_ENV=development BABEL_ENV=development babel src --out-dir dist/esm --copy-files --ignore __tests__,spec.js,test.js && node scripts/write-esm-package-json.js",
"postinstall": "yarn build-pr"
},
"browserslist": {
Expand All @@ -88,7 +245,6 @@
"devDependencies": {
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
"@playwright/test": "^1.38.1",
"cross-env": "^7.0.3",
"ejs": "^3.1.10",
"eslint": "^7.32.0",
"eslint-config-airbnb": "^18.2.0",
Expand All @@ -98,7 +254,6 @@
"eslint-plugin-react-hooks": "^4.6.0",
"jest": "^26.1.0",
"jest-styled-components": "^7.1.1",
"npm-run-all": "^4.1.5",
"prettier": "^2.8.8",
"react-styleguidist": "^11.1.7",
"react-test-renderer": "^17.0.2",
Expand Down
7 changes: 7 additions & 0 deletions scripts/write-esm-package-json.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const fs = require('fs');
const path = require('path');

const target = path.join(__dirname, '..', 'dist', 'esm', 'package.json');

fs.mkdirSync(path.dirname(target), { recursive: true });
fs.writeFileSync(target, `${JSON.stringify({ type: 'module' }, null, 2)}\n`);
3 changes: 3 additions & 0 deletions src/atoms-actions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { default as Button } from './components/Atoms/Button/Button';
export { default as ButtonWithStates } from './components/Atoms/ButtonWithStates/ButtonWithStates';
export { default as Link } from './components/Atoms/Link/Link';
2 changes: 2 additions & 0 deletions src/atoms-brand.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default as Logo } from './components/Atoms/Logo/Logo';
export { default as SocialIcons } from './components/Atoms/SocialIcons/SocialIcons';
3 changes: 3 additions & 0 deletions src/atoms-effects.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// this exception can be removed when we have more exports in this category
/* eslint-disable import/prefer-default-export */
export { default as Confetti } from './components/Atoms/Confetti/Confetti';
9 changes: 9 additions & 0 deletions src/atoms-form.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export { default as Input } from './components/Atoms/Input/Input';
export { default as Select } from './components/Atoms/Select/Select';
export { default as TextArea } from './components/Atoms/TextArea/TextArea';
export { default as Checkbox } from './components/Atoms/Checkbox/Checkbox';
export { default as RadioButton } from './components/Atoms/RadioButton/RadioButton';
export { default as TextInputWithDropdown } from './components/Atoms/TextInputWithDropdown/TextInputWithDropdown';
export { default as Label } from './components/Atoms/Label/Label';
export { default as ErrorText } from './components/Atoms/ErrorText/ErrorText';
export { default as InfoMessage } from './components/Atoms/InfoMessage/InfoMessage';
1 change: 1 addition & 0 deletions src/atoms-icons.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './components/Atoms/Icons';
2 changes: 2 additions & 0 deletions src/atoms-media.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default as Picture } from './components/Atoms/Picture/Picture';
export { default as AmbientVideo } from './components/Atoms/AmbientVideo/AmbientVideo';
3 changes: 3 additions & 0 deletions src/atoms-navigation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// this exception can be removed when we have more exports in this category
/* eslint-disable import/prefer-default-export */
export { default as Pagination } from './components/Atoms/Pagination/Pagination';
2 changes: 2 additions & 0 deletions src/atoms-text.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default as Text } from './components/Atoms/Text/Text';
export { default as RichText } from './components/Atoms/RichText/RichText';
8 changes: 8 additions & 0 deletions src/atoms.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export * from './atoms-form';
export * from './atoms-actions';
export * from './atoms-text';
export * from './atoms-media';
export * from './atoms-brand';
export * from './atoms-navigation';
export * from './atoms-icons';
export * from './atoms-effects';
Loading
Loading