From bd490e3af9c6210990c010bf54b605fb1e25dd8e Mon Sep 17 00:00:00 2001
From: Jordan Aasen <166539328+jaasen-livefront@users.noreply.github.com>
Date: Wed, 2 Apr 2025 16:15:59 -0700
Subject: [PATCH] [CL-390] - Spotlight Component (#14085)
* WIP spotlight and onboarding nudge
* finalize spotlight component
* finalize spotlight component
* revert changes
* re-add changes
* re-add frozen prop
* add documentation
* move to vault
* update to vault
* small css fixes to spotlight
* smaller button
* fix height for non-button
* remove unecessary class
* clean up styling
* more style cleanup
* favor gap instead of mt
---
.../spotlight/spotlight.component.html | 34 ++++++++
.../spotlight/spotlight.component.ts | 32 ++++++++
.../components/spotlight/spotlight.stories.ts | 80 +++++++++++++++++++
3 files changed, 146 insertions(+)
create mode 100644 libs/vault/src/components/spotlight/spotlight.component.html
create mode 100644 libs/vault/src/components/spotlight/spotlight.component.ts
create mode 100644 libs/vault/src/components/spotlight/spotlight.stories.ts
diff --git a/libs/vault/src/components/spotlight/spotlight.component.html b/libs/vault/src/components/spotlight/spotlight.component.html
new file mode 100644
index 00000000000..a8631a71020
--- /dev/null
+++ b/libs/vault/src/components/spotlight/spotlight.component.html
@@ -0,0 +1,34 @@
+
+
+
+
{{ title }}
+
+ {{ subtitle }}
+
+
+
+
+
+
+
+
+
diff --git a/libs/vault/src/components/spotlight/spotlight.component.ts b/libs/vault/src/components/spotlight/spotlight.component.ts
new file mode 100644
index 00000000000..e52669cc404
--- /dev/null
+++ b/libs/vault/src/components/spotlight/spotlight.component.ts
@@ -0,0 +1,32 @@
+import { CommonModule } from "@angular/common";
+import { Component, EventEmitter, Input, Output } from "@angular/core";
+
+import { ButtonModule, IconButtonModule, TypographyModule } from "@bitwarden/components";
+import { I18nPipe } from "@bitwarden/ui-common";
+
+@Component({
+ selector: "bit-spotlight",
+ templateUrl: "spotlight.component.html",
+ standalone: true,
+ imports: [ButtonModule, CommonModule, IconButtonModule, I18nPipe, TypographyModule],
+})
+export class SpotlightComponent {
+ // The title of the component
+ @Input({ required: true }) title: string | null = null;
+ // The subtitle of the component
+ @Input({ required: true }) subtitle: string | null = null;
+ // The text to display on the button
+ @Input() buttonText?: string;
+ // Wheter the component can be dismissed, if true, the component will not show a close button
+ @Input() persistent = false;
+ @Output() onDismiss = new EventEmitter();
+ @Output() onButtonClick = new EventEmitter();
+
+ handleButtonClick(): void {
+ this.onButtonClick.emit();
+ }
+
+ handleDismiss(): void {
+ this.onDismiss.emit();
+ }
+}
diff --git a/libs/vault/src/components/spotlight/spotlight.stories.ts b/libs/vault/src/components/spotlight/spotlight.stories.ts
new file mode 100644
index 00000000000..9f7757e4528
--- /dev/null
+++ b/libs/vault/src/components/spotlight/spotlight.stories.ts
@@ -0,0 +1,80 @@
+import { moduleMetadata, Meta, StoryObj } from "@storybook/angular";
+
+import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
+import {
+ ButtonModule,
+ I18nMockService,
+ IconButtonModule,
+ TypographyModule,
+} from "@bitwarden/components";
+
+import { SpotlightComponent } from "./spotlight.component";
+
+const meta: Meta = {
+ title: "Vault/Spotlight",
+ component: SpotlightComponent,
+ decorators: [
+ moduleMetadata({
+ imports: [ButtonModule, IconButtonModule, TypographyModule],
+ providers: [
+ {
+ provide: I18nService,
+ useFactory: () => {
+ return new I18nMockService({
+ close: "Close",
+ });
+ },
+ },
+ ],
+ }),
+ ],
+ args: {
+ title: "Primary",
+ subtitle: "Callout Text",
+ buttonText: "Button",
+ },
+};
+
+export default meta;
+type Story = StoryObj;
+
+export const Default: Story = {};
+
+export const WithoutButton: Story = {
+ args: {
+ buttonText: undefined,
+ },
+};
+
+export const Persistent: Story = {
+ args: {
+ persistent: true,
+ },
+};
+
+export const WithCustomButton: Story = {
+ args: {
+ buttonText: "Custom Button",
+ },
+ render: (args) => ({
+ props: args,
+ template: `
+
+
+
+ `,
+ }),
+};