@arbor-education/design-system.components 0.4.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/CLAUDE.md +9 -0
  3. package/dist/components/avatar/Avatar.d.ts +11 -0
  4. package/dist/components/avatar/Avatar.d.ts.map +1 -0
  5. package/dist/components/avatar/Avatar.js +17 -0
  6. package/dist/components/avatar/Avatar.js.map +1 -0
  7. package/dist/components/avatar/Avatar.stories.d.ts +14 -0
  8. package/dist/components/avatar/Avatar.stories.d.ts.map +1 -0
  9. package/dist/components/avatar/Avatar.stories.js +66 -0
  10. package/dist/components/avatar/Avatar.stories.js.map +1 -0
  11. package/dist/components/avatar/Avatar.test.d.ts +2 -0
  12. package/dist/components/avatar/Avatar.test.d.ts.map +1 -0
  13. package/dist/components/avatar/Avatar.test.js +51 -0
  14. package/dist/components/avatar/Avatar.test.js.map +1 -0
  15. package/dist/components/dropdown/Dropdown.d.ts +2 -0
  16. package/dist/components/dropdown/Dropdown.d.ts.map +1 -1
  17. package/dist/components/dropdown/Dropdown.js +5 -1
  18. package/dist/components/dropdown/Dropdown.js.map +1 -1
  19. package/dist/components/dropdown/items/DropdownGroup.d.ts +3 -0
  20. package/dist/components/dropdown/items/DropdownGroup.d.ts.map +1 -0
  21. package/dist/components/dropdown/items/DropdownGroup.js +8 -0
  22. package/dist/components/dropdown/items/DropdownGroup.js.map +1 -0
  23. package/dist/components/dropdown/items/DropdownSeparator.d.ts +3 -0
  24. package/dist/components/dropdown/items/DropdownSeparator.d.ts.map +1 -0
  25. package/dist/components/dropdown/items/DropdownSeparator.js +8 -0
  26. package/dist/components/dropdown/items/DropdownSeparator.js.map +1 -0
  27. package/dist/components/userDropdown/UserDropdown.d.ts +47 -0
  28. package/dist/components/userDropdown/UserDropdown.d.ts.map +1 -0
  29. package/dist/components/userDropdown/UserDropdown.js +13 -0
  30. package/dist/components/userDropdown/UserDropdown.js.map +1 -0
  31. package/dist/components/userDropdown/UserDropdown.stories.d.ts +12 -0
  32. package/dist/components/userDropdown/UserDropdown.stories.d.ts.map +1 -0
  33. package/dist/components/userDropdown/UserDropdown.stories.js +222 -0
  34. package/dist/components/userDropdown/UserDropdown.stories.js.map +1 -0
  35. package/dist/components/userDropdown/UserDropdown.test.d.ts +2 -0
  36. package/dist/components/userDropdown/UserDropdown.test.d.ts.map +1 -0
  37. package/dist/components/userDropdown/UserDropdown.test.js +197 -0
  38. package/dist/components/userDropdown/UserDropdown.test.js.map +1 -0
  39. package/dist/components/userDropdown/assets/arbor.png +0 -0
  40. package/dist/components/userDropdown/assets/govhub.png +0 -0
  41. package/dist/components/userDropdown/assets/key.png +0 -0
  42. package/dist/components/userDropdown/assets/logos.d.ts +7 -0
  43. package/dist/components/userDropdown/assets/logos.d.ts.map +1 -0
  44. package/dist/components/userDropdown/assets/logos.js +13 -0
  45. package/dist/components/userDropdown/assets/logos.js.map +1 -0
  46. package/dist/components/userDropdown/assets/robin.png +0 -0
  47. package/dist/components/userDropdown/assets/sampeople.png +0 -0
  48. package/dist/components/userDropdown/assets/timetabler.png +0 -0
  49. package/dist/components/userDropdown/internal/UserDropdownAppItem.d.ts +3 -0
  50. package/dist/components/userDropdown/internal/UserDropdownAppItem.d.ts.map +1 -0
  51. package/dist/components/userDropdown/internal/UserDropdownAppItem.js +9 -0
  52. package/dist/components/userDropdown/internal/UserDropdownAppItem.js.map +1 -0
  53. package/dist/components/userDropdown/internal/UserDropdownCollapsibleSection.d.ts +9 -0
  54. package/dist/components/userDropdown/internal/UserDropdownCollapsibleSection.d.ts.map +1 -0
  55. package/dist/components/userDropdown/internal/UserDropdownCollapsibleSection.js +11 -0
  56. package/dist/components/userDropdown/internal/UserDropdownCollapsibleSection.js.map +1 -0
  57. package/dist/components/userDropdown/internal/UserDropdownSignOut.d.ts +7 -0
  58. package/dist/components/userDropdown/internal/UserDropdownSignOut.d.ts.map +1 -0
  59. package/dist/components/userDropdown/internal/UserDropdownSignOut.js +9 -0
  60. package/dist/components/userDropdown/internal/UserDropdownSignOut.js.map +1 -0
  61. package/dist/components/userDropdown/internal/UserDropdownTrigger.d.ts +11 -0
  62. package/dist/components/userDropdown/internal/UserDropdownTrigger.d.ts.map +1 -0
  63. package/dist/components/userDropdown/internal/UserDropdownTrigger.js +10 -0
  64. package/dist/components/userDropdown/internal/UserDropdownTrigger.js.map +1 -0
  65. package/dist/components/userDropdown/internal/UserDropdownUserInfo.d.ts +8 -0
  66. package/dist/components/userDropdown/internal/UserDropdownUserInfo.d.ts.map +1 -0
  67. package/dist/components/userDropdown/internal/UserDropdownUserInfo.js +17 -0
  68. package/dist/components/userDropdown/internal/UserDropdownUserInfo.js.map +1 -0
  69. package/dist/index.css +400 -0
  70. package/dist/index.css.map +1 -1
  71. package/dist/index.d.ts +4 -0
  72. package/dist/index.d.ts.map +1 -1
  73. package/dist/index.js +3 -0
  74. package/dist/index.js.map +1 -1
  75. package/package.json +2 -2
  76. package/src/components/avatar/Avatar.stories.tsx +84 -0
  77. package/src/components/avatar/Avatar.test.tsx +60 -0
  78. package/src/components/avatar/Avatar.tsx +68 -0
  79. package/src/components/avatar/avatar.scss +71 -0
  80. package/src/components/dropdown/Dropdown.tsx +5 -1
  81. package/src/components/dropdown/dropdown.scss +4 -1
  82. package/src/components/dropdown/items/DropdownGroup.tsx +11 -0
  83. package/src/components/dropdown/items/DropdownSeparator.tsx +9 -0
  84. package/src/components/userDropdown/UserDropdown.stories.tsx +237 -0
  85. package/src/components/userDropdown/UserDropdown.test.tsx +349 -0
  86. package/src/components/userDropdown/UserDropdown.tsx +110 -0
  87. package/src/components/userDropdown/assets/arbor.png +0 -0
  88. package/src/components/userDropdown/assets/govhub.png +0 -0
  89. package/src/components/userDropdown/assets/key.png +0 -0
  90. package/src/components/userDropdown/assets/logos.ts +13 -0
  91. package/src/components/userDropdown/assets/robin.png +0 -0
  92. package/src/components/userDropdown/assets/sampeople.png +0 -0
  93. package/src/components/userDropdown/assets/timetabler.png +0 -0
  94. package/src/components/userDropdown/internal/UserDropdownAppItem.tsx +21 -0
  95. package/src/components/userDropdown/internal/UserDropdownCollapsibleSection.tsx +38 -0
  96. package/src/components/userDropdown/internal/UserDropdownSignOut.tsx +19 -0
  97. package/src/components/userDropdown/internal/UserDropdownTrigger.tsx +42 -0
  98. package/src/components/userDropdown/internal/UserDropdownUserInfo.tsx +60 -0
  99. package/src/components/userDropdown/userDropdown.scss +377 -0
  100. package/src/index.scss +2 -0
  101. package/src/index.ts +4 -0
  102. package/tsconfig.json +1 -1
  103. package/vite-env.d.ts +31 -0
