react-frontend-common-components 0.0.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 (78) hide show
  1. package/dist/index.d.ts +85 -0
  2. package/dist/index.js +26 -0
  3. package/dist/index.js.map +1 -0
  4. package/dist/index.mjs +26 -0
  5. package/dist/index.mjs.map +1 -0
  6. package/package.json +34 -0
  7. package/rollup.config.js +44 -0
  8. package/src/components/app-avatar/app-avatar.tsx +24 -0
  9. package/src/components/app-back-arrow/app-back-arrow.css +17 -0
  10. package/src/components/app-back-arrow/app-back-arrow.tsx +30 -0
  11. package/src/components/app-badge/app-badge.css +11 -0
  12. package/src/components/app-badge/app-badge.tsx +44 -0
  13. package/src/components/app-bread-crumb/app-bread-crumb.tsx +16 -0
  14. package/src/components/app-button/app-button.css +13 -0
  15. package/src/components/app-button/app-button.tsx +51 -0
  16. package/src/components/app-card/app-card.css +8 -0
  17. package/src/components/app-card/app-card.tsx +43 -0
  18. package/src/components/app-carousel/app-carousel.css +68 -0
  19. package/src/components/app-carousel/app-carousel.tsx +62 -0
  20. package/src/components/app-chart/app-chart.css +6 -0
  21. package/src/components/app-chart/app-chart.tsx +97 -0
  22. package/src/components/app-checkbox-text/app-checkbox-text.css +12 -0
  23. package/src/components/app-checkbox-text/app-checkbox-text.tsx +20 -0
  24. package/src/components/app-collapse/app-collapse.tsx +57 -0
  25. package/src/components/app-custom-loader/app-custom-loader.css +116 -0
  26. package/src/components/app-custom-loader/app-custom-loader.tsx +23 -0
  27. package/src/components/app-divider/app-divider.tsx +16 -0
  28. package/src/components/app-float-button/app-float-button.tsx +23 -0
  29. package/src/components/app-image-box/app-image-box.css +23 -0
  30. package/src/components/app-image-box/app-image-box.tsx +38 -0
  31. package/src/components/app-input/app-input.css +61 -0
  32. package/src/components/app-input/app-input.tsx +89 -0
  33. package/src/components/app-label/app-label.css +5 -0
  34. package/src/components/app-label/app-label.tsx +34 -0
  35. package/src/components/app-list/app-list.tsx +26 -0
  36. package/src/components/app-loader/app-loader.css +16 -0
  37. package/src/components/app-loader/app-loader.tsx +28 -0
  38. package/src/components/app-location-map/app-location-map.css +4 -0
  39. package/src/components/app-location-map/app-location-map.tsx +62 -0
  40. package/src/components/app-modal/app-modal.css +35 -0
  41. package/src/components/app-modal/app-modal.tsx +58 -0
  42. package/src/components/app-otp-field/app-otp-field.css +31 -0
  43. package/src/components/app-otp-field/app-otp-field.tsx +70 -0
  44. package/src/components/app-pagination/app-pagination.tsx +40 -0
  45. package/src/components/app-password-input/app-password-input.css +41 -0
  46. package/src/components/app-password-input/app-password-input.tsx +79 -0
  47. package/src/components/app-phone-field/app-phone-field.css +61 -0
  48. package/src/components/app-phone-field/app-phone-field.tsx +60 -0
  49. package/src/components/app-popover/app-popover.css +5 -0
  50. package/src/components/app-popover/app-popover.tsx +45 -0
  51. package/src/components/app-progress/app-progress.tsx +40 -0
  52. package/src/components/app-radio-group/app-radio-group.css +6 -0
  53. package/src/components/app-radio-group/app-radio-group.tsx +45 -0
  54. package/src/components/app-select/app-select.css +21 -0
  55. package/src/components/app-select/app-select.tsx +53 -0
  56. package/src/components/app-select-add/app-select-add.css +21 -0
  57. package/src/components/app-select-add/app-select-add.tsx +34 -0
  58. package/src/components/app-sidebar/app-sidebar.css +46 -0
  59. package/src/components/app-sidebar/app-sidebar.tsx +60 -0
  60. package/src/components/app-tab/app-tab.css +22 -0
  61. package/src/components/app-tab/app-tab.tsx +31 -0
  62. package/src/components/app-table/app-table.tsx +42 -0
  63. package/src/components/app-tag/app-tag.css +11 -0
  64. package/src/components/app-tag/app-tag.tsx +48 -0
  65. package/src/components/app-textarea/app-textarea.css +19 -0
  66. package/src/components/app-textarea/app-textarea.tsx +59 -0
  67. package/src/components/app-title/app-title.css +12 -0
  68. package/src/components/app-title/app-title.tsx +28 -0
  69. package/src/components/app-toggle-button/app-toggle-button.css +27 -0
  70. package/src/components/app-toggle-button/app-toggle-button.tsx +43 -0
  71. package/src/components/app-upload-image/app-upload-image.css +26 -0
  72. package/src/components/app-upload-image/app-upload-image.tsx +90 -0
  73. package/src/components/over-view-card/over-view-card.css +16 -0
  74. package/src/components/over-view-card/over-view-card.tsx +22 -0
  75. package/src/index.ts +5 -0
  76. package/src/themes/icons/icons.tsx +131 -0
  77. package/src/themes/images/profile-img.svg +14 -0
  78. package/tsconfig.json +20 -0
