@verifiedinc-public/shared-ui-elements 0.13.0 → 0.13.2-beta.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.
@@ -0,0 +1,11 @@
1
+ import { Meta, StoryObj } from '@storybook/react';
2
+ import { Alert } from '../../components/Alert';
3
+ type PropsAndCustomArgs = React.ComponentProps<typeof Alert> & {
4
+ text?: string;
5
+ withAction?: boolean;
6
+ };
7
+ declare const meta: Meta<PropsAndCustomArgs>;
8
+ export default meta;
9
+ type Story = StoryObj<PropsAndCustomArgs>;
10
+ export declare const Default: Story;
11
+ export declare const WithButton: Story;
@@ -0,0 +1,35 @@
1
+ import { StoryObj } from '@storybook/react';
2
+ import { CredentialRequestsEditor } from '../../components/CredentialRequestsEditor';
3
+ declare const meta: {
4
+ title: string;
5
+ component: typeof CredentialRequestsEditor;
6
+ render: (args: any, { loaded: { credentialRequests, schemas } }: import('@storybook/csf').StoryContext<import('@storybook/react').ReactRenderer, Omit<import('../../components/CredentialRequestsEditor/CredentialRequestsEditor.context').CredentialRequestsEditorProps, "children">>) => import("react").JSX.Element;
7
+ parameters: {
8
+ layout: string;
9
+ docs: {
10
+ description: {
11
+ component: string;
12
+ };
13
+ };
14
+ };
15
+ tags: string[];
16
+ argTypes: {
17
+ credentialRequests: {
18
+ description: string;
19
+ };
20
+ schemas: {
21
+ description: string;
22
+ };
23
+ addButtonText: {
24
+ type: "string";
25
+ description: string;
26
+ };
27
+ features: {
28
+ control: "object";
29
+ description: string;
30
+ };
31
+ };
32
+ };
33
+ export default meta;
34
+ type Story = StoryObj<typeof meta>;
35
+ export declare const Default: Story;
@@ -0,0 +1,41 @@
1
+ import { StoryObj } from '@storybook/react';
2
+ import { QRCodeDisplay } from '../../components';
3
+ declare const meta: {
4
+ title: string;
5
+ component: typeof QRCodeDisplay;
6
+ render: (args: any) => import("react").JSX.Element;
7
+ parameters: {
8
+ layout: string;
9
+ docs: {
10
+ description: {
11
+ component: string;
12
+ };
13
+ };
14
+ };
15
+ tags: string[];
16
+ argTypes: {
17
+ asset: {
18
+ type: "string";
19
+ description: string;
20
+ };
21
+ data: {
22
+ type: "string";
23
+ description: string;
24
+ };
25
+ svgSize: {
26
+ type: "number";
27
+ description: string;
28
+ };
29
+ logoSize: {
30
+ type: "number";
31
+ description: string;
32
+ };
33
+ fill: {
34
+ type: "string";
35
+ description: string;
36
+ };
37
+ };
38
+ };
39
+ export default meta;
40
+ type Story = StoryObj<typeof meta>;
41
+ export declare const Default: Story;
@@ -0,0 +1,44 @@
1
+ import { StoryObj } from '@storybook/react';
2
+ import { TextField } from '../../components/TextField';
3
+ declare const meta: {
4
+ title: string;
5
+ component: typeof TextField;
6
+ parameters: {
7
+ layout: string;
8
+ };
9
+ tags: string[];
10
+ argTypes: {
11
+ variant: {
12
+ description: string;
13
+ type: {
14
+ name: "enum";
15
+ value: string[];
16
+ };
17
+ table: {
18
+ defaultValue: {
19
+ summary: string;
20
+ };
21
+ };
22
+ };
23
+ size: {
24
+ description: string;
25
+ type: {
26
+ name: "enum";
27
+ value: string[];
28
+ };
29
+ table: {
30
+ defaultValue: {
31
+ summary: string;
32
+ };
33
+ };
34
+ };
35
+ };
36
+ args: {
37
+ size: "medium";
38
+ variant: "standard";
39
+ };
40
+ };
41
+ export default meta;
42
+ type Story = StoryObj<typeof meta>;
43
+ export declare const Outlined: Story;
44
+ export declare const OutlinedFixedLabel: Story;
@@ -0,0 +1,54 @@
1
+ import { StoryObj } from '@storybook/react';
2
+ import { Typography } from '../../components/Typography';
3
+ declare const meta: {
4
+ title: string;
5
+ component: typeof Typography;
6
+ parameters: {
7
+ layout: string;
8
+ };
9
+ tags: string[];
10
+ argTypes: {
11
+ align: {
12
+ options: string[];
13
+ control: {
14
+ type: "radio";
15
+ };
16
+ description: string;
17
+ table: {
18
+ defaultValue: {
19
+ summary: string;
20
+ };
21
+ };
22
+ };
23
+ variant: {
24
+ options: string[];
25
+ control: {
26
+ type: "radio";
27
+ };
28
+ description: string;
29
+ table: {
30
+ defaultValue: {
31
+ summary: string;
32
+ };
33
+ };
34
+ };
35
+ children: {
36
+ description: string;
37
+ type: "string";
38
+ };
39
+ };
40
+ };
41
+ export default meta;
42
+ type Story = StoryObj<typeof meta>;
43
+ export declare const Heading1: Story;
44
+ export declare const Heading2: Story;
45
+ export declare const Heading3: Story;
46
+ export declare const Heading4: Story;
47
+ export declare const Heading5: Story;
48
+ export declare const Heading6: Story;
49
+ export declare const Subtitle1: Story;
50
+ export declare const Subtitle2: Story;
51
+ export declare const Body1: Story;
52
+ export declare const Body2: Story;
53
+ export declare const Button: Story;
54
+ export declare const Overline: Story;
@@ -0,0 +1,28 @@
1
+ import { VerifiedImage } from '../../components/verified/VerifiedImage';
2
+ declare const _default: {
3
+ title: string;
4
+ component: typeof VerifiedImage;
5
+ parameters: {
6
+ layout: string;
7
+ };
8
+ argTypes: {
9
+ themeLight: {
10
+ control: {
11
+ type: string;
12
+ };
13
+ };
14
+ themeMain: {
15
+ control: {
16
+ type: string;
17
+ };
18
+ };
19
+ themeDark: {
20
+ control: {
21
+ type: string;
22
+ };
23
+ };
24
+ };
25
+ tags: string[];
26
+ };
27
+ export default _default;
28
+ export declare const Default: any;
@@ -0,0 +1,16 @@
1
+ import { StoryObj } from '@storybook/react';
2
+ import { PhoneInput } from '../../../components/form/PhoneInput';
3
+ declare const meta: {
4
+ title: string;
5
+ component: typeof PhoneInput;
6
+ parameters: {
7
+ layout: string;
8
+ };
9
+ tags: string[];
10
+ args: {
11
+ shouldHaveClearButton: true;
12
+ };
13
+ };
14
+ export default meta;
15
+ type Story = StoryObj<typeof meta>;
16
+ export declare const Default: Story;
@@ -0,0 +1,14 @@
1
+ import { ReactElement } from 'react';
2
+ import { StoryObj } from '@storybook/react';
3
+ declare function HookRender(props: any): ReactElement;
4
+ declare const meta: {
5
+ title: string;
6
+ component: typeof HookRender;
7
+ parameters: {
8
+ layout: string;
9
+ };
10
+ tags: string[];
11
+ };
12
+ export default meta;
13
+ type Story = StoryObj<typeof meta>;
14
+ export declare const TextPlain: Story;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@verifiedinc-public/shared-ui-elements",
3
- "version": "0.13.0",
3
+ "version": "0.13.2-beta.1",
4
4
  "description": "A set of UI components, utilities that is shareable with the core apps.",