@@ -0,0 +1,60 @@
1
+ import { expect, test, describe } from 'vitest';
2
+ import { render, screen } from '@testing-library/react';
3
+ import { Avatar } from './Avatar';
4
+ import '@testing-library/jest-dom/vitest';
5
+
6
+ describe('Avatar', () => {
7
+ test('renders with image when src is provided', () => {
8
+ render(<Avatar src="https://example.com/avatar.jpg" alt="Test User" />);
9
+ const image = screen.getByRole('img', { hidden: true });
10
+ expect(image).toBeInTheDocument();
11
+ expect(image).toHaveAttribute('src', 'https://example.com/avatar.jpg');
12
+ expect(image).toHaveAttribute('alt', 'Test User');
13
+ });
14
+
15
+ test('renders with initials when no src is provided', () => {
16
+ render(<Avatar initials="CM" alt="Christine Montgomery" />);
17
+ expect(screen.getByText('CM')).toBeInTheDocument();
18
+ expect(screen.getByLabelText('Christine Montgomery')).toBeInTheDocument();
19
+ });
20
+
21
+ test('renders placeholder when no src or initials provided', () => {
22
+ render(<Avatar alt="User avatar" />);
23
+ expect(screen.getByLabelText('User avatar')).toBeInTheDocument();
24
+ });
25
+
26
+ test('renders placeholder with default label when no alt provided', () => {
27
+ render(<Avatar />);
28
+ expect(screen.getByLabelText('User avatar')).toBeInTheDocument();
29
+ });
30
+
31
+ test('applies size variant class', () => {
32
+ const { container, rerender } = render(<Avatar size="small" />);
33
+ expect(container.firstChild).toHaveClass('ds-avatar--small');
34
+
35
+ rerender(<Avatar size="medium" />);
36
+ expect(container.firstChild).toHaveClass('ds-avatar--medium');
37
+
38
+ rerender(<Avatar size="large" />);
39
+ expect(container.firstChild).toHaveClass('ds-avatar--large');
40
+
41
+ rerender(<Avatar size="extra-large" />);
42
+ expect(container.firstChild).toHaveClass('ds-avatar--extra-large');
43
+ });
44
+
45
+ test('applies default medium size when no size specified', () => {
46
+ const { container } = render(<Avatar />);
47
+ expect(container.firstChild).toHaveClass('ds-avatar--medium');
48
+ });
49
+
50
+ test('applies custom className', () => {
51
+ const { container } = render(<Avatar className="custom-class" />);
52
+ expect(container.firstChild).toHaveClass('ds-avatar');
53
+ expect(container.firstChild).toHaveClass('custom-class');
54
+ });
55
+
56
+ test('spreads additional HTML attributes', () => {
57
+ const { container } = render(<Avatar data-testid="avatar-test" />);
58
+ expect(container.firstChild).toHaveAttribute('data-testid', 'avatar-test');
59
+ });
60
+ });
@@ -0,0 +1,68 @@
1
+ import classNames from 'classnames';
2
+ import React from 'react';
3
+
4
+ export type AvatarSize = 'small' | 'medium' | 'large' | 'extra-large';
5
+
6
+ export type AvatarProps = {
7
+ size?: AvatarSize;
8
+ src?: string;
9
+ alt?: string;
10
+ initials?: string;
11
+ className?: string;
12
+ } & React.HTMLAttributes<HTMLDivElement>;
13
+
14
+ export const Avatar = (props: AvatarProps) => {
15
+ const {
16
+ size = 'medium',
17
+ src,
18
+ alt = '',
19
+ initials,
20
+ className,
21
+ ...rest
22
+ } = props;
23
+
24
+ const renderContent = () => {
25
+ if (src) {
26
+ return (
27
+ <img
28
+ src={src}
29
+ alt={alt}
30
+ className="ds-avatar__image"
31
+ />
32
+ );
33
+ }
34
+
35
+ if (initials) {
36
+ return (
37
+ <span className="ds-avatar__initials" aria-label={alt}>
38
+ {initials}
39
+ </span>
40
+ );
41
+ }
42
+
43
+ return (
44
+ <span className="ds-avatar__placeholder" aria-label={alt || 'User avatar'}>
45
+ <svg
46
+ viewBox="0 0 24 24"
47
+ fill="currentColor"
48
+ className="ds-avatar__placeholder-icon"
49
+ >
50
+ <path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z" />
51
+ </svg>
52
+ </span>
53
+ );
54
+ };
55
+
56
+ return (
57
+ <div
58
+ className={classNames(
59
+ 'ds-avatar',
60
+ `ds-avatar--${size}`,
61
+ className,
62
+ )}
63
+ {...rest}
64
+ >
65
+ {renderContent()}
66
+ </div>
67
+ );
68
+ };
@@ -0,0 +1,71 @@
1
+ .ds-avatar {
2
+ display: inline-flex;
3
+ align-items: center;
4
+ justify-content: center;
5
+ overflow: hidden;
6
+ position: relative;
7
+ flex-shrink: 0;
8
+
9
+ // Size variants
10
+ &--small {
11
+ width: var(--avatar-small-size);
12
+ height: var(--avatar-small-size);
13
+ border-radius: var(--avatar-small-radius);
14
+ border: 1px solid var(--avatar-small-color-border);
15
+ background-color: var(--avatar-small-color-background);
16
+ }
17
+
18
+ &--medium {
19
+ width: var(--avatar-medium-size);
20
+ height: var(--avatar-medium-size);
21
+ border-radius: var(--avatar-medium-radius);
22
+ border: 1px solid var(--avatar-medium-color-border);
23
+ background-color: var(--avatar-medium-color-background);
24
+ }
25
+
26
+ &--large {
27
+ width: var(--avatar-large-size);
28
+ height: var(--avatar-large-size);
29
+ border-radius: var(--avatar-large-radius);
30
+ border: 1px solid var(--avatar-large-color-border);
31
+ background-color: var(--avatar-large-color-background);
32
+ }
33
+
34
+ &--extra-large {
35
+ width: var(--avatar-extra-large-size);
36
+ height: var(--avatar-extra-large-size);
37
+ border-radius: var(--avatar-extra-large-radius);
38
+ border: 1px solid var(--avatar-extra-large-color-border);
39
+ background-color: var(--avatar-extra-large-color-background);
40
+ }
41
+
42
+ &__image {
43
+ width: 100%;
44
+ height: 100%;
45
+ object-fit: cover;
46
+ pointer-events: none;
47
+ }
48
+
49
+ &__initials {
50
+ font-family: var(--type-body-bold-family);
51
+ font-weight: var(--type-body-bold-weight);
52
+ font-size: var(--type-body-bold-size);
53
+ color: var(--avatar-medium-color-text);
54
+ line-height: 1;
55
+ text-align: center;
56
+ }
57
+
58
+ &__placeholder {
59
+ display: flex;
60
+ align-items: center;
61
+ justify-content: center;
62
+ width: 100%;
63
+ height: 100%;
64
+ color: var(--color-grey-400);
65
+ }
66
+
67
+ &__placeholder-icon {
68
+ width: 60%;
69
+ height: 60%;
70
+ }
71
+ }
@@ -3,11 +3,13 @@ import { DropdownTrigger } from './DropdownTrigger';
3
3
  import { DropdownContent } from './DropdownContent';
