Add back storybook

This commit is contained in:
David Burke committed 2024-12-22 12:07:04 -05:00
1 parent f999c93328
commit 22f1b8aaf7
19 files changed
+2765 -203

No files matched your search

+4 -1
View File
@@ -46,5 +46,8 @@
],
"rules": {}
}
],
"extends": [
"plugin:storybook/recommended"
]
}
}
+2
View File
@@ -52,3 +52,5 @@ projects/marketing/routes.txt
buildStaticSite.js
projects/marketing/public/blog/blogIndex.json
projects/marketing/public/blog/rss.xml
*storybook.log
-15
View File
@@ -1,15 +0,0 @@
module.exports = {
stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
addons: [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/addon-actions",
"@storybook/addon-a11y",
"@storybook/addon-themes",
],
framework: {
name: "@storybook/angular",
options: {},
},
docs: {},
};
+16
View File
@@ -0,0 +1,16 @@
import type { StorybookConfig } from "@storybook/angular";
const config: StorybookConfig = {
stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"],
addons: [
"@storybook/addon-onboarding",
"@storybook/addon-essentials",
"@chromatic-com/storybook",
"@storybook/addon-interactions",
],
framework: {
name: "@storybook/angular",
options: {},
},
};
export default config;
+16 -38
View File
@@ -1,42 +1,20 @@
import { importProvidersFrom } from "@angular/core";
import { withThemeByClassName } from "@storybook/addon-themes";
import { applicationConfig } from "@storybook/angular";
import { setCompodocJson } from "@storybook/addon-docs/angular";
import docJson from "../documentation.json";
setCompodocJson(docJson);
import { applicationConfig, type Preview } from "@storybook/angular";
import "@angular/localize/init";
import { HttpClientTestingModule } from "@angular/common/http/testing";
import { MatSnackBarModule } from "@angular/material/snack-bar";
import { provideAnimations } from "@angular/platform-browser/animations";
import { RouterTestingModule } from "@angular/router/testing";
import { MicroSentryModule } from "@micro-sentry/angular";
export const decorators = [
withThemeByClassName({
themes: {
light: "light",
dark: "dark",
},
defaultTheme: "light",
}),
applicationConfig({
providers: [
importProvidersFrom(MatSnackBarModule),
importProvidersFrom(HttpClientTestingModule),
importProvidersFrom(RouterTestingModule),
provideAnimations(),
importProvidersFrom(MicroSentryModule.forRoot({})),
],
}),
];
export const parameters = {
actions: { argTypesRegex: "^on[A-Z].*" },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
const preview: Preview = {
parameters: {
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/i,
},
},
},
decorators: [
applicationConfig({
providers: [],
}),
],
};
export const tags = ["autodocs"];
export default preview;
+10
View File
@@ -0,0 +1,10 @@
// This tsconfig is used by Compodoc to generate the documentation for the project.
// If Compodoc is not used, this file can be deleted.
{
"extends": "./tsconfig.json",
// Exclude all files that are not needed for documentation generation.
"exclude": ["../src/test.ts", "../src/**/*.spec.ts", "../src/**/*.stories.ts"],
// Please make sure to include all files from which Compodoc should generate documentation.
"include": ["../src/**/*"],
"files": ["./typings.d.ts"]
}
+6 -17
View File
@@ -1,22 +1,11 @@
{
"extends": "../tsconfig.app.json",
"compilerOptions": {
"types": [
"node"
],
"skipLibCheck": true
"types": ["node"],
"allowSyntheticDefaultImports": true,
"resolveJsonModule": true
},
"exclude": [
"../src/test.ts",
"../src/**/*.spec.ts",
"../projects/**/*.spec.ts"
],
"include": [
"../src/**/*",
"../projects/**/*"
],
"files": [
"./preview.ts",
"./typings.d.ts"
]
"exclude": ["../src/test.ts", "../src/**/*.spec.ts"],
"include": ["../src/**/*.stories.*", "./preview.ts"],
"files": ["./typings.d.ts"]
}
+5
View File
@@ -2,3 +2,8 @@ declare module "*.md" {
const content: string;
export default content;
}
interface Window {
plausible?: any;
Cypress?: unknown;
}
+53 -16
View File
@@ -36,7 +36,10 @@
"base": "dist/glitchtip-frontend"
},
"index": "src/index.html",
"polyfills": ["zone.js", "@angular/localize/init"],
"polyfills": [
"zone.js",
"@angular/localize/init"
],
"tsConfig": "tsconfig.app.json",
"inlineStyleLanguage": "scss",
"assets": [
@@ -62,9 +65,15 @@
"output": "./static/assets/images/os-logos"
}
],
"styles": ["src/styles.scss"],
"styles": [
"src/styles.scss"
],
"stylePreprocessorOptions": {
"includePaths": ["./src/assets/styles", "", "."]
"includePaths": [
"./src/assets/styles",
"",
"."
]
},
"scripts": [],
"browser": "src/main.ts"
@@ -161,14 +170,24 @@
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"polyfills": ["zone.js", "zone.js/testing"],
"polyfills": [
"zone.js",
"zone.js/testing"
],
"tsConfig": "tsconfig.spec.json",
"karmaConfig": "karma.conf.js",
"inlineStyleLanguage": "scss",
"assets": ["src/favicon.ico", "src/assets"],
"styles": ["src/styles.scss"],
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.scss"
],
"stylePreprocessorOptions": {
"includePaths": ["./src/assets/styles"]
"includePaths": [
"./src/assets/styles"
]
},
"scripts": []
}
@@ -176,7 +195,10 @@
"lint": {
"builder": "@angular-eslint/builder:lint",
"options": {
"lintFilePatterns": ["src/**/*.ts", "src/**/*.html"]
"lintFilePatterns": [
"src/**/*.ts",
"src/**/*.html"
]
}
},
"storybook": {
@@ -194,7 +216,7 @@
"configDir": ".storybook",
"browserTarget": "glitchtip-frontend:build",
"compodoc": false,
"outputDir": "storybook-static"
"outputDir": "dist/storybook/glitchtip-frontend"
}
}
}
@@ -216,7 +238,10 @@
"outputPath": "dist/marketing",
"index": "projects/marketing/src/index.html",
"browser": "projects/marketing/src/main.ts",
"polyfills": ["zone.js", "@angular/localize/init"],
"polyfills": [
"zone.js",
"@angular/localize/init"
],
"tsConfig": "projects/marketing/tsconfig.app.json",
"inlineStyleLanguage": "scss",
"assets": [
@@ -230,9 +255,14 @@
"output": "static/sdk-docs"
}
],
"styles": ["projects/marketing/src/styles.scss"],
"styles": [
"projects/marketing/src/styles.scss"
],
"stylePreprocessorOptions": {
"includePaths": ["./src/assets/styles", ""]
"includePaths": [
"./src/assets/styles",
""
]
},
"scripts": [],
"server": "projects/marketing/src/main.server.ts",
@@ -286,7 +316,10 @@
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"polyfills": ["zone.js", "zone.js/testing"],
"polyfills": [
"zone.js",
"zone.js/testing"
],
"tsConfig": "projects/marketing/tsconfig.spec.json",
"inlineStyleLanguage": "scss",
"assets": [
@@ -295,7 +328,9 @@
"input": "projects/marketing/public"
}
],
"styles": ["projects/marketing/src/styles.scss"],
"styles": [
"projects/marketing/src/styles.scss"
],
"scripts": []
}
},
@@ -313,6 +348,8 @@
},
"cli": {
"analytics": "86390919-7a40-4e23-8811-d61b83438874",
"schematicCollections": ["@angular-eslint/schematics"]
"schematicCollections": [
"@angular-eslint/schematics"
]
}
}
}
+2499 -18
View File
File diff suppressed because it is too large. Load diff
+11 -1
View File
@@ -22,7 +22,8 @@
"docs:json": "compodoc -p ./tsconfig.json -e json -d .",
"extract-i18n": "ng extract-i18n",
"i18n-create-json": "bin/xliff-to-json/xliff-to-json src/locale/ && mv src/locale/*.json src/assets/i18n/",
"serve:ssr:marketing": "node dist/marketing/server/server.mjs"
"serve:ssr:marketing": "node dist/marketing/server/server.mjs",
"storybook": "ng run glitchtip-frontend:storybook"
},
"dependencies": {
"@angular/animations": "~19.0.5",
@@ -70,9 +71,16 @@
"@angular/language-service": "~19.0.5",
"@angular/localize": "~19.0.5",
"@babel/core": "^7.7.2",
"@chromatic-com/storybook": "^3.2.3",
"@compodoc/compodoc": "^1.1.19",
"@cypress/webpack-preprocessor": "^6.0.2",
"@openapitools/openapi-generator-cli": "^2.15.3",
"@storybook/addon-essentials": "^8.4.7",
"@storybook/addon-interactions": "^8.4.7",
"@storybook/addon-onboarding": "^8.4.7",
"@storybook/angular": "^8.4.7",
"@storybook/blocks": "^8.4.7",
"@storybook/test": "^8.4.7",
"@types/d3": "^7.4.0",
"@types/express": "^4.17.17",
"@types/fs-extra": "^11.0.4",
@@ -88,6 +96,7 @@
"cypress": "^13.13.3",
"cypress-localstorage-commands": "^2.2.6",
"eslint": "^8.0.0",
"eslint-plugin-storybook": "^0.11.1",
"jasmine-core": "^5.0.0",
"jasmine-spec-reporter": "~7.0.0",
"karma": "~6.4.2",
@@ -96,6 +105,7 @@
"karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "^2.1.0",
"ng-extract-i18n-merge": "^2.13.1",
"storybook": "^8.4.7",
"ts-loader": "^9.2.6",
"ts-node": "~7.0.0",
"typescript": "^5.6.3",
@@ -1,32 +0,0 @@
import { Meta } from "@storybook/angular";
import { of } from "rxjs";
import { totpUserKey } from "./test-data";
import { TOTPComponent } from "./totp.component";
export default {
title: "profile/TOTP",
component: TOTPComponent,
} as Meta;
export const Disabled = () => ({
props: {
TOTPKey$: of(null),
},
});
export const QRCode = () => ({
props: {
TOTPKey$: of(null),
step$: of(3),
TOTP$: of({
provisioning_uri: "https://www.example.com",
secret_key: "AAAAAAAAAA",
}),
},
});
export const Enabled = () => ({
props: {
TOTPKey$: of(totpUserKey),
},
});
@@ -1,65 +0,0 @@
// import { Meta, StoryObj } from "@storybook/angular";
// import { of } from "rxjs";
// import { SocialAuthComponent } from "./social-auth.component";
// const meta: Meta<SocialAuthComponent> = {
// title: "Profile/Social Auth",
// component: SocialAuthComponent,
// };
// const loadingOptions: { [index: string]: any } = {
// First: 3,
// Second: 4,
// None: null,
// };
// export default meta;
// type Story = StoryObj<SocialAuthComponent>;
// export const Default: Story = {
// args: {
// disconnectLoading$: of(loadingOptions["First"]),
// user$: of({
// username: "rain@bow.com",
// lastLogin: "2020-10-29T15:51:52.193929Z",
// isSuperuser: true,
// emails: [],
// identities: [
// {
// id: 3,
// name: "",
// provider: "google",
// uid: "secret",
// last_login: "2020-10-29T15:51:52.182486Z",
// date_joined: "2020-10-29T15:51:52.182546Z",
// email: "a@a.aa",
// username: null,
// },
// {
// id: 4,
// name: "",
// provider: "google",
// uid: "secret",
// last_login: "2020-10-29T15:51:52.182486Z",
// date_joined: "2020-10-29T15:51:52.182546Z",
// email: "b@b.bb",
// username: null,
// },
// ],
// id: "1",
// isActive: true,
// name: "",
// dateJoined: "2020-08-18T13:18:51.432490Z",
// hasPasswordAuth: true,
// email: "rain@bow.com",
// }),
// socialApps$: of([
// {
// provider: "google",
// name: "Google",
// client_id: "secrets secrets are no fun",
// authorize_url: "",
// scopes: [],
// },
// ]),
// },
// };
+8
View File
@@ -1,4 +1,12 @@
import { MatIconModule } from "@angular/material/icon";
import { moduleMetadata } from "@storybook/angular";
export default {
decorators: [
moduleMetadata({
imports: [MatIconModule],
}),
],
title: "Styles/General Styling",
};
+5
View File
@@ -0,0 +1,5 @@
{
"rules": {
"@typescript-eslint/consistent-type-imports": ["error", { "disallowTypeAnnotations": false }]
}
}
+48
View File
@@ -0,0 +1,48 @@
import { CommonModule } from '@angular/common';
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'storybook-button',
standalone: true,
imports: [CommonModule],
template: ` <button
type="button"
(click)="onClick.emit($event)"
[ngClass]="classes"
[ngStyle]="{ 'background-color': backgroundColor }"
>
{{ label }}
</button>`,
styleUrls: ['./button.css'],
})
export class ButtonComponent {
/** Is this the principal call to action on the page? */
@Input()
primary = false;
/** What background color to use */
@Input()
backgroundColor?: string;
/** How large should the button be? */
@Input()
size: 'small' | 'medium' | 'large' = 'medium';
/**
* Button contents
*
* @required
*/
@Input()
label = 'Button';
/** Optional click handler */
@Output()
onClick = new EventEmitter<Event>();
public get classes(): string[] {
const mode = this.primary ? 'storybook-button--primary' : 'storybook-button--secondary';
return ['storybook-button', `storybook-button--${this.size}`, mode];
}
}
+30
View File
@@ -0,0 +1,30 @@
.storybook-button {
display: inline-block;
cursor: pointer;
border: 0;
border-radius: 3em;
font-weight: 700;
line-height: 1;
font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
}
.storybook-button--primary {
background-color: #1ea7fd;
color: white;
}
.storybook-button--secondary {
box-shadow: rgba(0, 0, 0, 0.15) 0px 0px 0px 1px inset;
background-color: transparent;
color: #333;
}
.storybook-button--small {
padding: 10px 16px;
font-size: 12px;
}
.storybook-button--medium {
padding: 11px 20px;
font-size: 14px;
}
.storybook-button--large {
padding: 12px 24px;
font-size: 16px;
}
+49
View File
@@ -0,0 +1,49 @@
import type { Meta, StoryObj } from '@storybook/angular';
import { fn } from '@storybook/test';
import { ButtonComponent } from './button.component';
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories
const meta: Meta<ButtonComponent> = {
title: 'Example/Button',
component: ButtonComponent,
tags: ['autodocs'],
argTypes: {
backgroundColor: {
control: 'color',
},
},
// Use `fn` to spy on the onClick arg, which will appear in the actions panel once invoked: https://storybook.js.org/docs/essentials/actions#action-args
args: { onClick: fn() },
};
export default meta;
type Story = StoryObj<ButtonComponent>;
// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args
export const Primary: Story = {
args: {
primary: true,
label: 'Button',
},
};
export const Secondary: Story = {
args: {
label: 'Button',
},
};
export const Large: Story = {
args: {
size: 'large',
label: 'Button',
},
};
export const Small: Story = {
args: {
size: 'small',
label: 'Button',
},
};
+3
View File
@@ -0,0 +1,3 @@
export interface User {
name: string;
}