@myelmut/design-system 0.1.47 → 0.1.49

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 (313) hide show
  1. package/package.json +3 -2
  2. package/src/assets/fonts/PPMori-Regular.woff2 +0 -0
  3. package/src/assets/fonts/PPMori-RegularItalic.woff2 +0 -0
  4. package/src/assets/fonts/PPMori-SemiBold.woff2 +0 -0
  5. package/src/assets/fonts/PPPangaia-Medium.woff2 +0 -0
  6. package/src/assets/fonts/PPPangaia-MediumItalic.woff2 +0 -0
  7. package/src/assets/fonts/PPPangaia-Ultralight.woff2 +0 -0
  8. package/src/assets/illustrations/balls-light.webp +0 -0
  9. package/src/assets/illustrations/balls.webp +0 -0
  10. package/src/assets/illustrations/basket-light.webp +0 -0
  11. package/src/assets/illustrations/basket.webp +0 -0
  12. package/src/assets/illustrations/bowl-2-light.webp +0 -0
  13. package/src/assets/illustrations/bowl-2.webp +0 -0
  14. package/src/assets/illustrations/bowl-light.webp +0 -0
  15. package/src/assets/illustrations/bowl.webp +0 -0
  16. package/src/assets/illustrations/box-2-light.webp +0 -0
  17. package/src/assets/illustrations/box-2.webp +0 -0
  18. package/src/assets/illustrations/box-light.webp +0 -0
  19. package/src/assets/illustrations/box.webp +0 -0
  20. package/src/assets/illustrations/calendar-light.webp +0 -0
  21. package/src/assets/illustrations/calendar.webp +0 -0
  22. package/src/assets/illustrations/can-light.webp +0 -0
  23. package/src/assets/illustrations/can.webp +0 -0
  24. package/src/assets/illustrations/carrot-light.webp +0 -0
  25. package/src/assets/illustrations/carrot.webp +0 -0
  26. package/src/assets/illustrations/cat-light.webp +0 -0
  27. package/src/assets/illustrations/cat.webp +0 -0
  28. package/src/assets/illustrations/check-rounded.webp +0 -0
  29. package/src/assets/illustrations/chicken-light.webp +0 -0
  30. package/src/assets/illustrations/chicken.webp +0 -0
  31. package/src/assets/illustrations/cross-rounded.webp +0 -0
  32. package/src/assets/illustrations/crown-light.webp +0 -0
  33. package/src/assets/illustrations/crown.webp +0 -0
  34. package/src/assets/illustrations/dog-light.webp +0 -0
  35. package/src/assets/illustrations/dog.webp +0 -0
  36. package/src/assets/illustrations/face-light.webp +0 -0
  37. package/src/assets/illustrations/face.webp +0 -0
  38. package/src/assets/illustrations/food-bag-light.webp +0 -0
  39. package/src/assets/illustrations/food-bag.webp +0 -0
  40. package/src/assets/illustrations/france-light.webp +0 -0
  41. package/src/assets/illustrations/france.webp +0 -0
  42. package/src/assets/illustrations/fridge-light.webp +0 -0
  43. package/src/assets/illustrations/fridge.webp +0 -0
  44. package/src/assets/illustrations/glasses-light.webp +0 -0
  45. package/src/assets/illustrations/glasses.webp +0 -0
  46. package/src/assets/illustrations/half-label-light.webp +0 -0
  47. package/src/assets/illustrations/half-label.webp +0 -0
  48. package/src/assets/illustrations/kitten-light.webp +0 -0
  49. package/src/assets/illustrations/kitten.webp +0 -0
  50. package/src/assets/illustrations/label-light.webp +0 -0
  51. package/src/assets/illustrations/label.webp +0 -0
  52. package/src/assets/illustrations/leaf-light.webp +0 -0
  53. package/src/assets/illustrations/leaf.webp +0 -0
  54. package/src/assets/illustrations/liquid-light.webp +0 -0
  55. package/src/assets/illustrations/liquid.webp +0 -0
  56. package/src/assets/illustrations/magnifying-glass-light.webp +0 -0
  57. package/src/assets/illustrations/magnifying-glass.webp +0 -0
  58. package/src/assets/illustrations/meat-light.webp +0 -0
  59. package/src/assets/illustrations/meat.webp +0 -0
  60. package/src/assets/illustrations/molecule-light.webp +0 -0
  61. package/src/assets/illustrations/molecule.webp +0 -0
  62. package/src/assets/illustrations/paws-light.webp +0 -0
  63. package/src/assets/illustrations/paws.webp +0 -0
  64. package/src/assets/illustrations/plate-light.webp +0 -0
  65. package/src/assets/illustrations/plate.webp +0 -0
  66. package/src/assets/illustrations/pot-big-2-light.webp +0 -0
  67. package/src/assets/illustrations/pot-big-2.webp +0 -0
  68. package/src/assets/illustrations/pot-big-light.webp +0 -0
  69. package/src/assets/illustrations/pot-big.webp +0 -0
  70. package/src/assets/illustrations/pot-light.webp +0 -0
  71. package/src/assets/illustrations/pot.webp +0 -0
  72. package/src/assets/illustrations/puppy-light.webp +0 -0
  73. package/src/assets/illustrations/puppy.webp +0 -0
  74. package/src/assets/illustrations/quantity-light.webp +0 -0
  75. package/src/assets/illustrations/quantity.webp +0 -0
  76. package/src/assets/illustrations/sausage-light.webp +0 -0
  77. package/src/assets/illustrations/sausage.webp +0 -0
  78. package/src/assets/illustrations/sausages-light.webp +0 -0
  79. package/src/assets/illustrations/sausages.webp +0 -0
  80. package/src/assets/illustrations/skeleton-light.webp +0 -0
  81. package/src/assets/illustrations/skeleton.webp +0 -0
  82. package/src/assets/illustrations/sofa-light.webp +0 -0
  83. package/src/assets/illustrations/sofa.webp +0 -0
  84. package/src/assets/illustrations/sport-light.webp +0 -0
  85. package/src/assets/illustrations/sport.webp +0 -0
  86. package/src/assets/illustrations/steak-light.webp +0 -0
  87. package/src/assets/illustrations/steak.webp +0 -0
  88. package/src/assets/illustrations/truck-light.webp +0 -0
  89. package/src/assets/illustrations/truck.webp +0 -0
  90. package/src/assets/illustrations/warning-light.webp +0 -0
  91. package/src/assets/illustrations/warning.webp +0 -0
  92. package/src/assets/images/cat.webp +0 -0
  93. package/src/assets/images/dog.webp +0 -0
  94. package/src/assets/images/frequency/food-in-fridge.webp +0 -0
  95. package/src/assets/images/ingredients/beef.webp +0 -0
  96. package/src/assets/images/ingredients/beer-yeast.webp +0 -0
  97. package/src/assets/images/ingredients/calcium.webp +0 -0
  98. package/src/assets/images/ingredients/carrot.webp +0 -0
  99. package/src/assets/images/ingredients/chicken.webp +0 -0
  100. package/src/assets/images/ingredients/courgette.webp +0 -0
  101. package/src/assets/images/ingredients/dry-apple.webp +0 -0
  102. package/src/assets/images/ingredients/dry-carrot.webp +0 -0
  103. package/src/assets/images/ingredients/duck.webp +0 -0
  104. package/src/assets/images/ingredients/fish.webp +0 -0
  105. package/src/assets/images/ingredients/liquid.webp +0 -0
  106. package/src/assets/images/ingredients/oil.webp +0 -0
  107. package/src/assets/images/ingredients/pork.webp +0 -0
  108. package/src/assets/images/ingredients/potato.webp +0 -0
  109. package/src/assets/images/ingredients/quinoa.webp +0 -0
  110. package/src/assets/images/ingredients/rice.webp +0 -0
  111. package/src/assets/images/ingredients/seaweed.webp +0 -0
  112. package/src/assets/images/ingredients/turkey.webp +0 -0
  113. package/src/assets/images/ingredients/vitamins.webp +0 -0
  114. package/src/assets/images/tips/claudine-head.webp +0 -0
  115. package/src/assets/images/tips/claudine-tips-head-mobile.webp +0 -0
  116. package/src/assets/images/tips/claudine-tips-head-mobile@2x.webp +0 -0
  117. package/src/assets/images/tips/claudine-tips-head.webp +0 -0
  118. package/src/assets/images/tips/claudine-tips-head@2x.webp +0 -0
  119. package/src/assets/images/tips/claudine-tips-mobile.webp +0 -0
  120. package/src/assets/images/tips/claudine-tips-mobile@2x.webp +0 -0
  121. package/src/assets/images/tips/claudine-tips.webp +0 -0
  122. package/src/assets/images/tips/claudine-tips@2x.webp +0 -0
  123. package/src/assets/images/tips/payment-mobile.webp +0 -0
  124. package/src/assets/images/tips/payment-mobile@2x.webp +0 -0
  125. package/src/assets/images/tips/payment.webp +0 -0
  126. package/src/assets/images/tips/payment@2x.webp +0 -0
  127. package/src/assets/images/trash/dog-product-mobile.webp +0 -0
  128. package/src/assets/images/trash/dog-product.webp +0 -0
  129. package/src/assets/images/trash/full-cat.png +0 -0
  130. package/src/assets/images/trash/testimonial-1-mobile.webp +0 -0
  131. package/src/assets/images/trash/testimonial-1-mobile@2x.webp +0 -0
  132. package/src/assets/images/trash/testimonial-1.webp +0 -0
  133. package/src/assets/images/trash/testimonial-1@2x.webp +0 -0
  134. package/src/components/Accordions/FAQ/FaqItem.stories.tsx +61 -0
  135. package/src/components/Accordions/FAQ/FaqItem.tsx +55 -0
  136. package/src/components/Accordions/Ingredient/Ingredient.stories.tsx +38 -0
  137. package/src/components/Accordions/Ingredient/Ingredient.tsx +93 -0
  138. package/src/components/Accordions/index.tsx +4 -0
  139. package/src/components/Base/Banner/Banner.stories.tsx +33 -0
  140. package/src/components/Base/Banner/Banner.tsx +23 -0
  141. package/src/components/Base/Emblem/Emblem.stories.tsx +40 -0
  142. package/src/components/Base/Emblem/Emblem.tsx +22 -0
  143. package/src/components/Base/Logo/Logo.stories.tsx +46 -0
  144. package/src/components/Base/Logo/Logo.tsx +34 -0
  145. package/src/components/Base/ResponsiveImage/ResponsiveImage.stories.tsx +78 -0
  146. package/src/components/Base/ResponsiveImage/ResponsiveImage.tsx +56 -0
  147. package/src/components/Base/Text/Text.stories.tsx +115 -0
  148. package/src/components/Base/Text/Text.tsx +60 -0
  149. package/src/components/Base/Title/Title.stories.tsx +145 -0
  150. package/src/components/Base/Title/Title.tsx +77 -0
  151. package/src/components/Base/VideoPlayer/VideoPlayer.stories.tsx +60 -0
  152. package/src/components/Base/VideoPlayer/VideoPlayer.tsx +78 -0
  153. package/src/components/Base/index.tsx +9 -0
  154. package/src/components/Buttons/Button/Button.stories.tsx +158 -0
  155. package/src/components/Buttons/Button/Button.tsx +68 -0
  156. package/src/components/Buttons/CardButton/CardButton.stories.tsx +47 -0
  157. package/src/components/Buttons/CardButton/CardButton.tsx +25 -0
  158. package/src/components/Buttons/ClearButton/ClearButton.stories.tsx +26 -0
  159. package/src/components/Buttons/ClearButton/ClearButton.tsx +18 -0
  160. package/src/components/Buttons/FAQButton/FAQButton.stories.tsx +33 -0
  161. package/src/components/Buttons/FAQButton/FAQButton.tsx +27 -0
  162. package/src/components/Buttons/IllustratedCardButton/IllustratedCardButton.stories.tsx +71 -0
  163. package/src/components/Buttons/IllustratedCardButton/IllustratedCardButton.tsx +45 -0
  164. package/src/components/Buttons/SimpleIllustratedCardButton/SimpleIllustratedCardButton.stories.tsx +74 -0
  165. package/src/components/Buttons/SimpleIllustratedCardButton/SimpleIllustratedCardButton.tsx +43 -0
  166. package/src/components/Buttons/SocialButton/SocialButton.stories.tsx +56 -0
  167. package/src/components/Buttons/SocialButton/SocialButton.tsx +28 -0
  168. package/src/components/Buttons/Toggle/Toggle.tsx +64 -0
  169. package/src/components/Buttons/Toggle/Toogle.stories.tsx +66 -0
  170. package/src/components/Buttons/index.ts +10 -0
  171. package/src/components/Cards/CTACard/CTACard.stories.tsx +83 -0
  172. package/src/components/Cards/CTACard/CTACard.tsx +47 -0
  173. package/src/components/Cards/FeatureCard/FeatureCard.stories.tsx +96 -0
  174. package/src/components/Cards/FeatureCard/FeatureCard.tsx +50 -0
  175. package/src/components/Cards/FeatureIllustration/FeatureIllustration.stories.tsx +96 -0
  176. package/src/components/Cards/FeatureIllustration/FeatureIllustration.tsx +56 -0
  177. package/src/components/Cards/FeatureIllustration/index.ts +2 -0
  178. package/src/components/Cards/FoodCard/FoodCard.stories.tsx +43 -0
  179. package/src/components/Cards/FoodCard/FoodCard.tsx +37 -0
  180. package/src/components/Cards/FrequencySelectorCard/FrequencySelectorCard.stories.tsx +140 -0
  181. package/src/components/Cards/FrequencySelectorCard/FrequencySelectorCard.tsx +90 -0
  182. package/src/components/Cards/FrequencySelectorCard/index.ts +2 -0
  183. package/src/components/Cards/IllustratedCard/IllustratedCard.stories.tsx +54 -0
  184. package/src/components/Cards/IllustratedCard/IllustratedCard.tsx +44 -0
  185. package/src/components/Cards/PaymentCard/PaymentCard.stories.tsx +35 -0
  186. package/src/components/Cards/PaymentCard/PaymentCard.tsx +31 -0
  187. package/src/components/Cards/PlanCard/PlanCard.stories.tsx +140 -0
  188. package/src/components/Cards/PlanCard/PlanCard.tsx +119 -0
  189. package/src/components/Cards/Polaroid/Polaroid.stories.tsx +118 -0
  190. package/src/components/Cards/Polaroid/Polaroid.tsx +66 -0
  191. package/src/components/Cards/RecetteCard/RecetteCard.stories.tsx +86 -0
  192. package/src/components/Cards/RecetteCard/RecetteCard.tsx +47 -0
  193. package/src/components/Cards/StatCard/StatCard.stories.tsx +69 -0
  194. package/src/components/Cards/StatCard/StatCard.tsx +45 -0
  195. package/src/components/Cards/Testimonial/Testimonial.stories.tsx +65 -0
  196. package/src/components/Cards/Testimonial/Testimonial.tsx +62 -0
  197. package/src/components/Cards/TestimonialSlider/TestimonialSlider.stories.ts +53 -0
  198. package/src/components/Cards/TestimonialSlider/TestimonialSlider.tsx +50 -0
  199. package/src/components/Cards/Tips/Tips.stories.tsx +32 -0
  200. package/src/components/Cards/Tips/Tips.tsx +40 -0
  201. package/src/components/Cards/TransitionCard/TransitionCard.stories.tsx +50 -0
  202. package/src/components/Cards/TransitionCard/TransitionCard.tsx +66 -0
  203. package/src/components/Cards/UpCard/UpCard.stories.tsx +94 -0
  204. package/src/components/Cards/UpCard/UpCard.tsx +50 -0
  205. package/src/components/Cards/WizardTips/WizardTips.stories.tsx +48 -0
  206. package/src/components/Cards/WizardTips/WizardTips.tsx +33 -0
  207. package/src/components/Cards/index.ts +19 -0
  208. package/src/components/Inputs/ButtonSelect/ButtonSelect.stories.tsx +51 -0
  209. package/src/components/Inputs/ButtonSelect/ButtonSelect.tsx +34 -0
  210. package/src/components/Inputs/Checkbox/Checkbox.stories.tsx +47 -0
  211. package/src/components/Inputs/Checkbox/Checkbox.tsx +35 -0
  212. package/src/components/Inputs/Dropdown/Dropdown.stories.tsx +61 -0
  213. package/src/components/Inputs/Dropdown/Dropdown.tsx +108 -0
  214. package/src/components/Inputs/DropdownMenu/DropdownMenu.stories.tsx +75 -0
  215. package/src/components/Inputs/DropdownMenu/DropdownMenu.tsx +109 -0
  216. package/src/components/Inputs/ErrorMessage/ErrorMessage.stories.tsx +33 -0
  217. package/src/components/Inputs/ErrorMessage/ErrorMessage.tsx +18 -0
  218. package/src/components/Inputs/Filters/Filters.stories.tsx +54 -0
  219. package/src/components/Inputs/Filters/Filters.tsx +75 -0
  220. package/src/components/Inputs/Label/Label.stories.tsx +34 -0
  221. package/src/components/Inputs/Label/Label.tsx +16 -0
  222. package/src/components/Inputs/Newsletter/Newsletter.stories.tsx +67 -0
  223. package/src/components/Inputs/Newsletter/Newsletter.tsx +70 -0
  224. package/src/components/Inputs/QuantityInput/QuantityInput.stories.tsx +54 -0
  225. package/src/components/Inputs/QuantityInput/QuantityInput.tsx +46 -0
  226. package/src/components/Inputs/Tag/Tag.stories.tsx +33 -0
  227. package/src/components/Inputs/Tag/Tag.tsx +19 -0
  228. package/src/components/Inputs/TagSelect/TagSelect.stories.tsx +50 -0
  229. package/src/components/Inputs/TagSelect/TagSelect.tsx +48 -0
  230. package/src/components/Inputs/TextInput/TextInput.stories.tsx +40 -0
  231. package/src/components/Inputs/TextInput/TextInput.tsx +38 -0
  232. package/src/components/Inputs/WizardDropdown/WizardDropdown.stories.tsx +59 -0
  233. package/src/components/Inputs/WizardDropdown/WizardDropdown.tsx +93 -0
  234. package/src/components/Inputs/WizardTextInput/WizardTextInput.stories.tsx +40 -0
  235. package/src/components/Inputs/WizardTextInput/WizardTextInput.tsx +31 -0
  236. package/src/components/Inputs/index.ts +16 -0
  237. package/src/components/Navigation/Footer/Footer.stories.tsx +28 -0
  238. package/src/components/Navigation/Footer/Footer.tsx +130 -0
  239. package/src/components/Navigation/FooterTips/FooterTips.stories.tsx +22 -0
  240. package/src/components/Navigation/FooterTips/FooterTips.tsx +24 -0
  241. package/src/components/Navigation/MobileMenu/MobileMenu.stories.tsx +56 -0
  242. package/src/components/Navigation/MobileMenu/MobileMenu.tsx +45 -0
  243. package/src/components/Navigation/Navbar/Navbar.stories.tsx +128 -0
  244. package/src/components/Navigation/Navbar/Navbar.tsx +66 -0
  245. package/src/components/Navigation/NavbarDesktop/NavbarDesktop.stories.tsx +57 -0
  246. package/src/components/Navigation/NavbarDesktop/NavbarDesktop.tsx +48 -0
  247. package/src/components/Navigation/NavbarMobile/NavbarMobile.stories.tsx +59 -0
  248. package/src/components/Navigation/NavbarMobile/NavbarMobile.tsx +75 -0
  249. package/src/components/Navigation/Stepper/Stepper.stories.tsx +41 -0
  250. package/src/components/Navigation/Stepper/Stepper.tsx +19 -0
  251. package/src/components/Navigation/Tabs/Tabs.stories.tsx +120 -0
  252. package/src/components/Navigation/Tabs/Tabs.tsx +92 -0
  253. package/src/components/Navigation/WizardNavbar/WizardNavbar.stories.tsx +59 -0
  254. package/src/components/Navigation/WizardNavbar/WizardNavbar.tsx +83 -0
  255. package/src/components/Navigation/index.ts +11 -0
  256. package/src/components/SVG/Facebook.svg +3 -0
  257. package/src/components/SVG/Instagram.svg +5 -0
  258. package/src/components/SVG/Linkedin.svg +5 -0
  259. package/src/components/SVG/Tiktok.svg +7 -0
  260. package/src/components/SVG/arrow-plain.svg +3 -0
  261. package/src/components/SVG/arrow.svg +3 -0
  262. package/src/components/SVG/calendar.svg +4 -0
  263. package/src/components/SVG/check-circle.svg +5 -0
  264. package/src/components/SVG/check-rounded.svg +4 -0
  265. package/src/components/SVG/check.svg +3 -0
  266. package/src/components/SVG/cross-rounded.svg +3 -0
  267. package/src/components/SVG/cross.svg +4 -0
  268. package/src/components/SVG/dollar-rounded.svg +6 -0
  269. package/src/components/SVG/double-arrow.svg +3 -0
  270. package/src/components/SVG/filters.svg +8 -0
  271. package/src/components/SVG/hat-cook.svg +4 -0
  272. package/src/components/SVG/home-hero-shape-mobile.svg +3 -0
  273. package/src/components/SVG/home-hero-shape-small.svg +3 -0
  274. package/src/components/SVG/home-hero-shape.svg +3 -0
  275. package/src/components/SVG/index.ts +75 -0
  276. package/src/components/SVG/info.svg +3 -0
  277. package/src/components/SVG/magic-wand.svg +9 -0
  278. package/src/components/SVG/menu.svg +5 -0
  279. package/src/components/SVG/minus.svg +3 -0
  280. package/src/components/SVG/mute.svg +4 -0
  281. package/src/components/SVG/pause.svg +3 -0
  282. package/src/components/SVG/play.svg +3 -0
  283. package/src/components/SVG/plus.svg +4 -0
  284. package/src/components/SVG/polaroid-thread.svg +17 -0
  285. package/src/components/SVG/profil.svg +4 -0
  286. package/src/components/SVG/quote.svg +3 -0
  287. package/src/components/SVG/recipe-bg-shape.svg +3 -0
  288. package/src/components/SVG/star.svg +3 -0
  289. package/src/components/SVG/subtract.svg +3 -0
  290. package/src/components/SVG/trustpilot.svg +14 -0
  291. package/src/components/SVG/unmute.svg +5 -0
  292. package/src/components/index.ts +20 -0
  293. package/src/components/styles/Color/Color.stories.tsx +89 -0
  294. package/src/components/styles/Color/Color.tsx +47 -0
  295. package/src/components/styles/Icon/Icon.stories.tsx +103 -0
  296. package/src/components/styles/Icon/Icon.tsx +6 -0
  297. package/src/components/styles/Illustration/Illustration.stories.tsx +253 -0
  298. package/src/components/styles/Illustration/Illustration.tsx +45 -0
  299. package/src/components/styles/Typography/Typography.stories.tsx +37 -0
  300. package/src/components/styles/Typography/Typography.tsx +19 -0
  301. package/src/helpers/accordions.ts +39 -0
  302. package/src/helpers/clickoutside.ts +31 -0
  303. package/src/helpers/debounce.ts +10 -0
  304. package/src/helpers/index.ts +9 -0
  305. package/src/helpers/intersectionObserver.ts +101 -0
  306. package/src/helpers/keyboardControl.ts +58 -0
  307. package/src/helpers/responsive.ts +29 -0
  308. package/src/helpers/scroll.ts +16 -0
  309. package/src/index.ts +8 -0
  310. package/src/lib/i18n.ts +20 -0
  311. package/src/lib/locales/fr/design.json +42 -0
  312. package/src/styles/globals.css +205 -0
  313. package/src/types/svg.d.ts +8 -0