4
4
  import { DropdownItem } from './items/DropdownItem';
5
5
  import { DropdownSelectItem } from './items/DropdownSelectItem';
6
+ import { DropdownSeparator } from './items/DropdownSeparator';
7
+ import { DropdownGroup } from './items/DropdownGroup';
6
8
 
7
9
  export const Dropdown = (props: DropdownMenu.DropdownMenuProps) => {
8
10
  const { children, ...rest } = props;
9
11
  return (
10
- <DropdownMenu.Root {...rest}>
12
+ <DropdownMenu.Root modal={false} {...rest}>
11
13
  {children}
12
14
  </DropdownMenu.Root>
13
15
  );
@@ -17,3 +19,5 @@ Dropdown.Trigger = DropdownTrigger;
17
19
  Dropdown.Content = DropdownContent;
18
20
  Dropdown.Item = DropdownItem;
19
21
  Dropdown.SelectItem = DropdownSelectItem;
22
+ Dropdown.Separator = DropdownSeparator;
23
+ Dropdown.Group = DropdownGroup;
@@ -7,6 +7,9 @@
7
7
  border: 1px solid var(--color-grey-200);
8
8
  font-style: normal;
9
9
  line-height: 150%;
10
+ max-height: 300px;
11
+ max-height: var(--radix-popper-available-height);
12
+ overflow-y: auto;
10
13
  }
