This document describes how to contribute and provide examples for new components.
High level file structure and notable file locations.
sam-design-system
├── apps
│ ├── sam-design-system-site-e2e
│ └── sam-design-system-site
├── dist
├── libs
│ ├── documentation
│ └── packages
├── node_modules
├── scripts
│ └── generate-docs.js
├── tools
│ └── scripts
| ├── pack-and-publish.js
│ └── update-libs-version.js
├── angular.json
├── CODEOWNERS
├── jest.conf.js
├── karma.conf.js
├── nx.json
├── package-lock.json
├── package.json
├── tsconfig.json
└── tslint.json
The sample application in sam-design-system is a very basic angular application which consists of the header, side navigation, and a router-outlet
. The documentation library is lazy loaded and rendered through the app component router-outlet
.
High level file structure for the documentation library.
documentation/src/lib
├── apidoc
│ ├── sam-design-system-site-e2e
│ └── sam-design-system-site
├── components
│ ├── example-component
| | ├── demos
| | | ├── basic
| | | | ├── example-component-basic.component.html
| | | | ├── example-component-basic.component.scss
| | | | ├── example-component-basic.component.ts
| | | | ├── example-component-basic.module.ts
| | | | └── readme.md
| | | └── advanced
| | | ├── example-component-advanced.component.html
| | | ├── example-component-advanced.component.scss
| | | ├── example-component-advanced.component.ts
| | | ├── example-component-advanced.module.ts
| | | └── readme.md
| | ├── opening.md
| | ├── example-component.module.ts
| | └── closing.md
│ └── shared
├── pages
│ ├── introduction
│ └── overview
├── shared
│ ├── component-wrapper
│ ├── highlight
│ └── index.ts
└── documentation.module.js
The apidoc
folder contains the exported documentation of compodoc
which is triggered from npm run demo:docs
which is part of the federalist build process.
components/components.ts
→ Components documentationformly/formly.ts
→ Formly compodoc documentationlayouts/layouts.ts
→ Layout compodoc documentationindex.ts
→ Combined export file for all compodoc documentation. Prefer to import this as opposed to individual files.
The components
folder contains all demonstrable components and a shared
folder which contains helpers.
demos/basic/example-component-basic.component.html
→ The html template file for the basic example.demos/basic/example-component-basic.component.scss
→ The css file for the basic example.demos/basic/example-component-basic.component.ts
→ The typescript component file for the basic example.demos/basic/example-component-basic.module.ts
→ The typescript module file for the basic example.demos/basic/readme.md
→ A description markdown file for the basic example.(optional)
opening.md
→ A markdown file that is being ingested and passed through the route datareadme.opening
attribute to be shown between the title and the tab navigation.(optional)
example-component.module.ts
→ The overall example-component module which is responsible for registering eachdemo
example, providing the routing for each tab, and pulling in any markdown information.(see below)
closing.md
→ A markdown file that is being ingested and passed through the route datareadme.closing
attribute to be shown beneath all of the demos.(optional)
example-component.module.ts
The customizable configurations contain comments below.import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { HeaderBasic } from './demos/basic/header-basic.component'; import { DocumentationExamplesPage } from '../shared/examples-page/examples.component'; import { DocumentationAPIPage } from '../shared/api-page/docs-api.component'; import { DocumentationSourcePage } from '../shared/source-page/source.component'; import { DocumentationTemplatePage } from '../shared/template-page/template.component'; import { DocumentationComponentsSharedModule, DocumentationDemoList } from './../shared/index'; import { ComponentWrapperComponent } from './../../shared/component-wrapper/component-wrapper.component'; import { HeaderBasicModule } from './demos/basic/header-basic.module'; export declare var require: any; export const opening = require('!!raw-loader!./opening.md'); // load the content of the markdown in to a variable export const closing = require('!!raw-loader!./closing.md'); // load the content of the markdown in to a variable const DEMOS = { basic: { title: 'SAM Header', // Provide a title for this demo type: HeaderBasic, // Component to use for this demo code: require('!!raw-loader!./demos/basic/header-basic.component'), // Source Tab Content markup: require('!!raw-loader!./demos/basic/header-basic.component.html'), // Template Tab Content readme: require('!!raw-loader!./demos/basic/readme.md'), // Demo description markdown path: 'libs/documentation/src/lib/components/header/demos/basic' // Path to demo for the Github link } }; export const ROUTES = [ { path: '', pathMatch: 'full', redirectTo: 'examples' }, { path: '', component: ComponentWrapperComponent, data: { readme: { opening, // Opening section markdown (imported with require above) closing // Closing section markdown (imported with require above) }, items: [ // Defines what documentation to display on the API tab, repeats if multiple are specified { pkg: 'components', // Package specifies which compodocs to use (/apidocs/components/components.ts) type: 'components', // Within the compodocs, target the components section name: 'SdsHeaderComponent' // Show the SdsHeaderComponent object for API information } ] }, children: [ // You can omit any tab sections by removing the child routes here { path: 'examples', component: DocumentationExamplesPage }, { path: 'api', component: DocumentationAPIPage }, { path: 'source', component: DocumentationSourcePage }, { path: 'template', component: DocumentationTemplatePage } ] } ]; @NgModule({ imports: [ CommonModule, DocumentationComponentsSharedModule, HeaderBasicModule // Import all of your demo modules here (basic, advanced, etc) ] }) export class HeaderModule { constructor(demoList: DocumentationDemoList) { demoList.register('header', DEMOS); // Register the component with the demo list (name must match the route name) } }
The
shared
folder within components facilitates displaying theexamples
,api
,source
, andtemplate
page content.
The pages
folder holds any informational pages like introduction
or overview
that do not need to be part of the demo component structure.
The overall component for each component. It is responsible for the following:
title
→ An optional attribute of the route data, if it's not provided it will default to the component name.introducedVersion
→ An optional attribute of the route data which will show up at a chip to indicate what version the component was added to SDS.deprecatedVersion
→ An optional attribute of the route data which will show up at a chip to indicate when the component was added to SDSopening
→ A markdown string that is shown between the title and the tab navigation.closing
→ A markdown string that is shown beneath all of the demos.If the demo component's module provides child routes for
examples
,api
,source
, ortemplate
, they will be displayed as tabs.
A component for displaying source code with
ngx-highlightjs
on the demo card.
The overall library documentation module is where we register all of the example demo modules and routes.
documentation.module.ts
For each example, you must import your module and routes to the documentation module.import { IntroductionModule } from './pages/introduction/introduction.module'; import { IntroductionComponent } from './pages/introduction/introduction.component'; import { OverviewModule } from './pages/overview/overview.module'; import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { RouterModule, Routes } from '@angular/router'; import { DocumentationSharedModule } from './shared'; import { OverviewComponent } from './pages/overview/overview.component'; import { ROUTES as HEADER_ROUTES, HeaderModule } from './components/header/header.module'; // Import your ROUTES and Module declare var require: any; export const ROUTES: Routes = [ { path: '', pathMatch: 'full', redirectTo: 'components/header' }, { path: 'overview', component: OverviewComponent }, { path: 'introduction', component: IntroductionComponent }, { path: 'components', pathMatch: 'full', redirectTo: 'components/alert' }, { path: 'components/header', children: HEADER_ROUTES }, // Add your example component routes (the last segment should match the registered demo list name) ]; @NgModule({ imports: [ CommonModule, DocumentationSharedModule, RouterModule.forChild(ROUTES), HeaderModule, // Add your example component module to the imports array OverviewModule, IntroductionModule, ] }) export class DocumentationModule { }
packages
├── components
├── experimental
├── layouts
├── sam-formly
└── sam-material-extension
components
→ Common components and directivesexperimental
→ Experimental components [No Support Provided]layouts
→ Layout components which orchestrate multiple common components togethersam-formly
→ Form controls and supporting components built onngx-formly
sam-material-extension
→ Angular Material related components
generate-docs.js
→ Automates creatingcompodoc
documentation for a specific library and exports it for use in the documentation.
pack-and-publsh.js
→ Automates |npm build
|npm pack
|npm publish
| processupdate-libs-version.js
→ Automates bumping of librariespackage.json
version
angular.json
→ Angular CLI configurationCODEOWNERS
→ Github pull request approversjest.conf.js
→ JEST testing framework configurationkarma.conf.js
→ Karma test runner framework configurationnx.json
→ NX Workspace monorepo configuration and dependency taggingpackage-lock.json
→ Pre-processsed project dependenciespackage.json
→ Project version, dependencies, and scriptstsconfig.json
→ Typescript configurationtslint.json
→ Typescript linter configuration