dst-rg 1.0.0

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 (249) hide show
  1. package/.gitlab-ci.yml +43 -0
  2. package/.storybook/main.ts +15 -0
  3. package/.storybook/preview.ts +15 -0
  4. package/README.md +254 -0
  5. package/components.json +21 -0
  6. package/dist/Avatar.png +0 -0
  7. package/dist/assets/index-CCq7hmG3.js +186 -0
  8. package/dist/assets/index-Mg-hjQGu.css +1 -0
  9. package/dist/index.html +15 -0
  10. package/dist/test.png +0 -0
  11. package/dist/vite.svg +1 -0
  12. package/eslint.config.js +29 -0
  13. package/index.html +14 -0
  14. package/package.json +102 -0
  15. package/postcss.config.mjs +11 -0
  16. package/rollup.config.mjs +55 -0
  17. package/src/assets/react.svg +1 -0
  18. package/src/assets/style/animation.css +27 -0
  19. package/src/assets/style/box-shadow.css +25 -0
  20. package/src/assets/style/colors.css +402 -0
  21. package/src/assets/style/dark-theme.css +288 -0
  22. package/src/assets/style/font-size.css +14 -0
  23. package/src/assets/style/gradient.css +3 -0
  24. package/src/assets/style/index.css +12 -0
  25. package/src/assets/style/light-theme.css +148 -0
  26. package/src/assets/style/line-height.css +13 -0
  27. package/src/assets/style/max-width.css +5 -0
  28. package/src/assets/style/radius.css +13 -0
  29. package/src/assets/style/utility-colors.css +166 -0
  30. package/src/components/Accordion/_.stories.tsx +75 -0
  31. package/src/components/Accordion/_.test.tsx +77 -0
  32. package/src/components/Accordion/index.tsx +47 -0
  33. package/src/components/Accordion/type.ts +24 -0
  34. package/src/components/Avatar/_.stories.tsx +179 -0
  35. package/src/components/Avatar/_.style.ts +40 -0
  36. package/src/components/Avatar/_.test.tsx +150 -0
  37. package/src/components/Avatar/_.types.ts +66 -0
  38. package/src/components/Avatar/index.tsx +63 -0
  39. package/src/components/Badge/_.stories.tsx +75 -0
  40. package/src/components/Badge/_.style.ts +53 -0
  41. package/src/components/Badge/_.test.tsx +27 -0
  42. package/src/components/Badge/_.types.ts +11 -0
  43. package/src/components/Badge/index.tsx +42 -0
  44. package/src/components/Breadcrumbs/_.stories.tsx +95 -0
  45. package/src/components/Breadcrumbs/_.test.tsx +29 -0
  46. package/src/components/Breadcrumbs/_.type.ts +15 -0
  47. package/src/components/Breadcrumbs/index.tsx +103 -0
  48. package/src/components/Button/_.stories.tsx +85 -0
  49. package/src/components/Button/_.style.ts +56 -0
  50. package/src/components/Button/_.test.tsx +103 -0
  51. package/src/components/Button/_.types.ts +14 -0
  52. package/src/components/Button/index.tsx +70 -0
  53. package/src/components/Checkbox/_.stories.tsx +96 -0
  54. package/src/components/Checkbox/_.style.ts +24 -0
  55. package/src/components/Checkbox/_.test.tsx +85 -0
  56. package/src/components/Checkbox/_.types.ts +23 -0
  57. package/src/components/Checkbox/index.tsx +93 -0
  58. package/src/components/CheckboxGroup/PaymentCard/_.stories.tsx +104 -0
  59. package/src/components/CheckboxGroup/PaymentCard/_.style.ts +28 -0
  60. package/src/components/CheckboxGroup/PaymentCard/_.test.tsx +58 -0
  61. package/src/components/CheckboxGroup/PaymentCard/_.types.ts +28 -0
  62. package/src/components/CheckboxGroup/PaymentCard/index.tsx +71 -0
  63. package/src/components/CheckboxGroup/PlanCard/_.stories.tsx +165 -0
  64. package/src/components/CheckboxGroup/PlanCard/_.style.ts +32 -0
  65. package/src/components/CheckboxGroup/PlanCard/_.test.tsx +54 -0
  66. package/src/components/CheckboxGroup/PlanCard/_.types.ts +35 -0
  67. package/src/components/CheckboxGroup/PlanCard/index.tsx +53 -0
  68. package/src/components/CheckboxGroup/UserCard/_.stories.tsx +89 -0
  69. package/src/components/CheckboxGroup/UserCard/_.style.ts +42 -0
  70. package/src/components/CheckboxGroup/UserCard/_.test.tsx +66 -0
  71. package/src/components/CheckboxGroup/UserCard/_.types.ts +26 -0
  72. package/src/components/CheckboxGroup/UserCard/index.tsx +75 -0
  73. package/src/components/Dropdown/_.stories.tsx +180 -0
  74. package/src/components/Dropdown/_.style.ts +108 -0
  75. package/src/components/Dropdown/_.test.tsx +334 -0
  76. package/src/components/Dropdown/_.types.ts +12 -0
  77. package/src/components/Dropdown/index.tsx +130 -0
  78. package/src/components/FileUpload/_.stories.tsx +74 -0
  79. package/src/components/FileUpload/_.style.ts +0 -0
  80. package/src/components/FileUpload/_.test.tsx +222 -0
  81. package/src/components/FileUpload/_.types.ts +53 -0
  82. package/src/components/FileUpload/index.tsx +44 -0
  83. package/src/components/ImageMagnify/_.stories.tsx +226 -0
  84. package/src/components/ImageMagnify/_.style.ts +109 -0
  85. package/src/components/ImageMagnify/_.types.ts +44 -0
  86. package/src/components/ImageMagnify/index.tsx +204 -0
  87. package/src/components/Input/_.stories.tsx +177 -0
  88. package/src/components/Input/_.style.ts +79 -0
  89. package/src/components/Input/_.test.tsx +146 -0
  90. package/src/components/Input/_.types.ts +66 -0
  91. package/src/components/Input/index.tsx +231 -0
  92. package/src/components/InputTags/_.stories.tsx +51 -0
  93. package/src/components/InputTags/_.style.ts +28 -0
  94. package/src/components/InputTags/_.test.tsx +123 -0
  95. package/src/components/InputTags/_.types.ts +26 -0
  96. package/src/components/InputTags/index.tsx +140 -0
  97. package/src/components/Message/_.stories.tsx +79 -0
  98. package/src/components/Message/_.style.ts +87 -0
  99. package/src/components/Message/_.test.tsx +73 -0
  100. package/src/components/Message/_.types.ts +13 -0
  101. package/src/components/Message/index.tsx +57 -0
  102. package/src/components/Metric/_.stories.tsx +142 -0
  103. package/src/components/Metric/_.style.ts +14 -0
  104. package/src/components/Metric/_.test.tsx +166 -0
  105. package/src/components/Metric/_.types.ts +18 -0
  106. package/src/components/Metric/index.tsx +100 -0
  107. package/src/components/Modal/_.stories.tsx +93 -0
  108. package/src/components/Modal/_.style.ts +31 -0
  109. package/src/components/Modal/_.test.tsx +90 -0
  110. package/src/components/Modal/_.types.ts +14 -0
  111. package/src/components/Modal/index.tsx +82 -0
  112. package/src/components/Pagination/_.stories.tsx +118 -0
  113. package/src/components/Pagination/_.test.tsx +51 -0
  114. package/src/components/Pagination/index.tsx +256 -0
  115. package/src/components/Pagination/type.ts +48 -0
  116. package/src/components/PriceSlider/_.stories.tsx +107 -0
  117. package/src/components/PriceSlider/_.test.tsx +63 -0
  118. package/src/components/PriceSlider/_.type.tsx +19 -0
  119. package/src/components/PriceSlider/index.tsx +86 -0
  120. package/src/components/Progress/_.stories.tsx +93 -0
  121. package/src/components/Progress/_.style.ts +15 -0
  122. package/src/components/Progress/_.test.tsx +34 -0
  123. package/src/components/Progress/_.types.ts +17 -0
  124. package/src/components/Progress/index.tsx +173 -0
  125. package/src/components/Radio/_.stories.tsx +391 -0
  126. package/src/components/Radio/_.style.ts +33 -0
  127. package/src/components/Radio/_.test.tsx +77 -0
  128. package/src/components/Radio/_.types.ts +14 -0
  129. package/src/components/Radio/index.tsx +59 -0
  130. package/src/components/Select/_.stories.tsx +308 -0
  131. package/src/components/Select/_.style.ts +5 -0
  132. package/src/components/Select/_.types.ts +24 -0
  133. package/src/components/Select/index.tsx +172 -0
  134. package/src/components/Switch/_.stories.tsx +61 -0
  135. package/src/components/Switch/_.test.tsx +69 -0
  136. package/src/components/Switch/_.type.ts +12 -0
  137. package/src/components/Switch/index.tsx +70 -0
  138. package/src/components/Tabs/_.stories.tsx +508 -0
  139. package/src/components/Tabs/_.style.ts +63 -0
  140. package/src/components/Tabs/_.test.tsx +174 -0
  141. package/src/components/Tabs/_.type.ts +19 -0
  142. package/src/components/Tabs/index.tsx +35 -0
  143. package/src/components/Tag/_.stories.tsx +78 -0
  144. package/src/components/Tag/_.style.ts +71 -0
  145. package/src/components/Tag/_.test.tsx +44 -0
  146. package/src/components/Tag/_.types.ts +27 -0
  147. package/src/components/Tag/index.tsx +46 -0
  148. package/src/components/TextArea/_.stories.tsx +62 -0
  149. package/src/components/TextArea/_.style.ts +11 -0
  150. package/src/components/TextArea/_.test.tsx +43 -0
  151. package/src/components/TextArea/_.types.ts +29 -0
  152. package/src/components/TextArea/index.tsx +83 -0
  153. package/src/components/Toast/_.style.tsx +27 -0
  154. package/src/components/Toast/_.type.ts +30 -0
  155. package/src/components/Toast/_.utils.ts +23 -0
  156. package/src/components/Toast/container.tsx +171 -0
  157. package/src/components/Toast/index.tsx +29 -0
  158. package/src/components/Tooltip/_.stories.tsx +106 -0
  159. package/src/components/Tooltip/_.style.ts +27 -0
  160. package/src/components/Tooltip/_.test.tsx +54 -0
  161. package/src/components/Tooltip/_.types.ts +31 -0
  162. package/src/components/Tooltip/index.tsx +80 -0
  163. package/src/components/developers/AmirHossein.tsx +149 -0
  164. package/src/components/developers/Fardin.tsx +130 -0
  165. package/src/components/developers/Maryam.tsx +260 -0
  166. package/src/components/developers/Milad.tsx +431 -0
  167. package/src/components/developers/Rasoul.tsx +198 -0
  168. package/src/components/index.ts +28 -0
  169. package/src/components/ui/accordion.tsx +162 -0
  170. package/src/components/ui/avatars-component/avatar-description.tsx +30 -0
  171. package/src/components/ui/avatars-component/avatar-groups.tsx +68 -0
  172. package/src/components/ui/avatars-component/avatar-single.tsx +50 -0
  173. package/src/components/ui/card.tsx +92 -0
  174. package/src/components/ui/checkbox-group/plan-card/basic/_.test.tsx +66 -0
  175. package/src/components/ui/checkbox-group/plan-card/basic/index.tsx +70 -0
  176. package/src/components/ui/checkbox-group/plan-card/with-header/_.test.tsx +110 -0
  177. package/src/components/ui/checkbox-group/plan-card/with-header/header.test.tsx +96 -0
  178. package/src/components/ui/checkbox-group/plan-card/with-header/header.tsx +74 -0
  179. package/src/components/ui/checkbox-group/plan-card/with-header/index.tsx +65 -0
  180. package/src/components/ui/file-content/File-content.tsx +43 -0
  181. package/src/components/ui/file-uploader-components/file-uploader-box.tsx +76 -0
  182. package/src/components/ui/file-uploader-components/file-uploader-item.tsx +64 -0
  183. package/src/components/ui/icon-wrapper/_.test.tsx +60 -0
  184. package/src/components/ui/icon-wrapper/index.tsx +19 -0
  185. package/src/components/ui/input-component/input-label.tsx +11 -0
  186. package/src/components/ui/number.tsx +18 -0
  187. package/src/components/ui/pagination/card-minimal-center-align.tsx +96 -0
  188. package/src/components/ui/pagination/card-minimal-right-aligne.tsx +90 -0
  189. package/src/components/ui/pagination/default-pagination.tsx +128 -0
  190. package/src/components/ui/pagination/get-pagination-item.tsx +36 -0
  191. package/src/components/ui/pagination/pagination-card-button-group-aligned.tsx +94 -0
  192. package/src/components/ui/pagination/pagination-card-minimal-left-aligned.tsx +90 -0
  193. package/src/components/ui/pagination/pagination-content.tsx +15 -0
  194. package/src/components/ui/pagination/pagination-item.tsx +11 -0
  195. package/src/components/ui/pagination/pagination-link.tsx +42 -0
  196. package/src/components/ui/tab-components/tabs-content.tsx +15 -0
  197. package/src/components/ui/tab-components/tabs-list.tsx +27 -0
  198. package/src/components/ui/tab-components/tabs-trigger.tsx +25 -0
  199. package/src/components/ui/text-content-wrapper.tsx +36 -0
  200. package/src/hooks/useClickOutside.ts +23 -0
  201. package/src/icons/general/ArrowLeft.tsx +31 -0
  202. package/src/icons/general/ArrowRight.tsx +31 -0
  203. package/src/icons/general/activity-heart.tsx +31 -0
  204. package/src/icons/general/activity.tsx +31 -0
  205. package/src/icons/general/anchor.tsx +31 -0
  206. package/src/icons/general/archive.tsx +31 -0
  207. package/src/icons/general/arrow-left.tsx +25 -0
  208. package/src/icons/general/arrow-right.tsx +25 -0
  209. package/src/icons/general/asterisk-01.tsx +31 -0
  210. package/src/icons/general/asterisk-02.tsx +31 -0
  211. package/src/icons/general/at-sign.tsx +31 -0
  212. package/src/icons/general/attention-mark.tsx +43 -0
  213. package/src/icons/general/bookmark-add.tsx +31 -0
  214. package/src/icons/general/bookmark.tsx +31 -0
  215. package/src/icons/general/chevron-left.tsx +25 -0
  216. package/src/icons/general/chevron-right.tsx +25 -0
  217. package/src/icons/general/circle-minues.tsx +25 -0
  218. package/src/icons/general/circle-plus.tsx +25 -0
  219. package/src/icons/general/circle-question-mark.tsx +32 -0
  220. package/src/icons/general/circle.tsx +32 -0
  221. package/src/icons/general/copy.tsx +43 -0
  222. package/src/icons/general/email.tsx +32 -0
  223. package/src/icons/general/home.tsx +25 -0
  224. package/src/icons/general/layer.tsx +36 -0
  225. package/src/icons/general/leading.tsx +19 -0
  226. package/src/icons/general/master-card.tsx +37 -0
  227. package/src/icons/general/minus.tsx +36 -0
  228. package/src/icons/general/plus.tsx +19 -0
  229. package/src/icons/general/remove.tsx +32 -0
  230. package/src/icons/general/slash-divider.tsx +26 -0
  231. package/src/icons/general/tick-box.tsx +37 -0
  232. package/src/icons/general/trailing.tsx +19 -0
  233. package/src/icons/general/unkown-format.tsx +25 -0
  234. package/src/icons/general/visa-card.tsx +38 -0
  235. package/src/icons/general/x-close.tsx +35 -0
  236. package/src/icons/icons.type.ts +7 -0
  237. package/src/index.css +21 -0
  238. package/src/index.ts +3 -0
  239. package/src/lib/utils.ts +6 -0
  240. package/src/lib/zIndexUtils.ts +2 -0
  241. package/src/main.tsx +50 -0
  242. package/src/vite-env.d.ts +1 -0
  243. package/tests/setup.ts +8 -0
  244. package/tsconfig.app.json +31 -0
  245. package/tsconfig.json +7 -0
  246. package/tsconfig.node.json +24 -0
  247. package/tsconfig.rollup.json +12 -0
  248. package/vite.config.ts +20 -0
  249. package/vitest.config.ts +47 -0
