@memori.ai/ui 1.0.0-alpha

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 (274) hide show
  1. package/README.md +105 -0
  2. package/dist/components/Alert/Alert.d.ts +18 -0
  3. package/dist/components/Alert/index.d.ts +2 -0
  4. package/dist/components/Button/Button.d.ts +27 -0
  5. package/dist/components/Button/index.d.ts +2 -0
  6. package/dist/components/ButtonBase/ButtonBase.d.ts +28 -0
  7. package/dist/components/ButtonBase/index.d.ts +3 -0
  8. package/dist/components/Card/Card.d.ts +13 -0
  9. package/dist/components/Card/index.d.ts +2 -0
  10. package/dist/components/Checkbox/Checkbox.d.ts +11 -0
  11. package/dist/components/Checkbox/index.d.ts +2 -0
  12. package/dist/components/ConfirmDialog/ConfirmDialog.d.ts +12 -0
  13. package/dist/components/ConfirmDialog/index.d.ts +2 -0
  14. package/dist/components/Drawer/Drawer.d.ts +32 -0
  15. package/dist/components/Drawer/index.d.ts +2 -0
  16. package/dist/components/Dropdown/Dropdown.d.ts +11 -0
  17. package/dist/components/Dropdown/index.d.ts +2 -0
  18. package/dist/components/Expandable/Expandable.d.ts +15 -0
  19. package/dist/components/Expandable/helpers.d.ts +3 -0
  20. package/dist/components/Expandable/index.d.ts +2 -0
  21. package/dist/components/InputBase/InputBase.d.ts +49 -0
  22. package/dist/components/InputBase/index.d.ts +3 -0
  23. package/dist/components/Modal/Modal.d.ts +16 -0
  24. package/dist/components/Modal/index.d.ts +2 -0
  25. package/dist/components/Select/Select.d.ts +16 -0
  26. package/dist/components/Select/index.d.ts +2 -0
  27. package/dist/components/Slider/Slider.d.ts +12 -0
  28. package/dist/components/Slider/index.d.ts +2 -0
  29. package/dist/components/Spin/Spin.d.ts +9 -0
  30. package/dist/components/Spin/index.d.ts +2 -0
  31. package/dist/components/Tooltip/Tooltip.d.ts +11 -0
  32. package/dist/components/Tooltip/index.d.ts +2 -0
  33. package/dist/i18n/I18nWrapper.d.ts +6 -0
  34. package/dist/icons/AI.d.ts +5 -0
  35. package/dist/icons/Alert.d.ts +5 -0
  36. package/dist/icons/ArrowUp.d.ts +5 -0
  37. package/dist/icons/Bug.d.ts +5 -0
  38. package/dist/icons/Chat.d.ts +5 -0
  39. package/dist/icons/ChevronDown.d.ts +5 -0
  40. package/dist/icons/ChevronLeft.d.ts +5 -0
  41. package/dist/icons/ChevronRight.d.ts +5 -0
  42. package/dist/icons/ChevronUp.d.ts +5 -0
  43. package/dist/icons/Clear.d.ts +5 -0
  44. package/dist/icons/Close.d.ts +6 -0
  45. package/dist/icons/Code.d.ts +5 -0
  46. package/dist/icons/Copy.d.ts +5 -0
  47. package/dist/icons/DeepThought.d.ts +5 -0
  48. package/dist/icons/Delete.d.ts +5 -0
  49. package/dist/icons/Document.d.ts +5 -0
  50. package/dist/icons/Download.d.ts +5 -0
  51. package/dist/icons/Edit.d.ts +5 -0
  52. package/dist/icons/Expand.d.ts +5 -0
  53. package/dist/icons/Eye.d.ts +5 -0
  54. package/dist/icons/EyeInvisible.d.ts +5 -0
  55. package/dist/icons/Facebook.d.ts +5 -0
  56. package/dist/icons/Feedback.d.ts +5 -0
  57. package/dist/icons/File.d.ts +5 -0
  58. package/dist/icons/FileExcel.d.ts +5 -0
  59. package/dist/icons/FilePdf.d.ts +5 -0
  60. package/dist/icons/FileWord.d.ts +5 -0
  61. package/dist/icons/Fullscreen.d.ts +5 -0
  62. package/dist/icons/FullscreenExit.d.ts +5 -0
  63. package/dist/icons/Group.d.ts +5 -0
  64. package/dist/icons/History.d.ts +6 -0
  65. package/dist/icons/Image.d.ts +4 -0
  66. package/dist/icons/Info.d.ts +5 -0
  67. package/dist/icons/Link.d.ts +5 -0
  68. package/dist/icons/Linkedin.d.ts +5 -0
  69. package/dist/icons/Loading.d.ts +6 -0
  70. package/dist/icons/Logout.d.ts +5 -0
  71. package/dist/icons/Mail.d.ts +5 -0
  72. package/dist/icons/MapMarker.d.ts +5 -0
  73. package/dist/icons/MenuHorizontal.d.ts +6 -0
  74. package/dist/icons/MenuVertical.d.ts +6 -0
  75. package/dist/icons/Message.d.ts +5 -0
  76. package/dist/icons/Microphone.d.ts +5 -0
  77. package/dist/icons/Minus.d.ts +5 -0
  78. package/dist/icons/MinusCircle.d.ts +5 -0
  79. package/dist/icons/PaperClip.d.ts +5 -0
  80. package/dist/icons/Picture.d.ts +5 -0
  81. package/dist/icons/Plus.d.ts +5 -0
  82. package/dist/icons/Preview.d.ts +4 -0
  83. package/dist/icons/Print.d.ts +6 -0
  84. package/dist/icons/QuestionHelp.d.ts +5 -0
  85. package/dist/icons/Refresh.d.ts +5 -0
  86. package/dist/icons/SelectIcon.d.ts +5 -0
  87. package/dist/icons/Send.d.ts +5 -0
  88. package/dist/icons/Setting.d.ts +5 -0
  89. package/dist/icons/Share.d.ts +5 -0
  90. package/dist/icons/Sound.d.ts +5 -0
  91. package/dist/icons/SoundDeactivated.d.ts +5 -0
  92. package/dist/icons/Telegram.d.ts +5 -0
  93. package/dist/icons/ThumbDown.d.ts +5 -0
  94. package/dist/icons/ThumbUp.d.ts +5 -0
  95. package/dist/icons/Translation.d.ts +5 -0
  96. package/dist/icons/Twitter.d.ts +5 -0
  97. package/dist/icons/Upload.d.ts +4 -0
  98. package/dist/icons/User.d.ts +5 -0
  99. package/dist/icons/Warning.d.ts +5 -0
  100. package/dist/icons/WhatsApp.d.ts +5 -0
  101. package/dist/index.d.ts +13 -0
  102. package/dist/memori-ai-ui.css +2 -0
  103. package/dist/memori-ai-ui.es.js +6400 -0
  104. package/dist/memori-ai-ui.umd.js +23 -0
  105. package/package.json +97 -0
  106. package/src/components/Alert/Alert.css +95 -0
  107. package/src/components/Alert/Alert.stories.tsx +156 -0
  108. package/src/components/Alert/Alert.test.tsx +122 -0
  109. package/src/components/Alert/Alert.tsx +124 -0
  110. package/src/components/Alert/__snapshots__/Alert.test.tsx.snap +67 -0
  111. package/src/components/Alert/index.tsx +2 -0
  112. package/src/components/Button/Button.css +173 -0
  113. package/src/components/Button/Button.stories.tsx +173 -0
  114. package/src/components/Button/Button.test.tsx +80 -0
  115. package/src/components/Button/Button.tsx +104 -0
  116. package/src/components/Button/__snapshots__/Button.test.tsx.snap +204 -0
  117. package/src/components/Button/index.tsx +2 -0
  118. package/src/components/ButtonBase/ButtonBase.stories.tsx +194 -0
  119. package/src/components/ButtonBase/ButtonBase.tsx +84 -0
  120. package/src/components/ButtonBase/index.tsx +3 -0
  121. package/src/components/ButtonBase/styles.module.css +135 -0
  122. package/src/components/Card/Card.css +67 -0
  123. package/src/components/Card/Card.stories.tsx +104 -0
  124. package/src/components/Card/Card.test.tsx +67 -0
  125. package/src/components/Card/Card.tsx +58 -0
  126. package/src/components/Card/__snapshots__/Card.test.tsx.snap +321 -0
  127. package/src/components/Card/index.tsx +2 -0
  128. package/src/components/Checkbox/Checkbox.css +114 -0
  129. package/src/components/Checkbox/Checkbox.stories.tsx +77 -0
  130. package/src/components/Checkbox/Checkbox.test.tsx +50 -0
  131. package/src/components/Checkbox/Checkbox.tsx +61 -0
  132. package/src/components/Checkbox/__snapshots__/Checkbox.test.tsx.snap +131 -0
  133. package/src/components/Checkbox/index.tsx +2 -0
  134. package/src/components/ConfirmDialog/ConfirmDialog.css +44 -0
  135. package/src/components/ConfirmDialog/ConfirmDialog.stories.tsx +235 -0
  136. package/src/components/ConfirmDialog/ConfirmDialog.test.tsx +129 -0
  137. package/src/components/ConfirmDialog/ConfirmDialog.tsx +73 -0
  138. package/src/components/ConfirmDialog/__snapshots__/ConfirmDialog.test.tsx.snap +11 -0
  139. package/src/components/ConfirmDialog/index.tsx +2 -0
  140. package/src/components/Details/Details.css +66 -0
  141. package/src/components/Details/Details.stories.tsx +67 -0
  142. package/src/components/Drawer/Drawer.css +210 -0
  143. package/src/components/Drawer/Drawer.stories.tsx +275 -0
  144. package/src/components/Drawer/Drawer.test.tsx +158 -0
  145. package/src/components/Drawer/Drawer.tsx +242 -0
  146. package/src/components/Drawer/__snapshots__/Drawer.test.tsx.snap +21 -0
  147. package/src/components/Drawer/index.tsx +2 -0
  148. package/src/components/Dropdown/Dropdown.css +177 -0
  149. package/src/components/Dropdown/Dropdown.stories.tsx +73 -0
  150. package/src/components/Dropdown/Dropdown.test.tsx +88 -0
  151. package/src/components/Dropdown/Dropdown.tsx +88 -0
  152. package/src/components/Dropdown/__snapshots__/Dropdown.test.tsx.snap +141 -0
  153. package/src/components/Dropdown/index.tsx +2 -0
  154. package/src/components/Expandable/Expandable.css +15 -0
  155. package/src/components/Expandable/Expandable.stories.tsx +196 -0
  156. package/src/components/Expandable/Expandable.test.tsx +143 -0
  157. package/src/components/Expandable/Expandable.tsx +122 -0
  158. package/src/components/Expandable/__snapshots__/Expandable.test.tsx.snap +199 -0
  159. package/src/components/Expandable/helpers.ts +16 -0
  160. package/src/components/Expandable/index.tsx +2 -0
  161. package/src/components/InputBase/InputBase.stories.tsx +237 -0
  162. package/src/components/InputBase/InputBase.tsx +105 -0
  163. package/src/components/InputBase/index.tsx +3 -0
  164. package/src/components/InputBase/styles.module.css +96 -0
  165. package/src/components/Modal/Modal.css +95 -0
  166. package/src/components/Modal/Modal.stories.tsx +184 -0
  167. package/src/components/Modal/Modal.test.tsx +129 -0
  168. package/src/components/Modal/Modal.tsx +124 -0
  169. package/src/components/Modal/__snapshots__/Modal.test.tsx.snap +17 -0
  170. package/src/components/Modal/index.tsx +2 -0
  171. package/src/components/Select/Select.css +134 -0
  172. package/src/components/Select/Select.stories.tsx +85 -0
  173. package/src/components/Select/Select.test.tsx +85 -0
  174. package/src/components/Select/Select.tsx +84 -0
  175. package/src/components/Select/__snapshots__/Select.test.tsx.snap +261 -0
  176. package/src/components/Select/index.tsx +2 -0
  177. package/src/components/Slider/Slider.css +194 -0
  178. package/src/components/Slider/Slider.stories.tsx +85 -0
  179. package/src/components/Slider/Slider.test.tsx +55 -0
  180. package/src/components/Slider/Slider.tsx +157 -0
  181. package/src/components/Slider/__snapshots__/Slider.test.tsx.snap +419 -0
  182. package/src/components/Slider/index.tsx +2 -0
  183. package/src/components/Spin/Spin.css +31 -0
  184. package/src/components/Spin/Spin.stories.tsx +65 -0
  185. package/src/components/Spin/Spin.test.tsx +47 -0
  186. package/src/components/Spin/Spin.tsx +34 -0
  187. package/src/components/Spin/__snapshots__/Spin.test.tsx.snap +193 -0
  188. package/src/components/Spin/index.tsx +2 -0
  189. package/src/components/Table/Table.css +130 -0
  190. package/src/components/Table/Table.stories.tsx +274 -0
  191. package/src/components/Tooltip/Tooltip.css +160 -0
  192. package/src/components/Tooltip/Tooltip.stories.tsx +136 -0
  193. package/src/components/Tooltip/Tooltip.test.tsx +110 -0
  194. package/src/components/Tooltip/Tooltip.tsx +46 -0
  195. package/src/components/Tooltip/__snapshots__/Tooltip.test.tsx.snap +163 -0
  196. package/src/components/Tooltip/index.tsx +2 -0
  197. package/src/components/definitions.stories.tsx +150 -0
  198. package/src/i18n/I18nWrapper.tsx +13 -0
  199. package/src/i18n/i18n.ts +34 -0
  200. package/src/icons/AI.tsx +38 -0
  201. package/src/icons/Alert.tsx +31 -0
  202. package/src/icons/ArrowUp.tsx +28 -0
  203. package/src/icons/Bug.tsx +81 -0
  204. package/src/icons/Chat.tsx +30 -0
  205. package/src/icons/ChevronDown.tsx +26 -0
  206. package/src/icons/ChevronLeft.tsx +28 -0
  207. package/src/icons/ChevronRight.tsx +28 -0
  208. package/src/icons/ChevronUp.tsx +24 -0
  209. package/src/icons/Clear.tsx +23 -0
  210. package/src/icons/Close.tsx +30 -0
  211. package/src/icons/Code.tsx +30 -0
  212. package/src/icons/Copy.tsx +30 -0
  213. package/src/icons/DeepThought.tsx +38 -0
  214. package/src/icons/Delete.tsx +23 -0
  215. package/src/icons/Document.tsx +52 -0
  216. package/src/icons/Download.tsx +23 -0
  217. package/src/icons/Edit.tsx +17 -0
  218. package/src/icons/Expand.tsx +23 -0
  219. package/src/icons/Eye.tsx +17 -0
  220. package/src/icons/EyeInvisible.tsx +24 -0
  221. package/src/icons/Facebook.tsx +23 -0
  222. package/src/icons/Feedback.tsx +27 -0
  223. package/src/icons/File.tsx +17 -0
  224. package/src/icons/FileExcel.tsx +23 -0
  225. package/src/icons/FilePdf.tsx +23 -0
  226. package/src/icons/FileWord.tsx +23 -0
  227. package/src/icons/Fullscreen.tsx +23 -0
  228. package/src/icons/FullscreenExit.tsx +23 -0
  229. package/src/icons/Group.tsx +30 -0
  230. package/src/icons/History.tsx +33 -0
  231. package/src/icons/Image.tsx +37 -0
  232. package/src/icons/Info.tsx +37 -0
  233. package/src/icons/Link.tsx +17 -0
  234. package/src/icons/Linkedin.tsx +23 -0
  235. package/src/icons/Loading.tsx +28 -0
  236. package/src/icons/Logout.tsx +33 -0
  237. package/src/icons/Mail.tsx +17 -0
  238. package/src/icons/MapMarker.tsx +26 -0
  239. package/src/icons/MenuHorizontal.tsx +29 -0
  240. package/src/icons/MenuVertical.tsx +29 -0
  241. package/src/icons/Message.tsx +23 -0
  242. package/src/icons/Microphone.tsx +23 -0
  243. package/src/icons/Minus.tsx +23 -0
  244. package/src/icons/MinusCircle.tsx +24 -0
  245. package/src/icons/PaperClip.tsx +23 -0
  246. package/src/icons/Picture.tsx +23 -0
  247. package/src/icons/Plus.tsx +18 -0
  248. package/src/icons/Preview.tsx +31 -0
  249. package/src/icons/Print.tsx +37 -0
  250. package/src/icons/QuestionHelp.tsx +34 -0
  251. package/src/icons/Refresh.tsx +30 -0
  252. package/src/icons/SelectIcon.tsx +28 -0
  253. package/src/icons/Send.tsx +17 -0
  254. package/src/icons/Setting.tsx +23 -0
  255. package/src/icons/Share.tsx +23 -0
  256. package/src/icons/Sound.tsx +23 -0
  257. package/src/icons/SoundDeactivated.tsx +27 -0
  258. package/src/icons/Telegram.tsx +26 -0
  259. package/src/icons/ThumbDown.tsx +29 -0
  260. package/src/icons/ThumbUp.tsx +29 -0
  261. package/src/icons/Translation.tsx +24 -0
  262. package/src/icons/Twitter.tsx +23 -0
  263. package/src/icons/Upload.tsx +34 -0
  264. package/src/icons/User.tsx +17 -0
  265. package/src/icons/Warning.tsx +27 -0
  266. package/src/icons/WhatsApp.tsx +24 -0
  267. package/src/icons/icons.stories.css +5 -0
  268. package/src/icons/icons.stories.tsx +110 -0
  269. package/src/icons/loading.css +14 -0
  270. package/src/index.ts +15 -0
  271. package/src/styles/utils.css +17 -0
  272. package/src/styles.css +4 -0
  273. package/src/theme/variables.css +110 -0
  274. package/src/vite-env.d.ts +6 -0