5
5
  "private": false,
6
6
  "keywords": [],
@@ -89,7 +89,8 @@
89
89
  "typescript": "^5.2.2",
90
90
  "vite-plugin-dts": "^4.3.0",
91
91
  "vitest": "^1.6.0",
92
- "zod": "^3.23.8"
92
+ "zod": "^3.23.8",
93
+ "notistack": "^3.0.1"
93
94
  },
94
95
  "peerDependencies": {
95
96
  "@emotion/react": "^11.11.4",
@@ -107,6 +108,7 @@
107
108
  "react-dom": "^18",
108
109
  "react-hook-form": "^7.52.1",
109
110
  "react-imask": "^7.6.1",
110
- "zod": "^3.23.8"
111
+ "zod": "^3.23.8",
112
+ "notistack": "^3.0.1"
111
113
  }
112
114
  }
@@ -0,0 +1,145 @@
1
+ import { Close } from '@mui/icons-material';
2
+ import {
3
+ Alert,
4
+ type AlertColor,
5
+ Box,
6
+ IconButton,
7
+ type SxProps,
8
+ } from '@mui/material';
9
+ import { When } from '../When';
10
+ import {
11
+ closeSnackbar,
12
+ type CustomContentProps,
13
+ enqueueSnackbar,
14
+ SnackbarContent,
15
+ type SnackbarKey,
16
+ SnackbarProvider,
17
+ } from 'notistack';
18
+ import { forwardRef } from 'react';
19
+
20
+ declare module 'notistack' {
21
+ interface VariantOverrides {
22
+ default: false;
23
+ success: false;
24
+ info: false;
25
+ warning: false;
26
+ error: false;
27
+ customAlertComponent: {
28
+ onAction?: (id: SnackbarKey) => void;
29
+ icon?: JSX.Element;
30
+ severity?: AlertColor;
31
+ };
32
+ }
33
+ }
34
+
35
+ export type { SnackbarKey };
36
+ export { SnackbarProvider };
37
+
38
+ interface AlertAction {
39
+ onAction?: (id: SnackbarKey) => void;
40
+ icon?: JSX.Element;
41
+ }
42
+
43
+ interface CustomAlertComponentProps extends Partial<CustomContentProps> {
44
+ severity: AlertColor;
45
+ alertAction?: AlertAction;
46
+ showCloseIcon?: boolean;
47
+ sx?: SxProps;
48
+ }
49
+
50
+ /**
51
+ * Hook to manage snackbar messages
52
+ * It wraps the enqueueSnackbar and closeSnackbar functions from the notistack library
53
+ * @returns
54
+ * - updateSnackbar: Function to enqueue a snackbar message
55
+ * - closeSnackbar: Function to close one or all snackbar messages
56
+ * @see https://notistack.com/api-reference
57
+ */
58
+ export function useSnackbar(): {
59
+ updateSnackbar: (
60
+ message: string,
61
+ severity?: AlertColor,
62
+ options?: Omit<CustomAlertComponentProps, 'severity'>,
63
+ ) => void;
64
+ closeSnackbar: (key?: SnackbarKey) => void;
65
+ } {
66
+ const updateSnackbar = (
67
+ message: string,
68
+ severity: AlertColor = 'success',
69
+ options?: Omit<CustomAlertComponentProps, 'severity'>,
70
+ ): void => {
71
+ console.log({
72
+ severity,
73
+ variant: 'customAlertComponent',
74
+ persist: true,
75
+ ...options,
76
+ });
77
+ enqueueSnackbar(message, {
78
+ severity,
79
+ variant: 'customAlertComponent',
80
+ persist: true,
81
+ ...options,
82
+ });
83
+ };
84
+
85
+ return { updateSnackbar, closeSnackbar };
86
+ }
87
+
88
+ /**
89
+ * Custom Alert component to show snackbar messages
90
+ * This is a wrapper around the notistack SnackbarContent component
91
+ *
92
+ * Use it in the SnackbarProvider Components prop:
93
+ * @see https://notistack.com/features/customization#custom-component
94
+ * @example
95
+ * <SnackbarProvider
96
+ * Components={{ customAlertComponent: CustomAlertComponent }}
97
+ * />
98
+ */
99
+ export const CustomAlertComponent = forwardRef<
100
+ HTMLDivElement,
101
+ CustomAlertComponentProps
102
+ >(
103
+ (
104
+ { id, message, severity, alertAction, sx, showCloseIcon = true, ...props },
105
+ ref,
106
+ ) => {
107
+ return (
108
+ <SnackbarContent ref={ref} {...props}>
109
+ <Alert
110
+ severity={severity}
111
+ action={
112
+ <Box ml={1}>
113
+ <When value={alertAction}>
114
+ <IconButton
115
+ size='small'
116
+ onClick={() => id && alertAction?.onAction?.(id)}
117
+ color='inherit'
118
+ >
119
+ {alertAction?.icon}
120
+ </IconButton>
121
+ </When>
122
+ <When value={!alertAction && showCloseIcon}>
123
+ <IconButton
124
+ size='small'
125
+ onClick={() => {
126
+ closeSnackbar(id);
127
+ }}
128
+ color='inherit'
129
+ >
130
+ <Close />
131
+ </IconButton>
132
+ </When>
133
+ </Box>
134
+ }
135
+ sx={{
136
+ alignItems: 'center',
137
+ ...sx,
138
+ }}
139
+ >
140
+ {message}
141
+ </Alert>
142
+ </SnackbarContent>
143
+ );
144
+ },
145
+ );
@@ -140,10 +140,6 @@ function OTPInputComponent(
140
140
  const valuesString = values.join('');
141
141
  const firstEmptyInput = inputsRef.current[valuesString.length];
142
142
 
143
- for (const input of inputsRef.current) {
144
- input?.blur();
145
- }
146
-
147
143
  firstEmptyInput?.focus();
148
144
  firstEmptyInput?.select();
149
145
  }, [values]);
