1.0.0 • Published 10 months ago

idn-ui-kit v1.0.0

Weekly downloads
-
License
UNLICENSED
Repository
-
Last release
10 months ago

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

  1. Use a Type-suffixed name for the general type, e.g. MaterialType

  2. Use a Props-suffixed name for component-related property type, e.g. MaterialCardProps

  3. Use PascalCase

Components

A. Naming

  1. 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

  1. 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 = () => {...}
  2. Use PascalCase for naming. E.g. MaterialCard

C. Properties

  1. Use camelCase for naming. E.g. imageUrl, noOfLines, materialItems

  2. Use is or has prefixed names for a boolean value. E.g. isOpen, hasHeader

  3. 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.

  1. Use labels props

  2. We also have to make additional type of the labels with [Component Name][LabelsType] naming.

    type CreateQuizModalProps = {
        labels: CreateQuizModalLabelsType
        ...
    }
    type CreateQuizModalLabelsType = {
        modalTitle: string;
        quizNameLabel: string;
        ...
    }
    
    function QuizCard(props: CreateQuizModalProps) {...}

B. Naming

  1. Use camelCase

  2. Use [Context][Title] format for prominent text. E.g:

    {
        modalTitle: "Buat Kuis Baru",
        ...
    }
  3. Use [Context][Label] format for relatively short text . E.g:

     {
         quizNameLabel: "Judul Kuis",
         classroomLabel: "Kelas",
         ...
     }
  4. 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",
         ...
     }
  5. Use [Context][Action] format for actionable text. E.g:

     {
         createAction: "Buat Kuis",
         cancelAction: "Batalkan",
         ...
     }
  6. 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

  1. Apply semantic release and generate changelog $yarn changelog. This will automatically bump the version and generate the changelogs for each package.
  2. Create PR from the release branch, squash commit and then merge to master.
  3. $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