A component development and testing tool built for Angular, inspired by Storybook
npm install component-lab --save-dev
OR
yarn add component-lab --dev
Experiments are used to run your components, directives and pipes in many different isolated scenarios. Create an experiment in the directory where your component is located.
button.component.exp.ts
import { experimentOn } from 'component-lab';
export default experimentOn('Component Experiment Name')
.case('Experiment 1 Name', {
template: `
<app-button>
Foo
</app-button>
`
})
.case('Experiment 2 Name', {
template: `
<app-button>
Bar
</app-button>
`
});
Experiments can also provide both a template context object and an array of styles.
Some cases can be ignored by using xcase
instead of case
import { experimentOn } from 'component-lab';
export default experimentOn('My Button')
.case('Normal Button', {
template: `
<app-button></app-button>
`
})
.case('Warning Button', {
context: {
buttonLabel: 'Warning!',
onClick() {
console.log('Clicked!');
}
},
styles: [`
:host {
text-align: center;
}
`],
template: `
<app-button (click)="onClick()">
{{ buttonLabel }}
</app-button>
`
})
.xcase('Not Yet Implemented', {
template: `
<app-button raised>Raised Button</app-button>
`
});
Angular CLI
Custom Webpack Config
Create some experiments for your component, directive or pipe.
Create a lab.ts
file in your src
folder for your lab.
import { NgModule } from '@angular/core';
import { createLab } from 'component-lab';
import { ButtonComponent } from './app/button/button.component';
declare var require: any;
@NgModule({
declarations: [
ButtonComponent
],
exports: [
ButtonComponent
],
imports: [
],
providers: [],
})
export class LabModule { }
createLab({
/**
* NgModule to import. All components and pipes must be exported
* by this module to be useable in your experiments. Use an existing
* NgModule from your application or create a custom one.
*/
ngModule: LabModule,
loadExperiments() {
/**
* Function that returns an array of experiments.
*
* Here is an example using webpack's `require.context` to
* load all modules ending in `.exp.ts` and returning thier
* default exports as an array:
*/
const context = require.context('./', true, /\.exp\.ts/);
return context.keys().map(context).map(mod => mod.default);
}
});
lab.html
in your src
folder to use for the component-lab app.<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Component Lab</title>
<base href="https://github.com/synapse-wireless-labs/component-lab/blob/master/">
</head>
<body>
<component-lab>Loading...</component-lab>
</body>
</html>
tsconfig.lab.json
in your src folder. This file should be a copy of your tsconfig.app.json
with the angularCompilerOptions
added to specify an entryModule
with the path to the lab
.{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/app",
"baseUrl": "./",
"module": "es2015",
"types": []
},
"exclude": [
"test.ts",
"**/*.spec.ts"
],
"angularCompilerOptions": {
"entryModule": "lab#LabModule"
}
}
.angular-cli.json
file in the apps
array to point it to the lab files. {
"name": "component-lab",
"root": "src",
"outDir": "dist-lab",
"assets": [
"assets",
"favicon.ico"
],
"index": "lab.html",
"main": "lab.ts",
"polyfills": "polyfills.ts",
"test": "test.ts",
"tsconfig": "tsconfig.lab.json",
"testTsconfig": "tsconfig.spec.json",
"prefix": "app",
"styles": [
"styles.css"
],
"scripts": [],
"environmentSource": "environments/environment.ts",
"environments": {
"dev": "environments/environment.ts",
"prod": "environments/environment.prod.ts"
}
}
tsconfig.app.json
to exclude your lab files.{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/app",
"baseUrl": "./",
"module": "es2015",
"types": []
},
"exclude": [
"lab.ts",
"test.ts",
"**/*.spec.ts"
]
}
npm start -- --app component-lab --port 8080
OR
yarn start -- --app component-lab --port 8080
Create some experiments for your component, directive or pipe.
Create a lab.ts
file for your configuration.
import { NgModule } from '@angular/core';
import { createLab } from 'component-lab';
import { ButtonComponent } from './src/app/button/button.component';
declare var require: any;
@NgModule({
declarations: [
ButtonComponent
],
exports: [
ButtonComponent
],
imports: [
],
providers: [],
})
export class LabModule { }
createLab({
/**
* NgModule to import. All components and pipes must be exported
* by this module to be useable in your experiments
*/
ngModule: LabModule,
loadExperiments() {
/**
* Function that returns an array of experiments.
*
* Here is an example using webpack's `require.context` to
* load all modules ending in `.exp.ts` and returning thier
* default exports as an array:
*/
const context = require.context('./', true, /\.exp\.ts/);
return context.keys().map(context).map(mod => mod.default);
}
});
component-lab.config.js
file in the root of your project /**
* Export a single configuration object
*/
module.exports = {
/**
* Webpack configuration object used to load your experiments
*/
webpackConfig: { ... },
/**
* Host and port of the Component Lab webpack development server
*/
host: 'localhost',
port: 8080,
/**
* Additional list of files to include in the bundle
*/
include: [],
/**
* Dictionary of suites. Each suite should be a lab configuration
* module (see "Experiments")
*/
suites: {
feature: './src/lab.ts'
}
};
scripts
section of your package.json add a script to start Component Lab.{
"scripts": {
"component-lab": "component-lab"
}
}
npm run component-lab -- feature
OR
yarn run component-lab -- feature