suliskh / prodig

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

🌈 Prodig Design System

Prodig provides reusable React components. You can also use it in plain HTML via CSS nevertheless.

⚠️ IMPORTANT NOTE: Due to this issue, please use npm instead of Yarn as package manager.

1. Making Components

1.1. Setup

Prerequisites: you need to have NodeJS and npm

  • Clone prodig repository
     $ git clone git@github.com:kukuhsul/prodig.git
  • Install dependencies
     $ cd prodig
     path/to/prodig/$ npm install

1.2. Folder Structure

Below are the folder structure used in prodig:

β”œβ”€β”€ src/       	
β”‚   β”œβ”€β”€ components/		
β”‚   β”‚    β”œβ”€β”€ MyComponent/		
β”‚   β”‚    β”‚    β”œβ”€β”€ index.tsx
β”‚   β”‚    β”‚    β”œβ”€β”€ MyComponent.scss
β”‚   β”‚    β”œβ”€β”€ MyOtherComponent
β”‚   β”‚    └── . . .
β”‚   β”œβ”€β”€ fonts/
β”‚   β”œβ”€β”€ images/
β”‚   β”œβ”€β”€ styles/
β”‚   β”‚    β”œβ”€β”€ settings/ 
β”‚   β”‚    β”œβ”€β”€ bases/
β”‚   β”‚    β”œβ”€β”€ tools/
β”‚   β”‚    β”œβ”€β”€ utilities/
β”‚   β”‚    β”œβ”€β”€ index.scss (root style)
β”‚   └── index.ts (Main file: import and exports all assets. Used by `npm run build`)
β”œβ”€β”€ dist/ (containing bundled files, generated by: `npm run build`)
|		β”œβ”€β”€ fonts/
|		β”œβ”€β”€ images/
β”‚   β”œβ”€β”€ styles/
β”‚   |		 β”œβ”€β”€ settings/ 
β”‚   |		 β”œβ”€β”€ bases/
β”‚   |		 β”œβ”€β”€ tools/
β”‚   β”‚    β”œβ”€β”€ components/ (component-level styles)
β”‚   |		 β”œβ”€β”€ utilities/
β”‚   β”‚    β”œβ”€β”€ styles.scss (root style)
β”‚   |		 β”œβ”€β”€ styles.css (bundled CSS style)
β”‚   β”œβ”€β”€	index.js (Production main file, containing bundled component)
└── . . .

1.3. Commands List

