From f7b372a0b068e89b724115a6036902b539b8a4ad Mon Sep 17 00:00:00 2001 From: Oscar Hinton Date: Fri, 26 May 2023 15:58:06 +0200 Subject: [PATCH] [PM-2276] Upgrade Storybook to v7 (#5258) --- .github/whitelist-capital-letters.txt | 1 - .github/workflows/chromatic.yml | 5 + .storybook/main.js | 33 - .storybook/main.ts | 53 + .storybook/preview.js | 38 - .storybook/preview.tsx | 39 + .storybook/tsconfig.json | 1 + angular.json | 31 +- .../access-selector.stories.ts | 7 +- .../product-switcher.stories.ts | 65 +- .../shared/report-card/report-card.stories.ts | 14 +- .../shared/report-list/report-list.stories.ts | 14 +- .../vault-items/vault-items.stories.ts | 21 +- .../secrets-manager/layout/layout.stories.ts | 75 +- .../overview/onboarding.stories.ts | 26 +- .../secrets-manager/shared/header.stories.ts | 29 +- .../{in-forms.stories.mdx => in-forms.mdx} | 0 .../src/async-actions/in-forms.stories.ts | 26 +- .../{overview.stories.mdx => overview.mdx} | 0 ...{standalone.stories.mdx => standalone.mdx} | 0 .../src/async-actions/standalone.stories.ts | 39 +- libs/components/src/avatar/avatar.stories.ts | 55 +- .../src/badge-list/badge-list.stories.ts | 27 +- libs/components/src/badge/badge.stories.ts | 71 +- .../banner.mdx} | 18 +- libs/components/src/banner/banner.stories.ts | 50 +- .../src/breadcrumbs/breadcrumbs.stories.ts | 98 +- .../button.mdx} | 22 +- libs/components/src/button/button.stories.ts | 150 +- .../components/src/callout/callout.stories.ts | 50 +- .../src/checkbox/checkbox.stories.ts | 73 +- .../color-password.component.ts | 2 +- .../color-password/color-password.stories.ts | 62 +- .../src/dialog/dialog.service.stories.ts | 8 +- .../src/dialog/dialog/dialog.stories.ts | 208 +- ...ple-configurable-dialog.service.stories.ts | 8 +- .../dialog/simple-dialog.service.stories.ts | 8 +- .../simple-dialog/simple-dialog.stories.ts | 116 +- .../src/form-field/bit-validators.stories.ts | 20 +- .../src/form-field/error-summary.stories.ts | 53 +- .../src/form-field/form-field.stories.ts | 313 +- .../src/form-field/multi-select.stories.ts | 423 +- .../password-input-toggle.stories.ts | 83 +- libs/components/src/form/form.stories.ts | 129 +- .../src/icon-button/icon-button.stories.ts | 128 +- libs/components/src/icon/icon.stories.ts | 32 +- libs/components/src/index.ts | 1 + libs/components/src/input/index.ts | 1 + libs/components/src/link/link.stories.ts | 184 +- libs/components/src/menu/menu.stories.ts | 74 +- .../src/navigation/nav-group.stories.ts | 48 +- .../src/navigation/nav-item.stories.ts | 80 +- .../src/no-items/no-items.stories.ts | 44 +- .../src/progress/progress.stories.ts | 29 +- .../src/radio-button/radio-button.stories.ts | 122 +- libs/components/src/search/search.stories.ts | 20 +- libs/components/src/select/select.stories.ts | 40 +- .../{colors.stories.mdx => colors.mdx} | 6 +- .../{forms-docs.stories.mdx => forms.mdx} | 2 +- .../stories/{icons.stories.mdx => icons.mdx} | 4 +- .../{input-docs.stories.mdx => input.mdx} | 4 +- ...roduction.stories.mdx => introduction.mdx} | 6 +- .../src/stories/typography.stories.mdx | 59 - .../table.mdx} | 16 +- libs/components/src/table/table.stories.ts | 256 +- libs/components/src/tabs/tabs.stories.ts | 137 +- .../src/toggle-group/toggle-group.stories.ts | 54 +- libs/components/src/typography/typography.mdx | 67 + .../src/typography/typography.stories.ts | 102 +- libs/components/tailwind.config.js | 7 +- package-lock.json | 18634 ++++------------ package.json | 28 +- 72 files changed, 6340 insertions(+), 16409 deletions(-) delete mode 100644 .storybook/main.js create mode 100644 .storybook/main.ts delete mode 100644 .storybook/preview.js create mode 100644 .storybook/preview.tsx rename libs/components/src/async-actions/{in-forms.stories.mdx => in-forms.mdx} (100%) rename libs/components/src/async-actions/{overview.stories.mdx => overview.mdx} (100%) rename libs/components/src/async-actions/{standalone.stories.mdx => standalone.mdx} (100%) rename libs/components/src/{stories/banner-docs.stories.mdx => banner/banner.mdx} (82%) rename libs/components/src/{stories/button-docs.stories.mdx => button/button.mdx} (88%) create mode 100644 libs/components/src/input/index.ts rename libs/components/src/stories/{colors.stories.mdx => colors.mdx} (98%) rename libs/components/src/stories/{forms-docs.stories.mdx => forms.mdx} (97%) rename libs/components/src/stories/{icons.stories.mdx => icons.mdx} (99%) rename libs/components/src/stories/{input-docs.stories.mdx => input.mdx} (95%) rename libs/components/src/stories/{Introduction.stories.mdx => introduction.mdx} (99%) delete mode 100644 libs/components/src/stories/typography.stories.mdx rename libs/components/src/{stories/table-docs.stories.mdx => table/table.mdx} (96%) create mode 100644 libs/components/src/typography/typography.mdx diff --git a/.github/whitelist-capital-letters.txt b/.github/whitelist-capital-letters.txt index 9e585d170e..1fbed379d6 100644 --- a/.github/whitelist-capital-letters.txt +++ b/.github/whitelist-capital-letters.txt @@ -24,7 +24,6 @@ ./libs/angular/src/validators/notAllowedValueAsync.validator.ts ./libs/angular/src/services/theming/themeBuilder.ts ./libs/angular/src/interfaces/selectOptions.ts -./libs/components/src/stories/Introduction.stories.mdx ./libs/common/src/misc/nodeUtils.ts ./libs/common/src/misc/linkedFieldOption.decorator.ts ./libs/common/src/misc/serviceUtils.ts diff --git a/.github/workflows/chromatic.yml b/.github/workflows/chromatic.yml index 453a19423a..212a80de74 100644 --- a/.github/workflows/chromatic.yml +++ b/.github/workflows/chromatic.yml @@ -31,12 +31,17 @@ jobs: - name: Install Node dependencies run: npm ci + + # Manual build the storybook to resolve a chromatic/storybook bug related to TurboSnap + - name: Build Storybook + run: npm run build-storybook:ci - name: Publish to Chromatic uses: chromaui/action@a89b674adf766dbde41ad9ea2b2b60b91188a0f0 with: token: ${{ secrets.GITHUB_TOKEN }} projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} + storybookBuildDir: ./storybook-static exitOnceUploaded: true onlyChanged: true externals: "[\"libs/components/**/*.scss\", \"libs/components/tailwind.config*.js\"]" diff --git a/.storybook/main.js b/.storybook/main.js deleted file mode 100644 index 3db3964022..0000000000 --- a/.storybook/main.js +++ /dev/null @@ -1,33 +0,0 @@ -const TsconfigPathsPlugin = require("tsconfig-paths-webpack-plugin"); - -module.exports = { - stories: [ - "../libs/components/src/**/*.stories.mdx", - "../libs/components/src/**/*.stories.@(js|jsx|ts|tsx)", - "../apps/web/src/**/*.stories.mdx", - "../apps/web/src/**/*.stories.@(js|jsx|ts|tsx)", - "../bitwarden_license/bit-web/src/**/*.stories.mdx", - "../bitwarden_license/bit-web/src/**/*.stories.@(js|jsx|ts|tsx)", - ], - addons: [ - "@storybook/addon-links", - "@storybook/addon-essentials", - "@storybook/addon-a11y", - "storybook-addon-designs", - ], - framework: "@storybook/angular", - core: { - builder: "webpack5", - disableTelemetry: true, - }, - env: (config) => ({ - ...config, - FLAGS: JSON.stringify({ - secretsManager: true, - }), - }), - webpackFinal: async (config, { configType }) => { - config.resolve.plugins = [new TsconfigPathsPlugin()]; - return config; - }, -}; diff --git a/.storybook/main.ts b/.storybook/main.ts new file mode 100644 index 0000000000..a7f12f469b --- /dev/null +++ b/.storybook/main.ts @@ -0,0 +1,53 @@ +import { StorybookConfig } from "@storybook/angular"; +import TsconfigPathsPlugin from "tsconfig-paths-webpack-plugin"; +import remarkGfm from "remark-gfm"; + +const config: StorybookConfig = { + stories: [ + "../libs/components/src/**/*.mdx", + "../libs/components/src/**/*.stories.@(js|jsx|ts|tsx)", + "../apps/web/src/**/*.mdx", + "../apps/web/src/**/*.stories.@(js|jsx|ts|tsx)", + "../bitwarden_license/bit-web/src/**/*.mdx", + "../bitwarden_license/bit-web/src/**/*.stories.@(js|jsx|ts|tsx)", + ], + addons: [ + "@storybook/addon-links", + "@storybook/addon-essentials", + "@storybook/addon-a11y", + { + name: "@storybook/addon-docs", + options: { + mdxPluginOptions: { + mdxCompileOptions: { + remarkPlugins: [remarkGfm], + }, + }, + }, + }, + ], + framework: { + name: "@storybook/angular", + options: {}, + }, + core: { + disableTelemetry: true, + }, + env: (config) => ({ + ...config, + FLAGS: JSON.stringify({ + secretsManager: true, + }), + }), + webpackFinal: async (config, { configType }) => { + if (config.resolve) { + config.resolve.plugins = [new TsconfigPathsPlugin()] as any; + } + return config; + }, + docs: { + autodocs: true, + }, +}; + +export default config; diff --git a/.storybook/preview.js b/.storybook/preview.js deleted file mode 100644 index 754e8d2b88..0000000000 --- a/.storybook/preview.js +++ /dev/null @@ -1,38 +0,0 @@ -import { setCompodocJson } from "@storybook/addon-docs/angular"; -import { componentWrapperDecorator, addDecorator } from "@storybook/angular"; - -import docJson from "../documentation.json"; -setCompodocJson(docJson); - -export const parameters = { - actions: { argTypesRegex: "^on[A-Z].*" }, - controls: { - matchers: { - color: /(background|color)$/i, - date: /Date$/, - }, - }, - options: { - storySort: { - order: ["Documentation", ["Introduction", "Colors", "Icons"], "Component Library"], - }, - }, - docs: { inlineStories: true }, -}; - -// ng-template is used to scope any template reference variables and isolate the previews -const decorator = componentWrapperDecorator( - (story) => ` - -
${story}
-
- -
${story}
-
- - - -` -); - -addDecorator(decorator); diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx new file mode 100644 index 0000000000..86ab6ab374 --- /dev/null +++ b/.storybook/preview.tsx @@ -0,0 +1,39 @@ +import { setCompodocJson } from "@storybook/addon-docs/angular"; +import { componentWrapperDecorator } from "@storybook/angular"; +import type { Preview } from "@storybook/angular"; + +import docJson from "../documentation.json"; +setCompodocJson(docJson); + +const decorator = componentWrapperDecorator( + (story) => ` + +
${story}
+
+ +
${story}
+
+ + ` +); + +const preview: Preview = { + decorators: [decorator], + parameters: { + actions: { argTypesRegex: "^on[A-Z].*" }, + controls: { + matchers: { + color: /(background|color)$/i, + date: /Date$/, + }, + }, + options: { + storySort: { + order: ["Documentation", ["Introduction", "Colors", "Icons"], "Component Library"], + }, + }, + docs: { source: { type: "dynamic", excludeDecorators: true } }, + }, +}; + +export default preview; diff --git a/.storybook/tsconfig.json b/.storybook/tsconfig.json index 397be6b000..113cc5bcde 100644 --- a/.storybook/tsconfig.json +++ b/.storybook/tsconfig.json @@ -7,6 +7,7 @@ "exclude": ["../src/test.setup.ts", "../apps/src/**/*.spec.ts", "../libs/**/*.spec.ts"], "files": [ "./typings.d.ts", + "./preview.tsx", "../libs/components/src/main.ts", "../libs/components/src/polyfills.ts" ] diff --git a/angular.json b/angular.json index a2b82cc64e..4b62c771cb 100644 --- a/angular.json +++ b/angular.json @@ -135,20 +135,25 @@ } }, "defaultConfiguration": "development" - } - } - }, - "storybook": { - "projectType": "application", - "root": "libs/components", - "sourceRoot": "libs/components/src", - "architect": { - "build": { - "builder": "@angular-devkit/build-angular:browser", + }, + "storybook": { + "builder": "@storybook/angular:start-storybook", "options": { - "tsConfig": ".storybook/tsconfig.json", - "styles": ["libs/components/src/styles.scss", "libs/components/src/styles.css"], - "scripts": [] + "configDir": ".storybook", + "browserTarget": "components:build", + "compodoc": true, + "compodocArgs": ["-p", "./tsconfig.json", "-e", "json", "-d", "."], + "port": 6006 + } + }, + "build-storybook": { + "builder": "@storybook/angular:build-storybook", + "options": { + "configDir": ".storybook", + "browserTarget": "components:build", + "compodoc": true, + "compodocArgs": ["-e", "json", "-d", "."], + "outputDir": "storybook-static" } } } diff --git a/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.stories.ts b/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.stories.ts index e503aad587..4fa8e43520 100644 --- a/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.stories.ts +++ b/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.stories.ts @@ -1,6 +1,7 @@ +import { importProvidersFrom } from "@angular/core"; import { FormBuilder, FormsModule, ReactiveFormsModule } from "@angular/forms"; import { action } from "@storybook/addon-actions"; -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { applicationConfig, Meta, moduleMetadata, Story } from "@storybook/angular"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { @@ -39,12 +40,14 @@ export default { FormsModule, TabsModule, TableModule, - PreloadedEnglishI18nModule, JslibModule, IconButtonModule, ], providers: [], }), + applicationConfig({ + providers: [importProvidersFrom(PreloadedEnglishI18nModule)], + }), ], parameters: {}, argTypes: { diff --git a/apps/web/src/app/layouts/product-switcher/product-switcher.stories.ts b/apps/web/src/app/layouts/product-switcher/product-switcher.stories.ts index d9494b5eb2..82144afa72 100644 --- a/apps/web/src/app/layouts/product-switcher/product-switcher.stories.ts +++ b/apps/web/src/app/layouts/product-switcher/product-switcher.stories.ts @@ -1,6 +1,6 @@ -import { Component, Directive, Input } from "@angular/core"; +import { Component, Directive, Input, importProvidersFrom } from "@angular/core"; import { RouterModule } from "@angular/router"; -import { Meta, Story, moduleMetadata } from "@storybook/angular"; +import { Meta, Story, applicationConfig, moduleMetadata } from "@storybook/angular"; import { BehaviorSubject } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; @@ -49,36 +49,7 @@ export default { StoryLayoutComponent, StoryContentComponent, ], - imports: [ - JslibModule, - MenuModule, - IconButtonModule, - LinkModule, - RouterModule.forRoot( - [ - { - path: "", - component: StoryLayoutComponent, - children: [ - { - path: "", - redirectTo: "vault", - pathMatch: "full", - }, - { - path: "sm/:organizationId", - component: StoryContentComponent, - }, - { - path: "vault", - component: StoryContentComponent, - }, - ], - }, - ], - { useHash: true } - ), - ], + imports: [JslibModule, MenuModule, IconButtonModule, LinkModule, RouterModule], providers: [ { provide: OrganizationService, useClass: MockOrganizationService }, MockOrganizationService, @@ -93,6 +64,36 @@ export default { }, ], }), + applicationConfig({ + providers: [ + importProvidersFrom( + RouterModule.forRoot( + [ + { + path: "", + component: StoryLayoutComponent, + children: [ + { + path: "", + redirectTo: "vault", + pathMatch: "full", + }, + { + path: "sm/:organizationId", + component: StoryContentComponent, + }, + { + path: "vault", + component: StoryContentComponent, + }, + ], + }, + ], + { useHash: true } + ) + ), + ], + }), ], } as Meta; diff --git a/apps/web/src/app/reports/shared/report-card/report-card.stories.ts b/apps/web/src/app/reports/shared/report-card/report-card.stories.ts index 82c5c4e83b..f3dea693b3 100644 --- a/apps/web/src/app/reports/shared/report-card/report-card.stories.ts +++ b/apps/web/src/app/reports/shared/report-card/report-card.stories.ts @@ -1,5 +1,6 @@ +import { importProvidersFrom } from "@angular/core"; import { RouterTestingModule } from "@angular/router/testing"; -import { Meta, Story, moduleMetadata } from "@storybook/angular"; +import { Meta, Story, applicationConfig, moduleMetadata } from "@storybook/angular"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { BadgeModule, IconModule } from "@bitwarden/components"; @@ -15,15 +16,12 @@ export default { component: ReportCardComponent, decorators: [ moduleMetadata({ - imports: [ - JslibModule, - BadgeModule, - IconModule, - RouterTestingModule, - PreloadedEnglishI18nModule, - ], + imports: [JslibModule, BadgeModule, IconModule, RouterTestingModule], declarations: [PremiumBadgeComponent], }), + applicationConfig({ + providers: [importProvidersFrom(PreloadedEnglishI18nModule)], + }), ], args: { title: "Exposed Passwords", diff --git a/apps/web/src/app/reports/shared/report-list/report-list.stories.ts b/apps/web/src/app/reports/shared/report-list/report-list.stories.ts index 7a092d99d6..b477792dd4 100644 --- a/apps/web/src/app/reports/shared/report-list/report-list.stories.ts +++ b/apps/web/src/app/reports/shared/report-list/report-list.stories.ts @@ -1,5 +1,6 @@ +import { importProvidersFrom } from "@angular/core"; import { RouterTestingModule } from "@angular/router/testing"; -import { Meta, Story, moduleMetadata } from "@storybook/angular"; +import { Meta, Story, applicationConfig, moduleMetadata } from "@storybook/angular"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { BadgeModule, IconModule } from "@bitwarden/components"; @@ -17,15 +18,12 @@ export default { component: ReportListComponent, decorators: [ moduleMetadata({ - imports: [ - JslibModule, - BadgeModule, - RouterTestingModule, - PreloadedEnglishI18nModule, - IconModule, - ], + imports: [JslibModule, BadgeModule, RouterTestingModule, IconModule], declarations: [PremiumBadgeComponent, ReportCardComponent], }), + applicationConfig({ + providers: [importProvidersFrom(PreloadedEnglishI18nModule)], + }), ], args: { reports: Object.values(reports).map((report) => ({ diff --git a/apps/web/src/app/vault/components/vault-items/vault-items.stories.ts b/apps/web/src/app/vault/components/vault-items/vault-items.stories.ts index 28464289cf..2f40ad9ab4 100644 --- a/apps/web/src/app/vault/components/vault-items/vault-items.stories.ts +++ b/apps/web/src/app/vault/components/vault-items/vault-items.stories.ts @@ -1,6 +1,6 @@ -import { Component } from "@angular/core"; +import { importProvidersFrom } from "@angular/core"; import { RouterModule } from "@angular/router"; -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { applicationConfig, Meta, moduleMetadata, Story } from "@storybook/angular"; import { BehaviorSubject } from "rxjs"; import { AvatarUpdateService } from "@bitwarden/common/abstractions/account/avatar-update.service"; @@ -28,11 +28,6 @@ import { Unassigned } from "../../individual-vault/vault-filter/shared/models/ro import { VaultItemsComponent } from "./vault-items.component"; import { VaultItemsModule } from "./vault-items.module"; -@Component({ - template: "", -}) -class EmptyComponent {} - const organizations = [...new Array(3).keys()].map(createOrganization); const groups = [...Array(3).keys()].map(createGroupView); const collections = [...Array(5).keys()].map(createCollectionView); @@ -46,11 +41,7 @@ export default { component: VaultItemsComponent, decorators: [ moduleMetadata({ - imports: [ - VaultItemsModule, - PreloadedEnglishI18nModule, - RouterModule.forRoot([{ path: "**", component: EmptyComponent }], { useHash: true }), - ], + imports: [VaultItemsModule, RouterModule], providers: [ { provide: EnvironmentService, @@ -103,6 +94,12 @@ export default { }, ], }), + applicationConfig({ + providers: [ + importProvidersFrom(RouterModule.forRoot([], { useHash: true })), + importProvidersFrom(PreloadedEnglishI18nModule), + ], + }), ], args: { disabled: false, diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/layout/layout.stories.ts b/bitwarden_license/bit-web/src/app/secrets-manager/layout/layout.stories.ts index f3ae4f57c5..533f86a6e6 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/layout/layout.stories.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/layout/layout.stories.ts @@ -1,6 +1,6 @@ -import { Component } from "@angular/core"; +import { Component, importProvidersFrom } from "@angular/core"; import { RouterModule } from "@angular/router"; -import { Meta, Story, moduleMetadata } from "@storybook/angular"; +import { Meta, Story, applicationConfig, moduleMetadata } from "@storybook/angular"; import { BehaviorSubject } from "rxjs"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; @@ -28,43 +28,46 @@ export default { component: LayoutComponent, decorators: [ moduleMetadata({ - imports: [ - RouterModule.forRoot( - [ - { - path: "", - component: LayoutComponent, - children: [ - { - path: "", - redirectTo: "secrets", - pathMatch: "full", - }, - { - path: "secrets", - component: StoryContentComponent, - data: { - title: "secrets", - searchTitle: "searchSecrets", - }, - }, - { - outlet: "sidebar", - path: "", - component: NavigationComponent, - }, - ], - }, - ], - { useHash: true } - ), - LayoutModule, - IconModule, - PreloadedEnglishI18nModule, - ], + imports: [RouterModule, LayoutModule, IconModule], declarations: [StoryContentComponent], providers: [{ provide: OrganizationService, useClass: MockOrganizationService }], }), + applicationConfig({ + providers: [ + importProvidersFrom( + RouterModule.forRoot( + [ + { + path: "", + component: LayoutComponent, + children: [ + { + path: "", + redirectTo: "secrets", + pathMatch: "full", + }, + { + path: "secrets", + component: StoryContentComponent, + data: { + title: "secrets", + searchTitle: "searchSecrets", + }, + }, + { + outlet: "sidebar", + path: "", + component: NavigationComponent, + }, + ], + }, + ], + { useHash: true } + ) + ), + importProvidersFrom(PreloadedEnglishI18nModule), + ], + }), ], } as Meta; diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/overview/onboarding.stories.ts b/bitwarden_license/bit-web/src/app/secrets-manager/overview/onboarding.stories.ts index 73fc2738ec..a25e386307 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/overview/onboarding.stories.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/overview/onboarding.stories.ts @@ -1,5 +1,6 @@ +import { importProvidersFrom } from "@angular/core"; import { RouterModule } from "@angular/router"; -import { Meta, Story, moduleMetadata } from "@storybook/angular"; +import { Meta, Story, applicationConfig, moduleMetadata } from "@storybook/angular"; import { delay, of, startWith } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; @@ -14,24 +15,15 @@ export default { component: OnboardingComponent, decorators: [ moduleMetadata({ - imports: [ - JslibModule, - RouterModule.forRoot( - [ - { - path: "", - component: OnboardingComponent, - }, - ], - { useHash: true } - ), - LinkModule, - IconModule, - ProgressModule, - PreloadedEnglishI18nModule, - ], + imports: [JslibModule, RouterModule, LinkModule, IconModule, ProgressModule], declarations: [OnboardingTaskComponent], }), + applicationConfig({ + providers: [ + importProvidersFrom(RouterModule.forRoot([], { useHash: true })), + importProvidersFrom(PreloadedEnglishI18nModule), + ], + }), ], } as Meta; diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/shared/header.stories.ts b/bitwarden_license/bit-web/src/app/secrets-manager/shared/header.stories.ts index 8ded21b956..508573d466 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/shared/header.stories.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/shared/header.stories.ts @@ -1,6 +1,12 @@ -import { Component, Injectable } from "@angular/core"; +import { Component, Injectable, importProvidersFrom } from "@angular/core"; import { RouterModule } from "@angular/router"; -import { Meta, Story, moduleMetadata, componentWrapperDecorator } from "@storybook/angular"; +import { + Meta, + Story, + moduleMetadata, + componentWrapperDecorator, + applicationConfig, +} from "@storybook/angular"; import { BehaviorSubject, combineLatest, map } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; @@ -16,8 +22,8 @@ import { NavigationModule, TabsModule, TypographyModule, + InputModule, } from "@bitwarden/components"; -import { InputModule } from "@bitwarden/components/src/input/input.module"; import { PreloadedEnglishI18nModule } from "@bitwarden/web-vault/app/tests/preloaded-english-i18n.module"; import { HeaderComponent } from "./header.component"; @@ -68,15 +74,7 @@ export default { moduleMetadata({ imports: [ JslibModule, - RouterModule.forRoot( - [ - { - path: "", - component: HeaderComponent, - }, - ], - { useHash: true } - ), + RouterModule, AvatarModule, BreadcrumbsModule, ButtonModule, @@ -87,7 +85,6 @@ export default { TabsModule, TypographyModule, NavigationModule, - PreloadedEnglishI18nModule, ], declarations: [HeaderComponent, MockProductSwitcher, MockDynamicAvatar], providers: [ @@ -100,6 +97,12 @@ export default { }, ], }), + applicationConfig({ + providers: [ + importProvidersFrom(RouterModule.forRoot([], { useHash: true })), + importProvidersFrom(PreloadedEnglishI18nModule), + ], + }), ], } as Meta; diff --git a/libs/components/src/async-actions/in-forms.stories.mdx b/libs/components/src/async-actions/in-forms.mdx similarity index 100% rename from libs/components/src/async-actions/in-forms.stories.mdx rename to libs/components/src/async-actions/in-forms.mdx diff --git a/libs/components/src/async-actions/in-forms.stories.ts b/libs/components/src/async-actions/in-forms.stories.ts index ef789dc106..f72f1b6479 100644 --- a/libs/components/src/async-actions/in-forms.stories.ts +++ b/libs/components/src/async-actions/in-forms.stories.ts @@ -1,7 +1,7 @@ import { Component } from "@angular/core"; import { FormsModule, ReactiveFormsModule, Validators, FormBuilder } from "@angular/forms"; import { action } from "@storybook/addon-actions"; -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, moduleMetadata, StoryObj } from "@storybook/angular"; import { delay, of } from "rxjs"; import { ValidationService } from "@bitwarden/common/abstractions/validation.service"; @@ -145,16 +145,18 @@ export default { ], } as Meta; -const PromiseTemplate: Story = (args: PromiseExampleComponent) => ({ - props: args, - template: ``, -}); +type Story = StoryObj; -export const UsingPromise = PromiseTemplate.bind({}); +export const UsingPromise: Story = { + render: (args) => ({ + props: args, + template: ``, + }), +}; -const ObservableTemplate: Story = (args: PromiseExampleComponent) => ({ - props: args, - template: ``, -}); - -export const UsingObservable = ObservableTemplate.bind({}); +export const UsingObservable: Story = { + render: (args) => ({ + props: args, + template: ``, + }), +}; diff --git a/libs/components/src/async-actions/overview.stories.mdx b/libs/components/src/async-actions/overview.mdx similarity index 100% rename from libs/components/src/async-actions/overview.stories.mdx rename to libs/components/src/async-actions/overview.mdx diff --git a/libs/components/src/async-actions/standalone.stories.mdx b/libs/components/src/async-actions/standalone.mdx similarity index 100% rename from libs/components/src/async-actions/standalone.stories.mdx rename to libs/components/src/async-actions/standalone.mdx diff --git a/libs/components/src/async-actions/standalone.stories.ts b/libs/components/src/async-actions/standalone.stories.ts index 5a8edfaaac..e4dec780e0 100644 --- a/libs/components/src/async-actions/standalone.stories.ts +++ b/libs/components/src/async-actions/standalone.stories.ts @@ -1,6 +1,6 @@ import { Component } from "@angular/core"; import { action } from "@storybook/addon-actions"; -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; import { delay, of } from "rxjs"; import { LogService } from "@bitwarden/common/abstractions/log.service"; @@ -80,25 +80,24 @@ export default { ], } as Meta; -const PromiseTemplate: Story = (args: PromiseExampleComponent) => ({ - props: args, - template: ``, -}); +type PromiseStory = StoryObj; +type ObservableStory = StoryObj; -export const UsingPromise = PromiseTemplate.bind({}); +export const UsingPromise: PromiseStory = { + render: (args) => ({ + props: args, + template: ``, + }), +}; -const ObservableTemplate: Story = ( - args: ObservableExampleComponent -) => ({ - template: ``, -}); +export const UsingObservable: ObservableStory = { + render: (args) => ({ + template: ``, + }), +}; -export const UsingObservable = ObservableTemplate.bind({}); - -const RejectedPromiseTemplate: Story = ( - args: ObservableExampleComponent -) => ({ - template: ``, -}); - -export const RejectedPromise = RejectedPromiseTemplate.bind({}); +export const RejectedPromise: ObservableStory = { + render: (args) => ({ + template: ``, + }), +}; diff --git a/libs/components/src/avatar/avatar.stories.ts b/libs/components/src/avatar/avatar.stories.ts index 724dc5ec0e..d3a00fbe34 100644 --- a/libs/components/src/avatar/avatar.stories.ts +++ b/libs/components/src/avatar/avatar.stories.ts @@ -1,4 +1,4 @@ -import { Meta, Story } from "@storybook/angular"; +import { Meta, StoryObj } from "@storybook/angular"; import { AvatarComponent } from "./avatar.component"; @@ -18,41 +18,46 @@ export default { }, } as Meta; -const Template: Story = (args: AvatarComponent) => ({ - props: args, -}); +type Story = StoryObj; -export const Default = Template.bind({}); -Default.args = { - color: "#175ddc", +export const Default: Story = { + args: { + color: "#175ddc", + }, }; -export const Large = Template.bind({}); -Large.args = { - size: "large", +export const Large: Story = { + args: { + size: "large", + }, }; -export const Small = Template.bind({}); -Small.args = { - size: "small", +export const Small: Story = { + args: { + size: "small", + }, }; -export const LightBackground = Template.bind({}); -LightBackground.args = { - color: "#d2ffcf", +export const LightBackground: Story = { + args: { + color: "#d2ffcf", + }, }; -export const Border = Template.bind({}); -Border.args = { - border: true, +export const Border: Story = { + args: { + border: true, + }, }; -export const ColorByID = Template.bind({}); -ColorByID.args = { - id: 236478, +export const ColorByID: Story = { + args: { + id: "236478", + }, }; -export const ColorByText = Template.bind({}); -ColorByText.args = { - text: "Jason Doe", +export const ColorByText: Story = { + args: { + text: "Jason Doe", + }, }; diff --git a/libs/components/src/badge-list/badge-list.stories.ts b/libs/components/src/badge-list/badge-list.stories.ts index 91214d8317..4e580badb1 100644 --- a/libs/components/src/badge-list/badge-list.stories.ts +++ b/libs/components/src/badge-list/badge-list.stories.ts @@ -1,4 +1,4 @@ -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; @@ -38,16 +38,19 @@ export default { }, } as Meta; -const ListTemplate: Story = (args: BadgeListComponent) => ({ - props: args, - template: ` - - `, -}); +type Story = StoryObj; -export const Default = ListTemplate.bind({}); -Default.args = { - badgeType: "info", - maxItems: 3, - items: ["Badge 1", "Badge 2", "Badge 3", "Badge 4", "Badge 5"], +export const Default: Story = { + render: (args) => ({ + props: args, + template: ` + + `, + }), + + args: { + badgeType: "info", + maxItems: 3, + items: ["Badge 1", "Badge 2", "Badge 3", "Badge 4", "Badge 5"], + }, }; diff --git a/libs/components/src/badge/badge.stories.ts b/libs/components/src/badge/badge.stories.ts index a5584c1a89..2efe5450d0 100644 --- a/libs/components/src/badge/badge.stories.ts +++ b/libs/components/src/badge/badge.stories.ts @@ -1,5 +1,5 @@ import { CommonModule } from "@angular/common"; -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, moduleMetadata, StoryObj } from "@storybook/angular"; import { BadgeDirective } from "./badge.directive"; @@ -21,43 +21,54 @@ export default { url: "https://www.figma.com/file/Zt3YSeb6E6lebAffrNLa0h/Tailwind-Component-Library?node-id=1881%3A16956", }, }, -} as Meta; +} as Meta; -const Template: Story = (args: BadgeDirective) => ({ - props: args, - template: ` - Span Badge -

- Link Badge -

- Button - `, -}); +type Story = StoryObj; -export const Primary = Template.bind({}); -Primary.args = {}; - -export const Secondary = Template.bind({}); -Secondary.args = { - badgeType: "secondary", +export const Primary: Story = { + render: (args) => ({ + props: args, + template: ` + Span Badge +

+ Link Badge +

+ Button + `, + }), }; -export const Success = Template.bind({}); -Success.args = { - badgeType: "success", +export const Secondary: Story = { + ...Primary, + args: { + badgeType: "secondary", + }, }; -export const Danger = Template.bind({}); -Danger.args = { - badgeType: "danger", +export const Success: Story = { + ...Primary, + args: { + badgeType: "success", + }, }; -export const Warning = Template.bind({}); -Warning.args = { - badgeType: "warning", +export const Danger: Story = { + ...Primary, + args: { + badgeType: "danger", + }, }; -export const Info = Template.bind({}); -Info.args = { - badgeType: "info", +export const Warning: Story = { + ...Primary, + args: { + badgeType: "warning", + }, +}; + +export const Info: Story = { + ...Primary, + args: { + badgeType: "info", + }, }; diff --git a/libs/components/src/stories/banner-docs.stories.mdx b/libs/components/src/banner/banner.mdx similarity index 82% rename from libs/components/src/stories/banner-docs.stories.mdx rename to libs/components/src/banner/banner.mdx index 61b216523b..84c71cde95 100644 --- a/libs/components/src/stories/banner-docs.stories.mdx +++ b/libs/components/src/banner/banner.mdx @@ -1,6 +1,8 @@ -import { Meta, Story } from "@storybook/addon-docs"; +import { Meta, Story, Controls, Canvas, Primary } from "@storybook/addon-docs"; - +import * as stories from "./banner.stories"; + + # Banner @@ -15,6 +17,10 @@ persist across all pages a user navigates to. - Avoid stacking multiple banners. - Banners support a button link (text button). + + + + ## Types Icons should remain consistent across these types. Do not change the icon without consulting @@ -24,25 +30,25 @@ Use the following guidelines to help choose the correct type of banner. ### Premium - + Used primarily to encourage user to upgrade to premium. ### Info - + Used to communicate release notes, server maintenance or other informative event. ### Warning - + Used to alert the user of outdated info or versions. ### Danger - + Rarely used, but may be used to alert users over critical messages or very outdated versions. diff --git a/libs/components/src/banner/banner.stories.ts b/libs/components/src/banner/banner.stories.ts index e636124fe0..e2c8a0c82b 100644 --- a/libs/components/src/banner/banner.stories.ts +++ b/libs/components/src/banner/banner.stories.ts @@ -1,4 +1,4 @@ -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, moduleMetadata, StoryObj } from "@storybook/angular"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; @@ -39,34 +39,46 @@ export default { argTypes: { onClose: { action: "onClose" }, }, -} as Meta; +} as Meta; -const Template: Story = (args: BannerComponent) => ({ - props: args, - template: ` - +type Story = StoryObj; + +export const Premium: Story = { + args: { + bannerType: "premium", + }, + render: (args: BannerComponent) => ({ + props: args, + template: ` + Content Really Long Text Lorem Ipsum Ipsum Ipsum - - `, -}); + + `, + }), +}; -export const Premium = Template.bind({}); Premium.args = { bannerType: "premium", }; -export const Info = Template.bind({}); -Info.args = { - bannerType: "info", +export const Info: Story = { + ...Premium, + args: { + bannerType: "info", + }, }; -export const Warning = Template.bind({}); -Warning.args = { - bannerType: "warning", +export const Warning: Story = { + ...Premium, + args: { + bannerType: "warning", + }, }; -export const Danger = Template.bind({}); -Danger.args = { - bannerType: "danger", +export const Danger: Story = { + ...Premium, + args: { + bannerType: "danger", + }, }; diff --git a/libs/components/src/breadcrumbs/breadcrumbs.stories.ts b/libs/components/src/breadcrumbs/breadcrumbs.stories.ts index 782bb39e75..673b702727 100644 --- a/libs/components/src/breadcrumbs/breadcrumbs.stories.ts +++ b/libs/components/src/breadcrumbs/breadcrumbs.stories.ts @@ -1,6 +1,6 @@ -import { Component } from "@angular/core"; +import { Component, importProvidersFrom } from "@angular/core"; import { RouterModule } from "@angular/router"; -import { Meta, Story, moduleMetadata } from "@storybook/angular"; +import { Meta, StoryObj, applicationConfig, moduleMetadata } from "@storybook/angular"; import { IconButtonModule } from "../icon-button"; import { LinkModule } from "../link"; @@ -26,16 +26,19 @@ export default { decorators: [ moduleMetadata({ declarations: [BreadcrumbComponent], - imports: [ - LinkModule, - MenuModule, - IconButtonModule, - RouterModule.forRoot([{ path: "**", component: EmptyComponent }], { useHash: true }), + imports: [LinkModule, MenuModule, IconButtonModule, RouterModule], + }), + applicationConfig({ + providers: [ + importProvidersFrom( + RouterModule.forRoot([{ path: "**", component: EmptyComponent }], { useHash: true }) + ), ], }), ], args: { items: [], + show: 3, }, argTypes: { breadcrumbs: { @@ -45,47 +48,54 @@ export default { }, } as Meta; -const Template: Story = (args: BreadcrumbsComponent) => ({ - props: args, - template: ` -

Router links

-

- - {{item.name}} - -

+type Story = StoryObj; -

Click emit

-

- - {{item.name}} - -

- `, -}); +export const TopLevel: Story = { + render: (args) => ({ + props: args, + template: ` +

Router links

+

+ + {{item.name}} + +

+ +

Click emit

+

+ + {{item.name}} + +

+ `, + }), -export const TopLevel = Template.bind({}); -TopLevel.args = { - items: [{ icon: "bwi-star", name: "Top Level" }] as Breadcrumb[], + args: { + items: [{ icon: "bwi-star", name: "Top Level" }] as Breadcrumb[], + }, }; -export const SecondLevel = Template.bind({}); -SecondLevel.args = { - items: [ - { name: "Acme Vault", route: "/" }, - { icon: "bwi-collection", name: "Collection", route: "collection" }, - ] as Breadcrumb[], +export const SecondLevel: Story = { + ...TopLevel, + args: { + items: [ + { name: "Acme Vault", route: "/" }, + { icon: "bwi-collection", name: "Collection", route: "collection" }, + ] as Breadcrumb[], + }, }; -export const Overflow = Template.bind({}); -Overflow.args = { - items: [ - { name: "Acme Vault", route: "" }, - { icon: "bwi-collection", name: "Collection", route: "collection" }, - { icon: "bwi-collection", name: "Middle-Collection 1", route: "middle-collection-1" }, - { icon: "bwi-collection", name: "Middle-Collection 2", route: "middle-collection-2" }, - { icon: "bwi-collection", name: "Middle-Collection 3", route: "middle-collection-3" }, - { icon: "bwi-collection", name: "Middle-Collection 4", route: "middle-collection-4" }, - { icon: "bwi-collection", name: "End Collection", route: "end-collection" }, - ] as Breadcrumb[], +export const Overflow: Story = { + ...TopLevel, + args: { + items: [ + { name: "Acme Vault", route: "" }, + { icon: "bwi-collection", name: "Collection", route: "collection" }, + { icon: "bwi-collection", name: "Middle-Collection 1", route: "middle-collection-1" }, + { icon: "bwi-collection", name: "Middle-Collection 2", route: "middle-collection-2" }, + { icon: "bwi-collection", name: "Middle-Collection 3", route: "middle-collection-3" }, + { icon: "bwi-collection", name: "Middle-Collection 4", route: "middle-collection-4" }, + { icon: "bwi-collection", name: "End Collection", route: "end-collection" }, + ] as Breadcrumb[], + }, }; diff --git a/libs/components/src/stories/button-docs.stories.mdx b/libs/components/src/button/button.mdx similarity index 88% rename from libs/components/src/stories/button-docs.stories.mdx rename to libs/components/src/button/button.mdx index 3551be8cf6..fddbda36fb 100644 --- a/libs/components/src/stories/button-docs.stories.mdx +++ b/libs/components/src/button/button.mdx @@ -1,12 +1,18 @@ -import { Meta, Story } from "@storybook/addon-docs"; +import { Meta, Story, Primary, Controls } from "@storybook/addon-docs"; - +import * as stories from "./button.stories"; + + # Button Buttons are interactive elements that can be triggered using a mouse, keyboard, or touch. They are used to indicate actions that can be performed by a user such as submitting a form. + + + + ## Guidelines ### Choosing the `` or ` - Link - `, -}); +type Story = StoryObj; -export const Primary = Template.bind({}); -Primary.args = { - buttonType: "primary", +export const Primary: Story = { + render: (args) => ({ + props: args, + template: ` + + Link + `, + }), + args: { + buttonType: "primary", + }, }; -export const Secondary = Template.bind({}); -Secondary.args = { - buttonType: "secondary", +export const Secondary: Story = { + ...Primary, + args: { + buttonType: "secondary", + }, }; -export const Danger = Template.bind({}); -Danger.args = { - buttonType: "danger", +export const Danger: Story = { + ...Primary, + args: { + buttonType: "danger", + }, }; -const AllStylesTemplate: Story = (args) => ({ - props: args, - template: ` - - - - `, -}); - -export const Loading = AllStylesTemplate.bind({}); -Loading.args = { - disabled: false, - loading: true, +export const Loading: Story = { + render: (args) => ({ + props: args, + template: ` + + + + `, + }), + args: { + disabled: false, + loading: true, + }, }; -export const Disabled = AllStylesTemplate.bind({}); -Disabled.args = { - disabled: true, - loading: false, +export const Disabled: Story = { + ...Loading, + args: { + disabled: true, + loading: false, + }, }; -const DisabledWithAttributeTemplate: Story = (args) => ({ - props: args, - template: ` - - - - - - - - - - - `, -}); - -export const DisabledWithAttribute = DisabledWithAttributeTemplate.bind({}); -DisabledWithAttribute.args = { - disabled: true, - loading: false, +export const DisabledWithAttribute: Story = { + render: (args) => ({ + props: args, + template: ` + + + + + + + + + + + `, + }), + args: { + disabled: true, + loading: false, + }, }; -const BlockTemplate: Story = (args: ButtonComponent) => ({ - props: args, - template: ` - - - [block]="true" Link - - - block Link - - `, -}); - -export const Block = BlockTemplate.bind({}); -Block.args = { - block: true, +export const Block: Story = { + render: (args: ButtonComponent) => ({ + props: args, + template: ` + + + [block]="true" Link + + + block Link + + `, + }), + args: { + block: true, + }, }; diff --git a/libs/components/src/callout/callout.stories.ts b/libs/components/src/callout/callout.stories.ts index 89469a6f64..f8738e46b3 100644 --- a/libs/components/src/callout/callout.stories.ts +++ b/libs/components/src/callout/callout.stories.ts @@ -1,4 +1,4 @@ -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; @@ -35,31 +35,39 @@ export default { }, } as Meta; -const Template: Story = (args: CalloutComponent) => ({ - props: args, - template: ` - Content - `, -}); +type Story = StoryObj; -export const Success = Template.bind({}); -Success.args = { - type: "success", - title: "Success", +export const Success: Story = { + render: (args) => ({ + props: args, + template: ` + Content + `, + }), + args: { + type: "success", + title: "Success", + }, }; -export const Info = Template.bind({}); -Info.args = { - type: "info", - title: "Info", +export const Info: Story = { + ...Success, + args: { + type: "info", + title: "Info", + }, }; -export const Warning = Template.bind({}); -Warning.args = { - type: "warning", +export const Warning: Story = { + ...Success, + args: { + type: "warning", + }, }; -export const Danger = Template.bind({}); -Danger.args = { - type: "danger", +export const Danger: Story = { + ...Success, + args: { + type: "danger", + }, }; diff --git a/libs/components/src/checkbox/checkbox.stories.ts b/libs/components/src/checkbox/checkbox.stories.ts index a384dd2ce0..246e4ada7b 100644 --- a/libs/components/src/checkbox/checkbox.stories.ts +++ b/libs/components/src/checkbox/checkbox.stories.ts @@ -1,6 +1,6 @@ import { Component, Input } from "@angular/core"; import { FormsModule, ReactiveFormsModule, FormBuilder, Validators } from "@angular/forms"; -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; import { I18nService } from "@bitwarden/common/src/abstractions/i18n.service"; @@ -69,43 +69,44 @@ export default { }, } as Meta; -const DefaultTemplate: Story = (args: ExampleComponent) => ({ - props: args, - template: ``, -}); +type Story = StoryObj; -export const Default = DefaultTemplate.bind({}); -Default.parameters = { - docs: { - source: { - code: template, +export const Default: Story = { + render: (args) => ({ + props: args, + template: ``, + }), + parameters: { + docs: { + source: { + code: template, + }, }, }, -}; -Default.args = { - checked: false, - disabled: false, + args: { + checked: false, + disabled: false, + }, }; -const CustomTemplate: Story = (args) => ({ - props: args, - template: ` -
- - - -
- `, -}); -CustomTemplate.args = {}; - -export const Custom = CustomTemplate.bind({}); +export const Custom: Story = { + render: (args) => ({ + props: args, + template: ` +
+ + + +
+ `, + }), +}; diff --git a/libs/components/src/color-password/color-password.component.ts b/libs/components/src/color-password/color-password.component.ts index 14b825df71..04172bfa87 100644 --- a/libs/components/src/color-password/color-password.component.ts +++ b/libs/components/src/color-password/color-password.component.ts @@ -23,7 +23,7 @@ enum CharacterType { preserveWhitespaces: false, }) export class ColorPasswordComponent { - @Input() private password: string = null; + @Input() password: string = null; @Input() showCount = false; characterStyles: Record = { diff --git a/libs/components/src/color-password/color-password.stories.ts b/libs/components/src/color-password/color-password.stories.ts index cba57132bb..07418cad72 100644 --- a/libs/components/src/color-password/color-password.stories.ts +++ b/libs/components/src/color-password/color-password.stories.ts @@ -1,4 +1,4 @@ -import { Meta, Story } from "@storybook/angular"; +import { Meta, StoryObj } from "@storybook/angular"; import { ColorPasswordComponent } from "./color-password.component"; @@ -19,34 +19,40 @@ export default { }, } as Meta; -const Template: Story = (args: ColorPasswordComponent) => ({ - props: args, - template: ` - - `, -}); +type Story = StoryObj; -const WrappedTemplate: Story = (args: ColorPasswordComponent) => ({ - props: args, - template: ` -
- -
- `, -}); - -export const ColorPassword = Template.bind({}); - -export const WrappedColorPassword = WrappedTemplate.bind({}); - -export const ColorPasswordCount = Template.bind({}); -ColorPasswordCount.args = { - password: examplePassword, - showCount: true, +export const ColorPassword: Story = { + render: (args) => ({ + props: args, + template: ` + + `, + }), }; -export const WrappedColorPasswordCount = WrappedTemplate.bind({}); -WrappedColorPasswordCount.args = { - password: examplePassword, - showCount: true, +export const WrappedColorPassword: Story = { + render: (args) => ({ + props: args, + template: ` +
+ +
+ `, + }), +}; + +export const ColorPasswordCount: Story = { + ...ColorPassword, + args: { + password: examplePassword, + showCount: true, + }, +}; + +export const WrappedColorPasswordCount: Story = { + ...WrappedColorPassword, + args: { + password: examplePassword, + showCount: true, + }, }; diff --git a/libs/components/src/dialog/dialog.service.stories.ts b/libs/components/src/dialog/dialog.service.stories.ts index 5699c04abd..c189b28bc2 100644 --- a/libs/components/src/dialog/dialog.service.stories.ts +++ b/libs/components/src/dialog/dialog.service.stories.ts @@ -1,6 +1,6 @@ import { DIALOG_DATA, DialogModule, DialogRef } from "@angular/cdk/dialog"; import { Component, Inject } from "@angular/core"; -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; @@ -90,8 +90,6 @@ export default { }, } as Meta; -const Template: Story = (args: StoryDialogComponent) => ({ - props: args, -}); +type Story = StoryObj; -export const Default = Template.bind({}); +export const Default: Story = {}; diff --git a/libs/components/src/dialog/dialog/dialog.stories.ts b/libs/components/src/dialog/dialog/dialog.stories.ts index 6e01462013..ce9dedc128 100644 --- a/libs/components/src/dialog/dialog/dialog.stories.ts +++ b/libs/components/src/dialog/dialog/dialog.stories.ts @@ -1,4 +1,4 @@ -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; @@ -50,110 +50,118 @@ export default { }, } as Meta; -const Template: Story = (args: DialogComponent) => ({ - props: args, - template: ` - - {{title}} - Dialog body text goes here. - - - - - - - `, -}); +type Story = StoryObj; -export const Default = Template.bind({}); -Default.args = { - dialogSize: "default", - title: "Default", -}; - -export const Small = Template.bind({}); -Small.args = { - dialogSize: "small", - title: "Small", -}; - -export const LongTitle = Template.bind({}); -LongTitle.args = { - dialogSize: "small", - title: "Long_Title_That_Should_Be_Truncated", -}; - -export const Large = Template.bind({}); -Large.args = { - dialogSize: "large", - title: "Large", -}; - -export const Loading = Template.bind({}); -Loading.args = { - dialogSize: "large", - loading: true, - title: "Loading", -}; - -const TemplateScrolling: Story = (args: DialogComponent) => ({ - props: args, - template: ` - - Scrolling Example - - Dialog body text goes here.
- - repeating lines of characters
+export const Default: Story = { + render: (args: DialogComponent) => ({ + props: args, + template: ` + + {{title}} + Dialog body text goes here. + + + + - end of sequence! -
- - - - -
- `, -}); - -export const ScrollingContent = TemplateScrolling.bind({}); -ScrollingContent.args = { - dialogSize: "small", + + `, + }), + args: { + dialogSize: "default", + title: "Default", + }, }; -const TemplateTabbed: Story = (args: DialogComponent) => ({ - props: args, - template: ` - - Tab Content Example - - - First Tab Content - Second Tab Content - Third Tab Content - - - - - - - - `, -}); - -export const TabContent = TemplateTabbed.bind({}); -TabContent.args = { - dialogSize: "large", - disablePadding: true, +export const Small: Story = { + ...Default, + args: { + dialogSize: "small", + title: "Small", + }, }; -TabContent.story = { + +export const LongTitle: Story = { + ...Default, + args: { + dialogSize: "small", + title: "Long_Title_That_Should_Be_Truncated", + }, +}; + +export const Large: Story = { + ...Default, + args: { + dialogSize: "large", + title: "Large", + }, +}; + +export const Loading: Story = { + ...Default, + args: { + dialogSize: "large", + loading: true, + title: "Loading", + }, +}; + +export const ScrollingContent: Story = { + render: (args: DialogComponent) => ({ + props: args, + template: ` + + Scrolling Example + + Dialog body text goes here.
+ + repeating lines of characters
+
+ end of sequence! +
+ + + + +
+ `, + }), + args: { + dialogSize: "small", + }, +}; + +export const TabContent: Story = { + render: (args) => ({ + props: args, + template: ` + + Tab Content Example + + + First Tab Content + Second Tab Content + Third Tab Content + + + + + + + + `, + }), + args: { + dialogSize: "large", + disablePadding: true, + }, parameters: { docs: { storyDescription: `An example of using the \`bitTabGroup\` component within the Dialog. The content padding should be diff --git a/libs/components/src/dialog/simple-configurable-dialog/simple-configurable-dialog.service.stories.ts b/libs/components/src/dialog/simple-configurable-dialog/simple-configurable-dialog.service.stories.ts index 27c66538a0..f8910fdb8f 100644 --- a/libs/components/src/dialog/simple-configurable-dialog/simple-configurable-dialog.service.stories.ts +++ b/libs/components/src/dialog/simple-configurable-dialog/simple-configurable-dialog.service.stories.ts @@ -1,6 +1,6 @@ import { DialogModule } from "@angular/cdk/dialog"; import { Component } from "@angular/core"; -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; import { SimpleDialogType, SimpleDialogOptions } from "@bitwarden/angular/services/dialog"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; @@ -239,8 +239,6 @@ export default { }, } as Meta; -const Template: Story = (args: StoryDialogComponent) => ({ - props: args, -}); +type Story = StoryObj; -export const Default = Template.bind({}); +export const Default: Story = {}; diff --git a/libs/components/src/dialog/simple-dialog.service.stories.ts b/libs/components/src/dialog/simple-dialog.service.stories.ts index cab7270576..e4d60c96de 100644 --- a/libs/components/src/dialog/simple-dialog.service.stories.ts +++ b/libs/components/src/dialog/simple-dialog.service.stories.ts @@ -1,6 +1,6 @@ import { DialogModule, DialogRef, DIALOG_DATA } from "@angular/cdk/dialog"; import { Component, Inject } from "@angular/core"; -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; @@ -90,8 +90,6 @@ export default { }, } as Meta; -const Template: Story = (args: StoryDialogComponent) => ({ - props: args, -}); +type Story = StoryObj; -export const Default = Template.bind({}); +export const Default: Story = {}; diff --git a/libs/components/src/dialog/simple-dialog/simple-dialog.stories.ts b/libs/components/src/dialog/simple-dialog/simple-dialog.stories.ts index 1e5514abe5..27a82c4610 100644 --- a/libs/components/src/dialog/simple-dialog/simple-dialog.stories.ts +++ b/libs/components/src/dialog/simple-dialog/simple-dialog.stories.ts @@ -1,4 +1,4 @@ -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; import { ButtonModule } from "../../button"; import { DialogTitleContainerDirective } from "../directives/dialog-title-container.directive"; @@ -22,61 +22,63 @@ export default { }, } as Meta; -const Template: Story = (args: SimpleDialogComponent) => ({ - props: args, - template: ` - - Alert Dialog - Message Content - - - - - - `, -}); +type Story = StoryObj; -export const Default = Template.bind({}); - -const TemplateWithIcon: Story = (args: SimpleDialogComponent) => ({ - props: args, - template: ` - - - Premium Subscription Available - Message Content - - - - - - `, -}); - -export const CustomIcon = TemplateWithIcon.bind({}); - -const TemplateScroll: Story = (args: SimpleDialogComponent) => ({ - props: args, - template: ` - - Alert Dialog - - Message Content - Message text goes here.
- - repeating lines of characters
-
- end of sequence! -
- - - - -
- `, -}); - -export const ScrollingContent = TemplateScroll.bind({}); -ScrollingContent.args = { - useDefaultIcon: true, +export const Default: Story = { + render: (args) => ({ + props: args, + template: ` + + Alert Dialog + Message Content + + + + + + `, + }), +}; + +export const CustomIcon: Story = { + render: (args) => ({ + props: args, + template: ` + + + Premium Subscription Available + Message Content + + + + + + `, + }), +}; + +export const ScrollingContent: Story = { + render: (args: SimpleDialogComponent) => ({ + props: args, + template: ` + + Alert Dialog + + Message Content + Message text goes here.
+ + repeating lines of characters
+
+ end of sequence! +
+ + + + +
+ `, + }), + args: { + useDefaultIcon: true, + }, }; diff --git a/libs/components/src/form-field/bit-validators.stories.ts b/libs/components/src/form-field/bit-validators.stories.ts index e12b13dd40..9e717a3510 100644 --- a/libs/components/src/form-field/bit-validators.stories.ts +++ b/libs/components/src/form-field/bit-validators.stories.ts @@ -1,5 +1,5 @@ import { FormsModule, ReactiveFormsModule, FormBuilder } from "@angular/forms"; -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { StoryObj, Meta, moduleMetadata } from "@storybook/angular"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; @@ -46,11 +46,13 @@ const template = ` `; -export const ForbiddenCharacters: Story = (args: BitFormFieldComponent) => ({ - props: { - formObj: new FormBuilder().group({ - name: ["", forbiddenCharacters(["\\", "/", "@", "#", "$", "%", "^", "&", "*", "(", ")"])], - }), - }, - template, -}); +export const ForbiddenCharacters: StoryObj = { + render: (args: BitFormFieldComponent) => ({ + props: { + formObj: new FormBuilder().group({ + name: ["", forbiddenCharacters(["\\", "/", "@", "#", "$", "%", "^", "&", "*", "(", ")"])], + }), + }, + template, + }), +}; diff --git a/libs/components/src/form-field/error-summary.stories.ts b/libs/components/src/form-field/error-summary.stories.ts index f85e579002..16bfd99ac4 100644 --- a/libs/components/src/form-field/error-summary.stories.ts +++ b/libs/components/src/form-field/error-summary.stories.ts @@ -1,5 +1,5 @@ import { UntypedFormBuilder, FormsModule, ReactiveFormsModule, Validators } from "@angular/forms"; -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; @@ -50,29 +50,28 @@ function submit() { formObj.markAllAsTouched(); } -const Template: Story = (args: BitFormFieldComponent) => ({ - props: { - formObj: formObj, - submit: submit, - ...args, - }, - template: ` -
- - Name - - - - - Email - - - - - -
- `, -}); - -export const Default = Template.bind({}); -Default.props = {}; +export const Default: StoryObj = { + render: (args) => ({ + props: { + formObj: formObj, + submit: submit, + ...args, + }, + template: ` +
+ + Name + + + + + Email + + + + + +
+ `, + }), +}; diff --git a/libs/components/src/form-field/form-field.stories.ts b/libs/components/src/form-field/form-field.stories.ts index 1b46e6e6c5..c8c520bb81 100644 --- a/libs/components/src/form-field/form-field.stories.ts +++ b/libs/components/src/form-field/form-field.stories.ts @@ -7,7 +7,7 @@ import { ValidatorFn, Validators, } from "@angular/forms"; -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; @@ -87,173 +87,168 @@ function forbiddenNameValidator(nameRe: RegExp): ValidatorFn { function submit() { defaultFormObj.markAllAsTouched(); } +type Story = StoryObj; -const Template: Story = (args: BitFormFieldComponent) => ({ - props: { - formObj: defaultFormObj, - submit: submit, - ...args, - }, - template: ` -
+export const Default: Story = { + render: (args) => ({ + props: { + formObj: defaultFormObj, + submit: submit, + ...args, + }, + template: ` + + + Label + + Optional Hint + +
+ `, + }), +}; + +export const Required: Story = { + render: (args) => ({ + props: { + formObj: formObj, + ...args, + }, + template: ` Label - - Optional Hint + - - `, -}); + + + FormControl + + + `, + }), +}; -export const Default = Template.bind({}); -Default.props = {}; +export const Hint: Story = { + render: (args: BitFormFieldComponent) => ({ + props: { + formObj: formObj, + ...args, + }, + template: ` + + FormControl + + Long hint text + + `, + }), +}; -const RequiredTemplate: Story = (args: BitFormFieldComponent) => ({ - props: { - formObj: formObj, - ...args, - }, - template: ` - - Label - - +export const Disabled: Story = { + render: (args) => ({ + props: args, + template: ` + + Label + + + `, + }), + args: {}, +}; - - FormControl - - - `, -}); +export const InputGroup: Story = { + render: (args) => ({ + props: args, + template: ` + + Label + + $ + USD + + `, + }), + args: {}, +}; -export const Required = RequiredTemplate.bind({}); -Required.props = {}; +export const ButtonInputGroup: Story = { + render: (args) => ({ + props: args, + template: ` + + + + + + + + `, + }), + args: {}, +}; -const HintTemplate: Story = (args: BitFormFieldComponent) => ({ - props: { - formObj: formObj, - ...args, - }, - template: ` - - FormControl - - Long hint text - - `, -}); +export const DisabledButtonInputGroup: Story = { + render: (args) => ({ + props: args, + template: ` + + Label + + + + + + + `, + }), + args: {}, +}; -export const Hint = HintTemplate.bind({}); -Required.props = {}; +export const Select: Story = { + render: (args: BitFormFieldComponent) => ({ + props: args, + template: ` + + Label + + + `, + }), + args: {}, +}; -const DisabledTemplate: Story = (args: BitFormFieldComponent) => ({ - props: args, - template: ` - - Label - - - `, -}); +export const AdvancedSelect: Story = { + render: (args: BitFormFieldComponent) => ({ + props: args, + template: ` + + Label + + + + + + `, + }), +}; -export const Disabled = DisabledTemplate.bind({}); -Disabled.args = {}; - -const GroupTemplate: Story = (args: BitFormFieldComponent) => ({ - props: args, - template: ` - - Label - - $ - USD - - `, -}); - -export const InputGroup = GroupTemplate.bind({}); -InputGroup.args = {}; - -const ButtonGroupTemplate: Story = (args: BitFormFieldComponent) => ({ - props: args, - template: ` - - - - - - - - `, -}); - -export const ButtonInputGroup = ButtonGroupTemplate.bind({}); -ButtonInputGroup.args = {}; - -const DisabledButtonInputGroupTemplate: Story = ( - args: BitFormFieldComponent -) => ({ - props: args, - template: ` - - Label - - - - - - - `, -}); - -export const DisabledButtonInputGroup = DisabledButtonInputGroupTemplate.bind({}); -DisabledButtonInputGroup.args = {}; - -const SelectTemplate: Story = (args: BitFormFieldComponent) => ({ - props: args, - template: ` - - Label - - - `, -}); - -export const Select = SelectTemplate.bind({}); -Select.args = {}; - -const AdvancedSelectTemplate: Story = (args: BitFormFieldComponent) => ({ - props: args, - template: ` - - Label - - - - - - `, -}); - -export const AdvancedSelect = AdvancedSelectTemplate.bind({}); -AdvancedSelectTemplate.args = {}; - -const TextareaTemplate: Story = (args: BitFormFieldComponent) => ({ - props: args, - template: ` - - Textarea - - - `, -}); - -export const Textarea = TextareaTemplate.bind({}); -Textarea.args = {}; +export const Textarea: Story = { + render: (args: BitFormFieldComponent) => ({ + props: args, + template: ` + + Textarea + + + `, + }), + args: {}, +}; diff --git a/libs/components/src/form-field/multi-select.stories.ts b/libs/components/src/form-field/multi-select.stories.ts index a68064e07d..123f6602ae 100644 --- a/libs/components/src/form-field/multi-select.stories.ts +++ b/libs/components/src/form-field/multi-select.stories.ts @@ -7,7 +7,7 @@ import { } from "@angular/forms"; import { NgSelectModule } from "@ng-select/ng-select"; import { action } from "@storybook/addon-actions"; -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; @@ -75,209 +75,228 @@ function submit(formObj: FormGroup) { formObj.markAllAsTouched(); } -const MultiSelectTemplate: Story = (args: MultiSelectComponent) => ({ - props: { - formObj: formObjFactory(), - submit: submit, - ...args, - onItemsConfirmed: actionsData.onItemsConfirmed, +type Story = StoryObj; + +export const Loading: Story = { + render: (args) => ({ + props: { + formObj: formObjFactory(), + submit: submit, + ...args, + onItemsConfirmed: actionsData.onItemsConfirmed, + }, + template: ` +
+ + {{ name }} + + + {{ hint }} + + +
+ `, + }), + args: { + baseItems: [] as any, + name: "Loading", + hint: "This is what a loading multi-select looks like", + loading: true, }, - template: ` -
- - {{ name }} - - - {{ hint }} - - -
- `, -}); - -export const Loading = MultiSelectTemplate.bind({}); -Loading.args = { - baseItems: [], - name: "Loading", - hint: "This is what a loading multi-select looks like", - loading: "true", }; -export const Disabled = MultiSelectTemplate.bind({}); -Disabled.args = { - name: "Disabled", - disabled: "true", - hint: "This is what a disabled multi-select looks like", -}; - -export const Groups = MultiSelectTemplate.bind({}); -Groups.args = { - name: "Select groups", - hint: "Groups will be assigned to the associated member", - baseItems: [ - { id: "1", listName: "Group 1", labelName: "Group 1", icon: "bwi-family" }, - { id: "2", listName: "Group 2", labelName: "Group 2", icon: "bwi-family" }, - { id: "3", listName: "Group 3", labelName: "Group 3", icon: "bwi-family" }, - { id: "4", listName: "Group 4", labelName: "Group 4", icon: "bwi-family" }, - { id: "5", listName: "Group 5", labelName: "Group 5", icon: "bwi-family" }, - { id: "6", listName: "Group 6", labelName: "Group 6", icon: "bwi-family" }, - { id: "7", listName: "Group 7", labelName: "Group 7", icon: "bwi-family" }, - ], -}; - -export const Members = MultiSelectTemplate.bind({}); -Members.args = { - name: "Select members", - hint: "Members will be assigned to the associated group/collection", - baseItems: [ - { id: "1", listName: "Joe Smith (jsmith@mail.me)", labelName: "Joe Smith", icon: "bwi-user" }, - { - id: "2", - listName: "Tania Stone (tstone@mail.me)", - labelName: "Tania Stone", - icon: "bwi-user", - }, - { - id: "3", - listName: "Matt Matters (mmatters@mail.me)", - labelName: "Matt Matters", - icon: "bwi-user", - }, - { - id: "4", - listName: "Bob Robertson (brobertson@mail.me)", - labelName: "Bob Robertson", - icon: "bwi-user", - }, - { - id: "5", - listName: "Ashley Fletcher (aflectcher@mail.me)", - labelName: "Ashley Fletcher", - icon: "bwi-user", - }, - { id: "6", listName: "Rita Olson (rolson@mail.me)", labelName: "Rita Olson", icon: "bwi-user" }, - { - id: "7", - listName: "Final listName (fname@mail.me)", - labelName: "(fname@mail.me)", - icon: "bwi-user", - }, - ], -}; - -export const Collections = MultiSelectTemplate.bind({}); -Collections.args = { - name: "Select collections", - hint: "Collections will be assigned to the associated member", - baseItems: [ - { id: "1", listName: "Collection 1", labelName: "Collection 1", icon: "bwi-collection" }, - { id: "2", listName: "Collection 2", labelName: "Collection 2", icon: "bwi-collection" }, - { id: "3", listName: "Collection 3", labelName: "Collection 3", icon: "bwi-collection" }, - { - id: "3.5", - listName: "Child Collection 1 for Parent 1", - labelName: "Child Collection 1 for Parent 1", - icon: "bwi-collection", - parentGrouping: "Parent 1", - }, - { - id: "3.55", - listName: "Child Collection 2 for Parent 1", - labelName: "Child Collection 2 for Parent 1", - icon: "bwi-collection", - parentGrouping: "Parent 1", - }, - { - id: "3.59", - listName: "Child Collection 3 for Parent 1", - labelName: "Child Collection 3 for Parent 1", - icon: "bwi-collection", - parentGrouping: "Parent 1", - }, - { - id: "3.75", - listName: "Child Collection 1 for Parent 2", - labelName: "Child Collection 1 for Parent 2", - icon: "bwi-collection", - parentGrouping: "Parent 2", - }, - { id: "4", listName: "Collection 4", labelName: "Collection 4", icon: "bwi-collection" }, - { id: "5", listName: "Collection 5", labelName: "Collection 5", icon: "bwi-collection" }, - { id: "6", listName: "Collection 6", labelName: "Collection 6", icon: "bwi-collection" }, - { id: "7", listName: "Collection 7", labelName: "Collection 7", icon: "bwi-collection" }, - ], -}; - -export const MembersAndGroups = MultiSelectTemplate.bind({}); -MembersAndGroups.args = { - name: "Select groups and members", - hint: "Members/Groups will be assigned to the associated collection", - baseItems: [ - { id: "1", listName: "Group 1", labelName: "Group 1", icon: "bwi-family" }, - { id: "2", listName: "Group 2", labelName: "Group 2", icon: "bwi-family" }, - { id: "3", listName: "Group 3", labelName: "Group 3", icon: "bwi-family" }, - { id: "4", listName: "Group 4", labelName: "Group 4", icon: "bwi-family" }, - { id: "5", listName: "Group 5", labelName: "Group 5", icon: "bwi-family" }, - { id: "6", listName: "Joe Smith (jsmith@mail.me)", labelName: "Joe Smith", icon: "bwi-user" }, - { - id: "7", - listName: "Tania Stone (tstone@mail.me)", - labelName: "(tstone@mail.me)", - icon: "bwi-user", - }, - ], -}; - -export const RemoveSelected = MultiSelectTemplate.bind({}); -RemoveSelected.args = { - name: "Select groups", - hint: "Groups will be removed from the list once the dropdown is closed", - baseItems: [ - { id: "1", listName: "Group 1", labelName: "Group 1", icon: "bwi-family" }, - { id: "2", listName: "Group 2", labelName: "Group 2", icon: "bwi-family" }, - { id: "3", listName: "Group 3", labelName: "Group 3", icon: "bwi-family" }, - { id: "4", listName: "Group 4", labelName: "Group 4", icon: "bwi-family" }, - { id: "5", listName: "Group 5", labelName: "Group 5", icon: "bwi-family" }, - { id: "6", listName: "Group 6", labelName: "Group 6", icon: "bwi-family" }, - { id: "7", listName: "Group 7", labelName: "Group 7", icon: "bwi-family" }, - ], - removeSelectedItems: "true", -}; - -const StandaloneTemplate: Story = (args: MultiSelectComponent) => ({ - props: { - ...args, - onItemsConfirmed: actionsData.onItemsConfirmed, +export const Disabled: Story = { + ...Loading, + args: { + name: "Disabled", + disabled: true, + hint: "This is what a disabled multi-select looks like", + }, +}; + +export const Groups: Story = { + ...Loading, + args: { + name: "Select groups", + hint: "Groups will be assigned to the associated member", + baseItems: [ + { id: "1", listName: "Group 1", labelName: "Group 1", icon: "bwi-family" }, + { id: "2", listName: "Group 2", labelName: "Group 2", icon: "bwi-family" }, + { id: "3", listName: "Group 3", labelName: "Group 3", icon: "bwi-family" }, + { id: "4", listName: "Group 4", labelName: "Group 4", icon: "bwi-family" }, + { id: "5", listName: "Group 5", labelName: "Group 5", icon: "bwi-family" }, + { id: "6", listName: "Group 6", labelName: "Group 6", icon: "bwi-family" }, + { id: "7", listName: "Group 7", labelName: "Group 7", icon: "bwi-family" }, + ], + }, +}; + +export const Members: Story = { + ...Loading, + args: { + name: "Select members", + hint: "Members will be assigned to the associated group/collection", + baseItems: [ + { id: "1", listName: "Joe Smith (jsmith@mail.me)", labelName: "Joe Smith", icon: "bwi-user" }, + { + id: "2", + listName: "Tania Stone (tstone@mail.me)", + labelName: "Tania Stone", + icon: "bwi-user", + }, + { + id: "3", + listName: "Matt Matters (mmatters@mail.me)", + labelName: "Matt Matters", + icon: "bwi-user", + }, + { + id: "4", + listName: "Bob Robertson (brobertson@mail.me)", + labelName: "Bob Robertson", + icon: "bwi-user", + }, + { + id: "5", + listName: "Ashley Fletcher (aflectcher@mail.me)", + labelName: "Ashley Fletcher", + icon: "bwi-user", + }, + { + id: "6", + listName: "Rita Olson (rolson@mail.me)", + labelName: "Rita Olson", + icon: "bwi-user", + }, + { + id: "7", + listName: "Final listName (fname@mail.me)", + labelName: "(fname@mail.me)", + icon: "bwi-user", + }, + ], + }, +}; + +export const Collections: Story = { + ...Loading, + args: { + name: "Select collections", + hint: "Collections will be assigned to the associated member", + baseItems: [ + { id: "1", listName: "Collection 1", labelName: "Collection 1", icon: "bwi-collection" }, + { id: "2", listName: "Collection 2", labelName: "Collection 2", icon: "bwi-collection" }, + { id: "3", listName: "Collection 3", labelName: "Collection 3", icon: "bwi-collection" }, + { + id: "3.5", + listName: "Child Collection 1 for Parent 1", + labelName: "Child Collection 1 for Parent 1", + icon: "bwi-collection", + parentGrouping: "Parent 1", + }, + { + id: "3.55", + listName: "Child Collection 2 for Parent 1", + labelName: "Child Collection 2 for Parent 1", + icon: "bwi-collection", + parentGrouping: "Parent 1", + }, + { + id: "3.59", + listName: "Child Collection 3 for Parent 1", + labelName: "Child Collection 3 for Parent 1", + icon: "bwi-collection", + parentGrouping: "Parent 1", + }, + { + id: "3.75", + listName: "Child Collection 1 for Parent 2", + labelName: "Child Collection 1 for Parent 2", + icon: "bwi-collection", + parentGrouping: "Parent 2", + }, + { id: "4", listName: "Collection 4", labelName: "Collection 4", icon: "bwi-collection" }, + { id: "5", listName: "Collection 5", labelName: "Collection 5", icon: "bwi-collection" }, + { id: "6", listName: "Collection 6", labelName: "Collection 6", icon: "bwi-collection" }, + { id: "7", listName: "Collection 7", labelName: "Collection 7", icon: "bwi-collection" }, + ], + }, +}; + +export const MembersAndGroups: Story = { + ...Loading, + args: { + name: "Select groups and members", + hint: "Members/Groups will be assigned to the associated collection", + baseItems: [ + { id: "1", listName: "Group 1", labelName: "Group 1", icon: "bwi-family" }, + { id: "2", listName: "Group 2", labelName: "Group 2", icon: "bwi-family" }, + { id: "3", listName: "Group 3", labelName: "Group 3", icon: "bwi-family" }, + { id: "4", listName: "Group 4", labelName: "Group 4", icon: "bwi-family" }, + { id: "5", listName: "Group 5", labelName: "Group 5", icon: "bwi-family" }, + { id: "6", listName: "Joe Smith (jsmith@mail.me)", labelName: "Joe Smith", icon: "bwi-user" }, + { + id: "7", + listName: "Tania Stone (tstone@mail.me)", + labelName: "(tstone@mail.me)", + icon: "bwi-user", + }, + ], + }, +}; + +export const RemoveSelected: Story = { + ...Loading, + args: { + name: "Select groups", + hint: "Groups will be removed from the list once the dropdown is closed", + baseItems: [ + { id: "1", listName: "Group 1", labelName: "Group 1", icon: "bwi-family" }, + { id: "2", listName: "Group 2", labelName: "Group 2", icon: "bwi-family" }, + { id: "3", listName: "Group 3", labelName: "Group 3", icon: "bwi-family" }, + { id: "4", listName: "Group 4", labelName: "Group 4", icon: "bwi-family" }, + { id: "5", listName: "Group 5", labelName: "Group 5", icon: "bwi-family" }, + { id: "6", listName: "Group 6", labelName: "Group 6", icon: "bwi-family" }, + { id: "7", listName: "Group 7", labelName: "Group 7", icon: "bwi-family" }, + ], + removeSelectedItems: true, + }, +}; + +export const Standalone: Story = { + render: (args) => ({ + props: { + ...args, + onItemsConfirmed: actionsData.onItemsConfirmed, + }, + template: ` + + + `, + }), + args: { + baseItems: [ + { id: "1", listName: "Group 1", labelName: "Group 1", icon: "bwi-family" }, + { id: "2", listName: "Group 2", labelName: "Group 2", icon: "bwi-family" }, + { id: "3", listName: "Group 3", labelName: "Group 3", icon: "bwi-family" }, + { id: "4", listName: "Group 4", labelName: "Group 4", icon: "bwi-family" }, + { id: "5", listName: "Group 5", labelName: "Group 5", icon: "bwi-family" }, + { id: "6", listName: "Group 6", labelName: "Group 6", icon: "bwi-family" }, + { id: "7", listName: "Group 7", labelName: "Group 7", icon: "bwi-family" }, + ], + removeSelectedItems: true, }, - template: ` - - - `, -}); - -export const Standalone = StandaloneTemplate.bind({}); -Standalone.args = { - baseItems: [ - { id: "1", listName: "Group 1", labelName: "Group 1", icon: "bwi-family" }, - { id: "2", listName: "Group 2", labelName: "Group 2", icon: "bwi-family" }, - { id: "3", listName: "Group 3", labelName: "Group 3", icon: "bwi-family" }, - { id: "4", listName: "Group 4", labelName: "Group 4", icon: "bwi-family" }, - { id: "5", listName: "Group 5", labelName: "Group 5", icon: "bwi-family" }, - { id: "6", listName: "Group 6", labelName: "Group 6", icon: "bwi-family" }, - { id: "7", listName: "Group 7", labelName: "Group 7", icon: "bwi-family" }, - ], - removeSelectedItems: "true", }; diff --git a/libs/components/src/form-field/password-input-toggle.stories.ts b/libs/components/src/form-field/password-input-toggle.stories.ts index f39974615b..a1e916b5e1 100644 --- a/libs/components/src/form-field/password-input-toggle.stories.ts +++ b/libs/components/src/form-field/password-input-toggle.stories.ts @@ -1,5 +1,5 @@ import { FormsModule, ReactiveFormsModule } from "@angular/forms"; -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; @@ -38,49 +38,42 @@ export default { }, } as Meta; -const Template: Story = ( - args: BitPasswordInputToggleDirective -) => ({ - props: { - ...args, - }, - template: ` -
- - Password - - - -
- `, -}); +type Story = StoryObj; -export const Default = Template.bind({}); -Default.props = {}; - -const TemplateBinding: Story = ( - args: BitPasswordInputToggleDirective -) => ({ - props: { - ...args, - }, - template: ` -
- - Password - - - - - -
- `, -}); - -export const Binding = TemplateBinding.bind({}); -Binding.props = { - toggled: false, +export const Default: Story = { + render: (args) => ({ + props: args, + template: ` +
+ + Password + + + +
+ `, + }), +}; + +export const Binding: Story = { + render: (args) => ({ + props: args, + template: ` +
+ + Password + + + + + +
+ `, + }), + args: { + toggled: false, + }, }; diff --git a/libs/components/src/form/form.stories.ts b/libs/components/src/form/form.stories.ts index 45409850b3..4c0b05a083 100644 --- a/libs/components/src/form/form.stories.ts +++ b/libs/components/src/form/form.stories.ts @@ -7,7 +7,7 @@ import { ValidatorFn, Validators, } from "@angular/forms"; -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; @@ -81,67 +81,70 @@ function forbiddenNameValidator(nameRe: RegExp): ValidatorFn { }; } -const FullExampleTemplate: Story = (args) => ({ - props: { - formObj: exampleFormObj, - submit: () => exampleFormObj.markAllAsTouched(), - ...args, +type Story = StoryObj; + +export const FullExample: Story = { + render: (args) => ({ + props: { + formObj: exampleFormObj, + submit: () => exampleFormObj.markAllAsTouched(), + ...args, + }, + template: ` +
+ + Name + + + + + Email + + + + + Country + + + + + + + Age + + + + + Agree to terms + + Required for the service to work properly + + + + Subscribe to updates? + + Yes + + + No + + + Decide later + + + + +
+ `, + }), + + args: { + countries, }, - template: ` -
- - Name - - - - - Email - - - - - Country - - - - - - - Age - - - - - Agree to terms - - Required for the service to work properly - - - - Subscribe to updates? - - Yes - - - No - - - Decide later - - - - -
- `, -}); - -export const FullExample = FullExampleTemplate.bind({}); -FullExample.args = { - countries, }; diff --git a/libs/components/src/icon-button/icon-button.stories.ts b/libs/components/src/icon-button/icon-button.stories.ts index 944b50da72..4a0c56fbde 100644 --- a/libs/components/src/icon-button/icon-button.stories.ts +++ b/libs/components/src/icon-button/icon-button.stories.ts @@ -1,4 +1,4 @@ -import { Meta, Story } from "@storybook/angular"; +import { Meta, StoryObj } from "@storybook/angular"; import { BitIconButtonComponent, IconButtonType } from "./icon-button.component"; @@ -31,68 +31,72 @@ export default { }, } as Meta; -const Template: Story = (args: BitIconButtonComponent) => ({ - props: { ...args, buttonTypes }, - template: ` - - - - - - - +type Story = StoryObj; - - - - - - - - - - - - - - - - -
{{buttonType}}
Default - -
Disabled - -
Loading - -
- `, -}); - -export const Default = Template.bind({}); -Default.args = { - size: "default", +export const Default: Story = { + render: (args: BitIconButtonComponent) => ({ + props: { ...args, buttonTypes }, + template: ` + + + + + + + + + + + + + + + + + + + + + + + + +
{{buttonType}}
Default + +
Disabled + +
Loading + +
+ `, + }), + args: { + size: "default", + }, }; -export const Small = Template.bind({}); -Small.args = { - size: "small", +export const Small: Story = { + ...Default, + args: { + size: "small", + }, }; diff --git a/libs/components/src/icon/icon.stories.ts b/libs/components/src/icon/icon.stories.ts index a67516f2e8..95bf457517 100644 --- a/libs/components/src/icon/icon.stories.ts +++ b/libs/components/src/icon/icon.stories.ts @@ -1,4 +1,4 @@ -import { Meta, Story } from "@storybook/angular"; +import { Meta, StoryObj } from "@storybook/angular"; import { BitIconComponent } from "./icon.component"; @@ -10,18 +10,22 @@ export default { }, } as Meta; -const Template: Story = (args: BitIconComponent) => ({ - props: args, - template: ` -
- -
- `, -}); +type Story = StoryObj; -export const ReportExposedPasswords = Template.bind({}); - -export const UnknownIcon = Template.bind({}); -UnknownIcon.args = { - icon: "unknown", +export const ReportExposedPasswords: Story = { + render: (args) => ({ + props: args, + template: ` +
+ +
+ `, + }), +}; + +export const UnknownIcon: Story = { + ...ReportExposedPasswords, + args: { + icon: "unknown" as any, + }, }; diff --git a/libs/components/src/index.ts b/libs/components/src/index.ts index 7abe0864aa..dbc4f0b494 100644 --- a/libs/components/src/index.ts +++ b/libs/components/src/index.ts @@ -12,6 +12,7 @@ export * from "./dialog"; export * from "./form-field"; export * from "./icon-button"; export * from "./icon"; +export * from "./input"; export * from "./link"; export * from "./menu"; export * from "./multi-select"; diff --git a/libs/components/src/input/index.ts b/libs/components/src/input/index.ts new file mode 100644 index 0000000000..4036b8ab94 --- /dev/null +++ b/libs/components/src/input/index.ts @@ -0,0 +1 @@ +export * from "./input.module"; diff --git a/libs/components/src/link/link.stories.ts b/libs/components/src/link/link.stories.ts index 7ffc6fd2e2..76bb4d4752 100644 --- a/libs/components/src/link/link.stories.ts +++ b/libs/components/src/link/link.stories.ts @@ -1,4 +1,4 @@ -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; import { AnchorLinkDirective, ButtonLinkDirective } from "./link.directive"; import { LinkModule } from "./link.module"; @@ -24,97 +24,99 @@ export default { }, } as Meta; -const ButtonTemplate: Story = (args: ButtonLinkDirective) => ({ - props: args, - template: ` -
-
- -
-
- -
-
- -
-
- -
-
- `, -}); +type Story = StoryObj; -const AnchorTemplate: Story = (args: AnchorLinkDirective) => ({ - props: args, - template: ` -
-
- Anchor +export const Buttons: Story = { + render: (args) => ({ + props: args, + template: ` +
+
+ +
+
+ +
+
+ +
+
+ +
- - - -
- `, -}); - -export const Buttons = ButtonTemplate.bind({}); -Buttons.args = { - linkType: "primary", -}; - -export const Anchors = AnchorTemplate.bind({}); -Anchors.args = { - linkType: "primary", -}; - -const InlineTemplate: Story = (args) => ({ - props: args, - template: ` - - On the internet paragraphs often contain inline links, but few know that can be used for similar purposes. - - `, -}); - -export const Inline = InlineTemplate.bind({}); -Inline.args = { - linkType: "primary", -}; - -const DisabledTemplate: Story = (args) => ({ - props: args, - template: ` - - -
- -
- `, -}); - -export const Disabled = DisabledTemplate.bind({}); -Disabled.parameters = { - controls: { - exclude: ["linkType"], - hideNoControlsWarning: true, + `, + }), + args: { + linkType: "primary", + }, +}; + +export const Anchors: StoryObj = { + render: (args) => ({ + props: args, + template: ` + + `, + }), + args: { + linkType: "primary", + }, +}; + +export const Inline: Story = { + render: (args) => ({ + props: args, + template: ` + + On the internet paragraphs often contain inline links, but few know that can be used for similar purposes. + + `, + }), + args: { + linkType: "primary", + }, +}; + +export const Disabled: Story = { + render: (args) => ({ + props: args, + template: ` + + +
+ +
+ `, + }), + parameters: { + controls: { + exclude: ["linkType"], + hideNoControlsWarning: true, + }, }, }; diff --git a/libs/components/src/menu/menu.stories.ts b/libs/components/src/menu/menu.stories.ts index 786e7ca688..d0f78ed66d 100644 --- a/libs/components/src/menu/menu.stories.ts +++ b/libs/components/src/menu/menu.stories.ts @@ -1,5 +1,5 @@ import { OverlayModule } from "@angular/cdk/overlay"; -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; import { ButtonModule } from "../button/button.module"; @@ -30,40 +30,42 @@ export default { }, } as Meta; -const Template: Story = (args: MenuTriggerForDirective) => ({ - props: args, - template: ` - - Anchor link - Another link - - - - +type Story = StoryObj; -
-
- +export const OpenMenu: Story = { + render: (args) => ({ + props: args, + template: ` + + Anchor link + Another link + + + + + +
+
+ +
-
- `, -}); - -const TemplateWithButton: Story = (args: MenuTriggerForDirective) => ({ - props: args, - template: ` -
- -
- - - Anchor link - Another link - - - - `, -}); - -export const OpenMenu = Template.bind({}); -export const ClosedMenu = TemplateWithButton.bind({}); + `, + }), +}; +export const ClosedMenu: Story = { + render: (args) => ({ + props: args, + template: ` +
+ +
+ + + Anchor link + Another link + + + + `, + }), +}; diff --git a/libs/components/src/navigation/nav-group.stories.ts b/libs/components/src/navigation/nav-group.stories.ts index 1c22e2bfc7..5b6e5b807c 100644 --- a/libs/components/src/navigation/nav-group.stories.ts +++ b/libs/components/src/navigation/nav-group.stories.ts @@ -1,5 +1,5 @@ import { RouterTestingModule } from "@angular/router/testing"; -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { StoryObj, Meta, moduleMetadata } from "@storybook/angular"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; @@ -36,9 +36,10 @@ export default { }, } as Meta; -export const Default: Story = (args) => ({ - props: args, - template: ` +export const Default: StoryObj = { + render: (args) => ({ + props: args, + template: ` @@ -50,25 +51,28 @@ export const Default: Story = (args) => ({ `, -}); + }), +}; -export const Tree: Story = (args) => ({ - props: args, - template: ` - - - - - - - - +export const Tree: StoryObj = { + render: (args) => ({ + props: args, + template: ` + + + + + + + + + + + - - + - - - `, -}); + `, + }), +}; diff --git a/libs/components/src/navigation/nav-item.stories.ts b/libs/components/src/navigation/nav-item.stories.ts index e1a7128922..47960f874f 100644 --- a/libs/components/src/navigation/nav-item.stories.ts +++ b/libs/components/src/navigation/nav-item.stories.ts @@ -1,5 +1,5 @@ import { RouterTestingModule } from "@angular/router/testing"; -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { StoryObj, Meta, moduleMetadata } from "@storybook/angular"; import { IconButtonModule } from "../icon-button"; @@ -23,35 +23,42 @@ export default { }, } as Meta; -const Template: Story = (args: NavItemComponent) => ({ - props: args, - template: ` - - `, -}); +type Story = StoryObj; -export const Default = Template.bind({}); -Default.args = { - text: "Hello World", - icon: "bwi-filter", +export const Default: Story = { + render: (args) => ({ + props: args, + template: ` + + `, + }), + args: { + text: "Hello World", + icon: "bwi-filter", + }, }; -export const WithoutIcon = Template.bind({}); -WithoutIcon.args = { - text: "Hello World", - icon: "", +export const WithoutIcon: Story = { + ...Default, + args: { + text: "Hello World", + icon: "", + }, }; -export const WithoutRoute: Story = (args: NavItemComponent) => ({ - props: args, - template: ` - - `, -}); +export const WithoutRoute: Story = { + render: (args: NavItemComponent) => ({ + props: args, + template: ` + + `, + }), +}; -export const WithChildButtons: Story = (args: NavItemComponent) => ({ - props: args, - template: ` +export const WithChildButtons: Story = { + render: (args: NavItemComponent) => ({ + props: args, + template: ` `, -}); + }), +}; -export const MultipleItemsWithDivider: Story = (args: NavItemComponent) => ({ - props: args, - template: ` - - - - - - `, -}); +export const MultipleItemsWithDivider: Story = { + render: (args: NavItemComponent) => ({ + props: args, + template: ` + + + + + + `, + }), +}; diff --git a/libs/components/src/no-items/no-items.stories.ts b/libs/components/src/no-items/no-items.stories.ts index 0b08aafbc1..d8e5b59bdb 100644 --- a/libs/components/src/no-items/no-items.stories.ts +++ b/libs/components/src/no-items/no-items.stories.ts @@ -1,11 +1,13 @@ -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; import { ButtonModule } from "../button"; +import { NoItemsComponent } from "./no-items.component"; import { NoItemsModule } from "./no-items.module"; export default { title: "Component Library/No Items", + component: NoItemsComponent, decorators: [ moduleMetadata({ imports: [ButtonModule, NoItemsModule], @@ -13,23 +15,25 @@ export default { ], } as Meta; -const Template: Story = (args) => ({ - props: args, - template: ` - - No items found - Your description here. - - - `, -}); +type Story = StoryObj; -export const Default = Template.bind({}); +export const Default: Story = { + render: (args) => ({ + props: args, + template: ` + + No items found + Your description here. + + + `, + }), +}; diff --git a/libs/components/src/progress/progress.stories.ts b/libs/components/src/progress/progress.stories.ts index 079f936e3a..49a5398d2d 100644 --- a/libs/components/src/progress/progress.stories.ts +++ b/libs/components/src/progress/progress.stories.ts @@ -1,4 +1,4 @@ -import { Meta, Story } from "@storybook/angular"; +import { Meta, StoryObj } from "@storybook/angular"; import { ProgressComponent } from "./progress.component"; @@ -18,22 +18,23 @@ export default { }, } as Meta; -const Template: Story = (args: ProgressComponent) => ({ - props: args, -}); +type Story = StoryObj; -export const Empty = Template.bind({}); -Empty.args = { - barWidth: 0, +export const Empty: Story = { + args: { + barWidth: 0, + }, }; -export const Full = Template.bind({}); -Full.args = { - barWidth: 100, +export const Full: Story = { + args: { + barWidth: 100, + }, }; -export const CustomText = Template.bind({}); -CustomText.args = { - barWidth: 25, - text: "Loading...", +export const CustomText: Story = { + args: { + barWidth: 25, + text: "Loading...", + }, }; diff --git a/libs/components/src/radio-button/radio-button.stories.ts b/libs/components/src/radio-button/radio-button.stories.ts index 340e76c421..d3c5716698 100644 --- a/libs/components/src/radio-button/radio-button.stories.ts +++ b/libs/components/src/radio-button/radio-button.stories.ts @@ -1,5 +1,5 @@ import { FormsModule, ReactiveFormsModule, FormControl, FormGroup } from "@angular/forms"; -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; @@ -34,65 +34,67 @@ export default { url: "https://www.figma.com/file/Zt3YSeb6E6lebAffrNLa0h/Tailwind-Component-Library?node-id=3930%3A16850&t=xXPx6GJYsJfuMQPE-4", }, }, -} as Meta; +} as Meta; -const InlineTemplate: Story = (args: RadioGroupComponent) => ({ - props: { - formObj: new FormGroup({ - radio: new FormControl(0), - }), - }, - template: ` -
- - Group of radio buttons +type Story = StoryObj; - - First - +export const Inline: Story = { + render: () => ({ + props: { + formObj: new FormGroup({ + radio: new FormControl(0), + }), + }, + template: ` + + + Group of radio buttons + + + First + + + + Second + + + + Third + + + + `, + }), +}; - - Second - - - - Third - -
- - `, -}); - -export const Inline = InlineTemplate.bind({}); - -const BlockTemplate: Story = (args: RadioGroupComponent) => ({ - props: { - formObj: new FormGroup({ - radio: new FormControl(0), - }), - }, - template: ` -
- - Group of radio buttons - - - First - This is a hint for the first option - - - - Second - This is a hint for the second option - - - - Third - This is a hint for the third option - - -
- `, -}); - -export const Block = BlockTemplate.bind({}); +export const Block: Story = { + render: () => ({ + props: { + formObj: new FormGroup({ + radio: new FormControl(0), + }), + }, + template: ` +
+ + Group of radio buttons + + + First + This is a hint for the first option + + + + Second + This is a hint for the second option + + + + Third + This is a hint for the third option + + +
+ `, + }), +}; diff --git a/libs/components/src/search/search.stories.ts b/libs/components/src/search/search.stories.ts index 0968e9b6ed..3167c5c7d4 100644 --- a/libs/components/src/search/search.stories.ts +++ b/libs/components/src/search/search.stories.ts @@ -1,5 +1,5 @@ import { FormsModule, ReactiveFormsModule } from "@angular/forms"; -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; @@ -29,12 +29,14 @@ export default { ], } as Meta; -const Template: Story = (args: SearchComponent) => ({ - props: args, - template: ` - - `, -}); +type Story = StoryObj; -export const Default = Template.bind({}); -Default.args = {}; +export const Default: Story = { + render: (args: SearchComponent) => ({ + props: args, + template: ` + + `, + }), + args: {}, +}; diff --git a/libs/components/src/select/select.stories.ts b/libs/components/src/select/select.stories.ts index 9b38b05d6c..540279dab0 100644 --- a/libs/components/src/select/select.stories.ts +++ b/libs/components/src/select/select.stories.ts @@ -1,4 +1,4 @@ -import { Meta, moduleMetadata, Story } from "@storybook/angular"; +import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; @@ -37,22 +37,26 @@ export default { }, } as Meta; -const DefaultTemplate: Story = (args: MultiSelectComponent) => ({ - props: { - ...args, - }, - template: ` - - - - - `, -}); +type Story = StoryObj; -export const Default = DefaultTemplate.bind({}); -Default.args = {}; - -export const Disabled = DefaultTemplate.bind({}); -Disabled.args = { - disabled: true, +export const Default: Story = { + render: (args) => ({ + props: { + ...args, + }, + template: ` + + + + + `, + }), + args: {}, +}; + +export const Disabled: Story = { + ...Default, + args: { + disabled: true, + }, }; diff --git a/libs/components/src/stories/colors.stories.mdx b/libs/components/src/stories/colors.mdx similarity index 98% rename from libs/components/src/stories/colors.stories.mdx rename to libs/components/src/stories/colors.mdx index 57a15314e0..d77c726b26 100644 --- a/libs/components/src/stories/colors.stories.mdx +++ b/libs/components/src/stories/colors.mdx @@ -67,7 +67,8 @@ export const Table = (args) => ( ); - + `} + # Colors diff --git a/libs/components/src/stories/forms-docs.stories.mdx b/libs/components/src/stories/forms.mdx similarity index 97% rename from libs/components/src/stories/forms-docs.stories.mdx rename to libs/components/src/stories/forms.mdx index 0d8c94857c..f677684a9d 100644 --- a/libs/components/src/stories/forms-docs.stories.mdx +++ b/libs/components/src/stories/forms.mdx @@ -1,6 +1,6 @@ import { Meta, Story, Source } from "@storybook/addon-docs"; - + # Forms diff --git a/libs/components/src/stories/icons.stories.mdx b/libs/components/src/stories/icons.mdx similarity index 99% rename from libs/components/src/stories/icons.stories.mdx rename to libs/components/src/stories/icons.mdx index 1a74a8f4ec..b3a4cbbf99 100644 --- a/libs/components/src/stories/icons.stories.mdx +++ b/libs/components/src/stories/icons.mdx @@ -1,6 +1,6 @@ - +{/* Iconography.stories.mdx */} -import { Meta } from "@storybook/addon-docs/"; +import { Meta } from "@storybook/addon-docs"; diff --git a/libs/components/src/stories/input-docs.stories.mdx b/libs/components/src/stories/input.mdx similarity index 95% rename from libs/components/src/stories/input-docs.stories.mdx rename to libs/components/src/stories/input.mdx index 7f9b824354..0fd1a4890b 100644 --- a/libs/components/src/stories/input-docs.stories.mdx +++ b/libs/components/src/stories/input.mdx @@ -1,8 +1,8 @@ import { Meta } from "@storybook/addon-docs"; - + -# `bitInput` +# Input `bitInput` is an Angular directive to be used on ``, `