@@ -0,0 +1,94 @@
1
+ import { Meta, StoryObj } from '@storybook/react-vite';
2
+
3
+ import { UpCard } from './UpCard';
4
+
5
+ const meta = {
6
+ title: 'Components/Cards/UpCard',
7
+ component: UpCard,
8
+ tags: ['autodocs'],
9
+ parameters: {
10
+ layout: 'centered',
11
+ },
12
+ argTypes: {
13
+ title1: {
14
+ control: 'text',
15
+ },
16
+ description1: {
17
+ control: 'text',
18
+ },
19
+ title2: {
20
+ control: 'text',
21
+ },
22
+ description2: {
23
+ control: 'text',
24
+ },
25
+ step: {
26
+ control: 'text',
27
+ description: 'Step on first card',
28
+ },
29
+ illustration: {
30
+ control: 'text',
31
+ description: 'Illustration on second card. Name of the illustration asset',
32
+ },
33
+ align: {
34
+ control: 'select',
35
+ options: ['top', 'bottom'],
36
+ description: 'Align the component',
37
+ },
38
+ className: {
39
+ control: 'text',
40
+ description: 'Additional classes to apply to the component',
41
+ },
42
+ illustrationClassName: {
43
+ control: 'text',
44
+ description: 'Additional classes to apply to the illustration',
45
+ },
46
+ },
47
+ args: {
48
+ title1: 'L’étiquette : plus c’est long, moins c’est bon.',
49
+ description1: 'Butylhydroxyanisole, éthoxyquine, tartrazine E102 et autres termes barbares qui vous assureront une victoire au Scrabble contre votre grand-mère mais qui n’ont rien à faire dans la gamelle de nos poilus.',
50
+ title2: 'Pour quoi faire alors ?',
51
+ description2: 'Tous ces conservateurs, colorants et texturants ont pour but de flatter nos yeux de parents de chiens et de prolonger l’espérance de vie du paquet de croquettes… au détriment de celle du poilu.',
52
+ step: '01',
53
+ illustration: '/illustrations/warning.webp',
54
+ align: 'bottom',
55
+ },
56
+ globals: {
57
+ backgrounds: {
58
+ value: 'light',
59
+ },
60
+ },
61
+ } satisfies Meta<typeof UpCard>;
62
+
63
+ export default meta;
64
+
65
+ type Story = StoryObj<typeof meta>;
66
+
67
+ export const Default: Story = {};
68
+
69
+ export const Large: Story = {
70
+ args: {
71
+ title1: 'Rien ne se perd, tout s’ultra-transforme.',
72
+ description1:
73
+ 'La petfood industrielle utilise pour ses produits ce que l’on appelle des sous-produits de catégorie 3, dont la qualité est très… variable. \n \n Pour masquer leurs faiblesses nutritionnelles et les risques bactériologiques, on les passe à la moulinette d’un traitement thermique extrême à plus de 120°.',
74
+ title2: 'Résultat ?',
75
+ description2: 'Des croquettes uniformes, mais aussi l’apparition de composés indésirables comme l’acrylamide, suspecté d’être cancérigène.',
76
+ step: '02',
77
+ illustration: '/illustrations/molecule.webp',
78
+ illustrationClassName: 'md:!w-26',
79
+ },
80
+ };
81
+
82
+ export const AlignTop: Story = {
83
+ args: {
84
+ title1: 'Du saumon sur l’emballage mais pas dans le paquet.',
85
+ description1: 'Fun fact pas si fun : la réglementation n’impose pas que l’ingrédient mis en avant sur l’emballage soit le plus présent dans la composition. ',
86
+ title2: 'Autrement dit ?',
87
+ description2:
88
+ 'Une croquette qui contient 4 % de saumon et 25 % de porc a le droit de dire qu’elle est au saumon et d’arborer sur son emballage un ours qui dévore un saumon norvégien à même la rivière. Le tout, sans mentionner sur l’emballage que ce saumon a quand même vachement le goût de porc.',
89
+ step: '3',
90
+ illustration: '/illustrations/skeleton.webp',
91
+ align: 'top',
92
+ illustrationClassName: '-rotate-12 md:!w-38',
93
+ },
94
+ };
@@ -0,0 +1,50 @@
1
+ import clsx from 'clsx';
2
+
3
+ import { ParagraphTitle, Text } from '../../../components';
4
+
5
+ export interface UpCardProps {
6
+ title1: string;
7
+ description1: string;
8
+ title2: string;
9
+ description2: string;
10
+ step: string;
11
+ illustration: string;
12
+ align?: 'top' | 'bottom';
13
+ className?: string;
14
+ illustrationClassName?: string;
15
+ }
16
+
17
+ export const UpCard = ({ title1, description1, title2, description2, step, illustration, className, illustrationClassName, align = 'bottom' }: UpCardProps) => {
18
+ return (
19
+ <div className={clsx('flex max-md:flex-col max-md:gap-4', align === 'top' ? 'items-start' : 'md:items-end', className)}>
20
+ <div className="bg-lavender-blue-light text-claret-violet-dark flex w-63 -rotate-2 flex-col gap-4 p-4 max-md:-translate-x-10 md:w-87.5 md:px-11 md:py-8">
21
+ <ParagraphTitle size="heading-xl" className="hidden md:block">
22
+ {step}
23
+ </ParagraphTitle>
24
+ <ParagraphTitle size="heading-md" className="hidden md:block">
25
+ {title1}
26
+ </ParagraphTitle>
27
+ <ParagraphTitle size="heading-lg" className="block max-md:not-italic md:hidden">
28
+ {step}.&nbsp;{title1}
29
+ </ParagraphTitle>
30
+ <Text size="md" className="whitespace-pre-line max-md:not-italic">
31
+ {description1}
32
+ </Text>
33
+ </div>
34
+ <div className={clsx('bg-pink-oyster-light text-claret-violet-dark relative flex w-63.5 -rotate-2 flex-col gap-2 p-6 md:z-1 md:w-85.5 md:-translate-x-8 md:rotate-2 md:px-11 md:py-8', align === 'top' ? 'md:translate-y-26' : 'md:translate-y-18')}>
35
+ <div className={clsx('relative w-11.5 shrink-0 md:w-18', illustrationClassName)}>
36
+ <img src={illustration} alt={title2} className="w-full" />
37
+ </div>
38
+ <ParagraphTitle size="heading-md" className="hidden md:block">
39
+ {title2}
40
+ </ParagraphTitle>
41
+ <ParagraphTitle size="heading-lg" className="block max-md:not-italic md:hidden">
42
+ {step}.&nbsp;{title2}
43
+ </ParagraphTitle>
44
+ <Text size="md" className="whitespace-pre-line max-md:not-italic">
45
+ {description2}
46
+ </Text>
47
+ </div>
48
+ </div>
49
+ );
50
+ };
@@ -0,0 +1,48 @@
1
+ import React, { useState } from 'react';
2
+
3
+ import { Meta, StoryObj } from '@storybook/react-vite';
4
+
5
+ import { WizardTips } from './WizardTips';
6
+
7
+ const meta = {
8
+ title: 'Components/Cards/WizardTips',
9
+ component: WizardTips,
10
+ tags: ['autodocs'],
11
+ parameters: {
12
+ layout: 'centered',
13
+ },
14
+ argTypes: {
15
+ content: { control: 'text', description: 'Content of the wizard tips' },
16
+ className: { control: 'text', description: 'Additional classes' },
17
+ checkbox: { control: 'boolean', description: 'Wether the wizard tips is a checkbox input.' },
18
+ },
19
+ args: {
20
+ content: 'C’est vrai qu’ils sont beaux. Pas plus que le caniche toy marron, mais beau quand même.',
21
+ className: 'w-full',
22
+ },
23
+ globals: {
24
+ backgrounds: {
25
+ value: 'dark',
26
+ },
27
+ },
28
+ } satisfies Meta<typeof WizardTips>;
29
+
30
+ export default meta;
31
+
32
+ type Story = StoryObj<typeof meta>;
33
+
34
+ export const Default: Story = {};
35
+
36
+ export const Checkbox: Story = {
37
+ args: {
38
+ content:
39
+ 'Vous le savez, nous nous devons de préciser que vous pouvez refuser de recevoir les magnifiques mails que je vous écris où je vous parle nutrition, actualités Elmut et le plus important : de moi. \n\n Je le sais, il est proprement inimaginable de refuser la présence de ma jolie bouille dans vos e-mails. Mais sachez que vous pouvez le faire en cochant la case.',
40
+ checkbox: true,
41
+ className: 'w-80 md:w-166',
42
+ },
43
+ render: (arg) => {
44
+ const [checked, setChecked] = useState(false);
45
+
46
+ return <WizardTips {...arg} checked={checked} onChange={(value) => setChecked(value)} />;
47
+ },
48
+ };
@@ -0,0 +1,33 @@
1
+ import clsx from 'clsx';
2
+
3
+ import ClaudineHeadImage from '../../../assets/images/tips/claudine-head.webp';
4
+ import { Checkbox, Text } from '../../../components';
5
+
6
+ export interface WizardTipsProps {
7
+ content: string;
8
+ checkbox?: boolean;
9
+ onChange?: (value: boolean) => void;
10
+ checked?: boolean;
11
+ className?: string;
12
+ }
13
+
14
+ export const WizardTips = ({ content, className, checkbox = false, onChange = () => {}, checked = false }: WizardTipsProps) => {
15
+ return (
16
+ <div className={clsx('flex items-start', className)}>
17
+ <div className="border-beige-light bg-pink-oyster-light z-1 -me-3 h-17 w-17 shrink-0 overflow-hidden rounded-full border-5">
18
+ <img src={ClaudineHeadImage} alt="Claudine" loading="lazy" decoding="async" className="h-full w-full object-cover" />
19
+ </div>
20
+ <div className={clsx('bg-lavender-blue-light rounded-input text-claret-violet-dark p-5', checkbox && 'w-full', !checkbox && 'w-75')}>
21
+ {checkbox ? (
22
+ <Checkbox checked={checked} name="wizard-tips" onChange={onChange} className="items-start gap-3">
23
+ <Text size="legend" variant="span" className="whitespace-pre-line">
24
+ {content}
25
+ </Text>
26
+ </Checkbox>
27
+ ) : (
28
+ <Text size="button">“&nbsp;{content}&nbsp;“</Text>
29
+ )}
30
+ </div>
31
+ </div>
32
+ );
33
+ };
@@ -0,0 +1,19 @@
1
+ import { CTACard } from './CTACard/CTACard';
2
+ import { FeatureCard } from './FeatureCard/FeatureCard';
3
+ import { FeatureIllustration } from './FeatureIllustration/FeatureIllustration';
4
+ import { FoodCard } from './FoodCard/FoodCard';
5
+ import { FrequencySelectorCard } from './FrequencySelectorCard/FrequencySelectorCard';
6
+ import { IllustratedCard } from './IllustratedCard/IllustratedCard';
7
+ import { PaymentCard } from './PaymentCard/PaymentCard';
8
+ import { PlanCard } from './PlanCard/PlanCard';
9
+ import { Polaroid } from './Polaroid/Polaroid';
10
+ import { RecetteCard } from './RecetteCard/RecetteCard';
11
+ import { StatCard } from './StatCard/StatCard';
12
+ import { Testimonial } from './Testimonial/Testimonial';
13
+ import { TestimonialSliderCard } from './TestimonialSlider/TestimonialSlider';
14
+ import { Tips } from './Tips/Tips';
15
+ import { TransitionCard } from './TransitionCard/TransitionCard';
16
+ import { UpCard } from './UpCard/UpCard';
17
+ import { WizardTips } from './WizardTips/WizardTips';
18
+
19
+ export { Tips, WizardTips, Testimonial, StatCard, IllustratedCard, RecetteCard, TransitionCard, PaymentCard, FoodCard, UpCard, Polaroid, TestimonialSliderCard, PlanCard, FeatureCard, FrequencySelectorCard, FeatureIllustration, CTACard };
@@ -0,0 +1,51 @@
1
+ import React, { useState } from 'react';
2
+
3
+ import { Meta, StoryObj } from '@storybook/react-vite';
4
+
5
+ import { ButtonSelect } from './ButtonSelect';
6
+
7
+ const meta = {
8
+ title: 'Components/Inputs/ButtonSelect',
9
+ component: ButtonSelect,
10
+ tags: ['autodocs'],
11
+ parameters: {
12
+ layout: 'centered',
13
+ },
14
+ argTypes: {
15
+ id: { control: 'text', description: 'The id of the button select' },
16
+ hasError: { control: 'boolean', description: 'Whether the button select has an error' },
17
+ error: { control: 'text', description: 'The error message of the button select' },
18
+ options: { control: 'object', description: 'The options of the button select' },
19
+ value: { control: 'text', description: 'The value of the button select' },
20
+ onChange: { action: 'onChange' },
21
+ required: { control: 'boolean', description: 'Whether the button select is required' },
22
+ className: { control: 'text', description: 'Additional class names for the button select' },
23
+ },
24
+ globals: {
25
+ backgrounds: {
26
+ value: 'light',
27
+ },
28
+ },
29
+ } satisfies Meta<typeof ButtonSelect>;
30
+
31
+ export default meta;
32
+
33
+ type Story = StoryObj<typeof meta>;
34
+
35
+ export const Default: Story = {
36
+ args: {
37
+ label: 'Jack la Fripouille est stérilisée ?',
38
+ options: [
39
+ { label: 'oui', value: 'oui' },
40
+ { label: 'non', value: 'non' },
41
+ ],
42
+ value: '',
43
+ onChange: () => {},
44
+ id: 'button-select',
45
+ },
46
+ render: (arg) => {
47
+ const [value, setValue] = useState('');
48
+
49
+ return <ButtonSelect {...arg} value={value} onChange={(value) => setValue(value)} />;
50
+ },
51
+ };
@@ -0,0 +1,34 @@
1
+ import { Button, ErrorMessage, Label } from '../../../components';
2
+
3
+ export interface ButtonSelectProps {
4
+ label?: string;
5
+ options: { label: string; value: string }[];
6
+ value: string;
7
+ required?: boolean;
8
+ onChange: (value: string) => void;
9
+ hasError?: boolean;
10
+ error?: string;
11
+ id: string;
12
+ className?: string;
13
+ }
14
+
15
+ export const ButtonSelect = ({ label = '', id, options, value, onChange, required, hasError = false, error = '', className = '' }: ButtonSelectProps) => {
16
+ const handleChange = (e: React.MouseEvent<HTMLButtonElement>, value: string) => {
17
+ e.preventDefault();
18
+ onChange(value);
19
+ };
20
+
21
+ return (
22
+ <div className={className}>
23
+ {label.length > 0 && <Label label={label} required={required} className="mb-6" id={id} />}
24
+ <div className="flex flex-wrap justify-center gap-4 md:gap-3 lg:justify-start">
25
+ {options.map((option) => (
26
+ <Button type="button" variant={value === option.value ? 'primary' : 'secondary'} size="sm" color="dark" key={option.value} onClick={(e) => handleChange(e, option.value)}>
27
+ {option.label}
28
+ </Button>
29
+ ))}
30
+ </div>
31
+ <ErrorMessage id={`${id}-error`} hasError={hasError} message={error} />
32
+ </div>
33
+ );
34
+ };
@@ -0,0 +1,47 @@
1
+ import { useState } from 'react';
2
+ import React from 'react';
3
+
4
+ import { Meta, StoryObj } from '@storybook/react-vite';
5
+
6
+ import { Checkbox } from './Checkbox';
7
+
8
+ const meta = {
9
+ title: 'Components/Inputs/Checkbox',
10
+ component: Checkbox,
11
+ tags: ['autodocs'],
12
+ parameters: {
13
+ layout: 'centered',
14
+ },
15
+ argTypes: {
16
+ children: { control: 'text', description: 'The label of the checkbox. It is a React node.' },
17
+ checked: { control: 'boolean' },
18
+ onChange: { action: 'onChange' },
19
+ name: { control: 'text', description: 'The name of the checkbox field' },
20
+ className: { control: 'text', description: 'Additional classes to apply to the checkbox' },
21
+ },
22
+ args: {
23
+ name: 'checkbox',
24
+ onChange: () => {},
25
+ },
26
+ globals: {
27
+ backgrounds: {
28
+ value: 'light',
29
+ },
30
+ },
31
+ } satisfies Meta<typeof Checkbox>;
32
+
33
+ export default meta;
34
+
35
+ type Story = StoryObj<typeof meta>;
36
+
37
+ export const Default: Story = {
38
+ args: {
39
+ checked: false,
40
+ onChange: () => {},
41
+ },
42
+ render: (arg) => {
43
+ const [checked, setChecked] = useState(false);
44
+
45
+ return <Checkbox {...arg} checked={checked} onChange={(value) => setChecked(value)} />;
46
+ },
47
+ };
@@ -0,0 +1,35 @@
1
+ 'use client';
2
+
3
+ import { useCallback } from 'react';
4
+
5
+ import clsx from 'clsx';
6
+
7
+ import { CheckIcon } from '../../../components';
8
+ import { onKeyDown } from '../../../helpers';
9
+
10
+ export interface CheckboxProps {
11
+ children?: React.ReactNode;
12
+ checked: boolean;
13
+ name: string;
14
+ onChange: (value: boolean) => void;
15
+ className?: string;
16
+ }
17
+
18
+ export const Checkbox = ({ children, checked, name, onChange, className }: CheckboxProps) => {
19
+ const handleKeyDown = useCallback(
20
+ (e: React.KeyboardEvent<HTMLLabelElement>) => {
21
+ onKeyDown(e, () => onChange(!checked));
22
+ },
23
+ [onChange, checked],
24
+ );
25
+
26
+ return (
27
+ <label tabIndex={0} htmlFor={name} className={clsx('outline-claret-violet-dark flex cursor-pointer items-center gap-2.5 px-2 py-4', className)} onKeyDown={handleKeyDown}>
28
+ <input type="checkbox" className="peer hidden" id={name} checked={checked} onChange={() => onChange(!checked)} />
29
+ <span tabIndex={-1} className="peer-checked:bg-claret-violet-dark border-claret-violet-dark relative flex h-4 w-4 shrink-0 items-center justify-center overflow-hidden rounded-xs border text-white transition-colors duration-300 *:opacity-0 peer-checked:*:opacity-100">
30
+ <CheckIcon className="w-2 transition-opacity duration-300" />
31
+ </span>
32
+ {children}
33
+ </label>
34
+ );
35
+ };
@@ -0,0 +1,61 @@
1
+ import React, { useState } from 'react';
2
+
3
+ import { Meta, StoryObj } from '@storybook/react-vite';
4
+
5
+ import { Dropdown } from './Dropdown';
6
+
7
+ const meta = {
8
+ title: 'Components/Inputs/Dropdown',
9
+ component: Dropdown,
10
+ tags: ['autodocs'],
11
+ parameters: {
12
+ layout: 'centered',
13
+ },
14
+ argTypes: {
15
+ label: { control: 'text' },
16
+ placeholder: { control: 'text' },
17
+ id: { control: 'text' },
18
+ name: { control: 'text' },
19
+ options: { control: 'object' },
20
+ onChange: { action: 'onChange' },
21
+ disabled: { control: 'boolean' },
22
+ value: { control: 'text' },
23
+ hasError: { control: 'boolean' },
24
+ error: { control: 'text' },
25
+ required: { control: 'boolean' },
26
+ searchable: { control: 'boolean' },
27
+ },
28
+ globals: {
29
+ backgrounds: {
30
+ value: 'light',
31
+ },
32
+ },
33
+ } satisfies Meta<typeof Dropdown>;
34
+
35
+ export default meta;
36
+
37
+ type Story = StoryObj<typeof meta>;
38
+
39
+ export const Default: Story = {
40
+ args: {
41
+ label: 'Dropdown',
42
+ placeholder: 'Select an option',
43
+ id: 'dropdown',
44
+ name: 'dropdown',
45
+ options: [
46
+ { value: 'option1', label: 'Option 1' },
47
+ { value: 'option2', label: 'Option 2' },
48
+ { value: 'option3', label: 'Option 3' },
49
+ ],
50
+ className: 'w-80 md:w-100',
51
+ onChange: () => {},
52
+ value: '',
53
+ hasError: false,
54
+ error: '',
55
+ },
56
+ render: (arg) => {
57
+ const [value, setValue] = useState('');
58
+
59
+ return <Dropdown {...arg} onChange={(value) => setValue(value)} value={value} />;
60
+ },
61
+ };
@@ -0,0 +1,108 @@
1
+ 'use client';
2
+
3
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
4
+
5
+ import clsx from 'clsx';
6
+
7
+ import { ArrowIcon, DropdownMenu, ErrorMessage, Label } from '../../../components';
8
+ import { useClickOutside } from '../../../helpers';
9
+
10
+ interface DropdownOption {
11
+ value: string;
12
+ label: string;
13
+ }
14
+
15
+ export interface DropdownProps {
16
+ label?: string;
17
+ placeholder: string;
18
+ id: string;
19
+ name: string;
20
+ options: DropdownOption[];
21
+ className?: string;
22
+ disabled?: boolean;
23
+ onChange: (value: string) => void;
24
+ value: string;
25
+ required?: boolean;
26
+ hasError?: boolean;
27
+ error?: string;
28
+ searchable?: boolean;
29
+ }
30
+
31
+ export const Dropdown = ({ label = '', id, options, placeholder, name, className, error = '', hasError = false, disabled = false, onChange = () => {}, value, required, searchable = false }: DropdownProps) => {
32
+ const [isOpen, setIsOpen] = useState(false);
33
+ const [searchValue, setSearchValue] = useState('');
34
+ const ref = useRef<HTMLDivElement>(null);
35
+ const selectedLabel = useMemo(() => options.find((option) => option.value === value)?.label, [options, value]);
36
+
37
+ const handleBlur = useCallback(() => {
38
+ setIsOpen(false);
39
+ if ((!value || searchValue !== selectedLabel) && searchable) {
40
+ setSearchValue('');
41
+ onChange('');
42
+ }
43
+ }, [value, onChange, selectedLabel, searchValue]);
44
+
45
+ useClickOutside(ref as React.RefObject<HTMLDivElement>, handleBlur);
46
+
47
+ const filteredOptions = useMemo(() => (searchable ? options.filter((option) => option.label.toLowerCase().includes(searchValue.toLowerCase())) : options), [options, searchValue, searchable]);
48
+
49
+ const handleChange = useCallback(
50
+ (selection: string) => {
51
+ onChange(selection);
52
+ setSearchValue(options.find((option) => option.value === selection)?.label || '');
53
+ setIsOpen(false);
54
+ },
55
+ [onChange, selectedLabel],
56
+ );
57
+
58
+ useEffect(() => {
59
+ if (!value && searchable) {
60
+ setSearchValue('');
61
+ }
62
+ }, [value, searchable]);
63
+
64
+ // prettier-ignore
65
+ const containerClasses = clsx(
66
+ 'w-full',
67
+ className,
68
+ );
69
+ const dropdownClasses = clsx(
70
+ 'will-change-height hover:border-claret-violet-dark/40 bg-beige-light rounded-input text-md border-claret-violet-dark absolute relative inset-0 flex h-11 max-h-11 flex-col items-center overflow-hidden border transition-all duration-300',
71
+ isOpen && 'z-30 h-auto max-h-38 items-start bg-white',
72
+ disabled && 'border-claret-violet-dark/40',
73
+ );
74
+
75
+ return (
76
+ <div className={containerClasses}>
77
+ {label.length > 0 && <Label label={label} id={id} required={required} />}
78
+ <div className="relative h-11 w-full" ref={ref}>
79
+ <input type="hidden" name={name} id={id} value={value} />
80
+ <div className={dropdownClasses}>
81
+ {searchable ? (
82
+ <input type="text" name="search" disabled={disabled} onFocus={() => setIsOpen(true)} value={searchValue} placeholder={placeholder} onChange={(e) => setSearchValue(e.target.value)} className="w-full px-3 py-2.5 focus:outline-none" />
83
+ ) : (
84
+ !isOpen && (
85
+ <button
86
+ type="button"
87
+ tabIndex={disabled ? -1 : 0}
88
+ aria-expanded={isOpen}
89
+ aria-haspopup="listbox"
90
+ aria-labelledby={id}
91
+ disabled={disabled}
92
+ onClick={() => setIsOpen(!isOpen)}
93
+ className={clsx('text-md focus-visible:ring-claret-violet-dark w-full cursor-pointer px-3 py-2.5 text-left focus-visible:ring-2 focus-visible:outline-none focus-visible:ring-inset disabled:cursor-not-allowed')}
94
+ >
95
+ <span className={clsx(value && 'hidden', 'opacity-40')}>{disabled ? '-' : placeholder}</span>
96
+ <span className={clsx(value && 'block')}>{selectedLabel}</span>
97
+ </button>
98
+ )
99
+ )}
100
+ <DropdownMenu name={name} options={filteredOptions} value={value} onChange={handleChange} disabled={disabled} isOpen={isOpen} className={clsx('border-0 pe-9.5', isOpen && 'h-full', searchable && 'pt-0')} />
101
+
102
+ <ArrowIcon onClick={() => setIsOpen(!isOpen)} className={clsx('pointer-cursor absolute top-4.5 right-3 z-20 w-3 transition-transform duration-300', isOpen && 'rotate-180', disabled && 'opacity-40')} />
103
+ </div>
104
+ </div>
105
+ <ErrorMessage id={`${id}-error`} hasError={hasError} message={error} />
106
+ </div>
107
+ );
108
+ };
@@ -0,0 +1,75 @@
1
+ import React, { useState } from 'react';
2
+
3
+ import { Meta, StoryObj } from '@storybook/react-vite';
4
+
5
+ import { DropdownMenu } from './DropdownMenu';
6
+
7
+ const meta = {
8
+ title: 'Components/Inputs/DropdownMenu',
9
+ component: DropdownMenu,
10
+ tags: ['autodocs'],
11
+ parameters: {
12
+ layout: 'centered',
13
+ },
14
+ argTypes: {
15
+ isOpen: { control: 'boolean', description: 'Whether the dropdown menu is open' },
16
+ options: { control: 'object', description: 'The options to display in the dropdown menu' },
17
+ name: { control: 'text', description: 'The name of the dropdown menu' },
18
+ value: { control: 'text', description: 'The value of the dropdown menu' },
19
+ onChange: { action: 'onChange', description: 'The function to call when an option is selected' },
20
+ multiple: { control: 'boolean', description: 'Whether the dropdown menu has a multiple select' },
21
+ onChangeMultiple: { action: 'onChangeMultiple', description: 'The function to call when an option is selected multiple' },
22
+ },
23
+ globals: {
24
+ backgrounds: {
25
+ value: 'light',
26
+ },
27
+ },
28
+ } satisfies Meta<typeof DropdownMenu>;
29
+
30
+ export default meta;
31
+
32
+ type Story = StoryObj<typeof meta>;
33
+
34
+ export const Default: Story = {
35
+ args: {
36
+ isOpen: true,
37
+ options: [
38
+ { label: 'Option 1', value: 'option1' },
39
+ { label: 'Option 2', value: 'option2' },
40
+ { label: 'Option 3', value: 'option3' },
41
+ ],
42
+ name: 'menu',
43
+ className: '!w-80',
44
+ onChange: (value) => {
45
+ console.log('onChange', value);
46
+ },
47
+ multiple: false,
48
+ },
49
+ render: (arg) => {
50
+ const [value, setValue] = useState('');
51
+
52
+ return <DropdownMenu {...arg} value={value} onChange={(value) => setValue(value)} />;
53
+ },
54
+ };
55
+
56
+ export const Multiple: Story = {
57
+ args: {
58
+ isOpen: true,
59
+ options: [
60
+ { label: 'Option 1', value: 'option1' },
61
+ { label: 'Option 2', value: 'option2' },
62
+ { label: 'Option 3', value: 'option3' },
63
+ ],
64
+ name: 'menu',
65
+ className: '!w-80',
66
+ onChangeMultiple: () => {},
67
+ multiple: true,
68
+ },
69
+
70
+ render: (arg) => {
71
+ const [values, setValues] = useState<string[]>([]);
72
+
73
+ return <DropdownMenu {...arg} values={values} onChangeMultiple={(values) => setValues(values)} />;
74
+ },
75
+ };