Below are the commands list, you can found the command's detail in package.json file

  • build: build all
  • build:js: build and generate bundled JS components into the dist folder
  • build:css: build and generate CSS into the dist folder
  • clean: delete dist folder
  • copy-misc: copy miscellaneous files (e.g. README.md, package.json) to the dist folder
  • copy-assets: copy assets files (e.g. images, fonts) to the dist folder
  • format:css: run CSS/SCSS linter and fix error"
  • format:ts: run TS linter and fix error
  • lint:css: run CSS/SCSS linter (check .stylelintrc.json for configuration)
  • lint:ts: run TS linter (check tslint.json for configuration)
  • start: run development mode using storybook. (http://localhost:9001)

1.4. Editor Config

Editor configuration will helps us (as developer) to define and maintain consistent coding styles between different editors and IDEs. Those configuration can be found in .editorconfig file. If you are using VSCode, please install this plugin to automatically override user/workspace settings

1.5. Coding Styles

CSS/SASS

CSS/SASS code styles are referring to the most reasonable Airbnb CSS/SASS Styleguide. StyleLint will ensure all css/sass code is conformed with the above styleguide. Those configuration can be found in .stylelintrc file. StyleLint errors are displayed as warning messages.

We are using sustainable and scalable ITCSS architecture, which contains 5 layer of styles (see the styles/ folder):

  • Settings: global SCSS variables and configs (e.g. colors, sizes)
  • Tools: global SCSS functions and mixins (e.g. unit conversion)
  • Bases: basic styling (e.g. normalize, reset)
  • Components: components-level styles, located separately in each component's folder
  • Utilities: helper class, high specifity (e.g. text-align)

We are also using BEM naming convention:

  • Block (B): standalone entity that is meaningful on its own
  • Element (E): a part of a block that has no standalone meaning and is semantically tied to its block
  • Modifier (M): A flag on a block or element. Use them to change appearance or behavior
.button { //> B
	/* Styles goes here */
	
	&__icon { /* Styles goes here */ } //> E
	
	&--primary { /* Styles goes here */ } //> M
	&--secondary { /* Styles goes here */ } //> M
	&--disabled {	/* Styles goes here */ } //> M
}

Aditional file naming convention:

  • Component-level: Use PascalCase and match the component's name. Example: MyComponent.scss for MyComponent.tsx. [NO-LINT]
  • Other: use lowercase and dash "-" as separator of each word, and also add underscore _ prefix except the root style file. Examples: _tokens-color.scss, _typography.scss, index.scss

Typescript & React/TSX

Typescript and React/TSX code styles are referring to Airbnb: Javascript and Palantir: tslint-react. TSLint will ensure all ts/tsx code is conformed with the styleguide. Those configuration can be found in .tslint.json file. TSLint errors are displayed as error messages and will stop the building process.

Note: [NO-LINT] label means that no linter for the particular style. However, you still have to conform with the style

  1. Naming

    • Extensions: Use .tsx extension for components-level. Use .ts only for root file that export all components and assets. [NO-LINT]
    • Filename: Use PascalCase for filename. E.g., SomeFile.tsx. Use name index.tsx for the component root file, so that can be resolved by ./components/MyComponent. [NO-LINT]
    • Reference Naming: Use PascalCase for React components and camelCase for its instances. [NO-LINT]
       // good
       import MyComponent from './MyComponent';
       const myComponent = <MyComponent />;
  2. References

    • Always use const or let instead of var. [tslint rule: no-var-keyword]
    • Use const instead of let and var if a variable is only assigned to once when it is declared. [tslint: prefer-const]
  3. Semicolon
    Always use semicolon at the end of every statement [tslint rule: semicolon]

  4. Curly
    Always use curly braces for if/for/do/while statements, except for one line flow statements. [tslint rule: curly]

    // bad
    if (x > 0)
    	doStuff();
    		
    //good
    if (x > 0) doStuff();
    
    if (x > 0) {
    	doStuff();
    }
  5. Quotemark
    Use single quote '' for string literals, and use double quote "" for jsx attributes. [tslint rule: quotemark]

  6. Trailing Comma
    Use trailing comma for multiline objects and array. [tslint rule: trailing-comma]

  7. JSX: Formating

    • Multiline JSX: Multiline JSx expressions must be wrapped with parentheses. Opening parenthesis must be followed by a newline. Closing parenthesis must be preceded by a newline. [tslint rule: jsx-wrap-multiline]
       // bad
       const button = <button type="submit">
       	Submit
       </button>;
       
       // good
       const button = (
       	<button type="submit">
       		Submit
       	</button>
       );
    • JSX: Self Close: JSX elements with no child should be self-closed and have space before the trailing slash [tslint rules: jsx-self-close, jsx-space-before-trailing-slash]
       // bad
       <Button text="Proofn Button"></Button>
       <Button text="Proofn Button"/>
       
       // good
       <Button text="Proofn Button" />
    • Alignment: [1] JSX attributes must be indented further than the opening tag, sit on their own line and vertically aligned. JSX element that have only 1 attribute may sit on same line with the opening tag. [2] Tag closing must be on its own line and aligned with opening of tag. [3] Closing tag must be on its own line and aligned with opening tag. [tslint rule: jsx-alignment]
      // bad
      const  hello = (
      	<Hello
      	name="Proofn Guy" other="nothing" // ----- [1]
      	>
      		Something here</Hello> // ----- [3]
      );
      
      const otherHello = (
      	<Hello 
      		name="other Proofn Guy"
      		other="nothing"> // ----- [2]
      		 Something here
      	</Hello>
      );
      
      // good
      const  helloOneAttribute = (
      	<Hello name="Proofn Guy">
      		Something here
      	</Here>
      );
      
      const hello = (
      	<Hello 
      		name="Proofn Guy"
      		other="nothing"
      	>
      		Something here
      	</Hello>
      );
    • Curly Spacing: Do not pad JSX curly braces with spaces. [tslint rule: jsx-curly-spacing]
  8. JSX: No Lambda
    Creating new anonymous functions (with either the function syntax or ES2015 arrow syntax) inside the render call stack works against pure component rendering. When doing an equality check between two lambdas, React will always consider them unequal values and force the component to re-render more often than necessary. [tslint rule: jsx-no-lambda]

    	// bad
    	const otherButton = (
    		<button onClick={function () { /* do something */ }} />
    	);
    
    	const button = (
    		<button onClick={() => /* do something */}>
    			Click Me
    		</button>
    	);
    	
    	// good
    	const handleClick = () => {
    		console.log('clicked');
    	};
    
    	const button = (
    		<button onClick={handleClick}>
    			Click Me
    		</button>
    	);
  9. JSX: No Bind
    Do not use function binding in JSX attributes. Bind call in the render path creates a brand new function on every single render. Bind event handlers for the render method in the constructor. [tslint rule: jsx-no-bind]

    // bad
    class Button extends React.Component {
    	onClickHandler() {
    		// do something
    	}
    	render() {
    		return <button onClick={this.onClickHandler.bind(this)} />;
    	}
    }
    
    // good
    export interface Props {
    	name: string;
    }
    
    class Button extends React.Component<Props> {
    	constructor(props) {
    		super(props);
    
    		this.onClickHandler = this.onClickHandler.bind(this);
    	}
    
    	onClickHandler() {
    		// do something
    	}
    
    	render() {
    		return <div onClick={this.onClickHandler} />;
    	}
    }

2. Using Prodig Components

2.1. Setup

Prerequisites: you need to have NodeJS and npm

  • Clone prodig repository (outside the app folder)

     $ git clone git@github.com:kukuhsul/prodig.git
    
  • Inject prodig to the global npm module on your machine

     $ npm link
    

    Info: the above command will builds prodig and runs npm link to add symbolic link from your β€œglobal node_modules” directory to the prodig/publish folder.

  • Add prodig to the app, asumes app folder is proofn-frontend-app

     $ cd proofn-frontend-app
     path/to/proofn-frontend-app/$ npm link prodig
    

    Info: the above command will creates a symbolic link from ./node_modules/prodig to <global_node_modules>/prodig, so that we can use prodig as dependency of our app

2.2. Using React Components (Recommended)

You can use React Component by importing component directly from prodig

import { SomeComponent } from 'prodig';

2.3. Using CSS/SASS

You can use CSS/SASS by importing styles from prodig/dist/styles

3. TODO: Future Improvements

  • Improve storybook documentation
  • Add testing feature
  • Add image optimization pipeline
  • Use only PostCSS to compile handle style
  • Integrate linter in development mode (storybook)
  • Add prodig utilities to align libraris usage between prodig and consumer app
  • Fix postcss-modules plugin error on npm run build:js

4. Usefull Links

About


Languages

Language:CSS 46.3%Language:TypeScript 28.6%Language:JavaScript 25.1%