@jachymjachym/flamingo
v25.4.5
Published
Flamingo design system contains React UI components for shipping new features faster.
Readme
Welcome to Flamingo Design System
Flamingo design system contains React UI components for shipping new features faster.
Useful links:
Getting started
- In case of external repository add npm registry to
.npmrcand install dependencies@jachymjachym/flamingo@jachymjachym/flamingo-theme. In monorepo env everything works out-of-the-box.
.npmrc:
@ataccama:registry=https://artifactory.ataccama.dev/artifactory/api/npm/local-npm-dev- Setup fonts and wrap your app with
ThemeProvider:
import '@jachymjachym/flamingo/fonts.css'
import { ThemeProvider, oneTheme } from '@jachymjachym/flamingo-theme'<ThemeProvider theme={oneTheme}>{children}</ThemeProvider>- Add optional
FlamingoProviderto provide i18n for Flamingo components (lang provided by default isen):
import { FlamingoProvider } from '@jachymjachym/flamingo'<FlamingoProvider language={language} translation={translations}>
{children}
</FlamingoProvider>- Start using Flamingo components! Checkout Flamingo for more info.
Contribution
Contributing to Flamingo is as easy as creating new MR with your desired change / improvement. In monorepo context our apps use Flamingo always in the latest version.
Maintaining a changelog
Since we also provide Flamingo as NPM package we want to keep track of changes. To make it simpler
and predictable we use changeset tool. With each MR you should provide a changeset describing
the change.
Adding changeset
Run changeset-cli and follow the wizard to add your desired change. Select affected libraries (should be autodetect which libs were affected) and type of change based on semver.
pnpm changeset addThis will generate a text file in .changeset directory.
Screenshot testing
Screenshot testing is a great way to make sure your changes don't break anything. We use playwright
to take screenshots from flamingo-e2e app. More info about screenshot testing can be found in
flamingo-e2e README file
To run the tests locally:
pnpm nx run flamingo-e2e:e2eUpdating screenshots
If you are sure your changes are correct, you can update the screenshots by running:
pnpm nx run flamingo-e2e:e2e-updateCreating merge request
Thanks to CODEOWNERS file you will have to set the mandatory reviewers (you will see them in gitlab UI) to get the approval. Your flamingo changes can be in single MR with your other changes. Again thanks to CODEOWNERS appropriate approval will be required by flamingo team.
Contributing a new component
There are two libraries to which you can contribute:
@jachymjachym/flamingo
- Requires higher standard for design & documentation
- Components need to be in Figma library and approved by Flamingo team
- Components include guideline on Flamingo website
- Components include Storybook stories
- Placed in
libs/flamingo/src/lib/components
@jachymjachym/flamingo-hatchery
- When you don't have all guidelines or the design is not finished yet, flamingo-hatchery could be a great place to contribute
- You can easily and quickly share component code with your teams
- Storybook can be still provided and is appreciated (see
libs/flamingo/src/hatchery) - Placed in
libs/flamingo-hatchery/src/components - Once component is ready it can be moved to stable flamingo library
Development
Best way to develop your feature is to run it & test it in Storybook on your machine:
pnpm storybookTranslations
Library itself is not opinionated about i18n tool. But we provide a way how to do the translations.
- In case you need to add a localizable string, use
translationobject in your component:
const { translation } = useFlamingoContext()
// translations object contains all translations by flamingo- Extend the
defalutTranslationsobject with your new key inproviders/FlamingoProvider/index.tsxfile. - Default language is english
Icons
Add SVG icon to flamingo-icons/lib/src/icon/assets, then run
pnpm nx run flamingo-icons:generateCode conventions
For details checkout the DS code conversions Notion page.
Component exports from the library
When we have composite component which consist of several tightly coupled components (e.g. Stepper or ActionDropdown), export only one Object or component and add other child components as properties, so they can be accessed using dot notation.
Additional suggestions: In case the components are expected to be used together (like in ActionDropdown), the root component should be used as the main export. In case the components will probably used in multiple places across the codebase (like Stepper), export object with all the components.
Reason: Will have fewer exports from Flamingo library, dependencies are clear, naming is simpler (Main export provides namespace).
_Examples:
// Dropdown is react component
export const ActionsDropdown = Object.assign(Dropdown, { Item: DropdownItem })
// or
export const Stepper = {
Provider: StepperProvider,
Steps: StepperSteps,
StepContent: StepperStepContent,
PrevStep: StepperPrevStep,
NextStep: StepperNextStep,
}Export shape/Defining components
Wrap the component directly in forwardRef or other functions if necessary to avoid many declarations and renaming.
Reason: It may make the code harder to read, but it is much easier to type as TS can inherit the types.
_Examples:
export const TextInput = React.forwardRef<HTMLInputElement, TextInputProps>(
({ className, value, stateIcon, rightDecorator, hasError, testId, ...restProps }, ref) => {
const wrappedRightDecorator = ['string', 'number'].includes(typeof rightDecorator) ? (
<S.RightDecoratorWrapper color="muted">{rightDecorator}</S.RightDecoratorWrapper>
) : (
rightDecorator
)
return (
<S.InputWrapper
isDisabled={restProps.disabled}
className={className}
isReadonly={restProps.readOnly}
isInvalid={hasError || parseAriaInvalid(restProps['aria-invalid'])}
>
<S.Input
aria-invalid={hasError ? true : undefined}
{...restProps}
ref={ref}
value={value ?? undefined}
data-testid={testId || 'input'}
aria-readonly={restProps.readOnly ? true : undefined}
/>
{(stateIcon || rightDecorator) && (
<S.IconWrapper>
<Inline gap="S" alignY="center" nowrap>
{rightDecorator ? wrappedRightDecorator : null}
{stateIcon && <div aria-hidden>{stateIcon}</div>}
</Inline>
</S.IconWrapper>
)}
</S.InputWrapper>
)
}
)Forwarding refs
When we have smaller components with interactive DOM elements (eg. button, inputs, in general - form elements) we should support ref forwarding.
Unified Props API
Will be checked and addressed later (once we migrate all components from Gen2 to Flamingo). For now, try to avoid too many boolean flags on the components. Especially if those booleans are contradicting each other.
- Booleans should start with
isprefix (isDisabled). - Try to avoid setting booleans with falsy values, e.g. prefer
isEnabledinstead ofisDisabled={false}. - Avoid negative in the name of the props, don't do
isNotPrimary={true}(bet example I know).
