react-coaz
v1.0.9
Published
A comprehensive collection of reusable React UI components built for COAZ web apps.
Downloads
100
Readme
react-coaz
Reusable React UI components built for COAZ web apps, so they don't have to be rewritten for every new project.
Install
npm install react-coazimport { Input, Checkbox, ContentGroup, CIAward } from 'react-coaz';
import 'react-coaz/styles.css'; // import once, e.g. in main.jsxNo Tailwind setup required. All CSS the components need is pre-compiled
and shipped as dist/style.css — just import it once as shown above. You
don't need Tailwind, PostCSS, or any config in your own project for
react-coaz's components to render correctly.
Dependencies
react and react-dom (18+, required by createPopup/createDialog,
which use ReactDOM.createRoot) are peerDependencies — if you already have
compatible versions, nothing extra happens; if one is missing, npm installs
it; if you have an incompatible one, npm install fails with a clear
ERESOLVE error instead of silently duplicating React in node_modules.
react-icons and react-router-dom are regular dependencies — they
install automatically with react-coaz, no separate step needed.
react-loading-icons (used by Dialog's submit spinner) is also a regular
dependency, installed automatically.
html5-qrcode (used only by Scanner) is an optional peer dependency —
it is not installed automatically, and react-coaz still loads and works
fully without it. Only <Scanner /> needs it, loaded lazily the first time
it's rendered:
npm install html5-qrcode # only if you use <Scanner />If you render <Scanner /> without installing it, it shows an inline error
message rather than crashing your app.
Components
Layout & display: Scrollable, ContentGroup, Detail, NoContent,
Table, ListItem, UserItems (also exported as UserItem), Message
Forms: Input, Inputs (auto-laying-out group of inputs), Checkbox,
RadioButton, Select, TextArea, Time, FileInput, FormValidator +
useFormValidator hook
Navigation: MenuItem, Header
Overlays: createPopup (alias Createpopup), createDialog,
QuestionDialog
Other: Scanner (QR code scanner)
Icons (CoazIcons): Logo, CIAccount, CIAward, CIHandShake,
CIJob, CIRole, CIService, CISiteSettings, CISubscription,
CITransaction, CIUserSettings
Constants & helpers: sex (['MALE','FEMALE']), idTypes
(['NRC','PASSPORT','DRIVERS_LICENSE']), sc (screen-size breakpoint keys:
lg/md/sm/xs), getScreenSize() (reads window.screen.width and
returns one of those keys), deepCopy(value), formatDate(date, short?, time?)
Usage
Forms
import { useFormValidator, Input, Select, Checkbox } from 'react-coaz';
function LoginForm() {
const [register, handleChange, handleSubmit, errors] = useFormValidator(() => {
// runs only if there are no validation errors
});
return (
<form onSubmit={(e) => { e.preventDefault(); handleSubmit(); }}>
<Input id="email" name="email" label="Email" type="email"
register={register} checks={['empty']} errors={errors}
onChange={(e) => handleChange(e, () => {})} />
</form>
);
}Inputs lays out a whole group at once from a config array (handles
text/select/checkbox/time/textarea/file/blank types, responsive
column count via ResizeObserver):
import { Inputs } from 'react-coaz';
<Inputs
minWidth={220}
inputs={[
{ type: 'text', label: 'Name', name: 'name', value, onChange },
{ type: 'select', label: 'Role', name: 'role', value, onChange, options: () => <>{/* <option> tags */}</> },
]}
/>Popups & dialogs
import { useRef } from 'react';
import { createPopup, createDialog, QuestionDialog } from 'react-coaz';
// A small floating menu anchored to a button
const buttonRef = useRef(null);
<button ref={buttonRef} onClick={() => createPopup({
buttonRef,
Component: <div style={{ padding: 8 }}>Menu content</div>,
})}>Options</button>
// A modal dialog with a Submit/Cancel footer already wired up.
// Component receives {params, submitRef, setLoading, setEnableSubmit} --
// set submitRef.current = { submit: async () => ({ success: true }) } to
// hook up what "Submit" does.
createDialog({
title: 'Delete user?',
Component: QuestionDialog,
params: { message: 'This cannot be undone.', submit: async () => ({ success: true }) },
});Navigation
MenuItem and Header must be rendered inside a react-router <Router>.
Header's back button reads the current path and strips the last /_...
segment (matches COAZ's nested-route convention); it's hidden on /.
UserItems
A searchable, paginated user picker. It has no knowledge of your backend —
you supply a search(searchKey, page) function returning
{ users, pageNo, pageSize, totalElements, totalPages, last }:
import { UserItems } from 'react-coaz';
<UserItems
search={(searchKey, page) => myApi.searchUsers(searchKey, page)}
onSelect={(user) => setSelectedUser(user)}
buttons={[{ name: 'Remove', handler: (user) => removeUser(user) }]}
/>Optional: sharing the COAZ brand tokens in your own Tailwind config
If your app also uses Tailwind and you want the same color/font tokens
(theme, themeMedium, themeLight, themeLighter, text, textMedium,
textFent, helveticaNeueMedium, helveticaNeueLight) available for your
own custom classes, extend your config with the included preset. This is
purely optional — react-coaz's own components don't need it:
// tailwind.config.js
module.exports = {
presets: [require('react-coaz/tailwind-preset')],
};Local development against this package (before/without publishing)
From inside react-coaz/:
npm run build # outputs dist/ (runs the JS build, then the CSS build)
npm link # registers this package globallyThen, from your website project:
npm link react-coazRe-run npm run build after every change; restart your dev server if it
doesn't pick the change up.
To go back to the published version later: npm unlink react-coaz in the
website project, then npm install react-coaz.
Publishing to npm
npm login
npm run build
npm publish --access publicnpm run build runs two steps: vite build (bundles the JS), then a
Tailwind CLI pass that scans src/ and compiles every utility class the
components use into dist/style.css. tailwindcss, postcss, and
autoprefixer are devDependencies purely for that second step — nobody
who installs react-coaz installs them.
Bump version in package.json before every publish (semver: patch for
fixes, minor for new components, major for breaking changes) — npm rejects
re-publishing an existing version number.