@@ -0,0 +1,60 @@
1
+ import React from "react";
2
+ import { Layout, Menu } from "antd";
3
+ import "./app-sidebar.css";
4
+
5
+ const { Sider } = Layout;
6
+
7
+ interface SidebarProps {
8
+ links: {
9
+ label: string;
10
+ path: string;
11
+ icon: React.ReactNode;
12
+ tag?: React.ReactNode;
13
+ }[];
14
+ logo?: React.ReactNode;
15
+ footerLinks?: {
16
+ label: string;
17
+ path: string;
18
+ }[];
19
+ className?: string;
20
+ }
21
+
22
+ const Sidebar = ({ links, logo, footerLinks, className }: SidebarProps) => {
23
+ const handleNavigation = (path: string) => {
24
+ window.location.href = path;
25
+ };
26
+
27
+ const menuItems = links.map((link) => ({
28
+ key: link.path,
29
+ icon: link.icon,
30
+ label: (
31
+ <span onClick={() => handleNavigation(link.path)}>
32
+ {link.label}
33
+ {link.tag && <span className={"tag"}>{link.tag}</span>}
34
+ </span>
35
+ ),
36
+ }));
37
+
38
+ const footerMenuItems = footerLinks?.map((link) => ({
39
+ key: link.path,
40
+ label: (
41
+ <span onClick={() => handleNavigation(link.path)}>{link.label}</span>
42
+ ),
43
+ }));
44
+
45
+ return (
46
+ <div className={`sideBar ${className}`}>
47
+ <Sider className={"sider"}>
48
+ <div className={"logo"}>{logo}</div>
49
+ <Menu mode="inline" className={"menu"} items={menuItems} />
50
+ {footerLinks && (
51
+ <div className={"footer"}>
52
+ <Menu mode="inline" items={footerMenuItems} />
53
+ </div>
54
+ )}
55
+ </Sider>
56
+ </div>
57
+ );
58
+ };
59
+
60
+ export default Sidebar;
@@ -0,0 +1,22 @@
1
+ .appTab {
2
+ .tab {
3
+ .ant-tabs-nav {
4
+ &::before {
5
+ border: unset !important;
6
+ }
7
+ .ant-tabs-nav-wrap {
8
+ .ant-tabs-nav-list {
9
+ display: flex;
10
+ gap: 3.5rem;
11
+ align-items: center;
12
+ .ant-tabs-tab {
13
+ margin: 0;
14
+ }
15
+ .ant-tabs-ink-bar {
16
+ display: none;
17
+ }
18
+ }
19
+ }
20
+ }
21
+ }
22
+ }
@@ -0,0 +1,31 @@
1
+ import React from "react";
2
+ import { Tabs } from "antd";
3
+ import type { TabsProps } from "antd";
4
+ import "./app-tab.css";
5
+
6
+ interface AppTabProps {
7
+ className?: string;
8
+ items?: TabsProps["items"];
9
+ handleChange?: (activeKey: string) => void;
10
+ defaultActiveKey?: string;
11
+ }
12
+
13
+ const AppTab = ({
14
+ className,
15
+ items,
16
+ handleChange,
17
+ defaultActiveKey,
18
+ }: AppTabProps) => {
19
+ return (
20
+ <div className={`appTab ${className}`}>
21
+ <Tabs
22
+ defaultActiveKey={defaultActiveKey}
23
+ items={items}
24
+ onChange={handleChange}
25
+ className={"tab"}
26
+ />
27
+ </div>
28
+ );
29
+ };
30
+
31
+ export default AppTab;
@@ -0,0 +1,42 @@
1
+ import { Table, TableProps } from "antd";
2
+ import { ColumnsType } from "antd/lib/table";
3
+
4
+ interface AppTableProps<T> extends TableProps<T> {
5
+ columns: ColumnsType<T>;
6
+ dataSource: T[];
7
+ rowKey?: string;
8
+ bordered?: boolean;
9
+ pagination?: TableProps<T>["pagination"];
10
+ size?: "small" | "middle" | "large";
11
+ scroll?: TableProps<T>["scroll"];
12
+ className?: string;
13
+ }
14
+
15
+ const AppTable = <T extends object>({
16
+ columns,
17
+ dataSource,
18
+ rowKey,
19
+ bordered = false,
20
+ pagination = { pageSize: 10 },
21
+ size = "middle",
22
+ scroll,
23
+ className,
24
+ ...tableProps
25
+ }: AppTableProps<T>) => {
26
+ return (
27
+ <div className={className}>
28
+ <Table
29
+ columns={columns}
30
+ dataSource={dataSource}
31
+ rowKey={rowKey}
32
+ bordered={bordered}
33
+ pagination={pagination}
34
+ size={size}
35
+ scroll={scroll}
36
+ {...tableProps}
37
+ />
38
+ </div>
39
+ );
40
+ };
41
+
42
+ export default AppTable;
@@ -0,0 +1,11 @@
1
+ .appTab {
2
+ width: max-content;
3
+ .ant-tag {
4
+ display: flex;
5
+ align-items: center;
6
+ margin: 0;
7
+ border-radius: 8px;
8
+ padding: 4px 8px;
9
+ line-height: normal;
10
+ }
11
+ }
@@ -0,0 +1,48 @@
1
+ import React, { useState } from "react";
2
+ import { Tag } from "antd";
3
+ import "./app-tag.css";
4
+
5
+ interface AppTagProps {
6
+ color?: string;
7
+ closable?: boolean;
8
+ onClick?: (e: React.MouseEvent<HTMLElement, MouseEvent>) => void;
9
+ style?: React.CSSProperties;
10
+ className?: string;
11
+ children: React.ReactNode;
12
+ closeIcon?: React.ReactNode;
13
+ }
14
+
15
+ const AppTag = ({
16
+ color,
17
+ closable = false,
18
+ onClick,
19
+ style,
20
+ className,
21
+ children,
22
+ closeIcon,
23
+ }: AppTagProps) => {
24
+ const [visible, setVisible] = useState(true);
25
+
26
+ const handleClose = () => {
27
+ setVisible(false);
28
+ };
29
+
30
+ if (!visible) return null;
31
+
32
+ return (
33
+ <div className={`appTab ${className}`}>
34
+ <Tag
35
+ color={color}
36
+ closable={closable}
37
+ onClose={handleClose}
38
+ onClick={onClick}
39
+ style={style}
40
+ closeIcon={closeIcon}
41
+ >
42
+ {children}
43
+ </Tag>
44
+ </div>
45
+ );
46
+ };
47
+
48
+ export default AppTag;
@@ -0,0 +1,19 @@
1
+ .appTextArea {
2
+ .ant-input-outlined {
3
+ border-color: #bfbebe;
4
+ &:hover {
5
+ border-color: #bfbebe;
6
+ }
7
+ }
8
+
9
+ *:focus {
10
+ outline: 0 !important;
11
+ box-shadow: unset !important;
12
+ }
13
+ }
14
+
15
+ .error {
16
+ color: red;
17
+ font-size: 0.875rem;
18
+ margin-top: 0.25rem;
19
+ }
@@ -0,0 +1,59 @@
1
+ import { Input } from "antd";
2
+ import { ChangeEventHandler, KeyboardEventHandler } from "react";
3
+ import "./app-textarea.css";
4
+
5
+ interface textAreaProps {
6
+ id?: string;
7
+ label?: string;
8
+ name?: string;
9
+ value?: string;
10
+ dataTestId?: string;
11
+ defaultValue?: string;
12
+ onPressEnter?: KeyboardEventHandler<HTMLTextAreaElement>;
13
+ handleChange?: ChangeEventHandler<HTMLTextAreaElement>;
14
+ autoSize?: {
15
+ minRows?: number;
16
+ maxRows?: number;
17
+ };
18
+ rows?: number;
19
+ cols?: number;
20
+ placeholder?: string;
21
+ className?: string;
22
+ error?: string;
23
+ }
24
+
25
+ const AppTextarea = ({
26
+ id,
27
+ placeholder,
28
+ name,
29
+ value,
30
+ dataTestId,
31
+ defaultValue,
32
+ onPressEnter,
33
+ handleChange,
34
+ rows,
35
+ cols,
36
+ className,
37
+ error,
38
+ }: textAreaProps) => {
39
+ return (
40
+ <div className={`appTextArea ${className}`}>
41
+ <Input.TextArea
42
+ data-test-id={dataTestId}
43
+ id={id}
44
+ name={name}
45
+ placeholder={placeholder}
46
+ value={value}
47
+ className={"textArea"}
48
+ onChange={handleChange}
49
+ defaultValue={defaultValue}
50
+ onPressEnter={onPressEnter}
51
+ rows={rows}
52
+ cols={cols}
53
+ />
54
+ {error && <div className={"error"}>{error}</div>}
55
+ </div>
56
+ );
57
+ };
58
+
59
+ export default AppTextarea;
@@ -0,0 +1,12 @@
1
+ .titleComponent {
2
+ span {
3
+ color: #000;
4
+ text-align: center;
5
+ font-style: normal;
6
+ font-weight: 400;
7
+ line-height: normal;
8
+ }
9
+ .subText {
10
+ font-size: 1rem !important;
11
+ }
12
+ }
@@ -0,0 +1,28 @@
1
+ import React from "react";
2
+ import { Typography } from "antd";
3
+ import "./app-title.css";
4
+
5
+ const { Title, Text } = Typography;
6
+
7
+ interface TitleProps {
8
+ mainText: string;
9
+ className?: string;
10
+ subText?: string;
11
+ level?: 1 | 2 | 3 | 4 | 5;
12
+ }
13
+
14
+ const AppTitle = ({
15
+ mainText,
16
+ className = "",
17
+ subText,
18
+ level = 1,
19
+ }: TitleProps) => {
20
+ return (
21
+ <div className={`titleComponent ${className}`}>
22
+ <Title level={level}>{mainText}</Title>
23
+ {subText && <Text className={"subText"}>{subText}</Text>}
24
+ </div>
25
+ );
26
+ };
27
+
28
+ export default AppTitle;
@@ -0,0 +1,27 @@
1
+ .toggleContainer {
2
+ display: flex;
3
+ align-items: center;
4
+ .ant-switch {
5
+ height: 16px;
6
+ position: relative;
7
+ .ant-switch-handle {
8
+ top: 50%;
9
+ bottom: 50%;
10
+ transform: translateY(-50%);
11
+ }
12
+ }
13
+ &:not(.ant-switch.ant-switch-checked .ant-switch-handle) {
14
+ inset-inline-start: 0px;
15
+ }
16
+ & .ant-switch.ant-switch-checked .ant-switch-handle {
17
+ inset-inline-start: calc(100% - 18px);
18
+ }
19
+ }
20
+
21
+ .switch {
22
+ margin-right: 0.5rem;
23
+ }
24
+
25
+ .label {
26
+ font-size: 1rem;
27
+ }
@@ -0,0 +1,43 @@
1
+ import React, { useState } from "react";
2
+ import { Switch } from "antd";
3
+ import "./app-toggle-button.css";
4
+
5
+ interface AppToggleButtonProps {
6
+ initialChecked?: boolean;
7
+ onChange?: (checked: boolean) => void;
8
+ checkedLabel?: string;
9
+ uncheckedLabel?: string;
10
+ className?: string;
11
+ }
12
+
13
+ const AppToggleButton = ({
14
+ initialChecked = false,
15
+ onChange,
16
+ checkedLabel,
17
+ uncheckedLabel,
18
+ className,
19
+ }: AppToggleButtonProps) => {
20
+ const [isChecked, setIsChecked] = useState(initialChecked);
21
+
22
+ const handleToggle = (checked: boolean) => {
23
+ setIsChecked(checked);
24
+ if (onChange) {
25
+ onChange(checked);
26
+ }
27
+ };
28
+
29
+ return (
30
+ <div className={`toggleContainer ${className}`}>
31
+ <Switch
32
+ checked={isChecked}
33
+ onChange={handleToggle}
34
+ className={"switch"}
35
+ />
36
+ <span className={"label"}>
37
+ {isChecked ? checkedLabel : uncheckedLabel}
38
+ </span>
39
+ </div>
40
+ );
41
+ };
42
+
43
+ export default AppToggleButton;
@@ -0,0 +1,26 @@
1
+ .profileImageContainer {
2
+ display: flex;
3
+ align-items: center;
4
+ gap: 2rem;
5
+ }
6
+
7
+ .altTextWrapper {
8
+ font-size: 0.8rem;
9
+ text-align: center;
10
+ img {
11
+ border-radius: 0;
12
+ }
13
+ }
14
+
15
+ .profileImage {
16
+ width: 100px;
17
+ height: 100px;
18
+ border-radius: 50%;
19
+ object-fit: cover;
20
+ position: relative;
21
+ font-size: 0.8rem;
22
+ }
23
+
24
+ .fileInput {
25
+ display: none;
26
+ }
@@ -0,0 +1,90 @@
1
+ import React, { useState, useRef } from "react";
2
+ import Icons from "../../themes/icons/icons";
3
+ import "./app-upload-image.css";
4
+
5
+ interface AppUploadImageProps {
6
+ className?: string;
7
+ uploadIcon?: React.ReactNode;
8
+ value?: string;
9
+ text?: string;
10
+ onFileChange?: (file: File | null) => void;
11
+ alertMessages?: {
12
+ invalidType?: string;
13
+ sizeExceed?: string;
14
+ };
15
+ acceptedFormats?: string[];
16
+ maxSizeMb?: number;
17
+ altText?: string;
18
+ }
19
+
20
+ const AppUploadImage = ({
21
+ className,
22
+ uploadIcon,
23
+ value = "",
24
+ text = "Upload Image",
25
+ onFileChange,
26
+ alertMessages = {
27
+ invalidType: "You can only upload JPG/PNG/SVG file!",
28
+ sizeExceed: "Image must be smaller than 2MB!",
29
+ },
30
+ acceptedFormats = ["image/jpeg", "image/png", "image/svg+xml"],
31
+ maxSizeMb = 2,
32
+ altText = "Profile Image",
33
+ }: AppUploadImageProps) => {
34
+ const [imageUrl, setImageUrl] = useState<string>(value);
35
+ const fileInputRef = useRef<HTMLInputElement>(null);
36
+
37
+ const handleButtonClick = () => {
38
+ fileInputRef.current?.click();
39
+ };
40
+
41
+ const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
42
+ const file = event.target.files?.[0];
43
+ if (file) {
44
+ const isAcceptedFormat = acceptedFormats.includes(file.type);
45
+ const isLtMaxSize = file.size / 1024 / 1024 < maxSizeMb;
46
+
47
+ if (!isAcceptedFormat) {
48
+ alert(alertMessages.invalidType);
49
+ return;
50
+ }
51
+
52
+ if (!isLtMaxSize) {
53
+ alert(alertMessages.sizeExceed);
54
+ return;
55
+ }
56
+
57
+ const reader = new FileReader();
58
+ reader.onloadend = () => {
59
+ setImageUrl(reader.result as string);
60
+ if (onFileChange) {
61
+ onFileChange(file);
62
+ }
63
+ };
64
+ reader.readAsDataURL(file);
65
+ } else if (onFileChange) {
66
+ onFileChange(null);
67
+ }
68
+ };
69
+
70
+ return (
71
+ <div className={`profileImageContainer ${className}`}>
72
+ <div className={imageUrl === "" ? "altTextWrapper" : ""}>
73
+ <img className={"profileImage"} src={imageUrl} alt={altText} />
74
+ </div>
75
+ <button className={"uploadButton"} onClick={handleButtonClick}>
76
+ <span>{uploadIcon || Icons.uploadIcon}</span>
77
+ {text}
78
+ </button>
79
+ <input
80
+ type="file"
81
+ accept={acceptedFormats.join(",")}
82
+ className={"fileInput"}
83
+ ref={fileInputRef}
84
+ onChange={handleFileChange}
85
+ />
86
+ </div>
87
+ );
88
+ };
89
+
90
+ export default AppUploadImage;
@@ -0,0 +1,16 @@
1
+ .overViewCard {
2
+ border-radius: 12px;
3
+ padding: 0.5rem 1rem;
4
+ background-color: #f9f9f9;
5
+ width: max-content;
6
+ display: flex;
7
+ flex-direction: column;
8
+ align-items: center;
9
+ gap: 0.5rem;
10
+ .text {
11
+ font-size: 14px;
12
+ font-weight: 700;
13
+ line-height: 18.2px;
14
+ text-align: left;
15
+ }
16
+ }
@@ -0,0 +1,22 @@
1
+ import React from "react";
2
+ import { Typography } from "antd";
3
+ import "./over-view-card.css";
4
+
5
+ const { Text } = Typography;
6
+
7
+ interface OverViewCardProps {
8
+ className?: string;
9
+ text?: string;
10
+ number?: number;
11
+ }
12
+
13
+ const OverViewCard = ({ className, text, number }: OverViewCardProps) => {
14
+ return (
15
+ <div className={`overViewCard ${className}`}>
16
+ <Text>{text}</Text>
17
+ <span>{number}</span>
18
+ </div>
19
+ );
20
+ };
21
+
22
+ export default OverViewCard;
package/src/index.ts ADDED
@@ -0,0 +1,5 @@
1
+ export { default as AppInput } from "./components/app-input/app-input";
2
+ export { default as AppButton } from "./components/app-button/app-button";
3
+ export { default as AppSidebar } from "./components/app-sidebar/app-sidebar";
4
+ export { default as AppTextarea } from "./components/app-textarea/app-textarea";
5
+ export { default as AppTab } from "./components/app-tab/app-tab";