idn-ui-kit
v1.0.0
Published
<a alt="Nx logo" href="https://nx.dev" target="_blank" rel="noreferrer"><img src="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-logo.png" width="45"></a>
Downloads
1
Readme
IDN UI-KIT
✨ This workspace has been generated by Nx, a Smart, fast and extensible build system. ✨
Understand this workspace
Run nx graph
to see a diagram of the dependencies of the projects.
Remote caching
Run npx nx connect-to-nx-cloud
to enable remote caching and make CI faster.
Further help
Visit the Nx Documentation to learn more.
Code Conventions
Code conventions are a set of guidelines to keep our codebase consistent, readable, and predictable. It also helps us do a more efficient code review by avoiding nitpicks.
Typing
Use a Type-suffixed name for the general type, e.g.
MaterialType
Use a Props-suffixed name for component-related property type, e.g.
MaterialCardProps
Use PascalCase
Components
A. Naming
- Use format:
[Context][type]
to make it more intuitive because the reader would catch the context from the first word. E.g.MaterialCard
,QuizCard
,ClassCard
B. Declaration
Use function declaration instead of a function expression. It will allow us to have more freedom of declaration order because of the hoisting.
// ✅ Use function declaration function MaterialCard() {...} // ❌ Do not use function expression const MaterialCard = function() {...} const MaterialCard = () => {...}
Use PascalCase for naming. E.g.
MaterialCard
C. Properties
Use camelCase for naming. E.g.
imageUrl
,noOfLines
,materialItems
Use
is
orhas
prefixed names for a boolean value. E.g.isOpen
,hasHeader
Use
on
+Verb 1
for callback prop. E.g.onClick
,onCloseModal
D. Declaration order
To improve readability, we need to structure the declaration order as follows:
// Import statements
import Box from "@foundation/Box";
...
// Typings, constants
const FALLBACK_IMAGE = "https://imgx...."
type MaterialCardProps = {
title: string;
description: string;
imageSrc: string;
...
}
// Main component declaration
function MaterialCard({title, description, imageSrc}: MaterialCardProps) {
return (
<Box>
<MaterialCardHeader />
...
</Box>
)
}
// Export statement
export default MaterialCard;
// Sub component
function MaterialCardHeader() {...}
Structure
A. Folder structure
lib/
MaterialCard/
├── MaterialCard.tsx # Main component file
├── MaterialStyle.tsx # Styling component file
├── MaterialCard.stories.tsx # Storybook doc
├── MaterialCard.spec.tsx # Test specification
├── utils.ts # Utils
└── index.ts # Aggregator
QuizCard/
...
Note: component's index.ts
file serves as an aggregator
// index.ts
export { default } from "./MaterialCard";
export * form "./utils.ts"
B. Import statement
To avoid treeshake problem, do not aggregate the import statements. Instead, we can import per-component path:
// ✅ Import per components
import MaterialCard from '@foundation/MaterialCard';
import QuizCard from '@foundation/QuizCard';
// ❌ Do not ggregate the import statement
import { MaterialCard, QuizCard } from '@foundation';
Labels
A. Passing via Component's Property
To make the component reusable in different tenants, we have to abstract away the text contents (labels) by passing it via property.
Use
labels
propsWe also have to make additional
type
of thelabels
with[Component Name][LabelsType]
naming.type CreateQuizModalProps = { labels: CreateQuizModalLabelsType ... } type CreateQuizModalLabelsType = { modalTitle: string; quizNameLabel: string; ... } function QuizCard(props: CreateQuizModalProps) {...}
B. Naming
Use camelCase
Use
[Context][Title]
format for prominent text. E.g:{ modalTitle: "Buat Kuis Baru", ... }
Use
[Context][Label]
format for relatively short text . E.g:{ quizNameLabel: "Judul Kuis", classroomLabel: "Kelas", ... }
Use
[Context][Description]
format for relatively long text. E.g:{ modalDescription: "Buat kuis baru dan bagikan ke kelas atau siswa secara spesifik.", quizNameErrorDescription: "Judul kuis harus memiliki panjang minimal 10 karakter", ... }
Use
[Context][Action]
format for actionable text. E.g:{ createAction: "Buat Kuis", cancelAction: "Batalkan", ... }
Use function for dynamic value In most cases, we only use
string
as label type. If we want to add dynamic value to the label, we can assign it as a function that return string literal.{ successMessageDescription: (title: string) => `Kuis ${title} telah berhasil dibuat!` ... }
Publish
Production
- Apply semantic release and generate changelog
$yarn changelog
. This will automatically bump the version and generate the changelogs for each package. - Create PR from the release branch, squash commit and then merge to master.
$yarn release
on tag version
Canary
yarn canary --force-publish=[workspace-name-1],[workspace-name-2]
# force all workspaces to be published
yarn canary --force-publish
or you can click publish:canary
on Gitlab MR pipeline to publish with gitlab
Note
Please login first using
$npm login
Please check release branch on local and remote, if there is release branch then delete it using$git branch -D release