├── .babelrc
├── .devcontainer
└── devcontainer.json
├── .editorconfig
├── .github
├── ISSUE_TEMPLATE
│ ├── bug-report.yaml
│ └── feature-request.yaml
├── dependabot.yml
└── workflows
│ ├── codeql.yml
│ └── deploy-storybook.yml
├── .gitignore
├── .npmrc
├── .storybook
├── main.js
├── manager-head.html
├── manager.js
├── preview-body.html
├── preview-head.html
├── preview.js
├── theme.js
├── tsconfig.json
├── typings.d.ts
└── utils.ts
├── .vscode
├── extensions.json
├── launch.json
└── tasks.json
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── angular.json
├── package-lock.json
├── package.json
├── projects
└── showcase
│ ├── karma.conf.js
│ ├── src
│ ├── app
│ │ ├── app.component.html
│ │ ├── app.component.scss
│ │ ├── app.component.ts
│ │ ├── app.module.ts
│ │ ├── theme.service.spec.ts
│ │ └── theme.service.ts
│ ├── assets
│ │ └── .gitkeep
│ ├── environments
│ │ ├── environment.prod.ts
│ │ └── environment.ts
│ ├── favicon.ico
│ ├── index.html
│ ├── main.ts
│ ├── material-theme.scss
│ ├── polyfills.ts
│ ├── styles.scss
│ └── test.ts
│ ├── tsconfig.app.json
│ └── tsconfig.spec.json
├── public
└── favicon.ico
├── stories
├── assets
│ ├── arrow-next.svg
│ ├── arrow-next_disabled.svg
│ ├── arrow-previous.svg
│ ├── arrow-previous_disabled.svg
│ ├── code-brackets.svg
│ ├── colors.svg
│ ├── comments.svg
│ ├── diamond.svg
│ ├── direction.svg
│ ├── flow.svg
│ ├── image.png
│ ├── logo.png
│ ├── open_in_new.png
│ ├── plugin.svg
│ ├── repo.svg
│ └── stackalt.svg
├── components
│ ├── badge
│ │ └── badge.argtype.ts
│ ├── form-field
│ │ ├── form-field-argtype.ts
│ │ ├── form-field.mdx
│ │ └── form-field.stories.ts
│ ├── icon.mdx
│ ├── icon.stories.ts
│ ├── introduction.mdx
│ ├── progress-bar
│ │ ├── progress-bar.argtype.ts
│ │ ├── progress-bar.mdx
│ │ └── progress-bar.stories.ts
│ ├── progress-spinner
│ │ ├── progress-spinner.argtype.ts
│ │ ├── progress-spinner.mdx
│ │ └── progress-spinner.stories.ts
│ └── table
│ │ ├── table.argtype.ts
│ │ ├── table.mdx
│ │ └── table.stories.ts
├── introduction.mdx
├── theming-preview.jsx
├── theming-settings.jsx
├── theming.mdx
└── usecases
│ ├── authentication
│ └── change-password
│ │ ├── change-password.component.ts
│ │ └── change-password.stories.ts
│ ├── dialog
│ ├── confirmation-dialog.component.ts
│ └── confirmation-dialog.stories.ts
│ ├── introduction.mdx
│ ├── navigation
│ ├── collapsible-vertical-navigation
│ │ ├── collapsible-vertical-navigation.component.ts
│ │ └── collapsible-vertical-navigation.stories.ts
│ ├── fab-bottom-navigation
│ │ ├── fab-bottom-navigation.component.ts
│ │ └── fab-bottom-navigation.stories.ts
│ └── fab-icon-menu
│ │ ├── fab-icon-menu.component.ts
│ │ └── fab-icon-menu.stories.ts
│ ├── progress-indicators
│ └── toolbar-loader.stories.ts
│ └── settings
│ ├── generic-settings.component.ts
│ ├── generic-settings.stories.ts
│ ├── wifi-settings.component.ts
│ └── wifi-settings.stories.ts
└── tsconfig.json
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["@babel/preset-react", "@babel/preset-env"]
3 | }
4 |
--------------------------------------------------------------------------------
/.devcontainer/devcontainer.json:
--------------------------------------------------------------------------------
1 | {
2 | "image": "mcr.microsoft.com/devcontainers/universal:2",
3 | "features": {
4 | "ghcr.io/devcontainers/features/node:1": {},
5 | "ghcr.io/devcontainers-contrib/features/angular-cli:1": {}
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # Editor configuration, see https://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 2
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 | [*.ts]
12 | quote_type = single
13 |
14 | [*.md]
15 | max_line_length = off
16 | trim_trailing_whitespace = false
17 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug-report.yaml:
--------------------------------------------------------------------------------
1 | name: Bug Report
2 | description: Report a bug in Angular Material Storybook project
3 | labels:
4 | - bug
5 |
6 | body:
7 | - type: dropdown
8 | id: is-regression
9 | attributes:
10 | label: Is this a regression?
11 | options:
12 | - 'Yes'
13 | - 'No'
14 | validations:
15 | required: true
16 |
17 | - type: textarea
18 | id: description
19 | attributes:
20 | label: Description
21 | validations:
22 | required: true
23 |
24 | - type: input
25 | id: reproduction
26 | attributes:
27 | label: Please provide a link to a minimal reproduction of the bug
28 |
29 | - type: textarea
30 | id: exception-or-error
31 | attributes:
32 | label: Please provide the exception or error you saw
33 | render: true
34 |
35 | - type: textarea
36 | id: environment
37 | attributes:
38 | label: Please provide the environment you discovered this bug in
39 | render: true
40 |
41 | - type: textarea
42 | id: other
43 | attributes:
44 | label: Anything else?
45 |
46 | - type: dropdown
47 | id: contribute
48 | attributes:
49 | label: Do you want to create a pull request?
50 | options:
51 | - 'Yes'
52 | - 'No'
53 | validations:
54 | required: true
55 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature-request.yaml:
--------------------------------------------------------------------------------
1 | name: 'Feature Request'
2 | description: Suggest a feature for Angular Material Storybook project
3 |
4 | body:
5 |
6 | - type: textarea
7 | id: description
8 | attributes:
9 | label: Description
10 | validations:
11 | required: true
12 |
13 | - type: textarea
14 | id: proposed-solution
15 | attributes:
16 | label: Proposed solution
17 | validations:
18 | required: true
19 |
20 | - type: textarea
21 | id: alternatives-considered
22 | attributes:
23 | label: Alternatives considered
24 |
25 | - type: dropdown
26 | id: contribute
27 | attributes:
28 | label: Do you want to create a pull request?
29 | options:
30 | - 'Yes'
31 | - 'No'
32 | validations:
33 | required: true
34 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: npm
4 | directory: "/" # Location of package manifests
5 | schedule:
6 | interval: "weekly"
7 | open-pull-requests-limit: 10
8 | - package-ecosystem: github-actions
9 | directory: "/"
10 | schedule:
11 | interval: weekly
12 | open-pull-requests-limit: 10
13 |
--------------------------------------------------------------------------------
/.github/workflows/codeql.yml:
--------------------------------------------------------------------------------
1 | # For most projects, this workflow file will not need changing; you simply need
2 | # to commit it to your repository.
3 | #
4 | # You may wish to alter this file to override the set of languages analyzed,
5 | # or to provide custom queries or build logic.
6 | #
7 | # ******** NOTE ********
8 | # We have attempted to detect the languages in your repository. Please check
9 | # the `language` matrix defined below to confirm you have the correct set of
10 | # supported CodeQL languages.
11 | #
12 | name: "CodeQL"
13 |
14 | on:
15 | push:
16 | branches: [ "main" ]
17 | pull_request:
18 | # The branches below must be a subset of the branches above
19 | branches: [ "main" ]
20 | schedule:
21 | - cron: '27 12 * * 0'
22 |
23 | jobs:
24 | analyze:
25 | name: Analyze
26 | runs-on: ubuntu-latest
27 | permissions:
28 | actions: read
29 | contents: read
30 | security-events: write
31 |
32 | strategy:
33 | fail-fast: false
34 | matrix:
35 | language: [ 'javascript' ]
36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
37 | # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
38 |
39 | steps:
40 | - name: Checkout repository
41 | uses: actions/checkout@v3
42 |
43 | # Initializes the CodeQL tools for scanning.
44 | - name: Initialize CodeQL
45 | uses: github/codeql-action/init@v2
46 | with:
47 | languages: ${{ matrix.language }}
48 | # If you wish to specify custom queries, you can do so here or in a config file.
49 | # By default, queries listed here will override any specified in a config file.
50 | # Prefix the list here with "+" to use these queries and those in the config file.
51 |
52 | # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
53 | # queries: security-extended,security-and-quality
54 |
55 |
56 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
57 | # If this step fails, then you should remove it and run the build manually (see below)
58 | - name: Autobuild
59 | uses: github/codeql-action/autobuild@v2
60 |
61 | # ℹ️ Command-line programs to run using the OS shell.
62 | # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
63 |
64 | # If the Autobuild fails above, remove it and uncomment the following three lines.
65 | # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
66 |
67 | # - run: |
68 | # echo "Run, Build Application using script"
69 | # ./location_of_script_within_repo/buildscript.sh
70 |
71 | - name: Perform CodeQL Analysis
72 | uses: github/codeql-action/analyze@v2
73 | with:
74 | category: "/language:${{matrix.language}}"
75 |
--------------------------------------------------------------------------------
/.github/workflows/deploy-storybook.yml:
--------------------------------------------------------------------------------
1 | name: Publish Storybook
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | workflow_dispatch:
8 |
9 | permissions:
10 | contents: read
11 | pages: write
12 | id-token: write
13 |
14 | jobs:
15 | build:
16 | runs-on: ubuntu-latest
17 | steps:
18 | - uses: actions/checkout@v3
19 | - uses: actions/setup-node@v3
20 | with:
21 | node-version: "16"
22 | - name: Build Storybook
23 | run: |
24 | npm install
25 | npx ng run showcase:build-storybook
26 | - name: Upload artifact
27 | uses: actions/upload-pages-artifact@v1
28 | with:
29 | path: ./storybook-static
30 | # Deployment job
31 | deploy:
32 | environment:
33 | name: github-pages
34 | url: ${{ steps.deployment.outputs.page_url }}
35 | runs-on: ubuntu-latest
36 | needs: build
37 | steps:
38 | - name: Deploy to GitHub Pages
39 | id: deployment
40 | uses: actions/deploy-pages@v1
41 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # Compiled output
4 | /dist
5 | /tmp
6 | /out-tsc
7 | /bazel-out
8 |
9 | # Node
10 | /node_modules
11 | npm-debug.log
12 | yarn-error.log
13 |
14 | # IDEs and editors
15 | .idea/
16 | .project
17 | .classpath
18 | .c9/
19 | *.launch
20 | .settings/
21 | *.sublime-workspace
22 |
23 | # Visual Studio Code
24 | .vscode/*
25 | !.vscode/settings.json
26 | !.vscode/tasks.json
27 | !.vscode/launch.json
28 | !.vscode/extensions.json
29 | .history/*
30 |
31 | # Miscellaneous
32 | /.angular/cache
33 | .sass-cache/
34 | /connect.lock
35 | /coverage
36 | /libpeerconnection.log
37 | testem.log
38 | /typings
39 |
40 | # System files
41 | .DS_Store
42 | Thumbs.db
43 |
44 | # Storybook
45 | documentation.json
46 | storybook-static
47 | build-storybook.log
48 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | legacy-peer-deps=true
2 |
--------------------------------------------------------------------------------
/.storybook/main.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | "stories": ["../stories/**/*.mdx", "../stories/**/*.stories.@(js|jsx|ts|tsx)"],
3 | "addons": ["@storybook/addon-links", "@storybook/addon-essentials", "@storybook/addon-interactions", "storybook-addon-rtl", "storybook-addon-pseudo-states", "@storybook/addon-a11y"],
4 | "framework": {
5 | name: "@storybook/angular",
6 | options: {}
7 | },
8 | "staticDirs": ['../public', {
9 | from: "../stories/assets",
10 | to: "/static/assets"
11 | }],
12 | "features": {
13 | "interactionsDebugger": true
14 | },
15 | "core": {},
16 | // "docs": {
17 | // // You can change this value to `false` to remove all automaitcally generated Docs Pages
18 | // // We recommend instead to use them, and remove the "Overview" pages.
19 | // // But there might be some features/content missing, so you be the judge.
20 | // // For more information take a look here: https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#docs-page
21 | // "docsPage": "automatic",
22 | // },
23 | docs: {
24 | autodocs: true
25 | }
26 | };
27 |
--------------------------------------------------------------------------------
/.storybook/manager-head.html:
--------------------------------------------------------------------------------
1 |
2 |
15 |
--------------------------------------------------------------------------------
/.storybook/manager.js:
--------------------------------------------------------------------------------
1 | import { addons } from "@storybook/manager-api";
2 | import theme from "./theme";
3 |
4 | addons.setConfig({
5 | theme: theme,
6 | });
7 |
--------------------------------------------------------------------------------
/.storybook/preview-body.html:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/.storybook/preview-head.html:
--------------------------------------------------------------------------------
1 |
2 |
209 |
--------------------------------------------------------------------------------
/.storybook/preview.js:
--------------------------------------------------------------------------------
1 | import {setCompodocJson} from "@storybook/addon-docs/angular";
2 | import docJson from "../documentation.json";
3 | import { initializeRTL } from 'storybook-addon-rtl';
4 | import { componentWrapperDecorator } from '@storybook/angular';
5 |
6 | setCompodocJson(docJson);
7 | initializeRTL();
8 |
9 | export const parameters = {
10 | actions: {argTypesRegex: "^on[A-Z].*"},
11 | controls: {
12 | matchers: {
13 | color: /(background|color)$/i,
14 | date: /Date$/,
15 | },
16 | },
17 | viewMode: 'story',
18 | docs: {inlineStories: true},
19 | direction: 'ltr',
20 | layout: 'fullscreen',
21 | backgrounds: { disable: true }
22 | }
23 |
24 | export const decorators = [
25 | componentWrapperDecorator((story) => `
${story}
`),
26 | ];
27 |
--------------------------------------------------------------------------------
/.storybook/theme.js:
--------------------------------------------------------------------------------
1 | import { create } from '@storybook/theming';
2 | import CoverImage from '../stories/assets/logo.png';
3 |
4 | export default create({
5 | base: 'light',
6 | brandTitle: 'Angular Material Storybook',
7 | brandUrl: 'https://github.com/geromegrignon/angular-material-storybook',
8 | brandImage: CoverImage,
9 | brandTarget: '_self',
10 |
11 | barSelectedColor: 'rgba(0,68,85,1)',
12 | colorSecondary: 'rgba(0,68,85,1)',
13 | });
14 |
--------------------------------------------------------------------------------
/.storybook/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "allowSyntheticDefaultImports": true,
5 | "types": [
6 | "node",
7 | "jest",
8 | "testing-library__jest-dom",
9 | ],
10 | },
11 | "exclude": [
12 | "../src/test.ts",
13 | "../src/**/*.spec.ts",
14 | "../projects/**/*.spec.ts"
15 | ],
16 | "include": [
17 | "../src/**/*",
18 | "../projects/**/*",
19 | "../stories/**/*"
20 | ],
21 | "files": [
22 | "./typings.d.ts"
23 | ]
24 | }
25 |
--------------------------------------------------------------------------------
/.storybook/typings.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.md' {
2 | const content: string;
3 | export default content;
4 | }
5 |
--------------------------------------------------------------------------------
/.storybook/utils.ts:
--------------------------------------------------------------------------------
1 | export const defaultUsecasesParameters = {
2 | options: {
3 | showPanel: false
4 | },
5 | previewTabs: {
6 | 'storybook/docs/panel': {
7 | hidden: true
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846
3 | "recommendations": ["angular.ng-template"]
4 | }
5 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
3 | "version": "0.2.0",
4 | "configurations": [
5 | {
6 | "name": "ng serve",
7 | "type": "pwa-chrome",
8 | "request": "launch",
9 | "preLaunchTask": "npm: start",
10 | "url": "http://localhost:4200/"
11 | },
12 | {
13 | "name": "ng test",
14 | "type": "chrome",
15 | "request": "launch",
16 | "preLaunchTask": "npm: test",
17 | "url": "http://localhost:9876/debug.html"
18 | }
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | // For more information, visit: https://go.microsoft.com/fwlink/?LinkId=733558
3 | "version": "2.0.0",
4 | "tasks": [
5 | {
6 | "type": "npm",
7 | "script": "start",
8 | "isBackground": true,
9 | "problemMatcher": {
10 | "owner": "typescript",
11 | "pattern": "$tsc",
12 | "background": {
13 | "activeOnStart": true,
14 | "beginsPattern": {
15 | "regexp": "(.*?)"
16 | },
17 | "endsPattern": {
18 | "regexp": "bundle generation complete"
19 | }
20 | }
21 | }
22 | },
23 | {
24 | "type": "npm",
25 | "script": "test",
26 | "isBackground": true,
27 | "problemMatcher": {
28 | "owner": "typescript",
29 | "pattern": "$tsc",
30 | "background": {
31 | "activeOnStart": true,
32 | "beginsPattern": {
33 | "regexp": "(.*?)"
34 | },
35 | "endsPattern": {
36 | "regexp": "bundle generation complete"
37 | }
38 | }
39 | }
40 | }
41 | ]
42 | }
43 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | We as members, contributors, and leaders pledge to make participation in our
6 | community a harassment-free experience for everyone, regardless of age, body
7 | size, visible or invisible disability, ethnicity, sex characteristics, gender
8 | identity and expression, level of experience, education, socio-economic status,
9 | nationality, personal appearance, race, religion, or sexual identity
10 | and orientation.
11 |
12 | We pledge to act and interact in ways that contribute to an open, welcoming,
13 | diverse, inclusive, and healthy community.
14 |
15 | ## Our Standards
16 |
17 | Examples of behavior that contributes to a positive environment for our
18 | community include:
19 |
20 | * Demonstrating empathy and kindness toward other people
21 | * Being respectful of differing opinions, viewpoints, and experiences
22 | * Giving and gracefully accepting constructive feedback
23 | * Accepting responsibility and apologizing to those affected by our mistakes,
24 | and learning from the experience
25 | * Focusing on what is best not just for us as individuals, but for the
26 | overall community
27 |
28 | Examples of unacceptable behavior include:
29 |
30 | * The use of sexualized language or imagery, and sexual attention or
31 | advances of any kind
32 | * Trolling, insulting or derogatory comments, and personal or political attacks
33 | * Public or private harassment
34 | * Publishing others' private information, such as a physical or email
35 | address, without their explicit permission
36 | * Other conduct which could reasonably be considered inappropriate in a
37 | professional setting
38 |
39 | ## Enforcement Responsibilities
40 |
41 | Community leaders are responsible for clarifying and enforcing our standards of
42 | acceptable behavior and will take appropriate and fair corrective action in
43 | response to any behavior that they deem inappropriate, threatening, offensive,
44 | or harmful.
45 |
46 | Community leaders have the right and responsibility to remove, edit, or reject
47 | comments, commits, code, wiki edits, issues, and other contributions that are
48 | not aligned to this Code of Conduct, and will communicate reasons for moderation
49 | decisions when appropriate.
50 |
51 | ## Scope
52 |
53 | This Code of Conduct applies within all community spaces, and also applies when
54 | an individual is officially representing the community in public spaces.
55 | Examples of representing our community include using an official e-mail address,
56 | posting via an official social media account, or acting as an appointed
57 | representative at an online or offline event.
58 |
59 | ## Enforcement
60 |
61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
62 | reported to the community leaders responsible for enforcement at
63 | gerome.grignon.lp2@gmail.com.
64 | All complaints will be reviewed and investigated promptly and fairly.
65 |
66 | All community leaders are obligated to respect the privacy and security of the
67 | reporter of any incident.
68 |
69 | ## Enforcement Guidelines
70 |
71 | Community leaders will follow these Community Impact Guidelines in determining
72 | the consequences for any action they deem in violation of this Code of Conduct:
73 |
74 | ### 1. Correction
75 |
76 | **Community Impact**: Use of inappropriate language or other behavior deemed
77 | unprofessional or unwelcome in the community.
78 |
79 | **Consequence**: A private, written warning from community leaders, providing
80 | clarity around the nature of the violation and an explanation of why the
81 | behavior was inappropriate. A public apology may be requested.
82 |
83 | ### 2. Warning
84 |
85 | **Community Impact**: A violation through a single incident or series
86 | of actions.
87 |
88 | **Consequence**: A warning with consequences for continued behavior. No
89 | interaction with the people involved, including unsolicited interaction with
90 | those enforcing the Code of Conduct, for a specified period of time. This
91 | includes avoiding interactions in community spaces as well as external channels
92 | like social media. Violating these terms may lead to a temporary or
93 | permanent ban.
94 |
95 | ### 3. Temporary Ban
96 |
97 | **Community Impact**: A serious violation of community standards, including
98 | sustained inappropriate behavior.
99 |
100 | **Consequence**: A temporary ban from any sort of interaction or public
101 | communication with the community for a specified period of time. No public or
102 | private interaction with the people involved, including unsolicited interaction
103 | with those enforcing the Code of Conduct, is allowed during this period.
104 | Violating these terms may lead to a permanent ban.
105 |
106 | ### 4. Permanent Ban
107 |
108 | **Community Impact**: Demonstrating a pattern of violation of community
109 | standards, including sustained inappropriate behavior, harassment of an
110 | individual, or aggression toward or disparagement of classes of individuals.
111 |
112 | **Consequence**: A permanent ban from any sort of public interaction within
113 | the community.
114 |
115 | ## Attribution
116 |
117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage],
118 | version 2.0, available at
119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
120 |
121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct
122 | enforcement ladder](https://github.com/mozilla/diversity).
123 |
124 | [homepage]: https://www.contributor-covenant.org
125 |
126 | For answers to common questions about this code of conduct, see the FAQ at
127 | https://www.contributor-covenant.org/faq. Translations are available at
128 | https://www.contributor-covenant.org/translations.
129 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | Welcome on this project!
4 | These guidelines will help you to contribute.
5 |
6 |
7 | ## Contribution opportunities
8 |
9 | ### Add components examples
10 |
11 | The components part of the project showcases sample examples of Angular Material components in isolation.
12 | Some components or valuables examples might be missing as you are reading this.
13 |
14 | #### Add a missing component
15 |
16 | Create a folder matching the component name and using kebab-case format in the `stories/components` folder.
17 | For example a foldernamed `radio-button` for the Radio button component.
18 |
19 | Create a `.argtype.ts` file in this new folder.
20 | It'll define argtypes for the component for the ArgTable and Controls features.
21 |
22 | Create a `.stories.mdx` file in the same folder.
23 | It'll provide an overview of the component :
24 | - quick introduction
25 | - how to add it in an Angular application
26 | - link towards the official documentation
27 | - showcase stories
28 |
29 | Create a `.stories.ts` for stories.
30 |
31 | #### Add stories
32 |
33 |
34 | ### Add component use cases
35 |
36 | Showcase Angular Material working together in a real world situation.
37 | The limit is the sky but
38 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Gerome Grignon
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Angular Material Storybook
2 |
3 | This project is a collection of Angular Components showcased in isolation and in action with Storybook.
4 |
5 | ## Run the project locally
6 |
7 | Install dependancies
8 | ```
9 | npm install
10 | ```
11 |
12 | Run Storybook
13 | ```
14 | ng run showcase:storybook
15 | ```
16 |
17 | ## Contribute
18 |
19 | > Guidances in progress
20 |
21 | You can contribute by adding **Components** and **Usecases**
22 |
23 | ## Known bugs
24 |
25 | #### Canvas
26 | > error triggered by using ``
27 | [GitHub issue](https://github.com/storybookjs/storybook/issues/17269)
28 |
--------------------------------------------------------------------------------
/angular.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3 | "version": 1,
4 | "newProjectRoot": "projects",
5 | "projects": {
6 | "showcase": {
7 | "projectType": "application",
8 | "schematics": {
9 | "@schematics/angular:component": {
10 | "style": "scss"
11 | }
12 | },
13 | "root": "projects/showcase",
14 | "sourceRoot": "projects/showcase/src",
15 | "prefix": "app",
16 | "architect": {
17 | "build": {
18 | "builder": "@angular-devkit/build-angular:browser",
19 | "options": {
20 | "outputPath": "dist/showcase",
21 | "index": "projects/showcase/src/index.html",
22 | "main": "projects/showcase/src/main.ts",
23 | "polyfills": "projects/showcase/src/polyfills.ts",
24 | "tsConfig": "projects/showcase/tsconfig.app.json",
25 | "inlineStyleLanguage": "scss",
26 | "assets": [
27 | "projects/showcase/src/favicon.ico",
28 | "projects/showcase/src/assets"
29 | ],
30 | "styles": [
31 | "projects/showcase/src/styles.scss"
32 | ],
33 | "scripts": [],
34 | "allowedCommonJsDependencies": [
35 | "tinycolor2"
36 | ]
37 | },
38 | "configurations": {
39 | "production": {
40 | "budgets": [
41 | {
42 | "type": "initial",
43 | "maximumWarning": "500kb",
44 | "maximumError": "1mb"
45 | },
46 | {
47 | "type": "anyComponentStyle",
48 | "maximumWarning": "2kb",
49 | "maximumError": "4kb"
50 | }
51 | ],
52 | "fileReplacements": [
53 | {
54 | "replace": "projects/showcase/src/environments/environment.ts",
55 | "with": "projects/showcase/src/environments/environment.prod.ts"
56 | }
57 | ],
58 | "outputHashing": "all"
59 | },
60 | "development": {
61 | "buildOptimizer": false,
62 | "optimization": false,
63 | "vendorChunk": true,
64 | "extractLicenses": false,
65 | "sourceMap": true,
66 | "namedChunks": true
67 | }
68 | },
69 | "defaultConfiguration": "production"
70 | },
71 | "serve": {
72 | "builder": "@angular-devkit/build-angular:dev-server",
73 | "configurations": {
74 | "production": {
75 | "browserTarget": "showcase:build:production"
76 | },
77 | "development": {
78 | "browserTarget": "showcase:build:development"
79 | }
80 | },
81 | "defaultConfiguration": "development"
82 | },
83 | "extract-i18n": {
84 | "builder": "@angular-devkit/build-angular:extract-i18n",
85 | "options": {
86 | "browserTarget": "showcase:build"
87 | }
88 | },
89 | "test": {
90 | "builder": "@angular-devkit/build-angular:karma",
91 | "options": {
92 | "main": "projects/showcase/src/test.ts",
93 | "polyfills": "projects/showcase/src/polyfills.ts",
94 | "tsConfig": "projects/showcase/tsconfig.spec.json",
95 | "karmaConfig": "projects/showcase/karma.conf.js",
96 | "inlineStyleLanguage": "scss",
97 | "assets": [
98 | "projects/showcase/src/assets"
99 | ],
100 | "styles": [
101 | "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
102 | "projects/showcase/src/styles.scss"
103 | ],
104 | "scripts": []
105 | }
106 | },
107 | "storybook": {
108 | "builder": "@storybook/angular:start-storybook",
109 | "options": {
110 | "browserTarget": "showcase:build",
111 | "port": 6006
112 | }
113 | },
114 | "build-storybook": {
115 | "builder": "@storybook/angular:build-storybook",
116 | "options": {
117 | "browserTarget": "showcase:build"
118 | }
119 | }
120 | }
121 | }
122 | },
123 | "cli": {
124 | "analytics": "5e49e647-b64f-4051-b56c-774f5b25b1b9"
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-material-storybook",
3 | "version": "0.0.0",
4 | "scripts": {
5 | "ng": "ng",
6 | "start": "ng serve",
7 | "build": "ng build",
8 | "watch": "ng build --watch --configuration development",
9 | "test": "ng test",
10 | "docs:json": "compodoc -p ./tsconfig.json -e json -d .",
11 | "storybook": "npm run docs:json && storybook dev -p 6006",
12 | "build-storybook": "npm run docs:json && storybook build",
13 | "chromatic": "npx chromatic --project-token=2475ac9ed750"
14 | },
15 | "private": true,
16 | "dependencies": {
17 | "@angular/animations": "^15.2.0",
18 | "@angular/cdk": "^15.2.0",
19 | "@angular/common": "^15.2.0",
20 | "@angular/compiler": "^15.2.0",
21 | "@angular/core": "^15.2.0",
22 | "@angular/forms": "^15.2.0",
23 | "@angular/material": "^15.2.0",
24 | "@angular/platform-browser": "^15.2.0",
25 | "@angular/platform-browser-dynamic": "^15.2.0",
26 | "@angular/router": "^15.2.0",
27 | "rxjs": "~7.5.7",
28 | "tinycolor2": "^1.4.2",
29 | "tslib": "^2.4.1",
30 | "zone.js": "~0.12.0"
31 | },
32 | "devDependencies": {
33 | "@angular-devkit/build-angular": "^15.2.0",
34 | "@angular/cli": "~15.2.0",
35 | "@angular/compiler-cli": "^15.2.0",
36 | "@babel/core": "^7.21.0",
37 | "@babel/plugin-syntax-jsx": "^7.18.6",
38 | "@babel/preset-env": "^7.20.2",
39 | "@babel/preset-react": "^7.18.6",
40 | "@compodoc/compodoc": "^1.1.19",
41 | "@storybook/addon-a11y": "^7.0.0-beta.55",
42 | "@storybook/addon-actions": "^7.0.0-beta.55",
43 | "@storybook/addon-docs": "^7.0.0-beta.55",
44 | "@storybook/addon-essentials": "^7.0.0-beta.55",
45 | "@storybook/addon-interactions": "^7.0.0-beta.55",
46 | "@storybook/addon-links": "^7.0.0-beta.55",
47 | "@storybook/angular": "^7.0.0-beta.55",
48 | "@storybook/jest": "^0.0.11-next.0",
49 | "@storybook/manager-api": "^7.0.0-beta.55",
50 | "@storybook/testing-library": "^0.0.14-next.1",
51 | "@storybook/theming": "^7.0.0-beta.55",
52 | "@types/jasmine": "~4.3.0",
53 | "@types/tinycolor2": "^1.4.3",
54 | "babel-loader": "^9.1.0",
55 | "chromatic": "^6.14.0",
56 | "jasmine-core": "~4.5.0",
57 | "karma": "~6.4.1",
58 | "karma-chrome-launcher": "~3.1.0",
59 | "karma-coverage": "~2.2.0",
60 | "karma-jasmine": "~5.1.0",
61 | "karma-jasmine-html-reporter": "~2.0.0",
62 | "react": "^18.2.0",
63 | "react-dom": "^18.2.0",
64 | "storybook": "^7.0.0-beta.55",
65 | "storybook-addon-pseudo-states": "^2.0.0-next.0",
66 | "storybook-addon-rtl": "^0.4.4",
67 | "typescript": "~4.8.4"
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/projects/showcase/karma.conf.js:
--------------------------------------------------------------------------------
1 | // Karma configuration file, see link for more information
2 | // https://karma-runner.github.io/1.0/config/configuration-file.html
3 |
4 | module.exports = function (config) {
5 | config.set({
6 | basePath: '',
7 | frameworks: ['jasmine', '@angular-devkit/build-angular'],
8 | plugins: [
9 | require('karma-jasmine'),
10 | require('karma-chrome-launcher'),
11 | require('karma-jasmine-html-reporter'),
12 | require('karma-coverage'),
13 | require('@angular-devkit/build-angular/plugins/karma')
14 | ],
15 | client: {
16 | jasmine: {
17 | // you can add configuration options for Jasmine here
18 | // the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
19 | // for example, you can disable the random execution with `random: false`
20 | // or set a specific seed with `seed: 4321`
21 | },
22 | clearContext: false // leave Jasmine Spec Runner output visible in browser
23 | },
24 | jasmineHtmlReporter: {
25 | suppressAll: true // removes the duplicated traces
26 | },
27 | coverageReporter: {
28 | dir: require('path').join(__dirname, '../../coverage/showcase'),
29 | subdir: '.',
30 | reporters: [
31 | { type: 'html' },
32 | { type: 'text-summary' }
33 | ]
34 | },
35 | reporters: ['progress', 'kjhtml'],
36 | port: 9876,
37 | colors: true,
38 | logLevel: config.LOG_INFO,
39 | autoWatch: true,
40 | browsers: ['Chrome'],
41 | singleRun: false,
42 | restartOnFileChange: true
43 | });
44 | };
45 |
--------------------------------------------------------------------------------
/projects/showcase/src/app/app.component.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular-sanctuary/angular-material-storybook/bca464f8403b1bd0d85560c6ed8e93c547931a0b/projects/showcase/src/app/app.component.html
--------------------------------------------------------------------------------
/projects/showcase/src/app/app.component.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular-sanctuary/angular-material-storybook/bca464f8403b1bd0d85560c6ed8e93c547931a0b/projects/showcase/src/app/app.component.scss
--------------------------------------------------------------------------------
/projects/showcase/src/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import {ThemeService} from "./theme.service";
3 |
4 | @Component({
5 | selector: 'app-root',
6 | templateUrl: './app.component.html',
7 | styleUrls: ['./app.component.scss']
8 | })
9 | export class AppComponent {
10 | constructor(private readonly themeService: ThemeService) {
11 | themeService.saveIndigoPreset();
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/projects/showcase/src/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { BrowserModule } from '@angular/platform-browser';
3 |
4 | import { AppComponent } from './app.component';
5 | import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
6 |
7 | @NgModule({
8 | declarations: [
9 | AppComponent
10 | ],
11 | imports: [
12 | BrowserModule,
13 | BrowserAnimationsModule
14 | ],
15 | providers: [],
16 | bootstrap: [AppComponent]
17 | })
18 | export class AppModule { }
19 |
--------------------------------------------------------------------------------
/projects/showcase/src/app/theme.service.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed } from '@angular/core/testing';
2 |
3 | import { ThemeService } from './theme.service';
4 |
5 | describe('ThemeService', () => {
6 | let service: ThemeService;
7 |
8 | beforeEach(() => {
9 | TestBed.configureTestingModule({});
10 | service = TestBed.inject(ThemeService);
11 | });
12 |
13 | it('should be created', () => {
14 | expect(service).toBeTruthy();
15 | });
16 | });
17 |
--------------------------------------------------------------------------------
/projects/showcase/src/app/theme.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import * as tinycolor from "tinycolor2";
3 |
4 | @Injectable({
5 | providedIn: 'root'
6 | })
7 | export class ThemeService {
8 |
9 | constructor() { }
10 |
11 | saveLightPrimaryColor = (color: string) => {
12 | const primaryColorPalette = this.computeColors(color);
13 | this.updateTheme(primaryColorPalette, 'primary', 'light');
14 | }
15 |
16 | saveLightAccentColor(color: string) {
17 | const accentColorPalette = this.computeColors(color);
18 | this.updateTheme(accentColorPalette, 'accent', 'light');
19 | }
20 |
21 | saveLightWarnColor(color: string) {
22 | const warnColorPalette = this.computeColors(color);
23 | this.updateTheme(warnColorPalette, 'warn', 'light');
24 | }
25 |
26 | saveDarkPrimaryColor(color: string) {
27 | const primaryColorPalette = this.computeColors(color);
28 | this.updateTheme(primaryColorPalette, 'primary', 'dark');
29 | }
30 |
31 | saveDarkAccentColor(color: string) {
32 | const accentColorPalette = this.computeColors(color);
33 | this.updateTheme(accentColorPalette, 'accent', 'dark');
34 | }
35 |
36 | saveDarktWarnColor(color: string) {
37 | const warnColorPalette = this.computeColors(color);
38 | this.updateTheme(warnColorPalette, 'warn', 'dark');
39 | }
40 |
41 | saveIndigoPreset() {
42 | this.saveLightPrimaryColor('#3f51b5');
43 | this.saveLightAccentColor('#ff4081');
44 | this.saveLightWarnColor('#f44336');
45 | }
46 |
47 | saveDeepPurplePreset() {
48 | this.saveLightPrimaryColor('#673ab7');
49 | this.saveLightAccentColor('#ffd740');
50 | this.saveLightWarnColor('#f44336');
51 | }
52 |
53 | savePinkPreset() {
54 | this.saveLightPrimaryColor('#e91e63');
55 | this.saveLightAccentColor('#607d8b');
56 | this.saveLightWarnColor('#f44336');
57 | }
58 |
59 | savePurplePreset() {
60 | this.saveLightPrimaryColor('#9c27b0');
61 | this.saveLightAccentColor('#69f0ae');
62 | this.saveLightWarnColor('#f44336');
63 | }
64 |
65 | toggleDarkTheme() {
66 | document.documentElement.classList.toggle('dark-theme');
67 | }
68 |
69 | updateTheme(colors: any[], theme: any, mode: any) {
70 | colors.forEach(color => {
71 | document.body.style.setProperty(
72 | `--${mode}-theme-${theme}-${color.name}`,
73 | color.hex
74 | );
75 | document.body.style.setProperty(
76 | `--${mode}-theme-${theme}-contrast-${color.name}`,
77 | color.darkContrast ? 'black' : 'white'
78 | );
79 | });
80 | }
81 |
82 | computeColors(hex: any) {
83 | return [
84 | this.getColorObject(tinycolor(hex).lighten(52), '50'),
85 | this.getColorObject(tinycolor(hex).lighten(37), '100'),
86 | this.getColorObject(tinycolor(hex).lighten(26), '200'),
87 | this.getColorObject(tinycolor(hex).lighten(12), '300'),
88 | this.getColorObject(tinycolor(hex).lighten(6), '400'),
89 | this.getColorObject(tinycolor(hex), '500'),
90 | this.getColorObject(tinycolor(hex).darken(6), '600'),
91 | this.getColorObject(tinycolor(hex).darken(12), '700'),
92 | this.getColorObject(tinycolor(hex).darken(18), '800'),
93 | this.getColorObject(tinycolor(hex).darken(24), '900'),
94 | this.getColorObject(tinycolor(hex).lighten(50).saturate(30), 'A100'),
95 | this.getColorObject(tinycolor(hex).lighten(30).saturate(30), 'A200'),
96 | this.getColorObject(tinycolor(hex).lighten(10).saturate(15), 'A400'),
97 | this.getColorObject(tinycolor(hex).lighten(5).saturate(5), 'A700')
98 | ];
99 | }
100 |
101 | getColorObject(value: any, name: any) {
102 | const c = tinycolor(value);
103 | return {
104 | name: name,
105 | hex: c.toHexString(),
106 | darkContrast: c.isLight()
107 | };
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/projects/showcase/src/assets/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular-sanctuary/angular-material-storybook/bca464f8403b1bd0d85560c6ed8e93c547931a0b/projects/showcase/src/assets/.gitkeep
--------------------------------------------------------------------------------
/projects/showcase/src/environments/environment.prod.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: true
3 | };
4 |
--------------------------------------------------------------------------------
/projects/showcase/src/environments/environment.ts:
--------------------------------------------------------------------------------
1 | // This file can be replaced during build by using the `fileReplacements` array.
2 | // `ng build` replaces `environment.ts` with `environment.prod.ts`.
3 | // The list of file replacements can be found in `angular.json`.
4 |
5 | export const environment = {
6 | production: false
7 | };
8 |
9 | /*
10 | * For easier debugging in development mode, you can import the following file
11 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
12 | *
13 | * This import should be commented out in production mode because it will have a negative impact
14 | * on performance if an error is thrown.
15 | */
16 | // import 'zone.js/plugins/zone-error'; // Included with Angular CLI.
17 |
--------------------------------------------------------------------------------
/projects/showcase/src/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular-sanctuary/angular-material-storybook/bca464f8403b1bd0d85560c6ed8e93c547931a0b/projects/showcase/src/favicon.ico
--------------------------------------------------------------------------------
/projects/showcase/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Showcase
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/projects/showcase/src/main.ts:
--------------------------------------------------------------------------------
1 | import { enableProdMode } from '@angular/core';
2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
3 |
4 | import { AppModule } from './app/app.module';
5 | import { environment } from './environments/environment';
6 |
7 | if (environment.production) {
8 | enableProdMode();
9 | }
10 |
11 | platformBrowserDynamic().bootstrapModule(AppModule)
12 | .catch(err => console.error(err));
13 |
--------------------------------------------------------------------------------
/projects/showcase/src/material-theme.scss:
--------------------------------------------------------------------------------
1 | @use '@angular/material' as mat;
2 | @import '@angular/material/theming';
3 |
4 | // Light theme
5 |
6 | $light-theme-primary: (
7 | 50 : var(--light-theme-primary-50, #8ae7ff),
8 | 100 : var(--light-theme-primary-100, #3ed8ff),
9 | 200 : var(--light-theme-primary-200, #06ccff),
10 | 300 : var(--light-theme-primary-300, #0097bd),
11 | 400 : var(--light-theme-primary-400, #007e9f),
12 | 500 : var(--light-theme-primary-500, #006680),
13 | 600 : var(--light-theme-primary-600, #004e61),
14 | 700 : var(--light-theme-primary-700, #003543),
15 | 800 : var(--light-theme-primary-800, #001d24),
16 | 900 : var(--light-theme-primary-900, #000406),
17 | A100 : var(--light-theme-primary-A100, #80e5ff),
18 | A200 : var(--light-theme-primary-A200, #1ad0ff),
19 | A400 : var(--light-theme-primary-A400, #008fb3),
20 | A700 : var(--light-theme-primary-A700, #007a99),
21 | contrast: (
22 | 50: var(--light-theme-primary-contrast-50, black),
23 | 100: var(--light-theme-primary-contrast-100, black),
24 | 200: var(--light-theme-primary-contrast-200, black),
25 | 300: var(--light-theme-primary-contrast-300, white),
26 | 400: var(--light-theme-primary-contrast-400, white),
27 | 500: var(--light-theme-primary-contrast-500, white),
28 | 600: var(--light-theme-primary-contrast-600, white),
29 | 700: var(--light-theme-primary-contrast-700, white),
30 | 800: var(--light-theme-primary-contrast-800, white),
31 | 900: var(--light-theme-primary-contrast-900, white),
32 | A100: var(--light-theme-primary-contrast-A100, black),
33 | A200: var(--light-theme-primary-contrast-A200, black),
34 | A400: var(--light-theme-primary-contrast-A400, white),
35 | A700: var(--light-theme-primary-contrast-A700, white),
36 | )
37 | );
38 |
39 | $light-theme-accent: (
40 | 50 : var(--light-theme-accent-50, #ffffff),
41 | 100 : var(--light-theme-accent-100, #fef2e6),
42 | 200 : var(--light-theme-accent-200, #fbd6b0),
43 | 300 : var(--light-theme-accent-300, #f8b26c),
44 | 400 : var(--light-theme-accent-400, #f6a34f),
45 | 500 : var(--light-theme-accent-500, #f59432),
46 | 600 : var(--light-theme-accent-600, #f48515),
47 | 700 : var(--light-theme-accent-700, #df750b),
48 | 800 : var(--light-theme-accent-800, #c26609),
49 | 900 : var(--light-theme-accent-900, #a55708),
50 | A100 : var(--light-theme-accent-A100, #ffffff),
51 | A200 : var(--light-theme-accent-A200, #ffe0c1),
52 | A400 : var(--light-theme-accent-A400, #ffad5b),
53 | A700 : var(--light-theme-accent-A700, #fba146),
54 | contrast: (
55 | 50: var(--light-theme-accent-contrast-50, black),
56 | 100: var(--light-theme-accent-contrast-100, black),
57 | 200: var(--light-theme-accent-contrast-200, black),
58 | 300: var(--light-theme-accent-contrast-300, black),
59 | 400: var(--light-theme-accent-contrast-400, black),
60 | 500: var(--light-theme-accent-contrast-500, black),
61 | 600: var(--light-theme-accent-contrast-60, black),
62 | 700: var(--light-theme-accent-contrast-700, black),
63 | 800: var(--light-theme-accent-contrast-800, white),
64 | 900: var(--light-theme-accent-contrast-900, white),
65 | A100: var(--light-theme-accent-contrast-A100, black),
66 | A200: var(--light-theme-accent-contrast-A200, black),
67 | A400: var(--light-theme-accent-contrast-A400, black),
68 | A700: var(--light-theme-accent-contrast-A700, black),
69 | )
70 | );
71 |
72 | $light-theme-warn: (
73 | 50 : var(--light-theme-warn-50, #ffffff),
74 | 100 : var(--light-theme-warn-100, #feeae9),
75 | 200 : var(--light-theme-warn-200, #fbb9b4),
76 | 300 : var(--light-theme-warn-300, #f77970),
77 | 400 : var(--light-theme-warn-400, #f65e53),
78 | 500 : var(--light-theme-warn-500, #f44336),
79 | 600 : var(--light-theme-warn-600, #f22819),
80 | 700 : var(--light-theme-warn-700, #e11b0c),
81 | 800 : var(--light-theme-warn-800, #c3170b),
82 | 900 : var(--light-theme-warn-900, #a61409),
83 | A100 : var(--light-theme-warn-A100, #ffffff),
84 | A200 : var(--light-theme-warn-A200, #ffc8c4),
85 | A400 : var(--light-theme-warn-A400, #ff695e),
86 | A700 : var(--light-theme-warn-A700, #fa564a),
87 | contrast: (
88 | 50: var(--light-theme-warn-contrast-50, rgba(black, 0.87)),
89 | 100: var(--light-theme-warn-contrast-100, rgba(black, 0.87)),
90 | 200: var(--light-theme-warn-contrast-200, rgba(black, 0.87)),
91 | 300: var(--light-theme-warn-contrast-300, rgba(black, 0.87)),
92 | 400: var(--light-theme-warn-contrast-400, rgba(black, 0.87)),
93 | 500: var(--light-theme-warn-contrast-500, white),
94 | 600: var(--light-theme-warn-contrast-600, white),
95 | 700: var(--light-theme-warn-contrast-700, white),
96 | 800: var(--light-theme-warn-contrast-800, white),
97 | 900: var(--light-theme-warn-contrast-900, white),
98 | A100: var(--light-theme-warn-contrast-A100, rgba(black, 0.87)),
99 | A200: var(--light-theme-warn-contrast-A200, rgba(black, 0.87)),
100 | A400: var(--light-theme-warn-contrast-A400, rgba(black, 0.87)),
101 | A700: var(--light-theme-warn-contrast-A700, rgba(black, 0.87)),
102 | )
103 | );
104 |
105 | // Dark theme
106 |
107 | $dark-theme-primary: (
108 | 50 : var(--dark-theme-primary-50, #8ae7ff),
109 | 100 : var(--dark-theme-primary-100, #3ed8ff),
110 | 200 : var(--dark-theme-primary-200, #06ccff),
111 | 300 : var(--dark-theme-primary-300, #0097bd),
112 | 400 : var(--dark-theme-primary-400, #007e9f),
113 | 500 : var(--dark-theme-primary-500, #006680),
114 | 600 : var(--dark-theme-primary-600, #004e61),
115 | 700 : var(--dark-theme-primary-700, #003543),
116 | 800 : var(--dark-theme-primary-800, #001d24),
117 | 900 : var(--dark-theme-primary-900, #000406),
118 | A100 : var(--dark-theme-primary-A100, #80e5ff),
119 | A200 : var(--dark-theme-primary-A200, #1ad0ff),
120 | A400 : var(--dark-theme-primary-A400, #008fb3),
121 | A700 : var(--dark-theme-primary-A700, #007a99),
122 | contrast: (
123 | 50: var(--dark-theme-primary-contrast-50, black),
124 | 100: var(--dark-theme-primary-contrast-100, black),
125 | 200: var(--dark-theme-primary-contrast-200, black),
126 | 300: var(--dark-theme-primary-contrast-300, white),
127 | 400: var(--dark-theme-primary-contrast-400, white),
128 | 500: var(--dark-theme-primary-contrast-500, white),
129 | 600: var(--dark-theme-primary-contrast-600, white),
130 | 700: var(--dark-theme-primary-contrast-700, white),
131 | 800: var(--dark-theme-primary-contrast-800, white),
132 | 900: var(--dark-theme-primary-contrast-900, white),
133 | A100: var(--dark-theme-primary-contrast-A100, black),
134 | A200: var(--dark-theme-primary-contrast-A200, black),
135 | A400: var(--dark-theme-primary-contrast-A400, white),
136 | A700: var(--dark-theme-primary-contrast-A700, white),
137 | )
138 | );
139 |
140 | $dark-theme-accent: (
141 | 50 : var(--dark-theme-accent-50, #ffffff),
142 | 100 : var(--dark-theme-accent-100, #fef2e6),
143 | 200 : var(--dark-theme-accent-200, #fbd6b0),
144 | 300 : var(--dark-theme-accent-300, #f8b26c),
145 | 400 : var(--dark-theme-accent-400, #f6a34f),
146 | 500 : var(--dark-theme-accent-500, #f59432),
147 | 600 : var(--dark-theme-accent-600, #f48515),
148 | 700 : var(--dark-theme-accent-700, #df750b),
149 | 800 : var(--dark-theme-accent-800, #c26609),
150 | 900 : var(--dark-theme-accent-900, #a55708),
151 | A100 : var(--dark-theme-accent-A100, #ffffff),
152 | A200 : var(--dark-theme-accent-A200, #ffe0c1),
153 | A400 : var(--dark-theme-accent-A400, #ffad5b),
154 | A700 : var(--dark-theme-accent-A700, #fba146),
155 | contrast: (
156 | 50: var(--dark-theme-accent-contrast-50, black),
157 | 100: var(--dark-theme-accent-contrast-100, black),
158 | 200: var(--dark-theme-accent-contrast-200, black),
159 | 300: var(--dark-theme-accent-contrast-300, black),
160 | 400: var(--dark-theme-accent-contrast-400, black),
161 | 500: var(--dark-theme-accent-contrast-500, black),
162 | 600: var(--dark-theme-accent-contrast-60, black),
163 | 700: var(--dark-theme-accent-contrast-700, black),
164 | 800: var(--dark-theme-accent-contrast-800, white),
165 | 900: var(--dark-theme-accent-contrast-900, white),
166 | A100: var(--dark-theme-accent-contrast-A100, black),
167 | A200: var(--dark-theme-accent-contrast-A200, black),
168 | A400: var(--dark-theme-accent-contrast-A400, black),
169 | A700: var(--dark-theme-accent-contrast-A700, black),
170 | )
171 | );
172 |
173 | $dark-theme-warn: (
174 | 50 : var(--dark-theme-warn-50, #ffffff),
175 | 100 : var(--dark-theme-warn-100, #feeae9),
176 | 200 : var(--dark-theme-warn-200, #fbb9b4),
177 | 300 : var(--dark-theme-warn-300, #f77970),
178 | 400 : var(--dark-theme-warn-400, #f65e53),
179 | 500 : var(--dark-theme-warn-500, #f44336),
180 | 600 : var(--dark-theme-warn-600, #f22819),
181 | 700 : var(--dark-theme-warn-700, #e11b0c),
182 | 800 : var(--dark-theme-warn-800, #c3170b),
183 | 900 : var(--dark-theme-warn-900, #a61409),
184 | A100 : var(--dark-theme-warn-A100, #ffffff),
185 | A200 : var(--dark-theme-warn-A200, #ffc8c4),
186 | A400 : var(--dark-theme-warn-A400, #ff695e),
187 | A700 : var(--dark-theme-warn-A700, #fa564a),
188 | contrast: (
189 | 50: var(--dark-theme-warn-contrast-50, rgba(black, 0.87)),
190 | 100: var(--dark-theme-warn-contrast-100, rgba(black, 0.87)),
191 | 200: var(--dark-theme-warn-contrast-200, rgba(black, 0.87)),
192 | 300: var(--dark-theme-warn-contrast-300, rgba(black, 0.87)),
193 | 400: var(--dark-theme-warn-contrast-400, rgba(black, 0.87)),
194 | 500: var(--dark-theme-warn-contrast-500, white),
195 | 600: var(--dark-theme-warn-contrast-600, white),
196 | 700: var(--dark-theme-warn-contrast-700, white),
197 | 800: var(--dark-theme-warn-contrast-800, white),
198 | 900: var(--dark-theme-warn-contrast-900, white),
199 | A100: var(--dark-theme-warn-contrast-A100, rgba(black, 0.87)),
200 | A200: var(--dark-theme-warn-contrast-A200, rgba(black, 0.87)),
201 | A400: var(--dark-theme-warn-contrast-A400, rgba(black, 0.87)),
202 | A700: var(--dark-theme-warn-contrast-A700, rgba(black, 0.87)),
203 | )
204 | );
205 | /*
206 | $dynamic-light-theme-background: (
207 | status-bar: map_get(mat.$grey-palette, 300),
208 | app-bar: map_get(mat.$grey-palette, 100),
209 | background: map_get(mat.$grey-palette, 50),
210 | hover: rgba(black, 0.04),
211 | card: white,
212 | dialog: white,
213 | disabled-button: rgba(black, 0.12),
214 | raised-button: white,
215 | focused-button: $dark-focused,
216 | selected-button: map_get(mat.$grey-palette, 300),
217 | selected-disabled-button: map_get(mat.$grey-palette, 400),
218 | disabled-button-toggle: map_get(mat.$grey-palette, 200),
219 | unselected-chip: map_get(mat.$grey-palette, 300),
220 | disabled-list-option: map_get(mat.$grey-palette, 200),
221 | );
222 |
223 | $dynamic-light-theme-foreground: (
224 | base: black,
225 | divider: $dark-dividers,
226 | dividers: $dark-dividers,
227 | disabled: $dark-disabled-text,
228 | disabled-button: rgba(black, 0.26),
229 | disabled-text: $dark-disabled-text,
230 | elevation: black,
231 | hint-text: $dark-disabled-text,
232 | secondary-text: $dark-secondary-text,
233 | icon: rgba(black, 0.54),
234 | icons: rgba(black, 0.54),
235 | text: rgba(black, 0.87),
236 | slider-min: rgba(black, 0.87),
237 | slider-off: rgba(black, 0.26),
238 | slider-off-active: rgba(black, 0.38),
239 | );
240 |
241 |
242 |
243 | $dynamic-app-theme: (
244 | primary: mat.define-palette($dynamic-theme-primary),
245 | accent: mat.define-palette($dynamic-theme-accent),
246 | warn: mat.define-palette($dynamic-theme-warn),
247 | is-dark: false,
248 | foreground: $dynamic-light-theme-foreground,
249 | background: $dynamic-light-theme-background
250 | );
251 |
252 | */
253 | $dynamic-typography: mat.define-typography-config(
254 | $font-family: 'Roboto, "Helvetica Neue", sans-serif',
255 | $headline-1: mat.define-typography-level(112px, 112px, 300, $letter-spacing: -0.05em),
256 | $headline-2: mat.define-typography-level(56px, 56px, 400, $letter-spacing: -0.02em),
257 | $headline-3: mat.define-typography-level(45px, 48px, 400, $letter-spacing: -0.005em),
258 | $headline-4: mat.define-typography-level(34px, 40px, 400),
259 | $headline-5: mat.define-typography-level(24px, 32px, 400),
260 | $headline-6: mat.define-typography-level(20px, 32px, 500),
261 | $subtitle-1: mat.define-typography-level(16px, 28px, 400),
262 | $body-1: mat.define-typography-level(15px, 24px, 400),
263 | $subtitle-2: mat.define-typography-level(14px, 24px, 500),
264 | $body-2: mat.define-typography-level(14px, 20px, 400),
265 | $caption: mat.define-typography-level(12px, 20px, 400),
266 | $button: mat.define-typography-level(14px, 14px, 500),
267 | );
268 |
--------------------------------------------------------------------------------
/projects/showcase/src/polyfills.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * This file includes polyfills needed by Angular and is loaded before the app.
3 | * You can add your own extra polyfills to this file.
4 | *
5 | * This file is divided into 2 sections:
6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main
8 | * file.
9 | *
10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that
11 | * automatically update themselves. This includes recent versions of Safari, Chrome (including
12 | * Opera), Edge on the desktop, and iOS and Chrome on mobile.
13 | *
14 | * Learn more in https://angular.io/guide/browser-support
15 | */
16 |
17 | /***************************************************************************************************
18 | * BROWSER POLYFILLS
19 | */
20 |
21 | /**
22 | * By default, zone.js will patch all possible macroTask and DomEvents
23 | * user can disable parts of macroTask/DomEvents patch by setting following flags
24 | * because those flags need to be set before `zone.js` being loaded, and webpack
25 | * will put import in the top of bundle, so user need to create a separate file
26 | * in this directory (for example: zone-flags.ts), and put the following flags
27 | * into that file, and then add the following code before importing zone.js.
28 | * import './zone-flags';
29 | *
30 | * The flags allowed in zone-flags.ts are listed here.
31 | *
32 | * The following flags will work for all browsers.
33 | *
34 | * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
35 | * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
36 | * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
37 | *
38 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
39 | * with the following flag, it will bypass `zone.js` patch for IE/Edge
40 | *
41 | * (window as any).__Zone_enable_cross_context_check = true;
42 | *
43 | */
44 |
45 | /***************************************************************************************************
46 | * Zone JS is required by default for Angular itself.
47 | */
48 | import 'zone.js'; // Included with Angular CLI.
49 |
50 |
51 | /***************************************************************************************************
52 | * APPLICATION IMPORTS
53 | */
54 |
--------------------------------------------------------------------------------
/projects/showcase/src/styles.scss:
--------------------------------------------------------------------------------
1 | /* You can add global styles to this file, and also import other style files */
2 | @use '@angular/material' as mat;
3 | @import './material-theme';
4 |
5 | @include mat.all-component-typographies();
6 | @include mat.core();
7 |
8 | $light-primary: mat.define-palette($light-theme-primary);
9 | $light-accent: mat.define-palette($light-theme-accent);
10 | $light-warn: mat.define-palette($light-theme-warn);
11 |
12 | $light-theme: mat.define-light-theme((
13 | color: (
14 | primary: $light-primary,
15 | accent: $light-accent,
16 | warn: $light-warn,
17 | )
18 | ));
19 |
20 | $dark-primary: mat.define-palette($dark-theme-primary);
21 | $dark-accent: mat.define-palette($dark-theme-accent);
22 | $dark-warn: mat.define-palette($dark-theme-warn);
23 |
24 | $dark-theme: mat.define-dark-theme((
25 | color: (
26 | primary: $dark-primary,
27 | accent: $dark-accent,
28 | warn: $dark-warn,
29 | )
30 | ));
31 |
32 | @include mat.core-theme($light-theme);
33 | @include mat.all-component-themes($light-theme);
34 |
35 | html, body { height: 100%; }
36 | body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }
37 |
38 | .dark-theme {
39 | @include mat.core-color($dark-theme);
40 | @include mat.all-component-colors($dark-theme);
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/projects/showcase/src/test.ts:
--------------------------------------------------------------------------------
1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files
2 |
3 | import 'zone.js/testing';
4 | import { getTestBed } from '@angular/core/testing';
5 | import {
6 | BrowserDynamicTestingModule,
7 | platformBrowserDynamicTesting
8 | } from '@angular/platform-browser-dynamic/testing';
9 |
10 | // First, initialize the Angular testing environment.
11 | getTestBed().initTestEnvironment(
12 | BrowserDynamicTestingModule,
13 | platformBrowserDynamicTesting(),
14 | );
15 |
--------------------------------------------------------------------------------
/projects/showcase/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../out-tsc/app",
5 | "types": []
6 | },
7 | "files": [
8 | "src/main.ts",
9 | "src/polyfills.ts"
10 | ],
11 | "include": [
12 | "src/**/*.d.ts"
13 | ],
14 | "exclude": [
15 | // "**/*.stories.*"
16 | ]
17 | }
18 |
--------------------------------------------------------------------------------
/projects/showcase/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "extends": "../../tsconfig.json",
4 | "compilerOptions": {
5 | "outDir": "../../out-tsc/spec",
6 | "types": [
7 | "jasmine"
8 | ]
9 | },
10 | "files": [
11 | "src/test.ts",
12 | "src/polyfills.ts"
13 | ],
14 | "include": [
15 | "src/**/*.spec.ts",
16 | "src/**/*.d.ts"
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular-sanctuary/angular-material-storybook/bca464f8403b1bd0d85560c6ed8e93c547931a0b/public/favicon.ico
--------------------------------------------------------------------------------
/stories/assets/arrow-next.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/stories/assets/arrow-next_disabled.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/stories/assets/arrow-previous.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/stories/assets/arrow-previous_disabled.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/stories/assets/code-brackets.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/stories/assets/colors.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/stories/assets/comments.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/stories/assets/diamond.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/stories/assets/direction.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/stories/assets/flow.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/stories/assets/image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular-sanctuary/angular-material-storybook/bca464f8403b1bd0d85560c6ed8e93c547931a0b/stories/assets/image.png
--------------------------------------------------------------------------------
/stories/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular-sanctuary/angular-material-storybook/bca464f8403b1bd0d85560c6ed8e93c547931a0b/stories/assets/logo.png
--------------------------------------------------------------------------------
/stories/assets/open_in_new.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular-sanctuary/angular-material-storybook/bca464f8403b1bd0d85560c6ed8e93c547931a0b/stories/assets/open_in_new.png
--------------------------------------------------------------------------------
/stories/assets/plugin.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/stories/assets/repo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/stories/assets/stackalt.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/stories/components/badge/badge.argtype.ts:
--------------------------------------------------------------------------------
1 | export const badgeArgtypes = {
2 | matBadge: {
3 | description: 'The content for the badge',
4 | defaultValue: '3',
5 | table: {
6 | type: { summary: 'text' },
7 | defaultValue: { summary: '3' },
8 | },
9 | control: {
10 | type: 'text'
11 | }
12 | },
13 | matBadgeDescription: {
14 | description: 'Message used to describe the decorated element via aria-describedby',
15 | defaultValue: '',
16 | control: {
17 | type: 'text'
18 | }
19 | },
20 | matBadgeDisabled: {
21 | description: 'Whether the component is disabled',
22 | defaultValue: false,
23 | table: {
24 | type: { summary: 'boolean' },
25 | defaultValue: { summary: false },
26 | },
27 | control: {
28 | type: 'boolean'
29 | }
30 | },
31 | matBadgeHidden: {
32 | description: 'Whether the badge is hidden',
33 | defaultValue: false,
34 | table: {
35 | type: { summary: 'boolean' },
36 | defaultValue: { summary: false },
37 | },
38 | control: {
39 | type: 'boolean'
40 | }
41 | },
42 | matBadgeOverlap: {
43 | description: 'Whether the badge should overlap its contents or not',
44 | defaultValue: true,
45 | table: {
46 | type: { summary: 'boolean' },
47 | defaultValue: { summary: true },
48 | },
49 | control: {
50 | type: 'boolean'
51 | }
52 | },
53 | matBadgePosition: {
54 | description: 'Position the badge should reside',
55 | control: 'select',
56 | defaultValue: 'above after',
57 | table: {
58 | defaultValue: { summary: 'above after' },
59 | },
60 | options: [
61 | 'before',
62 | 'after',
63 | 'above',
64 | 'below',
65 | 'above after',
66 | 'above before',
67 | 'below before',
68 | 'below after',
69 | ]
70 | },
71 | matBadgeSize: {
72 | description: 'Size of the badge',
73 | defaultValue: 'medium',
74 | table: {
75 | defaultValue: { summary: 'medium' },
76 | },
77 | control: 'select',
78 | options: [
79 | 'small',
80 | 'medium',
81 | 'large'
82 | ]
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/stories/components/form-field/form-field-argtype.ts:
--------------------------------------------------------------------------------
1 | export const formFieldArgtypes = {
2 | appearance: {
3 | description: 'The form field appearance style',
4 | control: 'select',
5 | defaultValue: 'standard',
6 | table: {
7 | defaultValue: { summary: 'standard' },
8 | },
9 | options: [
10 | 'legacy',
11 | 'standard',
12 | 'fill',
13 | 'outline',
14 | ]
15 | },
16 | color: {
17 | description: 'Theme color palette',
18 | control: 'select',
19 | defaultValue: 'primary',
20 | table: {
21 | defaultValue: { summary: 'primary' },
22 | },
23 | options: [
24 | 'primary',
25 | 'accent',
26 | 'warn',
27 | ]
28 | },
29 | floatLabel: {
30 | description: 'Whether the label should always float, never float or float as the user types',
31 | control: 'select',
32 | defaultValue: 'primary',
33 | table: {
34 | defaultValue: { summary: 'primary' },
35 | },
36 | options: [
37 | 'always',
38 | 'never',
39 | 'auto',
40 | ]
41 | },
42 | hideRequiredMarker: {
43 | description: 'Whether the required marker should be hidden',
44 | defaultValue: false,
45 | table: {
46 | type: { summary: 'boolean' },
47 | defaultValue: { summary: false },
48 | },
49 | control: {
50 | type: 'boolean'
51 | }
52 | },
53 | hintLabel: {
54 | description: 'Text for the form field hint',
55 | defaultValue: '',
56 | table: {
57 | type: { summary: 'text' },
58 | defaultValue: { summary: '' },
59 | },
60 | control: {
61 | type: 'text'
62 | }
63 | },
64 | alignHint: {
65 | description: 'Whether to align the hint label at the start or end of the line',
66 | control: 'select',
67 | defaultValue: 'start',
68 | table: {
69 | defaultValue: { summary: 'start' },
70 | },
71 | options: [
72 | 'start',
73 | 'end',
74 | ]
75 | },
76 | }
77 |
--------------------------------------------------------------------------------
/stories/components/form-field/form-field.mdx:
--------------------------------------------------------------------------------
1 | import {Story} from '@storybook/blocks';
2 | import LinkTo from '@storybook/addon-links/react';
3 |
4 | import linkImage from '../../assets/open_in_new.png'
5 | import * as ComponentStories from './form-field.stories';
6 |
7 | # Form field
8 |
9 | > *mat-form-field* is a component used to wrap several Angular Material components and apply common Text field styles such as the underline, floating label, and hint messages.
10 |
11 |
12 |
13 | ## Installation
14 |
15 | `import {MatFormFieldModule} from '@angular/material/form-field';`
16 |
17 | [Official documentation](https://material.angular.io/components/form-field/overview)
18 |
19 |
20 |
21 | ## Basic usage
22 |
23 |
24 |
25 |
26 |
27 |
28 | Basic usage
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | ## State
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | Inactive
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | Filled
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | Hover
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 | Focused
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 | Disabled
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 | Error
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 | ## Appearance
115 |
116 | > supports 4 different appearance variants.
117 |
118 | Official
119 | documentation
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 | Legacy
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 | Standard
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 | Fill
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 | Outline
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 | ## Hints
172 |
173 | > Hint labels are additional descriptive text that appears below the form field's underline.
174 |
175 | Official
176 | documentation
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 | Left hint
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 | Right hint
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 | Double hints
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 | ## Prefix and suffix
219 |
220 | > Custom content can be included before and after the input tag, as a prefix or suffix.
221 |
222 | Official
223 | documentation
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 | Prefix
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 | Suffix
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 | Prefix and suffix
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 | ## Error message
266 |
267 | > Error messages can be shown under the form field underline.
268 |
269 | Official
270 | documentation
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 | Error message
279 |
280 |
281 |
282 |
283 |
284 |
285 |
--------------------------------------------------------------------------------
/stories/components/form-field/form-field.stories.ts:
--------------------------------------------------------------------------------
1 | import { Meta, moduleMetadata, StoryObj } from '@storybook/angular';
2 | import { MatFormFieldModule } from '@angular/material/form-field';
3 | import { MatInputModule } from '@angular/material/input';
4 | import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
5 | import { formFieldArgtypes } from './form-field-argtype';
6 | import { MatSelectModule } from '@angular/material/select';
7 | import { MatIconModule } from '@angular/material/icon';
8 | import { MatButtonModule } from '@angular/material/button';
9 | import { FormControl, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
10 | import { userEvent, within } from '@storybook/testing-library';
11 | import { expect } from '@storybook/jest';
12 |
13 | export default {
14 | title: 'components/Form field',
15 | tags: ['docsPage'],
16 | decorators: [
17 | moduleMetadata({
18 | imports: [
19 | BrowserAnimationsModule,
20 | MatFormFieldModule,
21 | MatInputModule,
22 | MatSelectModule,
23 | MatIconModule,
24 | MatButtonModule,
25 | ReactiveFormsModule,
26 | FormsModule,
27 | ],
28 | }),
29 | ],
30 | parameters: {
31 | controls: {
32 | expanded: true,
33 | },
34 | },
35 | argTypes: formFieldArgtypes,
36 | } as Meta;
37 |
38 | export const AAWithBasicUsage: StoryObj = {
39 | render: (args) => ({
40 | props: args,
41 | template: `
42 |
43 | Password
44 |
45 |
46 | `,
47 | }),
48 | // Added an example of how to use the play function
49 | // For more information, see https://storybook.js.org/docs/angular/writing-tests/interaction-testing
50 | play: async ({ canvasElement }) => {
51 | const canvas = within(canvasElement);
52 | await userEvent.type(canvas.getByLabelText('Password'), 'email@provider.com');
53 | await expect(canvas.getByLabelText('Password')).toHaveValue('email@provider.com');
54 | },
55 | name: 'basic usage',
56 | parameters: {
57 | controls: {
58 | exclude: ['alignHint'],
59 | },
60 | },
61 | };
62 |
63 | export const WithStateFilled: StoryObj = {
64 | render: (args) => ({
65 | props: args,
66 | template: `
67 |
68 | Password
69 |
70 |
71 | `,
72 | }),
73 | name: 'with state (filled)',
74 | parameters: {
75 | controls: {
76 | exclude: ['alignHint'],
77 | },
78 | },
79 | };
80 |
81 | export const WithStateDisabled: StoryObj = {
82 | render: (args) => ({
83 | props: args,
84 | template: `
85 |
86 | Password
87 |
88 |
89 | `,
90 | }),
91 | name: 'with state (disabled)',
92 | parameters: {
93 | controls: {
94 | exclude: ['alignHint'],
95 | },
96 | },
97 | };
98 |
99 | export const WithStateFocused: StoryObj = {
100 | render: (args) => ({
101 | props: args,
102 | template: `
103 |
104 | Password 1
105 |
106 |
107 | `,
108 | }),
109 | name: 'with state (focused)',
110 | parameters: {
111 | controls: {
112 | exclude: ['alignHint'],
113 | },
114 | },
115 | };
116 |
117 | export const WithStateHover: StoryObj = {
118 | render: (args) => ({
119 | props: args,
120 | template: `
121 |
122 | Password
123 |
124 |
125 | `,
126 | }),
127 | name: 'with state (hover)',
128 | parameters: {
129 | controls: {
130 | exclude: ['alignHint'],
131 | },
132 | pseudo: {
133 | hover: true,
134 | },
135 | },
136 | };
137 |
138 | export const WithAppearanceLegacy: StoryObj = {
139 | render: (args) => ({
140 | props: {
141 | ...args,
142 | appearance: 'legacy',
143 | },
144 | template: `
145 |
146 | Password
147 |
148 |
149 | `,
150 | }),
151 | name: 'with appearance (legacy)',
152 | parameters: {
153 | controls: {
154 | exclude: ['alignHint'],
155 | },
156 | },
157 | };
158 |
159 | export const WithAppearanceStandard: StoryObj = {
160 | render: (args) => ({
161 | props: {
162 | ...args,
163 | appearance: 'standard',
164 | },
165 | template: `
166 |
167 | Password
168 |
169 |
170 | `,
171 | }),
172 | name: 'with appearance (standard)',
173 | parameters: {
174 | controls: {
175 | exclude: ['alignHint'],
176 | },
177 | },
178 | };
179 |
180 | export const WithAppearanceFill: StoryObj = {
181 | render: (args) => ({
182 | props: {
183 | ...args,
184 | appearance: 'fill',
185 | },
186 | template: `
187 |
188 | Password
189 |
190 |
191 | `,
192 | }),
193 | name: 'with appearance (fill)',
194 | parameters: {
195 | controls: {
196 | exclude: ['alignHint'],
197 | },
198 | },
199 | };
200 |
201 | export const WithAppearanceOutline: StoryObj = {
202 | render: (args) => ({
203 | props: {
204 | ...args,
205 | appearance: 'outline',
206 | },
207 | template: `
208 |
209 | Password
210 |
211 |
212 | `,
213 | }),
214 | name: 'with appearance (outline)',
215 | parameters: {
216 | controls: {
217 | exclude: ['alignHint'],
218 | },
219 | },
220 | };
221 |
222 | export const WithStartHint: StoryObj = {
223 | render: (args) => ({
224 | props: args,
225 | template: `
226 |
227 | Password
228 |
229 | at least 8 characters
230 |
231 | `,
232 | }),
233 | name: 'with hint (start)',
234 | };
235 |
236 | export const WithEndHint: StoryObj = {
237 | render: (args) => ({
238 | props: args,
239 | template: `
240 |
241 | Contributions
242 |
243 | Components
244 | Use cases
245 |
246 | Choose an option ^
247 |
248 | `,
249 | }),
250 | name: 'with hint (end)',
251 | };
252 |
253 | export const WithDoubleHints: StoryObj = {
254 | render: (args) => ({
255 | props: args,
256 | template: `
257 |
258 | Username
259 |
260 | Max 10 characters
261 | {{input.value.length || 0}}/10
262 |
263 | `,
264 | }),
265 | name: 'with hint (double)',
266 | };
267 |
268 | export const WithPrefix: StoryObj = {
269 | render: (args) => ({
270 | props: {
271 | ...args,
272 | hide: true,
273 | },
274 | template: `
275 |
276 | Password
277 |
278 | key
279 |
280 | `,
281 | }),
282 | name: 'with prefix',
283 | parameters: {
284 | controls: {
285 | exclude: ['alignHint'],
286 | },
287 | },
288 | };
289 |
290 | export const WithSuffix: StoryObj = {
291 | render: (args) => ({
292 | props: {
293 | ...args,
294 | hide: true,
295 | },
296 | template: `
297 |
298 | Password
299 |
300 |
303 |
304 | `,
305 | }),
306 | name: 'with suffix',
307 | parameters: {
308 | controls: {
309 | exclude: ['alignHint'],
310 | },
311 | },
312 | };
313 |
314 | export const WithPrefixAndSuffix: StoryObj = {
315 | render: (args) => ({
316 | props: {
317 | ...args,
318 | hide: true,
319 | },
320 | template: `
321 |
335 |
336 | Amount
337 |
338 | $
339 | .00
340 |
341 | `,
342 | }),
343 | name: 'with prefix and suffix',
344 | parameters: {
345 | controls: {
346 | exclude: ['alignHint'],
347 | },
348 | },
349 | };
350 |
351 | const control = new FormControl('', Validators.required);
352 | control.markAsTouched();
353 |
354 | export const WithErrorMessage: StoryObj = {
355 | render: (args) => ({
356 | props: {
357 | ...args,
358 | control: control,
359 | },
360 | template: `
361 |
362 | Password
363 |
364 | This field is required
365 |
366 | `,
367 | }),
368 | name: 'with error message',
369 | parameters: {
370 | controls: {
371 | exclude: ['alignHint'],
372 | },
373 | },
374 | };
375 |
--------------------------------------------------------------------------------
/stories/components/icon.mdx:
--------------------------------------------------------------------------------
1 |
2 | import { Story } from '@storybook/blocks';
3 | import * as ComponentStories from './icon.stories';
4 |
5 | # Icon
6 |
7 | > *mat-icon* makes it easier to use vector-based icons in your app. This directive supports both icon fonts and SVG icons, but not bitmap-based formats (png, jpg, etc.).
8 |
9 |
10 |
11 | ## Installation
12 |
13 | `import {MatIconModule} from '@angular/material/icon';`
14 |
15 | [Official documentation](https://material.angular.io/components/icon/overview)
16 |
17 |
18 |
19 | ## Example
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/stories/components/icon.stories.ts:
--------------------------------------------------------------------------------
1 | import { Meta, moduleMetadata, StoryObj } from '@storybook/angular';
2 | import { MatIconModule } from '@angular/material/icon';
3 | import { MatBadgeModule } from '@angular/material/badge';
4 | import { MatButtonModule } from '@angular/material/button';
5 | import { badgeArgtypes } from './badge/badge.argtype';
6 |
7 | export default {
8 | title: 'Components/Icon',
9 | decorators: [
10 | moduleMetadata({
11 | imports: [MatIconModule, MatBadgeModule, MatButtonModule],
12 | }),
13 | ],
14 | parameters: {
15 | options: {
16 | controls: {
17 | disable: true,
18 | },
19 | },
20 | },
21 | } as Meta;
22 |
23 | export const BasicUsage: StoryObj = {
24 | render: (args) => ({
25 | props: args,
26 | template: `
27 |
28 | more_vert
29 | home
30 | menu
31 | favorite
32 | open_in_new
33 | `,
34 | }),
35 | name: 'basic usage',
36 | };
37 |
38 | export const WithBadge: StoryObj = {
39 | render: (args) => ({
40 | props: args,
41 | template: `
42 |
43 | more_vert
44 | home
45 | menu
46 | favorite
47 | open_in_new
48 | `,
49 | }),
50 | name: 'with badge',
51 | parameters: {
52 | controls: {
53 | expanded: true,
54 | },
55 | },
56 | argTypes: {
57 | ...badgeArgtypes,
58 | },
59 | };
60 |
61 | export const WithButtons: StoryObj = {
62 | render: (args) => ({
63 | props: args,
64 | template: `
65 |
66 |
67 |
68 |
69 |
70 |
71 | `,
72 | }),
73 | name: 'with buttons',
74 | };
75 |
76 | export const WithFloatingActionButtons: StoryObj = {
77 | render: (args) => ({
78 | props: args,
79 | template: `
80 |
81 |
82 |
83 |
84 |
85 |
86 | `,
87 | }),
88 | name: 'with floating action buttons',
89 | };
90 |
91 | export const WithMiniFloatingActionButtons: StoryObj = {
92 | render: (args) => ({
93 | props: args,
94 | template: `
95 |
96 |
97 |
98 |
99 |
100 |
101 | `,
102 | }),
103 | name: 'with mini floating action buttons',
104 | };
105 |
--------------------------------------------------------------------------------
/stories/components/introduction.mdx:
--------------------------------------------------------------------------------
1 | import { Meta } from '@storybook/addon-docs';
2 | import LinkTo from '@storybook/addon-links/react';
3 |
4 |
5 |
6 |
83 |
84 | # Angular Material Components
85 |
86 | > Basic examples of Angular Material components in isolation.
87 |
88 | Components
89 |
90 |
91 |
96 |
97 | Form field
98 | Wraps input fields so they are displayed consistently.
99 |
100 |
101 |
102 |
107 |
108 | Icon
109 | Renders a specific icon.
110 |
111 |
112 |
113 |
118 |
119 | Progress bar
120 | A linear progress indicator.
121 |
122 |
123 |
124 |
129 |
130 | Progress spinner
131 | A circular progress indicator.
132 |
133 |
134 |
135 |
140 |
141 | Table
142 | A configurable component for displaying tabular data.
143 |
144 |
145 |
146 |
--------------------------------------------------------------------------------
/stories/components/progress-bar/progress-bar.argtype.ts:
--------------------------------------------------------------------------------
1 | export const progressBarArgtypes = {
2 | bufferValue: {
3 | description: 'Buffer value of the progress bar',
4 | defaultValue: 0,
5 | table: {
6 | type: { summary: 'range' },
7 | defaultValue: { summary: 0 },
8 | },
9 | control: {
10 | type: 'range',
11 | min: 0,
12 | max: 100,
13 | step: 1
14 | }
15 | },
16 | color: {
17 | description: 'Theme color palette',
18 | control: 'select',
19 | defaultValue: 'primary',
20 | table: {
21 | defaultValue: { summary: 'primary' },
22 | },
23 | options: [
24 | 'primary',
25 | 'accent',
26 | 'warn',
27 | ]
28 | },
29 | mode: {
30 | description: 'Mode of the progress bar',
31 | control: 'select',
32 | defaultValue: 'indeterminate',
33 | table: {
34 | defaultValue: { summary: 'indeterminate' },
35 | },
36 | options: [
37 | 'determinate',
38 | 'indeterminate',
39 | 'buffer',
40 | 'query'
41 | ]
42 | },
43 | value: {
44 | description: 'Value of the progress bar',
45 | defaultValue: 0,
46 | table: {
47 | type: { summary: 'range' },
48 | defaultValue: { summary: 0 },
49 | },
50 | control: {
51 | type: 'range',
52 | min: 0,
53 | max: 100,
54 | step: 1
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/stories/components/progress-bar/progress-bar.mdx:
--------------------------------------------------------------------------------
1 | import { Story } from '@storybook/blocks';
2 | import * as ComponentStories from './progress-bar.stories';
3 |
4 |
5 | # Progress bar
6 |
7 | > *mat-progress-bar* is a horizontal progress-bar for indicating progress and activity.
8 |
9 |
10 |
11 | ## Installation
12 |
13 | `import {MatProgressBarModule} from '@angular/material/progress-bar';`
14 |
15 | [Official documentation](https://material.angular.io/components/progress-bar/overview)
16 |
17 |
18 |
19 | ## Example
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/stories/components/progress-bar/progress-bar.stories.ts:
--------------------------------------------------------------------------------
1 | import { Meta, moduleMetadata, StoryObj } from '@storybook/angular';
2 | import { MatProgressBarModule } from '@angular/material/progress-bar';
3 | import { progressBarArgtypes } from './progress-bar.argtype';
4 |
5 | export default {
6 | title: 'components/Progress bar',
7 | decorators: [
8 | moduleMetadata({
9 | imports: [MatProgressBarModule],
10 | }),
11 | ],
12 | argTypes: progressBarArgtypes,
13 | parameters: {
14 | controls: {
15 | expanded: true,
16 | exclude: ['mode'],
17 | },
18 | },
19 | } as Meta;
20 |
21 | export const WithBasicUsage: StoryObj = {
22 | render: (args) => ({
23 | props: args,
24 | template: `
25 |
31 |
32 |
33 |
34 |
35 | `,
36 | }),
37 | name: 'basic usage',
38 | };
39 |
--------------------------------------------------------------------------------
/stories/components/progress-spinner/progress-spinner.argtype.ts:
--------------------------------------------------------------------------------
1 | export const progressSpinnerArgtypes = {
2 | color: {
3 | description: 'Theme color palette',
4 | control: 'select',
5 | defaultValue: 'primary',
6 | table: {
7 | defaultValue: { summary: 'primary' },
8 | },
9 | options: [
10 | 'primary',
11 | 'accent',
12 | 'warn',
13 | ]
14 | },
15 | diameter: {
16 | description: 'The diameter of the progress spinner (will set width and height of svg)',
17 | defaultValue: 100,
18 | table: {
19 | type: { summary: 'number' },
20 | defaultValue: { summary: 100 },
21 | },
22 | control: {
23 | type: 'number'
24 | }
25 | },
26 | mode: {
27 | description: 'Mode of the progress circle',
28 | control: 'select',
29 | defaultValue: 'indeterminate',
30 | table: {
31 | defaultValue: { summary: 'indeterminate' },
32 | },
33 | options: [
34 | 'determinate',
35 | 'indeterminate',
36 | 'buffer',
37 | 'query'
38 | ]
39 | },
40 | strokeWidth: {
41 | description: 'Stroke width of the progress spinner',
42 | defaultValue: 5,
43 | table: {
44 | type: { summary: 'number' },
45 | defaultValue: { summary: 5 },
46 | },
47 | control: {
48 | type: 'number'
49 | }
50 | },
51 | value: {
52 | description: 'Value of the progress circle',
53 | defaultValue: 70,
54 | table: {
55 | type: { summary: 'range' },
56 | defaultValue: { summary: 70 },
57 | },
58 | control: {
59 | type: 'range',
60 | min: 0,
61 | max: 100,
62 | step: 1
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/stories/components/progress-spinner/progress-spinner.mdx:
--------------------------------------------------------------------------------
1 | import { Story } from '@storybook/blocks';
2 | import * as ComponentStories from './progress-spinner.stories';
3 |
4 |
5 | # Progress spinner
6 |
7 | > *mat-progress-spinner* and *mat-spinner* are a circular indicators of progress and activity.
8 |
9 |
10 |
11 | ## Installation
12 |
13 | `import {MatProgressSpinnerModule} from '@angular/material/progress-spinner';`
14 |
15 | [Official documentation](https://material.angular.io/components/progress-spinner/overview)
16 |
17 |
18 |
19 | ## Example
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/stories/components/progress-spinner/progress-spinner.stories.ts:
--------------------------------------------------------------------------------
1 | import { Meta, moduleMetadata, StoryObj } from '@storybook/angular';
2 | import { progressSpinnerArgtypes } from './progress-spinner.argtype';
3 | import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
4 | export default {
5 | title: 'components/Progress spinner',
6 | decorators: [
7 | moduleMetadata({
8 | imports: [MatProgressSpinnerModule],
9 | }),
10 | ],
11 | argTypes: progressSpinnerArgtypes,
12 | parameters: {
13 | controls: {
14 | expanded: true,
15 | exclude: ['mode'],
16 | },
17 | },
18 | } as Meta;
19 |
20 | export const WithBasicUsage: StoryObj = {
21 | render: (args) => ({
22 | props: args,
23 | template: `
24 |
29 |
30 |
31 | `,
32 | }),
33 | name: 'basic usage',
34 | };
35 |
--------------------------------------------------------------------------------
/stories/components/table/table.argtype.ts:
--------------------------------------------------------------------------------
1 | export const tableArgtypes = {};
2 |
--------------------------------------------------------------------------------
/stories/components/table/table.mdx:
--------------------------------------------------------------------------------
1 | import { Story } from '@storybook/blocks';
2 | import * as ComponentStories from './table.stories';
3 |
4 | # Table
5 |
6 | > The *mat-table* provides a Material Design styled data-table that can be used to display rows of data.
7 |
8 |
9 |
10 | ## Installation
11 |
12 | `import {MatTableModule} from '@angular/material/table';`
13 |
14 | [Official documentation](https://material.angular.io/components/table/overview)
15 |
16 |
17 |
18 | ## Example
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/stories/components/table/table.stories.ts:
--------------------------------------------------------------------------------
1 | import { Meta, moduleMetadata, StoryObj } from '@storybook/angular';
2 | import { MatTableModule } from '@angular/material/table';
3 | export default {
4 | title: 'Components/Table',
5 | decorators: [
6 | moduleMetadata({
7 | imports: [MatTableModule],
8 | }),
9 | ],
10 | parameters: {
11 | layout: 'fullscreen',
12 | controls: {
13 | expanded: true,
14 | },
15 | },
16 | } as Meta;
17 | export const WithBasicUsage: StoryObj = {
18 | render: (args) => ({
19 | props: {
20 | ...args,
21 | displayedColumns: ['position', 'name', 'weight', 'symbol'],
22 | dataSource: [
23 | {
24 | position: 1,
25 | name: 'Hydrogen',
26 | weight: 1.0079,
27 | symbol: 'H',
28 | },
29 | {
30 | position: 2,
31 | name: 'Helium',
32 | weight: 4.0026,
33 | symbol: 'He',
34 | },
35 | {
36 | position: 3,
37 | name: 'Lithium',
38 | weight: 6.941,
39 | symbol: 'Li',
40 | },
41 | {
42 | position: 4,
43 | name: 'Beryllium',
44 | weight: 9.0122,
45 | symbol: 'Be',
46 | },
47 | {
48 | position: 5,
49 | name: 'Boron',
50 | weight: 10.811,
51 | symbol: 'B',
52 | },
53 | {
54 | position: 6,
55 | name: 'Carbon',
56 | weight: 12.0107,
57 | symbol: 'C',
58 | },
59 | {
60 | position: 7,
61 | name: 'Nitrogen',
62 | weight: 14.0067,
63 | symbol: 'N',
64 | },
65 | {
66 | position: 8,
67 | name: 'Oxygen',
68 | weight: 15.9994,
69 | symbol: 'O',
70 | },
71 | {
72 | position: 9,
73 | name: 'Fluorine',
74 | weight: 18.9984,
75 | symbol: 'F',
76 | },
77 | {
78 | position: 10,
79 | name: 'Neon',
80 | weight: 20.1797,
81 | symbol: 'Ne',
82 | },
83 | ],
84 | },
85 | template: `
86 |
91 |
92 |
93 |
95 |
96 |
97 |
98 | No. |
99 | {{element.position}} |
100 |
101 |
102 |
103 |
104 | Name |
105 | {{element.name}} |
106 |
107 |
108 |
109 |
110 | Weight |
111 | {{element.weight}} |
112 |
113 |
114 |
115 |
116 | Symbol |
117 | {{element.symbol}} |
118 |
119 |
120 |
121 |
122 |
123 | `,
124 | }),
125 | name: 'basic usage',
126 | };
127 |
--------------------------------------------------------------------------------
/stories/introduction.mdx:
--------------------------------------------------------------------------------
1 | import { Meta } from '@storybook/blocks'
2 | import LinkTo from '@storybook/addon-links/react';
3 |
4 | import Code from './assets/code-brackets.svg';
5 | import Colors from './assets/colors.svg';
6 | import Comments from './assets/comments.svg';
7 | import Plugin from './assets/plugin.svg';
8 | import Repo from './assets/repo.svg';
9 | import StackAlt from './assets/stackalt.svg';
10 |
11 |
12 |
13 |
14 |
15 |
92 |
93 | # Welcome to Angular Material Storybook
94 |
95 | > Material Design components for Angular in action.
96 |
97 | Configure
98 |
99 |
100 |
101 |
102 |
103 | Theming
104 | How to dynamically change the theme palette of your UI.
105 |
106 |
107 |
108 |
109 | Discover
110 |
111 |
112 |
113 |
114 |
115 | Components
116 | Basic examples of Angular Material components in isolation.
117 |
118 |
119 |
120 |
121 |
122 | Usecases
123 | Discover real-world use cases.
124 |
125 |
126 |
127 |
128 | About this project
129 |
130 |
146 |
147 | Learn
148 |
173 |
--------------------------------------------------------------------------------
/stories/theming-preview.jsx:
--------------------------------------------------------------------------------
1 | import React, {useState} from 'react';
2 | import { Story } from "@storybook/blocks";
3 | import ArrowPrevious from './assets/arrow-previous.svg';
4 | import ArrowPreviousDisabled from './assets/arrow-previous_disabled.svg';
5 | import ArrowNext from './assets/arrow-next.svg';
6 | import ArrowNextDisabled from './assets/arrow-next_disabled.svg';
7 |
8 | export default function ThemingPreview(props) {
9 | const [activeStory, setActiveStory] = useState(props.stories[0]);
10 |
11 | const displayPreviousPreview = () => {
12 | let currentIndex = props.stories.findIndex(item => item.id === activeStory.id);
13 | setActiveStory(props.stories[--currentIndex]);
14 | }
15 |
16 | const displayNextPreview = () => {
17 | let currentIndex = props.stories.findIndex(item => item.id === activeStory.id);
18 | setActiveStory(props.stories[++currentIndex]);
19 | }
20 |
21 | return (
22 |
23 |
24 |
27 | {activeStory.name}
28 |
31 |
32 |
33 |
34 |
35 | )
36 | }
37 |
--------------------------------------------------------------------------------
/stories/theming-settings.jsx:
--------------------------------------------------------------------------------
1 | import React, {useState} from 'react';
2 | import * as tinycolor from "tinycolor2";
3 | import Diamond from './assets/diamond.svg';
4 |
5 | export default function ThemingSettings() {
6 | const [lightPrimaryColor, setLightPrimaryColor] = useState(window.getComputedStyle(document.documentElement).getPropertyValue('--light-theme-primary-500') || '#006680');
7 | const [lightAccentColor, setLightAccentColor] = useState(window.getComputedStyle(document.documentElement).getPropertyValue('--light-theme-accent-500') || '#F59432');
8 | const [lightWarnColor, setLightWarnColor] = useState(window.getComputedStyle(document.documentElement).getPropertyValue('--light-theme-warn-500') || '#f44336');
9 |
10 | const [lightPrimaryPalette, setLightPrimaryPalette] = useState(computeColors('#006680'));
11 | const [lightAccentPalette, setLightAccentPalette] = useState(computeColors('#F59432'));
12 | const [lightWarnPalette, setLightWarnPalette] = useState(computeColors('#f44336'));
13 |
14 | const [darkPrimaryColor, setDarkPrimaryColor] = useState(window.getComputedStyle(document.documentElement).getPropertyValue('--dark-theme-primary-500') || '#006680');
15 | const [darkAccentColor, setDarkAccentColor] = useState(window.getComputedStyle(document.documentElement).getPropertyValue('--dark-theme-accent-500') || '#F59432');
16 | const [darkWarnColor, setDarkWarnColor] = useState(window.getComputedStyle(document.documentElement).getPropertyValue('--dark-theme-warn-500') || '#f44336');
17 |
18 | const [darkPrimaryPalette, setDarkPrimaryPalette] = useState(computeColors('#006680'));
19 | const [darkAccentPalette, setDarkAccentPalette] = useState(computeColors('#F59432'));
20 | const [darkWarnPalette, setDarkWarnPalette] = useState(computeColors('#f44336'));
21 |
22 | const [darkMode, setDarkMode] = useState(document.documentElement.classList.contains('dark-theme'));
23 |
24 | const saveLightPrimaryColor = (e) => {
25 | const primaryColor = e.target?.value || e;
26 | setLightPrimaryColor(primaryColor);
27 | const primaryColorPalette = computeColors(primaryColor);
28 | setLightPrimaryPalette(primaryColorPalette);
29 | updateTheme(primaryColorPalette, 'primary', 'light');
30 | }
31 |
32 | const saveLightAccentColor = (e) => {
33 | const accentColor = e.target?.value || e;
34 | setLightAccentColor(accentColor);
35 | const accentColorPalette = computeColors(accentColor);
36 | setLightAccentPalette(accentColorPalette);
37 | updateTheme(accentColorPalette, 'accent', 'light');
38 | }
39 |
40 | const saveLightWarnColor = (e) => {
41 | const warnColor = e.target?.value || e;
42 | setLightWarnColor(warnColor);
43 | const warnColorPalette = computeColors(warnColor);
44 | setLightWarnPalette(warnColorPalette);
45 | updateTheme(warnColorPalette, 'warn', 'light');
46 | }
47 |
48 | const saveDarkPrimaryColor = (e) => {
49 | const primaryColor = e.target?.value || e;
50 | setDarkPrimaryColor(primaryColor);
51 | const primaryColorPalette = computeColors(primaryColor);
52 | setDarkPrimaryPalette(primaryColorPalette);
53 | updateTheme(primaryColorPalette, 'primary', 'dark');
54 | }
55 |
56 | const saveDarkAccentColor = (e) => {
57 | const accentColor = e.target?.value || e;
58 | setDarkAccentColor(accentColor);
59 | const accentColorPalette = computeColors(accentColor);
60 | setDarkAccentPalette(accentColorPalette);
61 | updateTheme(accentColorPalette, 'accent', 'dark');
62 | }
63 |
64 | const saveDarkWarnColor = (e) => {
65 | const warnColor = e.target?.value || e;
66 | setDarkWarnColor(warnColor);
67 | const warnColorPalette = computeColors(warnColor);
68 | setDarkWarnPalette(warnColorPalette);
69 | updateTheme(warnColorPalette, 'warn', 'dark');
70 | }
71 |
72 | const saveIndigoPreset = () => {
73 | saveLightPrimaryColor('#3f51b5');
74 | setLightPrimaryColor('#3f51b5');
75 | saveLightAccentColor('#ff4081');
76 | setLightAccentColor('#ff4081');
77 | saveLightWarnColor('#f44336');
78 | setLightWarnColor('#f44336');
79 | }
80 |
81 | const saveDeepPurplePreset = () => {
82 | saveLightPrimaryColor('#673ab7');
83 | setLightPrimaryColor('#673ab7');
84 | saveLightAccentColor('#ffd740');
85 | setLightAccentColor('#ffd740');
86 | saveLightWarnColor('#f44336');
87 | setLightWarnColor('#f44336');
88 | }
89 |
90 | const savePinkPreset = () => {
91 | saveLightPrimaryColor('#e91e63');
92 | setLightPrimaryColor('#e91e63');
93 | saveLightAccentColor('#607d8b');
94 | setLightAccentColor('#607d8b');
95 | saveLightWarnColor('#f44336');
96 | setLightWarnColor('#f44336');
97 | }
98 |
99 | const savePurplePreset = () => {
100 | saveLightPrimaryColor('#9c27b0');
101 | setLightPrimaryColor('#9c27b0');
102 | saveLightAccentColor('#69f0ae');
103 | setLightAccentColor('#69f0ae');
104 | saveLightWarnColor('#f44336');
105 | setLightWarnColor('#f44336');
106 | }
107 |
108 | const toggleDarkTheme = (mode) => {
109 | const newMode = mode ?? !darkMode;
110 | if(newMode) {
111 | document.documentElement.classList.add('dark-theme');
112 | } else {
113 | document.documentElement.classList.remove('dark-theme');
114 | }
115 | setDarkMode(newMode);
116 | }
117 |
118 | return (
119 | <>
120 |
121 |
122 |
123 |
124 |
125 |
129 |
170 |
171 |
212 |
213 |
214 |
215 | Presets
216 |
217 |
218 |
223 |
224 |
229 |
230 |
235 |
236 |
241 |
242 | >
243 | );
244 | }
245 |
246 | function updateTheme(colors, theme, mode) {
247 | colors.forEach(color => {
248 | document.body.style.setProperty(
249 | `--${mode}-theme-${theme}-${color.name}`,
250 | color.hex
251 | );
252 | document.body.style.setProperty(
253 | `--${mode}-theme-${theme}-contrast-${color.name}`,
254 | color.darkContrast ? 'black' : 'white'
255 | );
256 | });
257 | }
258 |
259 | function computeColors(hex) {
260 | return [
261 | getColorObject(tinycolor(hex).lighten(52), '50'),
262 | getColorObject(tinycolor(hex).lighten(37), '100'),
263 | getColorObject(tinycolor(hex).lighten(26), '200'),
264 | getColorObject(tinycolor(hex).lighten(12), '300'),
265 | getColorObject(tinycolor(hex).lighten(6), '400'),
266 | getColorObject(tinycolor(hex), '500'),
267 | getColorObject(tinycolor(hex).darken(6), '600'),
268 | getColorObject(tinycolor(hex).darken(12), '700'),
269 | getColorObject(tinycolor(hex).darken(18), '800'),
270 | getColorObject(tinycolor(hex).darken(24), '900'),
271 | getColorObject(tinycolor(hex).lighten(50).saturate(30), 'A100'),
272 | getColorObject(tinycolor(hex).lighten(30).saturate(30), 'A200'),
273 | getColorObject(tinycolor(hex).lighten(10).saturate(15), 'A400'),
274 | getColorObject(tinycolor(hex).lighten(5).saturate(5), 'A700')
275 | ];
276 | }
277 |
278 | function getColorObject(value, name) {
279 | const c = tinycolor(value);
280 | return {
281 | name: name,
282 | hex: c.toHexString(),
283 | darkContrast: c.isLight()
284 | };
285 | }
286 |
--------------------------------------------------------------------------------
/stories/theming.mdx:
--------------------------------------------------------------------------------
1 | import { Meta } from '@storybook/blocks'
2 |
3 | import ThemingSettings from "./theming-settings";
4 | import ThemingPreview from "./theming-preview";
5 |
6 |
7 |
8 |
33 |
--------------------------------------------------------------------------------
/stories/usecases/authentication/change-password/change-password.component.ts:
--------------------------------------------------------------------------------
1 | import {Component} from "@angular/core";
2 | import {MatFormFieldModule} from "@angular/material/form-field";
3 | import {MatButtonModule} from "@angular/material/button";
4 | import {MatInputModule} from "@angular/material/input";
5 | import {MatIconModule} from "@angular/material/icon";
6 |
7 | @Component({
8 | template: `
9 |
35 | `,
36 | styles: [
37 | ':host {display: flex; justify-content: center; height: 100%; width: 100%}',
38 | '.form-container {display: flex; flex-direction: column; justify-content: center;}',
39 | '.change-password__save-button {margin-block-start: 1rem; margin-block-end: 1rem}',
40 | '.change-password__cancel-button {margin-block-end: 1rem}',
41 | '.change-password__title {margin-block-end: 3rem}'
42 | ],
43 | standalone: true,
44 | imports: [
45 | MatButtonModule,
46 | MatIconModule,
47 | MatFormFieldModule,
48 | MatInputModule,
49 | ]
50 | })
51 | export class ChangePasswordComponent {
52 | constructor() {
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/stories/usecases/authentication/change-password/change-password.stories.ts:
--------------------------------------------------------------------------------
1 | import { Meta, moduleMetadata, StoryObj } from '@storybook/angular';
2 | import { ChangePasswordComponent } from './change-password.component';
3 | import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
4 | import { defaultUsecasesParameters } from '../../../../.storybook/utils';
5 |
6 | export default {
7 | title: 'usecases/authentication/change password',
8 | component: ChangePasswordComponent,
9 | parameters: {
10 | ...defaultUsecasesParameters,
11 | },
12 | decorators: [
13 | moduleMetadata({
14 | imports: [BrowserAnimationsModule],
15 | }),
16 | ],
17 | } as Meta;
18 |
19 | export const ChangePassword: StoryObj = {
20 | render: (args) => ({
21 | props: args,
22 | }),
23 | name: 'change password',
24 | };
25 |
--------------------------------------------------------------------------------
/stories/usecases/dialog/confirmation-dialog.component.ts:
--------------------------------------------------------------------------------
1 | import {Component, ViewEncapsulation} from "@angular/core";
2 | import {MatDialog, MatDialogModule} from "@angular/material/dialog";
3 | import {MatIconModule} from "@angular/material/icon";
4 | import {MatButtonModule} from "@angular/material/button";
5 |
6 | @Component({
7 | template: `
8 |
11 | `,
12 | styles: [
13 | 'section {display: flex; justify-content: center; align-items: center; height: 100%}',
14 | '.dialog-border mat-dialog-container {border-radius: 20px; border: 5px solid green} '
15 | ],
16 | standalone: true,
17 | imports: [
18 | MatDialogModule,
19 | MatButtonModule
20 | ],
21 | encapsulation: ViewEncapsulation.None
22 | })
23 | export class ConfirmationDialogComponent {
24 | constructor(private readonly dialog: MatDialog) {}
25 |
26 | openDialog(): void {
27 | this.dialog.open(ConfirmationDialogDialogComponent, {
28 | width: '250px',
29 | autoFocus: false,
30 | panelClass: 'dialog-border'
31 | });
32 | }
33 | }
34 |
35 | @Component({
36 | template: `
37 | check_circle
38 | Your order has been created successfully!
39 |
40 | `,
41 | styles: [
42 | ':host {display: flex; justify-content: center; align-items: center; flex-direction: column}',
43 | 'h3 {text-align: center}',
44 | 'mat-icon {color: green; height: 6rem; width: 6rem; font-size: 6rem}'
45 | ],
46 | standalone: true,
47 | imports: [
48 | MatIconModule,
49 | MatButtonModule,
50 | MatDialogModule
51 | ]
52 | })
53 | class ConfirmationDialogDialogComponent {
54 | }
55 |
--------------------------------------------------------------------------------
/stories/usecases/dialog/confirmation-dialog.stories.ts:
--------------------------------------------------------------------------------
1 | import { Meta, moduleMetadata, StoryObj } from '@storybook/angular';
2 | import { ConfirmationDialogComponent } from './confirmation-dialog.component';
3 | import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
4 | import { defaultUsecasesParameters } from '../../../.storybook/utils';
5 |
6 | export default {
7 | title: 'Usecases/Dialog',
8 | component: ConfirmationDialogComponent,
9 | decorators: [
10 | moduleMetadata({
11 | imports: [BrowserAnimationsModule],
12 | }),
13 | ],
14 | parameters: {
15 | ...defaultUsecasesParameters,
16 | },
17 | } as Meta;
18 |
19 | export const Template: StoryObj = {
20 | render: (args) => ({
21 | props: args,
22 | }),
23 | name: 'success (custom css)',
24 | };
25 |
--------------------------------------------------------------------------------
/stories/usecases/introduction.mdx:
--------------------------------------------------------------------------------
1 | import { Meta } from '@storybook/addon-docs';
2 |
3 |
4 |
5 |
82 |
83 | # Angular Material usecases
84 |
85 | > Discover real-world use cases.
86 |
87 | Components
88 |
89 |
108 |
--------------------------------------------------------------------------------
/stories/usecases/navigation/collapsible-vertical-navigation/collapsible-vertical-navigation.component.ts:
--------------------------------------------------------------------------------
1 | import {Component} from "@angular/core";
2 | import {MatIconModule} from "@angular/material/icon";
3 | import {MatListModule} from "@angular/material/list";
4 | import {MatSidenavModule} from "@angular/material/sidenav";
5 | import {MatBadgeModule} from "@angular/material/badge";
6 | import {BrowserAnimationsModule} from "@angular/platform-browser/animations";
7 |
8 | @Component({
9 | selector: 'app-fab-bottom-navigation',
10 | template: `
11 |
12 |
13 |
14 |
15 | account_circle
16 | Profile
17 |
18 |
19 | notifications
20 | Notifications
21 |
22 |
23 | home
24 | Dashboard
25 |
26 |
27 | shopping_cart
28 | Cart
29 |
30 |
31 | stars
32 | Wish list
33 |
34 |
35 | settings
36 | Settings
37 |
38 |
39 |
40 | Main content
41 | `,
42 | styles:[
43 | 'mat-drawer-container {height: 100%; width: 100%;}',
44 | 'a[matLine] {max-width: 0;transition-property: max-width;transition-duration: 0.3s;}',
45 | 'mat-nav-list:hover a[matLine] {max-width: 1000px;}',
46 | '::ng-deep .mat-list-text {padding-left: 0 !important;transition-property: padding-left;transition-duration: 0.4s;}',
47 | 'mat-nav-list:hover ::ng-deep .mat-list-text {padding-left: 16px !important;}'
48 | ],
49 | standalone: true,
50 | imports: [
51 | BrowserAnimationsModule,
52 | MatListModule,
53 | MatSidenavModule,
54 | MatIconModule,
55 | MatBadgeModule,
56 | ]
57 | })
58 | export class CollapsibleVerticalNavigationComponent {
59 | }
60 |
--------------------------------------------------------------------------------
/stories/usecases/navigation/collapsible-vertical-navigation/collapsible-vertical-navigation.stories.ts:
--------------------------------------------------------------------------------
1 | import { Meta, StoryObj } from '@storybook/angular';
2 | import { defaultUsecasesParameters } from '../../../../.storybook/utils';
3 | import { CollapsibleVerticalNavigationComponent } from './collapsible-vertical-navigation.component';
4 |
5 | export default {
6 | title: 'Usecases/Navigation',
7 | component: CollapsibleVerticalNavigationComponent,
8 | parameters: {
9 | ...defaultUsecasesParameters,
10 | viewport: {
11 | defaultViewport: 'mobile1',
12 | },
13 | },
14 | } as Meta;
15 |
16 | export const CollapsibleVerticalNavigation: StoryObj = {
17 | render: (args) => ({
18 | props: args,
19 | }),
20 | name: 'collapsible vertical navigation',
21 | };
22 |
--------------------------------------------------------------------------------
/stories/usecases/navigation/fab-bottom-navigation/fab-bottom-navigation.component.ts:
--------------------------------------------------------------------------------
1 | import {Component} from "@angular/core";
2 | import {MatToolbarModule} from "@angular/material/toolbar";
3 | import {MatIconModule} from "@angular/material/icon";
4 | import {MatButtonModule} from "@angular/material/button";
5 |
6 | @Component({
7 | selector: 'app-fab-bottom-navigation',
8 | template: `
9 |
10 |
18 |
26 |
29 | `,
30 | styles:[
31 | ':host {height: 100vh; margin: 0;}',
32 | 'mat-toolbar {position: absolute;bottom: 0;display: flex;justify-content: space-between;}',
33 | 'section {width: 40%;display: flex;justify-content: space-around;}',
34 | 'a[mat-icon-button]:not([color]) {color: darkslategrey;}',
35 | 'button[mat-fab] {position: absolute;margin-left: auto;margin-right: auto;left: 0;right: 0;text-align: center;bottom: 30px;}'
36 | ],
37 | standalone: true,
38 | imports: [MatToolbarModule, MatIconModule, MatButtonModule]
39 | })
40 | export class FabBottomNavigationComponent {
41 | }
42 |
--------------------------------------------------------------------------------
/stories/usecases/navigation/fab-bottom-navigation/fab-bottom-navigation.stories.ts:
--------------------------------------------------------------------------------
1 | import { Meta, StoryObj } from '@storybook/angular';
2 | import { FabBottomNavigationComponent } from './fab-bottom-navigation.component';
3 | import { defaultUsecasesParameters } from '../../../../.storybook/utils';
4 |
5 | export default {
6 | title: 'Usecases/Navigation',
7 | component: FabBottomNavigationComponent,
8 | parameters: {
9 | ...defaultUsecasesParameters,
10 | viewport: {
11 | defaultViewport: 'mobile1',
12 | },
13 | },
14 | } as Meta;
15 |
16 | export const Template: StoryObj = {
17 | render: (args) => ({
18 | props: args,
19 | }),
20 | name: 'bottom navigation 1',
21 | };
22 |
--------------------------------------------------------------------------------
/stories/usecases/navigation/fab-icon-menu/fab-icon-menu.component.ts:
--------------------------------------------------------------------------------
1 | import {Component} from "@angular/core";
2 | import {MatButtonModule} from "@angular/material/button";
3 | import {MatIconModule} from "@angular/material/icon";
4 | import {OverlayModule} from "@angular/cdk/overlay";
5 |
6 | @Component({
7 | selector: 'app-fab-icon-menu',
8 | template: `
9 |
13 |
18 |
40 |
41 | ,
42 | `,
43 | styles: [
44 | ':host {height: 100vh; margin: 0;}',
45 | '.fab-menu-btn {position: absolute;right: 1rem; bottom: 1rem;}',
46 | '.fab-menu-list {list-style-type: none; padding:0; margin: 0;}',
47 | '.fab-menu-list li {margin-block-end: 0.5rem;}',
48 | '.fab-menu-list li button {background: white;}',
49 | ],
50 | standalone: true,
51 | imports: [
52 | MatButtonModule,
53 | MatIconModule,
54 | OverlayModule
55 | ]
56 | })
57 | export class FabIconMenuComponent {
58 | isOpen = false;
59 | }
60 |
--------------------------------------------------------------------------------
/stories/usecases/navigation/fab-icon-menu/fab-icon-menu.stories.ts:
--------------------------------------------------------------------------------
1 | import { Meta, StoryObj } from '@storybook/angular';
2 | import { defaultUsecasesParameters } from '../../../../.storybook/utils';
3 | import { FabIconMenuComponent } from './fab-icon-menu.component';
4 |
5 | export default {
6 | title: 'Usecases/Navigation',
7 | component: FabIconMenuComponent,
8 | parameters: {
9 | ...defaultUsecasesParameters,
10 | viewport: {
11 | defaultViewport: 'mobile1',
12 | },
13 | },
14 | } as Meta;
15 |
16 | export const Fab: StoryObj = {
17 | render: (args) => ({
18 | props: args,
19 | }),
20 | name: 'fab menu (with icons)',
21 | };
22 |
--------------------------------------------------------------------------------
/stories/usecases/progress-indicators/toolbar-loader.stories.ts:
--------------------------------------------------------------------------------
1 | import { Meta, moduleMetadata, StoryObj } from '@storybook/angular';
2 | import { MatToolbarModule } from '@angular/material/toolbar';
3 | import { MatProgressBarModule } from '@angular/material/progress-bar';
4 | import { MatButtonModule } from '@angular/material/button';
5 | import { MatIconModule } from '@angular/material/icon';
6 | import { progressBarArgtypes } from '../../components/progress-bar/progress-bar.argtype';
7 | import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
8 | import { progressSpinnerArgtypes } from '../../components/progress-spinner/progress-spinner.argtype';
9 | import { MatBadgeModule } from '@angular/material/badge';
10 | import { defaultUsecasesParameters } from '../../../.storybook/utils';
11 |
12 | export default {
13 | title: 'usecases/Progress indicators',
14 | decorators: [
15 | moduleMetadata({
16 | imports: [
17 | MatToolbarModule,
18 | MatProgressBarModule,
19 | MatProgressSpinnerModule,
20 | MatButtonModule,
21 | MatIconModule,
22 | MatBadgeModule,
23 | ],
24 | }),
25 | ],
26 | argTypes: progressBarArgtypes,
27 | parameters: {
28 | ...defaultUsecasesParameters,
29 | },
30 | } as Meta;
31 |
32 | export const Toolbar: StoryObj = {
33 | render: (args) => ({
34 | props: args,
35 | template: `
36 |
42 |
43 |
46 |
49 |
50 | `,
51 | }),
52 | name: 'toolbar',
53 | };
54 |
55 | export const Fullscreen: StoryObj = {
56 | render: (args) => ({
57 | props: args,
58 | template: `
59 |
77 |
78 |
79 |
80 | Getting your files
81 |
82 |
83 |
84 | Getting your files
85 |
86 |
87 | `,
88 | }),
89 | name: 'fullscreen',
90 | argTypes: {
91 | ...progressSpinnerArgtypes,
92 | ...progressBarArgtypes,
93 | },
94 | };
95 |
--------------------------------------------------------------------------------
/stories/usecases/settings/generic-settings.component.ts:
--------------------------------------------------------------------------------
1 | import {Component} from "@angular/core";
2 | import {MatDividerModule} from "@angular/material/divider";
3 | import {MatRadioModule} from "@angular/material/radio";
4 | import {MatIconModule} from "@angular/material/icon";
5 | import {MatSlideToggleModule} from "@angular/material/slide-toggle";
6 | import {CommonModule} from "@angular/common";
7 | import {MatButtonModule} from "@angular/material/button";
8 | import {FormsModule} from "@angular/forms";
9 | import {MatToolbarModule} from "@angular/material/toolbar";
10 |
11 | @Component({
12 | template: `
13 |
14 |
15 | SETTINGS
16 |
17 |
18 | DIRECT MESSAGES
19 |
20 |
21 | from all users
22 |
23 |
24 | from my friends
25 |
26 |
27 | no direct messages
28 |
29 |
30 |
31 |
32 | PREFERENCES
33 |
49 |
50 |
51 | SECURITY
52 |
53 |
54 | `,
55 | styles: [
56 | `
57 | :host {
58 | display: flex;
59 | flex-direction: column;
60 | }
61 | .settings-header__icon {
62 | margin-inline-end: 1rem;
63 | }
64 |
65 | .settings__main-container {
66 | display: flex;
67 | flex-direction: column;
68 | padding: 1rem;
69 | }
70 |
71 |
72 | .settings__messages-group {
73 | display: flex;
74 | flex-direction: column;
75 | }
76 |
77 | .settings__messages-field + .settings__messages-field {
78 | margin-block-start: 0.5rem;
79 | }
80 |
81 | .settings__preferences-list {
82 | list-style-type: none;
83 | margin: 0;
84 | padding: 0;
85 | }
86 |
87 | .settings__prefences-item {
88 | display: flex;
89 | justify-content: space-between;
90 | }
91 |
92 | .settings__prefences-item + .settings__prefences-item {
93 | margin-block-start: 0.5rem;
94 | }
95 |
96 | .settings__prefences-item-title {
97 | display: flex;
98 | align-items: center;
99 | }
100 |
101 | @media (min-width: 800px) {
102 | :host {
103 | align-items: center;
104 | }
105 | .settings__main-container {
106 | max-width: 400px;
107 | width: calc(100% - 2rem);
108 | }
109 | }
110 | `
111 | ],
112 | standalone: true,
113 | imports: [
114 | CommonModule,
115 | MatDividerModule,
116 | MatSlideToggleModule,
117 | MatIconModule,
118 | MatRadioModule,
119 | FormsModule,
120 | MatToolbarModule,
121 | MatButtonModule
122 | ]
123 | })
124 | export class GenericSettingsComponent {
125 | constructor() {
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/stories/usecases/settings/generic-settings.stories.ts:
--------------------------------------------------------------------------------
1 | import { Meta, StoryObj } from '@storybook/angular';
2 | import { GenericSettingsComponent } from './generic-settings.component';
3 | import { defaultUsecasesParameters } from '../../../.storybook/utils';
4 |
5 | export default {
6 | title: 'usecases/Settings',
7 | component: GenericSettingsComponent,
8 | parameters: {
9 | ...defaultUsecasesParameters,
10 | },
11 | } as Meta;
12 |
13 | export const Generic: StoryObj = {
14 | render: (args) => ({
15 | props: args,
16 | }),
17 | name: 'generic',
18 | };
19 |
--------------------------------------------------------------------------------
/stories/usecases/settings/wifi-settings.component.ts:
--------------------------------------------------------------------------------
1 | import {Component} from "@angular/core";
2 | import {MatToolbarModule} from "@angular/material/toolbar";
3 | import {MatIconModule} from "@angular/material/icon";
4 | import {MatSlideToggleModule} from "@angular/material/slide-toggle";
5 | import {MatListModule} from "@angular/material/list";
6 | import {MatDividerModule} from "@angular/material/divider";
7 | import {MatButtonModule} from "@angular/material/button";
8 |
9 | @Component({
10 | template: `
11 |
12 |
13 | Wi-Fi
14 |
15 |
16 | Activate Wi-Fi
17 |
18 |
19 |
20 |
21 |
29 |
30 |
31 |
32 |
33 | signal_wifi_4_bar
34 | 7D7ZIOH3
35 | very fast
36 |
37 |
38 |
39 |
40 | network_wifi_2_bar
41 | ez89u321j
42 | slow
43 |
44 |
45 |
46 |
47 | network_wifi_3_bar
48 | huhuHI89Zza
49 | fast
50 |
51 |
52 |
53 | `,
54 | styles: [
55 | `
56 | .wifi-header__back-button {
57 | margin-inline-end: 1rem;
58 | }
59 |
60 | .wifi-toolbar__activate {
61 | display: flex;
62 | align-items: center;
63 | justify-content: space-between;
64 | }
65 |
66 | .wifi__activated {
67 | color: green;
68 | }
69 | `
70 | ],
71 | standalone: true,
72 | imports: [
73 | MatToolbarModule,
74 | MatIconModule,
75 | MatSlideToggleModule,
76 | MatListModule,
77 | MatDividerModule,
78 | MatButtonModule
79 | ]
80 | })
81 | export class WifiSettingsComponent {
82 | constructor() {
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/stories/usecases/settings/wifi-settings.stories.ts:
--------------------------------------------------------------------------------
1 | import { Meta, StoryObj } from '@storybook/angular';
2 | import { WifiSettingsComponent } from './wifi-settings.component';
3 | import { defaultUsecasesParameters } from '../../../.storybook/utils';
4 |
5 | export default {
6 | title: 'usecases/Settings',
7 | component: WifiSettingsComponent,
8 | parameters: {
9 | ...defaultUsecasesParameters,
10 | },
11 | } as Meta;
12 |
13 | export const Wifi: StoryObj = {
14 | render: (args) => ({
15 | props: args,
16 | }),
17 | name: 'Wi-Fi',
18 | };
19 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "compileOnSave": false,
4 | "compilerOptions": {
5 | "baseUrl": "./",
6 | "outDir": "./dist/out-tsc",
7 | "forceConsistentCasingInFileNames": true,
8 | "strict": true,
9 | "noImplicitOverride": true,
10 | "noPropertyAccessFromIndexSignature": true,
11 | "noImplicitReturns": true,
12 | "noFallthroughCasesInSwitch": true,
13 | "sourceMap": true,
14 | "declaration": false,
15 | "downlevelIteration": true,
16 | "experimentalDecorators": true,
17 | "moduleResolution": "node",
18 | "importHelpers": true,
19 | "target": "ES2022",
20 | "module": "es2020",
21 | "lib": [
22 | "es2020",
23 | "dom"
24 | ],
25 | "useDefineForClassFields": false
26 | },
27 | "angularCompilerOptions": {
28 | "enableI18nLegacyMessageIdFormat": false,
29 | "strictInjectionParameters": true,
30 | "strictInputAccessModifiers": true,
31 | "strictTemplates": true
32 | }
33 | }
34 |
--------------------------------------------------------------------------------