@@ -0,0 +1,96 @@
1
+ import { render, screen, fireEvent } from "@testing-library/react";
2
+ import "@testing-library/jest-dom";
3
+ import { describe, it, expect, vi } from "vitest";
4
+ import { Header } from "./header";
5
+
6
+ describe("Header Component", () => {
7
+ const onChange = vi.fn();
8
+ const renderFunction = ({
9
+ type = "checkbox",
10
+ }: {
11
+ type?: "checkbox" | "radio";
12
+ }) => {
13
+ return render(
14
+ <Header
15
+ title="Plan Title"
16
+ size="sm"
17
+ disabled={false}
18
+ checkboxIndex={1}
19
+ id="plan-id"
20
+ value="plan-value"
21
+ onChange={onChange}
22
+ type={type}
23
+ />
24
+ );
25
+ };
26
+
27
+ it("renders correctly with title", () => {
28
+ renderFunction({ type: "checkbox" });
29
+ const titleElement = screen.getByText("Plan Title");
30
+ expect(titleElement).toBeInTheDocument();
31
+ });
32
+
33
+ it("renders the correct icon", () => {
34
+ renderFunction({ type: "checkbox" });
35
+ const iconElement = screen.getByTestId("layer-icon");
36
+ expect(iconElement).toBeInTheDocument();
37
+ });
38
+
39
+ it("renders checkbox when type is checkbox", () => {
40
+ renderFunction({ type: "checkbox" });
41
+
42
+ const checkboxElement = screen.getByTestId("checkbox");
43
+ expect(checkboxElement).toBeInTheDocument();
44
+ });
45
+
46
+ it("renders radio button when type is radio", () => {
47
+ renderFunction({ type: "radio" });
48
+
49
+ const radioElement = screen.getByRole("radio");
50
+ expect(radioElement).toBeInTheDocument();
51
+ });
52
+
53
+ it("calls onChange when checkbox is clicked", () => {
54
+ renderFunction({ type: "checkbox" });
55
+
56
+ const checkbox = screen.getByTestId("checkbox");
57
+ fireEvent.click(checkbox);
58
+
59
+ expect(onChange).toHaveBeenCalled();
60
+ });
61
+
62
+ it("calls onChange when radio button is clicked", () => {
63
+ renderFunction({ type: "radio" });
64
+
65
+ const radio = screen.getByRole("radio");
66
+ fireEvent.click(radio);
67
+
68
+ expect(onChange).toHaveBeenCalled();
69
+ });
70
+
71
+ it("does not call onChange when checkbox is clicked and disabled", () => {
72
+ renderFunction({ type: "checkbox" });
73
+
74
+ const checkbox = screen.getByTestId("checkbox");
75
+ fireEvent.click(checkbox);
76
+
77
+ expect(onChange).toHaveBeenCalled();
78
+ });
79
+
80
+ it("applies the correct classes when disabled", () => {
81
+ renderFunction({ type: "checkbox" });
82
+
83
+ const header = screen.getByTestId("header");
84
+ expect(header).toHaveClass(
85
+ "flex items-center border-b border-rborder-secondary p-4 w-full gap-2 group-focus-within:border-rbg-brand-solid group-focus-within:border-b-2 border-b"
86
+ );
87
+ });
88
+
89
+ it("applies the correct classes when enabled", () => {
90
+ renderFunction({ type: "checkbox" });
91
+ const header = screen.getByTestId("header");
92
+ expect(header).toHaveClass(
93
+ "group-focus-within:border-rbg-brand-solid group-focus-within:border-b-2 border-b"
94
+ );
95
+ });
96
+ });
@@ -0,0 +1,74 @@
1
+ import { Checkbox } from "@/components/Checkbox";
2
+ import { CommonCheckboxProps } from "@/components/CheckboxGroup/PlanCard/_.types";
3
+ import { Radio } from "@/components/Radio";
4
+ import IconWrapper from "@/components/ui/icon-wrapper";
5
+ import Layer from "@/icons/general/layer";
6
+
7
+ export const Header = ({
8
+ title,
9
+ size,
10
+ disabled,
11
+ checkboxIndex,
12
+ id,
13
+ name = "",
14
+ value = "",
15
+ onChange,
16
+ inputProps,
17
+ checked,
18
+ type,
19
+ ...props
20
+ }: {
21
+ title: string;
22
+ name?: string;
23
+ value?: string;
24
+ } & CommonCheckboxProps) => {
25
+ const bgClass =
26
+ disabled ||
27
+ "group-focus-within:border-rbg-brand-solid group-focus-within:border-b-2 border-b";
28
+
29
+ return (
30
+ <div
31
+ data-testid="header"
32
+ className={`flex items-center border-b-2 border-rborder-secondary p-4 w-full gap-2 ${bgClass}`}
33
+ {...props}
34
+ >
35
+ <IconWrapper>
36
+ <Layer width="20" height="20" />
37
+ </IconWrapper>
38
+
39
+ <div className="flex flex-col grow justify-between">
40
+ <div className="flex text-sm">
41
+ <h3 className="font-medium text-foreground text-rtext-secondary-700">
42
+ {title}
43
+ </h3>
44
+ </div>
45
+ </div>
46
+
47
+ <div className="flex items-start gap-2">
48
+ {type === "radio" ? (
49
+ <Radio
50
+ onChange={onChange}
51
+ checked={checked}
52
+ disabled={disabled}
53
+ value={value}
54
+ name={name}
55
+ size={size}
56
+ id={id}
57
+ {...inputProps}
58
+ />
59
+ ) : (
60
+ <Checkbox
61
+ checkboxIndex={checkboxIndex}
62
+ disabled={disabled}
63
+ id={id}
64
+ name={name}
65
+ onChange={onChange}
66
+ size={size}
67
+ value={value}
68
+ {...inputProps}
69
+ />
70
+ )}
71
+ </div>
72
+ </div>
73
+ );
74
+ };
@@ -0,0 +1,65 @@
1
+ import { Badge } from "@/components/Badge";
2
+ import { PlanCardProps } from "@/components/CheckboxGroup/PlanCard/_.types";
3
+ import { Header } from "./header";
4
+
5
+ export function PlanCardWithHeader({
6
+ per,
7
+ size = "sm",
8
+ title = "",
9
+ price,
10
+ description,
11
+ checked,
12
+ badgeContent,
13
+ checkboxIndex = 1,
14
+ id = "",
15
+ value = "value",
16
+ name = "",
17
+ onChange,
18
+ disabled,
19
+ type,
20
+ }: Readonly<PlanCardProps>) {
21
+ return (
22
+ <>
23
+ <Header
24
+ type={type}
25
+ onChange={onChange}
26
+ name={name}
27
+ disabled={disabled}
28
+ checked={checked}
29
+ value={value}
30
+ data-testid="header"
31
+ checkboxIndex={checkboxIndex}
32
+ title={title}
33
+ size={size}
34
+ id={id}
35
+ />
36
+ <div className="p-4 flex w-full">
37
+ <div className="grow space-y-1">
38
+ <div className="flex items-end text-sm gap-1">
39
+ <span className="text-3xl font-semibold text-foreground text-rtext-secondary-700">
40
+ {price}
41
+ </span>
42
+ <span className="h-fit">{per}</span>
43
+ </div>
44
+ <div>{description}</div>
45
+ </div>
46
+ <span>
47
+ {badgeContent && (
48
+ <Badge
49
+ size="md"
50
+ type="badgeColor"
51
+ dir="rtl"
52
+ color="success"
53
+ className="!bg-white !border-rborder-primary !text-rtext-secondary-700"
54
+ icon={
55
+ <span className="w-1.5 h-1.5 rounded-full bg-rfg-success-primary"></span>
56
+ }
57
+ >
58
+ {badgeContent}
59
+ </Badge>
60
+ )}
61
+ </span>
62
+ </div>
63
+ </>
64
+ );
65
+ }
@@ -0,0 +1,43 @@
1
+ import { cn } from "@/lib/utils";
2
+
3
+ export const FileContent = ({
4
+ icon,
5
+ title,
6
+ size,
7
+ sizeFormat,
8
+ className,
9
+ dir = "rtl",
10
+ }: {
11
+ icon: React.ReactNode;
12
+ title: string;
13
+ size?: string;
14
+ className?: string;
15
+ dir?: "rtl" | "ltr";
16
+ sizeFormat?: string;
17
+ }) => {
18
+ return (
19
+ <div
20
+ className={cn(
21
+ "w-full flex gap-3 py-2.5 px-3.5 border border-rborder-secondary bg-rbg-primary rounded-md",
22
+ className,
23
+ dir == "ltr" && "flex-row-reverse "
24
+ )}
25
+ >
26
+ <div className="w-10 h-10">{icon ?? null}</div>
27
+ <div className="flex flex-col max-w-4/5 ">
28
+ <span className="text-rtext-secondary-700 font-medium text-sm w-full truncate ">
29
+ {title}
30
+ </span>
31
+ <span
32
+ className={cn(
33
+ "text-rtext-tertiary-600 flex gap-0.5 items-center text-sm font-normal truncate",
34
+ dir == "ltr" && "flex-row-reverse"
35
+ )}
36
+ >
37
+ {size}
38
+ {sizeFormat}
39
+ </span>
40
+ </div>
41
+ </div>
42
+ );
43
+ };
@@ -0,0 +1,76 @@
1
+ import { Button } from "@/components/Button";
2
+ import { FileUploaderBoxProps } from "@/components/FileUpload/_.types";
3
+ import { cn } from "@/lib/utils";
4
+ import { UploadCloud } from "lucide-react";
5
+
6
+ export const FileUploaderBox = ({
7
+ icon,
8
+ mainText,
9
+ subText,
10
+ formatText,
11
+ acceptableFormats,
12
+ disable,
13
+ multiItem,
14
+ onChange,
15
+ }: FileUploaderBoxProps) => {
16
+ return (
17
+ <div
18
+ className={cn(
19
+ "relative w-full py-4 px-6 flex justify-center items-center gap-1 rounded-xl border border-rborder-secondary bg-rbg-primary ",
20
+ disable && "bg-rbg-disabled-subtle",
21
+ !disable &&
22
+ "hover:border-rborder-brand focus:border-rborder-brand focus-within:border-rborder-brand"
23
+ )}
24
+ >
25
+ <div className="text-center flex flex-col justify-center items-center gap-2">
26
+ {icon ?? (
27
+ <Button
28
+ variant={"secondaryGray"}
29
+ aria-hidden="true"
30
+ disabled={disable}
31
+ >
32
+ <UploadCloud data-testid="default-uploadcloud" />
33
+ </Button>
34
+ )}
35
+ <div className="flex flex-col justify-center items-center gap-1">
36
+ <div className="flex items-center gap-1">
37
+ <label
38
+ htmlFor="file-upload"
39
+ className={cn(
40
+ " cursor-pointer rounded-md text-rbutton-tertiary-color-fg font-normal text-sm",
41
+ disable && "text-rbg-disabled-subtle"
42
+ )}
43
+ >
44
+ <span className={cn(disable && "text-rfg-disabled")}>
45
+ {mainText}
46
+ </span>
47
+ <input
48
+ id="file-upload"
49
+ name="file-upload"
50
+ data-testid="file-input"
51
+ type="file"
52
+ className="absolute overflow-hidden top-0 left-0 w-full h-full opacity-0 cursor-pointer"
53
+ disabled={disable}
54
+ multiple={multiItem}
55
+ accept={
56
+ acceptableFormats
57
+ ? Array.isArray(acceptableFormats)
58
+ ? acceptableFormats
59
+ .map((f) => (f.startsWith(".") ? f : `.${f}`))
60
+ .join(", ")
61
+ : acceptableFormats
62
+ : undefined
63
+ }
64
+ onChange={onChange}
65
+ />
66
+ </label>
67
+ <p className="text-rtext-tertiary-600 text-sm">{subText}</p>
68
+ </div>
69
+ <p className="text-xs text-rtext-tertiary-600 font-normal">
70
+ {formatText}
71
+ </p>
72
+ </div>
73
+ </div>
74
+ </div>
75
+ );
76
+ };
@@ -0,0 +1,64 @@
1
+ import { Button } from "@/components/Button";
2
+ import { FileUploaderItemProps } from "@/components/FileUpload/_.types";
3
+ import { Progress } from "@/components/Progress";
4
+ import { UnkownFormat } from "@/icons/general/unkown-format";
5
+ import { cn } from "@/lib/utils";
6
+ import { Trash2 } from "lucide-react";
7
+
8
+ export const FileUploaderItem = ({
9
+ item,
10
+ loadType,
11
+ onDelete,
12
+ }: FileUploaderItemProps) => {
13
+ return (
14
+ <div
15
+ className={cn(
16
+ "p-4 flex gap-3 w-full rounded-xl border border-rborder-secondary bg-rbg-primary",
17
+ item?.status == "failed" && "border-rborder-error"
18
+ )}
19
+ >
20
+ <div className=" flex justify-start items-start w-10 h-10">
21
+ {item?.icon ?? (
22
+ <UnkownFormat width={20} height={20} data-testid="fallback-icon" />
23
+ )}
24
+ </div>
25
+ <div className="flex flex-col gap-1 w-full">
26
+ <div className="flex justify-between">
27
+ <div className="flex flex-col w-1/2">
28
+ <span className="font-medium text-rtext-secondary-700 overflow-hidden text-ellipsis text-sm">
29
+ {item?.title}
30
+ </span>
31
+ <span className="text-rtext-tertiary-600 font-normal text-sm overflow-hidden text-ellipsis">
32
+ {item?.size}
33
+ </span>
34
+ </div>
35
+ <Button
36
+ className={cn(
37
+ "self-centertext-rbutton-tertiary-fg",
38
+ item?.status == "failed" && "text-rbutton-secondary-error-fg"
39
+ )}
40
+ onClick={() => {
41
+ onDelete(item?.id);
42
+ }}
43
+ variant={"linkGray"}
44
+ >
45
+ <Trash2 width={20} height={20} />
46
+ </Button>
47
+ </div>
48
+ {loadType == "progressBar" && (
49
+ <Progress
50
+ type="line"
51
+ value={item?.progressValue}
52
+ label={item?.percentage}
53
+ size="lg"
54
+ indicatorVariant="bg-rfg-brand-primary-600"
55
+ backgroundVariant="bg-rbg-quaternary"
56
+ dir="rtl"
57
+ className="h-2"
58
+ labelClassName="text-end"
59
+ />
60
+ )}
61
+ </div>
62
+ </div>
63
+ );
64
+ };
@@ -0,0 +1,60 @@
1
+ import { render, screen } from "@testing-library/react";
2
+ import "@testing-library/jest-dom";
3
+ import { describe, expect, it } from "vitest";
4
+
5
+ import IconWrapper from ".";
6
+ // adjust the import based on your file structure
7
+
8
+ describe("IconWrapper", () => {
9
+ it("renders children correctly", () => {
10
+ render(
11
+ <IconWrapper>
12
+ <span>Test Icon</span>
13
+ </IconWrapper>
14
+ );
15
+
16
+ expect(screen.getByText("Test Icon")).toBeInTheDocument();
17
+ });
18
+
19
+ it("applies passed className", () => {
20
+ render(
21
+ <IconWrapper className="custom-class">
22
+ <span>Styled Icon</span>
23
+ </IconWrapper>
24
+ );
25
+
26
+ const wrapper = screen.getByText("Styled Icon").parentElement;
27
+ expect(wrapper).toHaveClass("custom-class");
28
+ });
29
+
30
+ it("merges className with default styles", () => {
31
+ render(
32
+ <IconWrapper className="custom-class">
33
+ <span>Check Class Merge</span>
34
+ </IconWrapper>
35
+ );
36
+
37
+ const wrapper = screen.getByText("Check Class Merge").parentElement;
38
+ expect(wrapper).toHaveClass("flex items-center justify-center");
39
+ expect(wrapper).toHaveClass("custom-class");
40
+ expect(wrapper).toHaveClass(
41
+ "border",
42
+ "rounded-md",
43
+ "shadow-rshadow-sm-01",
44
+ "p-2.5",
45
+ "w-fit",
46
+ "h-fit"
47
+ );
48
+ });
49
+
50
+ it("forwards props to div element", () => {
51
+ render(
52
+ <IconWrapper data-testid="icon-wrapper" aria-label="icon-label">
53
+ <span>Forward Props</span>
54
+ </IconWrapper>
55
+ );
56
+
57
+ const wrapper = screen.getByTestId("icon-wrapper");
58
+ expect(wrapper).toHaveAttribute("aria-label", "icon-label");
59
+ });
60
+ });
@@ -0,0 +1,19 @@
1
+ function IconWrapper({
2
+ children,
3
+ className,
4
+ ...props
5
+ }: {
6
+ className?: string;
7
+ children: React.ReactNode;
8
+ }) {
9
+ return (
10
+ <div
11
+ className={`${className} flex items-center justify-center border border-disabled-subtle-br rounded-md shadow-rshadow-sm-01 p-2.5 w-fit h-fit`}
12
+ {...props}
13
+ >
14
+ {children}
15
+ </div>
16
+ );
17
+ }
18
+
19
+ export default IconWrapper;
@@ -0,0 +1,11 @@
1
+ import { inputLabelProps } from "@/components/Input/_.types";
2
+ import { twMerge } from "tailwind-merge";
3
+
4
+ export const InputLabel = ({ id, label, required, labelClass, labelStarClass }: inputLabelProps) => {
5
+ return (
6
+ <label htmlFor={id} className={twMerge("text-sm font-medium text-rtext-secondary-700", labelClass)}>
7
+ {label}
8
+ {required && <span className={twMerge("dv-required-label text-rtext-brand-tertiary-600 mx-1", labelStarClass)}>*</span>}
9
+ </label>
10
+ );
11
+ };
@@ -0,0 +1,18 @@
1
+ import { cn } from "@/lib/utils";
2
+ import { TagProps } from "../Tag/_.types";
3
+ import { numberVariants } from "../Tag/_.style";
4
+
5
+ function Number({ number, size }: Readonly<TagProps>) {
6
+ return (
7
+ <div
8
+ className={cn(
9
+ numberVariants({ size }),
10
+ "bg-gray-light-100 rounded-[3px]"
11
+ )}
12
+ >
13
+ {number}
14
+ </div>
15
+ );
16
+ }
17
+
18
+ export default Number;
@@ -0,0 +1,96 @@
1
+ import ArrowLeft from "@/icons/general/arrow-left";
2
+ import ArrowRight from "@/icons/general/arrow-right";
3
+ import { cn } from "@/lib/utils";
4
+ import { PaginationProps } from "../../Pagination/type";
5
+ import { PaginationContent } from "./pagination-content";
6
+ import { PaginationItem } from "./pagination-item";
7
+ import { PaginationLink } from "./pagination-link";
8
+
9
+ const PaginationCardMinimalCenter = ({
10
+ currentPage,
11
+ totalPages,
12
+ onPageChange,
13
+ dir = "rtl",
14
+ labels,
15
+ previousClassName,
16
+ nextClassName,
17
+ className,
18
+ prevIcon,
19
+ nextIcon,
20
+ ...props
21
+ }: PaginationProps) => {
22
+ const isRtl = dir === "rtl";
23
+
24
+ return (
25
+ <nav
26
+ role="navigation"
27
+ aria-label="pagination"
28
+ className={cn("", className)}
29
+ {...props}
30
+ >
31
+ <PaginationContent className="flex justify-between items-center">
32
+ <div className="flex">
33
+ <PaginationItem className="md:block hidden">
34
+ <PaginationLink
35
+ size="default"
36
+ aria-label="Go to first page"
37
+ disabled={currentPage === 1}
38
+ onClick={() => onPageChange?.(1)}
39
+ >
40
+ {labels?.first}
41
+ </PaginationLink>
42
+ </PaginationItem>
43
+
44
+ <PaginationItem>
45
+ <PaginationLink
46
+ aria-label="Go to previous page"
47
+ size="default"
48
+ className={cn("gap-1", previousClassName)}
49
+ onClick={() => onPageChange?.(currentPage - 1)}
50
+ disabled={currentPage === 1}
51
+ >
52
+ <div className="md:block hidden">{labels?.prev || "قبلی"}</div>
53
+ <div className="md:hidden block">
54
+ {isRtl ? prevIcon || <ArrowRight /> : nextIcon || <ArrowLeft />}
55
+ </div>
56
+ </PaginationLink>
57
+ </PaginationItem>
58
+ </div>
59
+
60
+ <span className="text-sm font-medium">
61
+ {labels?.page} {currentPage} {labels?.of} {totalPages}
62
+ </span>
63
+
64
+ <div className="flex">
65
+ <PaginationItem>
66
+ <PaginationLink
67
+ aria-label="Go to next page"
68
+ size="default"
69
+ className={cn("gap-1", nextClassName)}
70
+ onClick={() => onPageChange?.(currentPage + 1)}
71
+ disabled={currentPage === totalPages}
72
+ >
73
+ <span className="md:block hidden">{labels?.next || "بعدی"}</span>
74
+ <div className="md:hidden block">
75
+ {isRtl ? prevIcon || <ArrowLeft /> : nextIcon || <ArrowRight />}
76
+ </div>
77
+ </PaginationLink>
78
+ </PaginationItem>
79
+
80
+ <PaginationItem className="md:block hidden">
81
+ <PaginationLink
82
+ size="default"
83
+ aria-label="Go to last page"
84
+ disabled={currentPage === totalPages}
85
+ onClick={() => onPageChange?.(totalPages)}
86
+ >
87
+ {labels?.last}
88
+ </PaginationLink>
89
+ </PaginationItem>
90
+ </div>
91
+ </PaginationContent>
92
+ </nav>
93
+ );
94
+ };
95
+
96
+ export default PaginationCardMinimalCenter;