11
14
 
12
15
  .ds-dropdown__item {
@@ -42,4 +45,4 @@
42
45
  .ds-dropdown__item--check-icon {
43
46
  margin-left: auto;
44
47
  }
45
- }
48
+ }
@@ -0,0 +1,11 @@
1
+ import { DropdownMenu } from 'radix-ui';
2
+ import classNames from 'classnames';
3
+
4
+ export const DropdownGroup = (props: DropdownMenu.DropdownMenuGroupProps) => {
5
+ const { children, className = '', ...rest } = props;
6
+ return (
7
+ <DropdownMenu.Group className={classNames('ds-dropdown__group', className)} {...rest}>
8
+ {children}
9
+ </DropdownMenu.Group>
10
+ );
11
+ };
@@ -0,0 +1,9 @@
1
+ import { DropdownMenu } from 'radix-ui';
2
+ import classNames from 'classnames';
3
+
4
+ export const DropdownSeparator = (props: DropdownMenu.DropdownMenuSeparatorProps) => {
5
+ const { className = '', ...rest } = props;
6
+ return (
7
+ <DropdownMenu.Separator className={classNames('ds-dropdown__separator', className)} {...rest} />
8
+ );
9
+ };
@@ -0,0 +1,237 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+ import { UserDropdown } from './UserDropdown';
3
+ import { ArborLogo, GovhubLogo, KeyLogo, RobinLogo, SampeopleLogo, TimetablerLogo } from './assets/logos';
4
+
5
+ const meta: Meta<typeof UserDropdown> = {
6
+ title: 'Components/UserDropdown',
7
+ component: UserDropdown,
8
+ tags: ['autodocs'],
9
+ };
10
+
11
+ type Story = StoryObj<typeof UserDropdown>;
12
+
13
+ // Mock avatar image (placeholder)
14
+ const avatarSrc = 'data:image/svg+xml,%3Csvg width="32" height="32" xmlns="http://www.w3.org/2000/svg"%3E%3Ccircle cx="16" cy="16" r="16" fill="%233cad51"/%3E%3Ctext x="16" y="21" font-family="Arial" font-size="14" font-weight="bold" fill="white" text-anchor="middle"%3ECM%3C/text%3E%3C/svg%3E';
15
+
16
+ // Import real logos from assets
17
+ const logoArborWorkflows = ArborLogo;
18
+ const logoGovernorHub = GovhubLogo;
19
+ const logoTheKey = KeyLogo;
20
+ const logoRobin = RobinLogo;
21
+ const logoSamPeople = SampeopleLogo;
22
+ const logoTimetabler = TimetablerLogo;
23
+
24
+ const AppLogo = ({ src, alt }: { src: string; alt: string }) => (
25
+ <img src={src} alt={alt} width={24} height={24} style={{ objectFit: 'contain' }} />
26
+ );
27
+
28
+ // Mock company logo SVG
29
+ const mockLogoSrc = 'data:image/svg+xml,%3Csvg width="50" height="30" xmlns="http://www.w3.org/2000/svg"%3E%3Crect width="50" height="30" rx="4" fill="%233cad51"/%3E%3Ctext x="25" y="20" font-family="Arial" font-size="14" font-weight="bold" fill="white" text-anchor="middle"%3ELogo%3C/text%3E%3C/svg%3E';
30
+
31
+ export const Default: Story = {
32
+ args: {
33
+ user: {
34
+ name: 'Christine Montgomery-Smith',
35
+ subtitle: 'Business Manager',
36
+ avatarSrc,
37
+ avatarAlt: 'Christine Montgomery-Smith',
38
+ },
39
+ logoSrc: mockLogoSrc,
40
+ logoAlt: 'Arbor',
41
+ sections: [
42
+ {
43
+ label: 'My Apps',
44
+ apps: [
45
+ {
46
+ logo: <AppLogo src={logoArborWorkflows} alt="Arbor Workflows" />,
47
+ name: 'Arbor Workflows',
48
+ onClick: () => { console.log('Open Arbor Workflows'); },
49
+ },
50
+ {
51
+ logo: <AppLogo src={logoGovernorHub} alt="GovernorHub" />,
52
+ name: 'GovernorHub',
53
+ onClick: () => { console.log('Open GovernorHub'); },
54
+ },
55
+ {
56
+ logo: <AppLogo src={logoTheKey} alt="The Key" />,
57
+ name: 'The Key',
58
+ onClick: () => { console.log('Open The Key'); },
59
+ },
60
+ ],
61
+ },
62
+ ],
63
+ discoverSection: {
64
+ label: 'Discover the Arbor suite',
65
+ defaultOpen: true,
66
+ apps: [
67
+ {
68
+ logo: <AppLogo src={logoArborWorkflows} alt="Arbor Finance" />,
69
+ name: 'Arbor Finance',
70
+ description: 'Cloud-based accounting',
71
+ onClick: () => { console.log('Open Arbor Finance'); },
72
+ },
73
+ {
74
+ logo: <AppLogo src={logoRobin} alt="Robin" />,
75
+ name: 'Robin',
76
+ description: 'AI website compliance checks',
77
+ onClick: () => { console.log('Open Robin'); },
78
+ },
79
+ {
80
+ logo: <AppLogo src={logoSamPeople} alt="SAMPeople" />,
81
+ name: 'SAMPeople',
82
+ description: 'HR and recruitment',
83
+ onClick: () => { console.log('Open SAMPeople'); },
84
+ },
85
+ {
86
+ logo: <AppLogo src={logoTimetabler} alt="Timetabler" />,
87
+ name: 'Timetabler',
88
+ description: 'Schedule timetables and more',
89
+ onClick: () => { console.log('Open Timetabler'); },
90
+ },
91
+ ],
92
+ },
93
+ userInfoAction: { type: 'link', onClick: () => { console.log('View profile'); } },
94
+ onSignOut: () => { console.log('Sign out'); },
95
+ signOutLabel: 'Sign out of Arbor',
96
+ },
97
+ };
98
+
99
+ export const WithApps: Story = {
100
+ args: {
101
+ user: {
102
+ name: 'Christine Montgomery-Smith',
103
+ subtitle: 'Business Manager',
104
+ avatarInitials: 'CM',
105
+ },
106
+ sections: [
107
+ {
108
+ label: 'Quick Actions',
109
+ apps: [
110
+ { name: 'Settings', onClick: () => { console.log('Settings'); } },
111
+ { name: 'Help', onClick: () => { console.log('Help'); } },
112
+ ],
113
+ },
114
+ ],
115
+ onSignOut: () => { console.log('Sign out'); },
116
+ },
117
+ };
118
+
119
+ export const Minimal: Story = {
120
+ args: {
121
+ user: {
122
+ name: 'Christine Montgomery',
123
+ avatarInitials: 'CM',
124
+ avatarAlt: 'Christine Montgomery',
125
+ },
126
+ onSignOut: () => { console.log('Sign out'); },
127
+ },
128
+ };
129
+
130
+ export const WithMenu: Story = {
131
+ args: {
132
+ user: {
133
+ name: 'Christine Montgomery-Smith',
134
+ subtitle: 'Business Manager',
135
+ avatarSrc,
136
+ avatarAlt: 'Christine Montgomery-Smith',
137
+ },
138
+ logoSrc: mockLogoSrc,
139
+ logoAlt: 'Arbor',
140
+ sections: [
141
+ {
142
+ label: 'My Apps',
143
+ apps: [
144
+ {
145
+ logo: <AppLogo src={logoArborWorkflows} alt="Arbor Workflows" />,
146
+ name: 'Arbor Workflows',
147
+ onClick: () => { console.log('Open Arbor Workflows'); },
148
+ },
149
+ ],
150
+ },
151
+ ],
152
+ userInfoAction: {
153
+ type: 'menu',
154
+ items: [
155
+ { label: 'Help centre', onClick: () => { console.log('Help centre'); } },
156
+ { label: 'About', onClick: () => { console.log('About'); } },
157
+ { label: 'Leave feedback', onClick: () => { console.log('Leave feedback'); } },
158
+ ],
159
+ },
160
+ onSignOut: () => { console.log('Sign out'); },
161
+ signOutLabel: 'Sign out of Arbor',
162
+ },
163
+ };
164
+
165
+ export const DarkVariant: Story = {
166
+ args: {
167
+ user: {
168
+ name: 'Christine Montgomery-Smith',
169
+ subtitle: 'Business Manager',
170
+ avatarSrc,
171
+ avatarAlt: 'Christine Montgomery-Smith',
172
+ },
173
+ logoSrc: mockLogoSrc,
174
+ logoAlt: 'Arbor',
175
+ variant: 'dark',
176
+ sections: [
177
+ {
178
+ label: 'My Apps',
179
+ apps: [
180
+ {
181
+ logo: <AppLogo src={logoArborWorkflows} alt="Arbor Workflows" />,
182
+ name: 'Arbor Workflows',
183
+ onClick: () => { console.log('Open Arbor Workflows'); },
184
+ },
185
+ ],
186
+ },
187
+ ],
188
+ onSignOut: () => { console.log('Sign out'); },
189
+ signOutLabel: 'Sign out of Arbor',
190
+ },
191
+ parameters: {
192
+ backgrounds: {
193
+ default: 'dark',
194
+ values: [
195
+ { name: 'dark', value: '#2f2f2f' },
196
+ ],
197
+ },
198
+ },
199
+ };
200
+
201
+ export const LightVariant: Story = {
202
+ args: {
203
+ user: {
204
+ name: 'Christine Montgomery-Smith',
205
+ subtitle: 'Business Manager',
206
+ avatarSrc,
207
+ avatarAlt: 'Christine Montgomery-Smith',
208
+ },
209
+ logoSrc: mockLogoSrc,
210
+ logoAlt: 'Arbor',
211
+ variant: 'light',
212
+ sections: [
213
+ {
214
+ label: 'My Apps',
215
+ apps: [
216
+ {
217
+ logo: <AppLogo src={logoArborWorkflows} alt="Arbor Workflows" />,
218
+ name: 'Arbor Workflows',
219
+ onClick: () => { console.log('Open Arbor Workflows'); },
220
+ },
221
+ ],
222
+ },
223
+ ],
224
+ onSignOut: () => { console.log('Sign out'); },
225
+ signOutLabel: 'Sign out of Arbor',
226
+ },
227
+ parameters: {
228
+ backgrounds: {
229
+ default: 'light',
230
+ values: [
231
+ { name: 'light', value: '#ffffff' },
232
+ ],
233
+ },
234
+ },
235
+ };
236
+
237
+ export default meta;