@@ -165,6 +161,7 @@ function OTPInputComponent(
165
161
 
166
162
  // Calls onChange when all OTP fields are filled.
167
163
  if (newValueString.length === 6) {
164
+ inputsRef.current.forEach((input) => input?.blur());
168
165
  props.onChange?.({ target: { value: newValueString } });
169
166
  }
170
167
 
@@ -8,3 +8,4 @@ export * from './Image';
8
8
  export * from './form/';
9
9
  export * from './verified';
10
10
  export * from './QRCodeDisplay';
11
+ export * from './Snackbar';
package/src/index.ts CHANGED
@@ -1,3 +1,11 @@
1
+ /**
2
+ * The shared-ui-elements library is a collection of reusable, customizable UI components developed for Verified Inc..
3
+ *
4
+ * @see https://github.com/VerifiedInc/shared-ui-elements
5
+ *
6
+ * @packageDocumentation
7
+ */
8
+
1
9
  export * from './components';
2
10
  export * from './hooks';
3
11
  export * from './styles';
@@ -0,0 +1,65 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+
3
+ import { Portal, Stack } from '@mui/material';
4
+ import { fn } from '@storybook/test';
5
+ import { Button } from '../../components';
6
+ import { SnackbarProvider, useSnackbar } from '../../components/Snackbar';
7
+
8
+ const Snackbar = (): React.JSX.Element => {
9
+ const { updateSnackbar, closeSnackbar } = useSnackbar();
10
+
11
+ const renderButton = (
12
+ message: string,
13
+ severity: string,
14
+ ): React.JSX.Element => (
15
+ <Button
16
+ onClick={() => {
17
+ updateSnackbar(message, severity as any);
18
+ }}
19
+ >
20
+ {message}
21
+ </Button>
22
+ );
23
+
24
+ return (
25
+ <Stack>
26
+ <Portal>
27
+ <SnackbarProvider />
28
+ </Portal>
29
+ {renderButton('Success', 'success')}
30
+ {renderButton('Error', 'error')}
31
+ {renderButton('Warning', 'warning')}
32
+ {renderButton('Info', 'info')}
33
+ <Button
34
+ onClick={() => {
35
+ closeSnackbar();
36
+ }}
37
+ >
38
+ Clear all
39
+ </Button>
40
+ </Stack>
41
+ );
42
+ };
43
+
44
+ const meta = {
45
+ title: 'Components/Snackbar',
46
+
47
+ component: Snackbar,
48
+ parameters: {
49
+ // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout
50
+ layout: 'centered',
51
+ },
52
+ // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs
53
+ tags: ['autodocs'],
54
+ args: {
55
+ name: 'otp',
56
+ onChange: fn(),
57
+ disabled: false,
58
+ },
59
+ } satisfies Meta<typeof Snackbar>;
60
+
61
+ export default meta;
62
+ type Story = StoryObj<typeof Snackbar>;
63
+
64
+ // More on writing stories with args: https://storybook.js.org/docs/writing-stories/args
65
+ export const Default: Story = {};