@sharma-divyansh/eclinicalworks
v1.0.2
Published
eCW Design System — Angular components and CSS tokens
Downloads
453
Maintainers
Readme
Design System
Angular 21 component library with design tokens, Storybook documentation, accessibility testing, and visual regression via Chromatic.
Table of contents
- Getting started
- Development setup
- Commands
- Project structure
- Tech stack
- Contributing
- Deprecation policy
- CI
- Releasing
Getting started
Prerequisites
| Tool | Version | |------|---------| | Node.js | 22+ | | npm | 11+ | | Angular CLI | 21+ |
1 — Install
npm install @sharma-divyansh/eclinicalworksThe library is published to the public npm registry, so no authentication is needed to install it. Angular 21+ packages (@angular/core, @angular/common, @angular/forms, @angular/cdk, …) are peer dependencies — your application must provide them.
Contributing to the design system itself rather than consuming it? See Development setup to clone and run it locally.
2 — Import design tokens
Add the token stylesheet to your application's global styles. Tokens are CSS custom properties on :root — primitives, semantic aliases, and component-scoped variables all in one import.
/* styles.scss */
@use '@sharma-divyansh/eclinicalworks/tokens/index' as *;If Sass can't resolve the package path, add node_modules to your Sass load paths in angular.json:
"stylePreprocessorOptions": {
"includePaths": ["node_modules"]
}Once imported, every token is available globally:
.my-element {
color: var(--color-user-base);
font-size: var(--font-size-14);
border-radius: var(--radius-md);
}3 — Use a component
All components are standalone Angular 21 components. Import them directly into any @Component or NgModule imports array.
import { ButtonComponent } from '@sharma-divyansh/eclinicalworks';
@Component({
selector: 'app-my-feature',
standalone: true,
imports: [ButtonComponent],
template: `<ds-button label="Save" type="primary"></ds-button>`,
})
export class MyFeatureComponent {}Token quick reference
Always use semantic tokens in product code — never primitive tokens directly.
| Category | Token | Value |
|----------|-------|-------|
| Brand blue | --color-user-base | Primary interactive colour |
| Success | --color-status-success | Positive state |
| Error | --color-status-error | Destructive / error state |
| Warning | --color-status-warning | Caution state |
| Text primary | --color-text-primary | Body text on white |
| Text muted | --color-text-muted | Secondary / supporting text |
| Border | --color-border-default | Standard 1px border |
| Font size | --font-size-14 | Base body font (14px) |
| Radius | --radius-md | Standard corner radius |
See Foundations → Color Palette and Foundations → Typography in Storybook for the full reference.
Development setup
To work on the design system itself, clone the repo and install dependencies:
git clone https://github.com/divyansh98sharma/design-system.git
cd design-system
npm install --legacy-peer-deps
--legacy-peer-depsis required because@storybook/test-runnerhas not yet released a version declaring compatibility with Storybook 10.
# Start Storybook dev server → http://localhost:6006
npm run storybook
# Start Angular app → http://localhost:4200
npm startCompodoc generates documentation.json for Storybook's API tables. Run it once before starting Storybook if the file is stale:
npx compodoc -p tsconfig.app.json --watchCommands
Storybook
npm run storybook # dev server
npm run build-storybook # static build
npm run test-storybook # interaction + a11y tests (requires storybook running)Angular
npm start # dev server
npm run build # production build
npm run watch # incremental watch build
npm test # unit testsDesign tokens
npm run tokens:build # compile Style Dictionary tokens
npm run tokens:watch # watch mode
npm run tokens:clean # remove generated filesProject structure
src/ds/ # Design system components
avatar/
button/
checkbox/
chip/
...each component has .component.ts, .component.html, .component.scss, .stories.ts
src/ds/tokens/
_primitives.scss # Raw values (do not use directly)
_primitives.generated.scss # Style Dictionary output
_semantic.scss # Intent-based aliases from primitives
_component.scss # Component-scoped tokens
_typography.scss # Type scale
_deprecated.scss # Deprecated token aliases (removed in next major)
index.scss # Single import entry point
src/ds/docs/ # Storybook documentation pages (MDX)
.storybook/
main.ts # Addons, framework, story globs
preview.ts # Global decorators, sort order, deprecation banner
theme.ts # Custom Storybook UI theme
.github/workflows/
storybook-tests.yml # Interaction, a11y, and Chromatic tests
tokens-sync.yml # Token pipelineTech stack
| Tool | Purpose |
|------|---------|
| Angular 21 | Component framework |
| Storybook 10 | Component docs and development |
| @storybook/addon-a11y | Accessibility panel and axe-core checks |
| @chromatic-com/storybook | Visual regression via Chromatic |
| @storybook/test-runner | Runs play interaction tests in CI via Playwright |
| Vitest | Angular unit tests |
| Style Dictionary | Token pipeline (design → CSS custom properties) |
| Compodoc | API documentation generation |
Contributing
PR workflow
- Branch from main — use the naming convention below
- Build and write stories — Playground + all variants + at least one
playinteraction test - Check accessibility — open every story → Accessibility tab, fix all red violations
- Open a PR — CI runs Chromatic visual regression; review snapshot diffs and accept intended changes
- Merge — after review and Chromatic approval, squash-merge into main
Branch naming
| Type | Pattern | Example |
|------|---------|---------|
| New component | feat/component-name | feat/date-picker |
| Bug fix | fix/description | fix/button-focus-ring |
| Token update | chore/token-name | chore/palette-tokens |
| Documentation | docs/section-name | docs/storybook-sections |
| CI / infra | ci/description | ci/dependabot-auto-merge |
New component checklist
- [ ] Standalone component with
ChangeDetectionStrategy.OnPush - [ ] All
@Input()names match Figma property names exactly - [ ] Component tokens added to
_component.scssunder the component's section - [ ] No hardcoded hex values or pixel values — all from tokens
- [ ]
:hostsetsdisplay: inline-flexordisplay: block; no external margins - [ ]
.stories.tsincludes Playground + all variants + at least oneplaytest - [ ] Storybook Accessibility tab passes with zero violations
- [ ] Keyboard navigation works (Tab, Enter/Space, arrow keys where applicable)
- [ ] Icon-only interactions have
aria-label - [ ] Component exported from the public API
Component file structure
src/ds/my-component/
├── my-component.component.ts # Angular component
├── my-component.component.html # Template
├── my-component.component.scss # Scoped styles (component tokens only)
└── my-component.stories.ts # Storybook storiesToken conventions
/* naming: component — property — variant — state */
--button-primary-bg
--button-primary-bg-hover
--chip-ai-border-colorAlways alias through the semantic layer — never use a primitive value as a component token default.
Deprecation policy
Nothing is removed without a warning period. The lifecycle for any component, token, or API is:
Still works → Minor version (deprecated, warning added) → Major version (removed)There is always at least one minor version between deprecation and removal.
Deprecating a component
/**
* @deprecated since v2.1 — use NewButtonComponent instead.
* Will be removed in v3.0.
*/
@Component({ selector: 'ds-old-button', ... })
export class OldButtonComponent { }Add 'deprecated' to the story's tags array — Storybook shows an amber banner on the canvas:
const meta: Meta<OldButtonComponent> = {
title: 'Atoms/Old Button',
tags: ['autodocs', 'deprecated'],
};Deprecating a token
Move the token from _component.scss to _deprecated.scss, redirecting to the replacement:
/* _deprecated.scss */
:root {
/* @deprecated v2.1 — use --chip-bg-neutral */
--chip-bg-default: var(--chip-bg-neutral);
}Consumers continue to compile and render correctly until the major version removes the alias.
Deprecating a prop
/** @deprecated since v2.2 — use btnStyle */
@Input() set style(value: string) {
this.btnStyle = value as ButtonStyle;
}Currently deprecated
| Type | Name | Since | Replacement | Removes in | |------|------|-------|-------------|------------| | — | No deprecations yet | — | — | — |
CI
Two GitHub Actions jobs run on every push and pull request to main:
| Job | What it does |
|-----|-------------|
| Interaction & Accessibility Tests | Builds Storybook, serves it, runs test-storybook via Playwright |
| Visual Tests (Chromatic) | Sends snapshots to Chromatic for visual diffing |
To enable Chromatic, add a CHROMATIC_PROJECT_TOKEN secret in Settings → Secrets → Actions.
Releasing
The library is published to the public npm registry as
@sharma-divyansh/eclinicalworks.
Anyone can install it with no authentication:
npm install @sharma-divyansh/eclinicalworksPublishing is automated via npm Trusted Publishing (OIDC) — there is no
npm token to manage or rotate. The .github/workflows/publish.yml workflow
runs whenever a GitHub Release is published, builds the library with
ng-packagr, and publishes it (with build provenance) using a short-lived OIDC
credential trusted by npm.
Cutting a release
The one rule: bump the version before tagging. npm publishes the
versionfield frompackage.json(not the git tag), and a version can never be republished — so every release starts with a version bump.
Bump the version on
main:npm version patch --no-git-tag-version # 1.0.1 -> 1.0.2 (use minor / major as needed)Commit and merge it to
main(semver:patch= fixes,minor= new components/features,major= breaking changes).Publish a GitHub Release with a matching tag:
gh release create v1.0.2 --target main --title "v1.0.2" --generate-notes…or via the UI: Releases → Draft new release → choose tag
v1.0.2→ Publish release.Done. The workflow builds and publishes automatically (~1–2 min). Verify:
npm view @sharma-divyansh/eclinicalworks version
Notes
- No local publishing. Do not run
npm publishby hand and do not put an npm token in~/.npmrc— OIDC handles authentication in CI. - Trusted Publisher config lives on npmjs.com (package → Settings →
Trusted Publisher): repository
divyansh98sharma/design-system, workflowpublish.yml. It must match the workflow for OIDC to succeed. - If a release fails, check
gh run list --workflow=publish.yml. The most common cause is forgetting step 1 (the version already exists) — bump and release again.