@@ -0,0 +1,131 @@
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
+
3
+ exports[`renders Checkbox checked and disabled unchanged 1`] = `
4
+ <div>
5
+ <label
6
+ class="memori-checkbox memori-checkbox--disabled"
7
+ >
8
+ <span
9
+ class="memori-checkbox--input-wrapper"
10
+ >
11
+ <input
12
+ checked=""
13
+ class="memori-checkbox--input"
14
+ disabled=""
15
+ type="checkbox"
16
+ />
17
+ <span
18
+ class="memori-checkbox--inner"
19
+ />
20
+ </span>
21
+ <span
22
+ class="memori-checkbox--text"
23
+ >
24
+ Check me
25
+ </span>
26
+ </label>
27
+ </div>
28
+ `;
29
+
30
+ exports[`renders Checkbox checked unchanged 1`] = `
31
+ <div>
32
+ <label
33
+ class="memori-checkbox"
34
+ >
35
+ <span
36
+ class="memori-checkbox--input-wrapper"
37
+ >
38
+ <input
39
+ checked=""
40
+ class="memori-checkbox--input"
41
+ type="checkbox"
42
+ />
43
+ <span
44
+ class="memori-checkbox--inner"
45
+ />
46
+ </span>
47
+ <span
48
+ class="memori-checkbox--text"
49
+ >
50
+ Check me
51
+ </span>
52
+ </label>
53
+ </div>
54
+ `;
55
+
56
+ exports[`renders Checkbox disabled unchanged 1`] = `
57
+ <div>
58
+ <label
59
+ class="memori-checkbox memori-checkbox--disabled"
60
+ >
61
+ <span
62
+ class="memori-checkbox--input-wrapper"
63
+ >
64
+ <input
65
+ class="memori-checkbox--input"
66
+ disabled=""
67
+ type="checkbox"
68
+ />
69
+ <span
70
+ class="memori-checkbox--inner"
71
+ />
72
+ </span>
73
+ <span
74
+ class="memori-checkbox--text"
75
+ >
76
+ Check me
77
+ </span>
78
+ </label>
79
+ </div>
80
+ `;
81
+
82
+ exports[`renders Checkbox indeterminate unchanged 1`] = `
83
+ <div>
84
+ <label
85
+ class="memori-checkbox memori-checkbox--indeterminate"
86
+ >
87
+ <span
88
+ class="memori-checkbox--input-wrapper"
89
+ >
90
+ <input
91
+ checked=""
92
+ class="memori-checkbox--input"
93
+ type="checkbox"
94
+ />
95
+ <span
96
+ class="memori-checkbox--inner"
97
+ />
98
+ </span>
99
+ <span
100
+ class="memori-checkbox--text"
101
+ >
102
+ Check me
103
+ </span>
104
+ </label>
105
+ </div>
106
+ `;
107
+
108
+ exports[`renders Checkbox unchanged 1`] = `
109
+ <div>
110
+ <label
111
+ class="memori-checkbox"
112
+ >
113
+ <span
114
+ class="memori-checkbox--input-wrapper"
115
+ >
116
+ <input
117
+ class="memori-checkbox--input"
118
+ type="checkbox"
119
+ />
120
+ <span
121
+ class="memori-checkbox--inner"
122
+ />
123
+ </span>
124
+ <span
125
+ class="memori-checkbox--text"
126
+ >
127
+ Check me
128
+ </span>
129
+ </label>
130
+ </div>
131
+ `;
@@ -0,0 +1,2 @@
1
+ import Checkbox from './Checkbox'
2
+ export { Checkbox }
@@ -0,0 +1,44 @@
1
+ /* Confirmation dialog styles */
2
+ .memori-confirm-dialog--backdrop {
3
+ position: fixed;
4
+ z-index: 100;
5
+ background-color: rgb(0 0 0 / 50%);
6
+ inset: 0;
7
+ }
8
+
9
+ .memori-confirm-dialog--container {
10
+ position: fixed;
11
+ z-index: 101;
12
+ display: flex;
13
+ align-items: center;
14
+ justify-content: center;
15
+ padding: 1rem;
16
+ inset: 0;
17
+ }
18
+
19
+ .memori-confirm-dialog--panel {
20
+ width: 100%;
21
+ max-width: 28rem;
22
+ padding: 1.5rem;
23
+ border-radius: 0.5rem;
24
+ background-color: white;
25
+ box-shadow:
26
+ 0 20px 25px -5px rgb(0 0 0 / 10%),
27
+ 0 10px 10px -5px rgb(0 0 0 / 4%);
28
+ }
29
+
30
+ .memori-confirm-dialog--title {
31
+ margin-bottom: 0.75rem;
32
+ font-size: 1.25rem;
33
+ font-weight: 600;
34
+ }
35
+
36
+ .memori-confirm-dialog--message {
37
+ margin-bottom: 1.5rem;
38
+ }
39
+
40
+ .memori-confirm-dialog--actions {
41
+ display: flex;
42
+ justify-content: flex-end;
43
+ gap: 0.5rem;
44
+ }
@@ -0,0 +1,235 @@
1
+ import React from 'react'
2
+ import type { Meta, StoryObj } from '@storybook/react'
3
+ import ConfirmDialog, { type Props } from './ConfirmDialog'
4
+ import Button from '../Button/Button'
5
+
6
+ const meta = {
7
+ title: 'UI/ConfirmDialog',
8
+ component: ConfirmDialog,
9
+ tags: ['autodocs'],
10
+ argTypes: {
11
+ isOpen: {
12
+ control: {
13
+ type: 'boolean',
14
+ },
15
+ },
16
+ title: {
17
+ control: {
18
+ type: 'text',
19
+ },
20
+ },
21
+ message: {
22
+ control: {
23
+ type: 'text',
24
+ },
25
+ },
26
+ confirmText: {
27
+ control: {
28
+ type: 'text',
29
+ },
30
+ },
31
+ cancelText: {
32
+ control: {
33
+ type: 'text',
34
+ },
35
+ },
36
+ },
37
+ parameters: {
38
+ controls: { expanded: true },
39
+ },
40
+ } satisfies Meta<typeof ConfirmDialog>
41
+
42
+ export default meta
43
+ type Story = StoryObj<typeof meta>
44
+
45
+ export const Default: Story = {
46
+ args: {
47
+ isOpen: false,
48
+ onClose: () => {},
49
+ onConfirm: () => {},
50
+ title: 'Confirm Action',
51
+ message: 'Are you sure you want to proceed with this action?',
52
+ confirmText: 'Confirm',
53
+ cancelText: 'Cancel',
54
+ },
55
+ }
56
+
57
+ export const Open: Story = {
58
+ args: {
59
+ isOpen: true,
60
+ onClose: () => {},
61
+ onConfirm: () => {},
62
+ title: 'Confirm Action',
63
+ message: 'Are you sure you want to proceed with this action?',
64
+ confirmText: 'Confirm',
65
+ cancelText: 'Cancel',
66
+ },
67
+ }
68
+
69
+ export const WithCustomTitle: Story = {
70
+ args: {
71
+ isOpen: true,
72
+ onClose: () => {},
73
+ onConfirm: () => {},
74
+ title: 'Delete Item',
75
+ message: 'Are you sure you want to proceed with this action?',
76
+ confirmText: 'Confirm',
77
+ cancelText: 'Cancel',
78
+ },
79
+ }
80
+
81
+ export const WithCustomMessage: Story = {
82
+ args: {
83
+ isOpen: true,
84
+ onClose: () => {},
85
+ onConfirm: () => {},
86
+ title: 'Confirm Action',
87
+ message:
88
+ 'This action cannot be undone. All associated data will be permanently deleted from the system.',
89
+ confirmText: 'Confirm',
90
+ cancelText: 'Cancel',
91
+ },
92
+ }
93
+
94
+ export const WithCustomButtonText: Story = {
95
+ args: {
96
+ isOpen: true,
97
+ onClose: () => {},
98
+ onConfirm: () => {},
99
+ title: 'Delete Item',
100
+ message:
101
+ 'Are you sure you want to delete this item? This action cannot be undone.',
102
+ confirmText: 'Yes, Delete',
103
+ cancelText: 'No, Keep It',
104
+ },
105
+ }
106
+
107
+ const DeleteTemplate = (args: Props) => {
108
+ const [isOpen, setIsOpen] = React.useState(false)
109
+ const [isDeleted, setIsDeleted] = React.useState(false)
110
+
111
+ const handleConfirm = () => {
112
+ setIsDeleted(true)
113
+ setIsOpen(false)
114
+ console.log('Item deleted!')
115
+ }
116
+
117
+ return (
118
+ <>
119
+ {isDeleted ? (
120
+ <div
121
+ style={{
122
+ padding: '12px',
123
+ background: '#f8d7da',
124
+ color: '#721c24',
125
+ borderRadius: '4px',
126
+ marginBottom: '20px',
127
+ }}
128
+ >
129
+ Item has been deleted successfully!
130
+ </div>
131
+ ) : (
132
+ <Button onClick={() => setIsOpen(true)}>Delete Item</Button>
133
+ )}
134
+
135
+ <ConfirmDialog
136
+ {...args}
137
+ isOpen={isOpen}
138
+ onClose={() => setIsOpen(false)}
139
+ onConfirm={handleConfirm}
140
+ />
141
+ </>
142
+ )
143
+ }
144
+
145
+ export const DeleteConfirmation: Story = {
146
+ args: {
147
+ isOpen: true,
148
+ onClose: () => {},
149
+ onConfirm: () => {},
150
+ title: 'Delete Item',
151
+ message:
152
+ 'Are you sure you want to delete this item? This action cannot be undone.',
153
+ confirmText: 'Delete',
154
+ cancelText: 'Cancel',
155
+ },
156
+ render: args => <DeleteTemplate {...args} />,
157
+ }
158
+
159
+ const SaveTemplate = (args: Props) => {
160
+ const [isOpen, setIsOpen] = React.useState(false)
161
+ const [navigatedAway, setNavigatedAway] = React.useState(false)
162
+
163
+ const handleTryNavigate = () => {
164
+ setIsOpen(true)
165
+ }
166
+
167
+ const handleConfirm = () => {
168
+ setNavigatedAway(true)
169
+ setIsOpen(false)
170
+ console.log('Navigated without saving!')
171
+ }
172
+
173
+ return (
174
+ <>
175
+ {navigatedAway ? (
176
+ <div
177
+ style={{
178
+ padding: '12px',
179
+ background: '#d4edda',
180
+ color: '#155724',
181
+ borderRadius: '4px',
182
+ marginBottom: '20px',
183
+ }}
184
+ >
185
+ Navigated away without saving changes.
186
+ </div>
187
+ ) : (
188
+ <div>
189
+ <div
190
+ style={{
191
+ padding: '20px',
192
+ border: '1px solid #ddd',
193
+ borderRadius: '4px',
194
+ marginBottom: '20px',
195
+ }}
196
+ >
197
+ <h3>Unsaved Form</h3>
198
+ <p>This is a form with unsaved changes.</p>
199
+ <input
200
+ type="text"
201
+ placeholder="Your name"
202
+ style={{ padding: '8px', marginBottom: '10px', width: '100%' }}
203
+ />
204
+ <textarea
205
+ placeholder="Your message"
206
+ style={{ padding: '8px', width: '100%', height: '100px' }}
207
+ />
208
+ </div>
209
+ <Button onClick={handleTryNavigate}>Navigate Away</Button>
210
+ </div>
211
+ )}
212
+
213
+ <ConfirmDialog
214
+ {...args}
215
+ isOpen={isOpen}
216
+ onClose={() => setIsOpen(false)}
217
+ onConfirm={handleConfirm}
218
+ />
219
+ </>
220
+ )
221
+ }
222
+
223
+ export const UnsavedChanges: Story = {
224
+ args: {
225
+ isOpen: true,
226
+ onClose: () => {},
227
+ onConfirm: () => {},
228
+ title: 'Unsaved Changes',
229
+ message:
230
+ 'You have unsaved changes. Are you sure you want to leave without saving?',
231
+ confirmText: 'Leave',
232
+ cancelText: 'Stay',
233
+ },
234
+ render: args => <SaveTemplate {...args} />,
235
+ }
@@ -0,0 +1,129 @@
1
+ import React from 'react'
2
+ import { expect, it, vi } from 'vitest'
3
+ import { render, screen, fireEvent } from '@testing-library/react'
4
+ import ConfirmDialog from './ConfirmDialog'
5
+
6
+ it('renders ConfirmDialog unchanged', () => {
7
+ const { container } = render(
8
+ <ConfirmDialog
9
+ isOpen={false}
10
+ onClose={vi.fn()}
11
+ onConfirm={vi.fn()}
12
+ title="Test Title"
13
+ message="Test Message"
14
+ confirmText="Confirm"
15
+ cancelText="Cancel"
16
+ />,
17
+ )
18
+ expect(container).toMatchSnapshot()
19
+ })
20
+
21
+ it('renders ConfirmDialog open unchanged', () => {
22
+ const { container } = render(
23
+ <ConfirmDialog
24
+ isOpen={true}
25
+ onClose={vi.fn()}
26
+ onConfirm={vi.fn()}
27
+ title="Test Title"
28
+ message="Test Message"
29
+ confirmText="Confirm"
30
+ cancelText="Cancel"
31
+ />,
32
+ )
33
+ expect(container).toMatchSnapshot()
34
+ })
35
+
36
+ it('renders ConfirmDialog with custom title unchanged', () => {
37
+ const { container } = render(
38
+ <ConfirmDialog
39
+ isOpen={true}
40
+ onClose={vi.fn()}
41
+ onConfirm={vi.fn()}
42
+ title="Custom Title"
43
+ message="Test Message"
44
+ confirmText="Confirm"
45
+ cancelText="Cancel"
46
+ />,
47
+ )
48
+ expect(container).toMatchSnapshot()
49
+ })
50
+
51
+ it('renders ConfirmDialog with custom message unchanged', () => {
52
+ const { container } = render(
53
+ <ConfirmDialog
54
+ isOpen={true}
55
+ onClose={vi.fn()}
56
+ onConfirm={vi.fn()}
57
+ title="Test Title"
58
+ message="Custom confirmation message for testing purposes"
59
+ confirmText="Confirm"
60
+ cancelText="Cancel"
61
+ />,
62
+ )
63
+ expect(container).toMatchSnapshot()
64
+ })
65
+
66
+ it('renders ConfirmDialog with custom button text unchanged', () => {
67
+ const { container } = render(
68
+ <ConfirmDialog
69
+ isOpen={true}
70
+ onClose={vi.fn()}
71
+ onConfirm={vi.fn()}
72
+ title="Test Title"
73
+ message="Test Message"
74
+ confirmText="Yes, proceed"
75
+ cancelText="No, go back"
76
+ />,
77
+ )
78
+ expect(container).toMatchSnapshot()
79
+ })
80
+
81
+ it('calls onClose when cancel button is clicked', () => {
82
+ const onCloseMock = vi.fn()
83
+ render(
84
+ <ConfirmDialog
85
+ isOpen={true}
86
+ onClose={onCloseMock}
87
+ onConfirm={vi.fn()}
88
+ title="Test Title"
89
+ message="Test Message"
90
+ confirmText="Confirm"
91
+ cancelText="Cancel"
92
+ />,
93
+ )
94
+
95
+ // Get all Cancel buttons and click the last one (most recently rendered)
96
+ const cancelButtons = screen.getAllByText('Cancel')
97
+ const lastCancelButton = cancelButtons[cancelButtons.length - 1]
98
+ if (lastCancelButton) {
99
+ fireEvent.click(lastCancelButton)
100
+ expect(onCloseMock).toHaveBeenCalledTimes(1)
101
+ } else {
102
+ throw new Error('Cancel button not found')
103
+ }
104
+ })
105
+
106
+ it('calls onConfirm when confirm button is clicked', () => {
107
+ const onConfirmMock = vi.fn()
108
+ render(
109
+ <ConfirmDialog
110
+ isOpen={true}
111
+ onClose={vi.fn()}
112
+ onConfirm={onConfirmMock}
113
+ title="Test Title"
114
+ message="Test Message"
115
+ confirmText="Confirm"
116
+ cancelText="Cancel"
117
+ />,
118
+ )
119
+
120
+ // Get all Confirm buttons and click the last one (most recently rendered)
121
+ const confirmButtons = screen.getAllByText('Confirm')
122
+ const lastConfirmButton = confirmButtons[confirmButtons.length - 1]
123
+ if (lastConfirmButton) {
124
+ fireEvent.click(lastConfirmButton)
125
+ expect(onConfirmMock).toHaveBeenCalledTimes(1)
126
+ } else {
127
+ throw new Error('Confirm button not found')
128
+ }
129
+ })
@@ -0,0 +1,73 @@
1
+ import React from 'react'
2
+ import { Dialog, Transition } from '@headlessui/react'
3
+ import Button from '../Button/Button'
4
+
5
+ import './ConfirmDialog.css'
6
+
7
+ export interface Props {
8
+ isOpen: boolean
9
+ onClose: () => void
10
+ onConfirm: () => void
11
+ title: string
12
+ message: string
13
+ confirmText: string
14
+ cancelText: string
15
+ }
16
+
17
+ // Custom confirm dialog component
18
+ const ConfirmDialog: React.FC<Props> = ({
19
+ isOpen,
20
+ onClose,
21
+ onConfirm,
22
+ title,
23
+ message,
24
+ confirmText,
25
+ cancelText,
26
+ }) => {
27
+ return (
28
+ <Transition
29
+ appear
30
+ show={isOpen}
31
+ as={React.Fragment}
32
+ >
33
+ <Dialog
34
+ as="div"
35
+ className="memori-confirm-dialog"
36
+ onClose={onClose}
37
+ >
38
+ <div className="memori-confirm-dialog--backdrop" />
39
+ <div className="memori-confirm-dialog--container">
40
+ <Transition.Child
41
+ as={React.Fragment}
42
+ enter="ease-out duration-300"
43
+ enterFrom="opacity-0 scale-95"
44
+ enterTo="opacity-100 scale-100"
45
+ leave="ease-in duration-200"
46
+ leaveFrom="opacity-100 scale-100"
47
+ leaveTo="opacity-0 scale-95"
48
+ >
49
+ <Dialog.Panel className="memori-confirm-dialog--panel">
50
+ <Dialog.Title className="memori-confirm-dialog--title">
51
+ {title}
52
+ </Dialog.Title>
53
+ <Dialog.Description className="memori-confirm-dialog--message">
54
+ {message}
55
+ </Dialog.Description>
56
+ <div className="memori-confirm-dialog--actions">
57
+ <Button onClick={onClose}>{cancelText}</Button>
58
+ <Button
59
+ primary
60
+ onClick={onConfirm}
61
+ >
62
+ {confirmText}
63
+ </Button>
64
+ </div>
65
+ </Dialog.Panel>
66
+ </Transition.Child>
67
+ </div>
68
+ </Dialog>
69
+ </Transition>
70
+ )
71
+ }
72
+
73
+ export default ConfirmDialog
@@ -0,0 +1,11 @@
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
+
3
+ exports[`renders ConfirmDialog open unchanged 1`] = `<div />`;
4
+
5
+ exports[`renders ConfirmDialog unchanged 1`] = `<div />`;
6
+
7
+ exports[`renders ConfirmDialog with custom button text unchanged 1`] = `<div />`;
8
+
9
+ exports[`renders ConfirmDialog with custom message unchanged 1`] = `<div />`;
10
+
11
+ exports[`renders ConfirmDialog with custom title unchanged 1`] = `<div />`;
@@ -0,0 +1,2 @@
1
+ import ConfirmDialog from './ConfirmDialog'
2
+ export { ConfirmDialog }
@@ -0,0 +1,66 @@
1
+ details.memori--details {
2
+ display: block;
3
+ margin-top: 0.5rem;
4
+ margin-bottom: 1.5rem;
5
+ }
6
+
7
+ details.memori--details + details.memori--details {
8
+ margin-top: 0;
9
+ }
10
+
11
+ details.memori--details summary {
12
+ cursor: pointer;
13
+ font-size: 1.15rem;
14
+ line-height: 1;
15
+ list-style-type: none;
16
+ transition: color 0.2s ease-in-out;
17
+ }
18
+
19
+ details.memori--details summary::-webkit-details-marker {
20
+ display: none;
21
+ }
22
+
23
+ details.memori--details summary::marker {
24
+ display: none;
25
+ }
26
+
27
+ details.memori--details summary::-moz-list-bullet {
28
+ list-style-type: none;
29
+ }
30
+
31
+ details.memori--details summary::after {
32
+ display: block;
33
+ width: 1rem;
34
+ height: 1rem;
35
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(162, 175, 185)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
36
+ background-position: right center;
37
+ background-repeat: no-repeat;
38
+ background-size: 1rem auto;
39
+ content: '';
40
+ float: right;
41
+ margin-inline-start: 1.5rem;
42
+ transform: rotate(-90deg);
43
+ transition: transform 0.2s ease-in-out;
44
+ }
45
+
46
+ details.memori--details summary:focus {
47
+ outline: none;
48
+ }
49
+
50
+ details.memori--details summary:focus-visible {
51
+ color: var(--memori-primary);
52
+ outline: 1px solid var(--memori-primary);
53
+ outline-offset: 1.5rem;
54
+ }
55
+
56
+ details.memori--details[open] > summary {
57
+ margin-bottom: 1rem;
58
+ }
59
+
60
+ details.memori--details[open] > summary:not(:focus) {
61
+ color: var(--memori-primary);
62
+ }
63
+
64
+ details.memori--details[open] > summary::after {
65
+ transform: rotate(0deg);
66
+ }