@adobe-commerce/elsie 1.0.0-alpha04071347

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 (340) hide show
  1. package/.elsie.js +21 -0
  2. package/.eslintrc.js +18 -0
  3. package/README.md +52 -0
  4. package/__mocks__/svg.js +11 -0
  5. package/bin/builders/build/index.js +20 -0
  6. package/bin/builders/generate/api/index.js +65 -0
  7. package/bin/builders/generate/api/templates/function.js +9 -0
  8. package/bin/builders/generate/api/templates/index.js +7 -0
  9. package/bin/builders/generate/api/templates/story.js +23 -0
  10. package/bin/builders/generate/api/templates/unit-test.js +15 -0
  11. package/bin/builders/generate/component/index.js +87 -0
  12. package/bin/builders/generate/component/templates/Component.js +43 -0
  13. package/bin/builders/generate/component/templates/css.js +24 -0
  14. package/bin/builders/generate/component/templates/index.js +8 -0
  15. package/bin/builders/generate/component/templates/stories.js +46 -0
  16. package/bin/builders/generate/component/templates/unit-test.js +19 -0
  17. package/bin/builders/generate/config/index.js +54 -0
  18. package/bin/builders/generate/config/templates/elsie.js +29 -0
  19. package/bin/builders/generate/container/index.js +65 -0
  20. package/bin/builders/generate/container/templates/Component.js +18 -0
  21. package/bin/builders/generate/container/templates/index.js +8 -0
  22. package/bin/builders/generate/container/templates/stories.js +34 -0
  23. package/bin/builders/generate/container/templates/unit-test.js +19 -0
  24. package/bin/builders/generate/index.js +283 -0
  25. package/bin/builders/gql/createOrClearDirectory.js +33 -0
  26. package/bin/builders/gql/getSchemaRef.js +25 -0
  27. package/bin/builders/gql/index.js +71 -0
  28. package/bin/builders/lint/index.js +5 -0
  29. package/bin/builders/serve/index.js +44 -0
  30. package/bin/builders/storybook/index.js +5 -0
  31. package/bin/builders/test/index.js +5 -0
  32. package/bin/index.js +26 -0
  33. package/bin/lib/cli.js +8 -0
  34. package/bin/lib/config.js +12 -0
  35. package/bin/lib/log-message.js +11 -0
  36. package/bin/lib/string.js +26 -0
  37. package/bin/lib/validate-typeof.js +28 -0
  38. package/bin/lib/write-file.js +30 -0
  39. package/bin/lib/write-parent-index.js +45 -0
  40. package/config/eslint.js +113 -0
  41. package/config/jest.js +90 -0
  42. package/config/prettier.js +16 -0
  43. package/config/setEnvVars.js +14 -0
  44. package/config/storybook/addon.js +130 -0
  45. package/config/storybook/components/FileTree/FileTree.jsx +192 -0
  46. package/config/storybook/components/FileTree/index.js +10 -0
  47. package/config/storybook/components/Flex/Flex.jsx +21 -0
  48. package/config/storybook/components/Flex/Flex.module.css +29 -0
  49. package/config/storybook/components/Flex/index.js +10 -0
  50. package/config/storybook/components/OptionsTable/OptionsTable.jsx +88 -0
  51. package/config/storybook/components/OptionsTable/OptionsTable.module.css +104 -0
  52. package/config/storybook/components/OptionsTable/index.js +10 -0
  53. package/config/storybook/components/Panel/Panel.module.css +56 -0
  54. package/config/storybook/components/Panel/Panel.tsx +46 -0
  55. package/config/storybook/components/Panel/index.ts +10 -0
  56. package/config/storybook/components/Screenshot/Screenshot.jsx +23 -0
  57. package/config/storybook/components/Screenshot/Screenshot.module.css +28 -0
  58. package/config/storybook/components/Screenshot/index.js +10 -0
  59. package/config/storybook/components/Steps/Steps.jsx +21 -0
  60. package/config/storybook/components/Steps/Steps.module.css +43 -0
  61. package/config/storybook/components/Steps/index.js +10 -0
  62. package/config/storybook/components/StoryWrapper/StoryWrapper.jsx +18 -0
  63. package/config/storybook/components/StoryWrapper/StoryWrapper.module.css +22 -0
  64. package/config/storybook/components/StoryWrapper/index.js +10 -0
  65. package/config/storybook/components/Summary/Summary.jsx +19 -0
  66. package/config/storybook/components/Summary/Summary.module.css +20 -0
  67. package/config/storybook/components/Summary/index.js +10 -0
  68. package/config/storybook/components/Variants/Variants.js +57 -0
  69. package/config/storybook/components/Variants/docs.css +48 -0
  70. package/config/storybook/components/Variants/index.js +10 -0
  71. package/config/storybook/components/video/index.jsx +28 -0
  72. package/config/storybook/manager.js +23 -0
  73. package/config/storybook/preview.jsx +88 -0
  74. package/config/storybook/theming/fonts.css +68 -0
  75. package/config/storybook/theming/logo.svg +19 -0
  76. package/config/storybook/theming/manager.css +63 -0
  77. package/config/storybook/theming/preview.css +93 -0
  78. package/config/storybook/theming/theme.js +61 -0
  79. package/config/tsconfig-base.json +16 -0
  80. package/config/tsconfig-preact.json +15 -0
  81. package/config/vite.mjs +306 -0
  82. package/package.json +113 -0
  83. package/post-release.sh +5 -0
  84. package/src/components/Accordion/Accordion.css +88 -0
  85. package/src/components/Accordion/Accordion.stories.tsx +582 -0
  86. package/src/components/Accordion/Accordion.tsx +177 -0
  87. package/src/components/Accordion/index.ts +11 -0
  88. package/src/components/ActionButton/ActionButton.css +100 -0
  89. package/src/components/ActionButton/ActionButton.stories.tsx +169 -0
  90. package/src/components/ActionButton/ActionButton.tsx +53 -0
  91. package/src/components/ActionButton/index.ts +10 -0
  92. package/src/components/ActionButtonGroup/ActionButtonGroup.css +77 -0
  93. package/src/components/ActionButtonGroup/ActionButtonGroup.stories.tsx +97 -0
  94. package/src/components/ActionButtonGroup/ActionButtonGroup.tsx +91 -0
  95. package/src/components/ActionButtonGroup/index.ts +10 -0
  96. package/src/components/AlertBanner/AlertBanner.css +144 -0
  97. package/src/components/AlertBanner/AlertBanner.stories.tsx +165 -0
  98. package/src/components/AlertBanner/AlertBanner.tsx +90 -0
  99. package/src/components/AlertBanner/index.ts +11 -0
  100. package/src/components/Breadcrumbs/Breadcrumbs.css +60 -0
  101. package/src/components/Breadcrumbs/Breadcrumbs.stories.tsx +195 -0
  102. package/src/components/Breadcrumbs/Breadcrumbs.tsx +71 -0
  103. package/src/components/Breadcrumbs/index.ts +11 -0
  104. package/src/components/Button/Button.css +213 -0
  105. package/src/components/Button/Button.mdx +133 -0
  106. package/src/components/Button/Button.stories.tsx +398 -0
  107. package/src/components/Button/Button.tsx +121 -0
  108. package/src/components/Button/index.ts +11 -0
  109. package/src/components/Card/Card.css +34 -0
  110. package/src/components/Card/Card.stories.tsx +76 -0
  111. package/src/components/Card/Card.tsx +34 -0
  112. package/src/components/Card/index.ts +10 -0
  113. package/src/components/CartItem/CartItem.css +509 -0
  114. package/src/components/CartItem/CartItem.stories.tsx +628 -0
  115. package/src/components/CartItem/CartItem.tsx +467 -0
  116. package/src/components/CartItem/CartItemSkeleton.tsx +38 -0
  117. package/src/components/CartItem/index.ts +12 -0
  118. package/src/components/CartList/CartList.css +35 -0
  119. package/src/components/CartList/CartList.stories.tsx +111 -0
  120. package/src/components/CartList/CartList.tsx +40 -0
  121. package/src/components/CartList/index.ts +11 -0
  122. package/src/components/Checkbox/Checkbox.css +255 -0
  123. package/src/components/Checkbox/Checkbox.stories.tsx +290 -0
  124. package/src/components/Checkbox/Checkbox.tsx +138 -0
  125. package/src/components/Checkbox/index.ts +10 -0
  126. package/src/components/ColorSwatch/ColorSwatch.css +132 -0
  127. package/src/components/ColorSwatch/ColorSwatch.stories.tsx +274 -0
  128. package/src/components/ColorSwatch/ColorSwatch.tsx +127 -0
  129. package/src/components/ColorSwatch/index.ts +11 -0
  130. package/src/components/ContentGrid/ContentGrid.css +54 -0
  131. package/src/components/ContentGrid/ContentGrid.stories.tsx +137 -0
  132. package/src/components/ContentGrid/ContentGrid.tsx +57 -0
  133. package/src/components/ContentGrid/index.ts +11 -0
  134. package/src/components/Divider/Divider.css +22 -0
  135. package/src/components/Divider/Divider.stories.tsx +62 -0
  136. package/src/components/Divider/Divider.tsx +33 -0
  137. package/src/components/Divider/index.ts +11 -0
  138. package/src/components/Field/Field.css +83 -0
  139. package/src/components/Field/Field.stories.tsx +238 -0
  140. package/src/components/Field/Field.tsx +84 -0
  141. package/src/components/Field/index.ts +10 -0
  142. package/src/components/Header/Header.css +56 -0
  143. package/src/components/Header/Header.stories.tsx +180 -0
  144. package/src/components/Header/Header.tsx +81 -0
  145. package/src/components/Header/index.ts +11 -0
  146. package/src/components/Icon/Icon.css +26 -0
  147. package/src/components/Icon/Icon.stories.helpers.jsx +21 -0
  148. package/src/components/Icon/Icon.stories.tsx +98 -0
  149. package/src/components/Icon/Icon.tsx +112 -0
  150. package/src/components/Icon/index.ts +10 -0
  151. package/src/components/IllustratedMessage/IllustratedMessage.css +61 -0
  152. package/src/components/IllustratedMessage/IllustratedMessage.stories.tsx +126 -0
  153. package/src/components/IllustratedMessage/IllustratedMessage.tsx +78 -0
  154. package/src/components/IllustratedMessage/index.ts +11 -0
  155. package/src/components/Image/Image.css +52 -0
  156. package/src/components/Image/Image.stories.tsx +89 -0
  157. package/src/components/Image/Image.tsx +66 -0
  158. package/src/components/Image/index.ts +10 -0
  159. package/src/components/ImageSwatch/ImageSwatch.css +154 -0
  160. package/src/components/ImageSwatch/ImageSwatch.stories.tsx +310 -0
  161. package/src/components/ImageSwatch/ImageSwatch.tsx +123 -0
  162. package/src/components/ImageSwatch/index.ts +11 -0
  163. package/src/components/InLineAlert/InLineAlert.css +116 -0
  164. package/src/components/InLineAlert/InLineAlert.stories.tsx +326 -0
  165. package/src/components/InLineAlert/InLineAlert.tsx +128 -0
  166. package/src/components/InLineAlert/index.ts +11 -0
  167. package/src/components/Incrementer/Incrementer.css +165 -0
  168. package/src/components/Incrementer/Incrementer.stories.tsx +172 -0
  169. package/src/components/Incrementer/Incrementer.tsx +192 -0
  170. package/src/components/Incrementer/index.ts +10 -0
  171. package/src/components/Input/Input.css +304 -0
  172. package/src/components/Input/Input.stories.tsx +155 -0
  173. package/src/components/Input/Input.tsx +166 -0
  174. package/src/components/Input/index.ts +11 -0
  175. package/src/components/InputDate/InputDate.css +56 -0
  176. package/src/components/InputDate/InputDate.stories.tsx +117 -0
  177. package/src/components/InputDate/InputDate.tsx +120 -0
  178. package/src/components/InputDate/index.ts +11 -0
  179. package/src/components/InputPassword/InputPassword.css +31 -0
  180. package/src/components/InputPassword/InputPassword.stories.tsx +148 -0
  181. package/src/components/InputPassword/InputPassword.tsx +135 -0
  182. package/src/components/InputPassword/PasswordStatusIndicator/PasswordStatusIndicator.css +31 -0
  183. package/src/components/InputPassword/PasswordStatusIndicator/PasswordStatusIndicator.tsx +96 -0
  184. package/src/components/InputPassword/PasswordStatusIndicator/index.ts +11 -0
  185. package/src/components/InputPassword/index.ts +11 -0
  186. package/src/components/Modal/Modal.css +125 -0
  187. package/src/components/Modal/Modal.stories.tsx +250 -0
  188. package/src/components/Modal/Modal.tsx +157 -0
  189. package/src/components/Modal/index.ts +10 -0
  190. package/src/components/Pagination/Pagination.css +95 -0
  191. package/src/components/Pagination/Pagination.stories.tsx +117 -0
  192. package/src/components/Pagination/Pagination.tsx +149 -0
  193. package/src/components/Pagination/index.ts +11 -0
  194. package/src/components/Picker/Picker.css +220 -0
  195. package/src/components/Picker/Picker.stories.tsx +318 -0
  196. package/src/components/Picker/Picker.tsx +203 -0
  197. package/src/components/Picker/index.ts +10 -0
  198. package/src/components/Price/Price.css +57 -0
  199. package/src/components/Price/Price.stories.tsx +110 -0
  200. package/src/components/Price/Price.tsx +75 -0
  201. package/src/components/Price/index.ts +10 -0
  202. package/src/components/PriceRange/PriceRange.css +66 -0
  203. package/src/components/PriceRange/PriceRange.stories.tsx +240 -0
  204. package/src/components/PriceRange/PriceRange.tsx +248 -0
  205. package/src/components/PriceRange/index.ts +11 -0
  206. package/src/components/ProgressSpinner/ProgressSpinner.css +91 -0
  207. package/src/components/ProgressSpinner/ProgressSpinner.stories.tsx +300 -0
  208. package/src/components/ProgressSpinner/ProgressSpinner.tsx +86 -0
  209. package/src/components/ProgressSpinner/index.ts +11 -0
  210. package/src/components/RadioButton/RadioButton.css +134 -0
  211. package/src/components/RadioButton/RadioButton.stories.tsx +126 -0
  212. package/src/components/RadioButton/RadioButton.tsx +86 -0
  213. package/src/components/RadioButton/index.ts +11 -0
  214. package/src/components/Skeleton/Skeleton.css +145 -0
  215. package/src/components/Skeleton/Skeleton.stories.tsx +265 -0
  216. package/src/components/Skeleton/Skeleton.tsx +133 -0
  217. package/src/components/Skeleton/index.ts +10 -0
  218. package/src/components/Tag/Tag.css +26 -0
  219. package/src/components/Tag/Tag.stories.tsx +103 -0
  220. package/src/components/Tag/Tag.tsx +38 -0
  221. package/src/components/Tag/index.ts +11 -0
  222. package/src/components/TextArea/TextArea.css +140 -0
  223. package/src/components/TextArea/TextArea.stories.tsx +130 -0
  224. package/src/components/TextArea/TextArea.tsx +89 -0
  225. package/src/components/TextArea/index.ts +11 -0
  226. package/src/components/TextSwatch/TextSwatch.css +152 -0
  227. package/src/components/TextSwatch/TextSwatch.stories.tsx +277 -0
  228. package/src/components/TextSwatch/TextSwatch.tsx +131 -0
  229. package/src/components/TextSwatch/index.ts +11 -0
  230. package/src/components/ToggleButton/ToggleButton.css +95 -0
  231. package/src/components/ToggleButton/ToggleButton.stories.tsx +190 -0
  232. package/src/components/ToggleButton/ToggleButton.tsx +75 -0
  233. package/src/components/ToggleButton/index.ts +11 -0
  234. package/src/components/UIProvider/UIProvider.css +140 -0
  235. package/src/components/UIProvider/UIProvider.tsx +61 -0
  236. package/src/components/UIProvider/debugger.css +47 -0
  237. package/src/components/UIProvider/index.ts +10 -0
  238. package/src/components/UIProvider/normalize.css +26 -0
  239. package/src/components/index.ts +49 -0
  240. package/src/docs/API/event-bus.mdx +52 -0
  241. package/src/docs/API/graphql.mdx +214 -0
  242. package/src/docs/API/initializer.mdx +119 -0
  243. package/src/docs/API/render.mdx +125 -0
  244. package/src/docs/Design/colors.mdx +202 -0
  245. package/src/docs/Design/designBlocks.jsx +87 -0
  246. package/src/docs/Design/getTokenData.ts +28 -0
  247. package/src/docs/Design/grid.mdx +365 -0
  248. package/src/docs/Design/overview.mdx +69 -0
  249. package/src/docs/Design/shapes.mdx +100 -0
  250. package/src/docs/Design/spacing.mdx +22 -0
  251. package/src/docs/Design/typography.mdx +126 -0
  252. package/src/docs/Utilities/classList.mdx +52 -0
  253. package/src/docs/Utilities/debounce.mdx +49 -0
  254. package/src/docs/Utilities/deepmerge.mdx +12 -0
  255. package/src/docs/Utilities/getFormErrors.mdx +41 -0
  256. package/src/docs/Utilities/getFormValues.mdx +38 -0
  257. package/src/docs/assets/Banner.png +0 -0
  258. package/src/docs/assets/Colors.png +0 -0
  259. package/src/docs/assets/DropinBanner.png +0 -0
  260. package/src/docs/assets/ShapeStyles.png +0 -0
  261. package/src/docs/assets/Spacing.png +0 -0
  262. package/src/docs/assets/Typography.png +0 -0
  263. package/src/docs/cli-usage.mdx +181 -0
  264. package/src/docs/components/overview.mdx +124 -0
  265. package/src/docs/quick-start.mdx +245 -0
  266. package/src/docs/slots.mdx +211 -0
  267. package/src/docs/welcome.mdx +52 -0
  268. package/src/i18n/en_US.json +146 -0
  269. package/src/i18n/index.ts +26 -0
  270. package/src/icons/Add.svg +9 -0
  271. package/src/icons/AddressBook.svg +3 -0
  272. package/src/icons/Bulk.svg +24 -0
  273. package/src/icons/Burger.svg +5 -0
  274. package/src/icons/Card.svg +7 -0
  275. package/src/icons/Cart.svg +11 -0
  276. package/src/icons/Check.svg +8 -0
  277. package/src/icons/CheckWithCircle.svg +4 -0
  278. package/src/icons/ChevronDown.svg +3 -0
  279. package/src/icons/ChevronRight.svg +8 -0
  280. package/src/icons/ChevronUp.svg +3 -0
  281. package/src/icons/Close.svg +4 -0
  282. package/src/icons/Coupon.svg +3 -0
  283. package/src/icons/Date.svg +4 -0
  284. package/src/icons/Delivery.svg +11 -0
  285. package/src/icons/EmptyBox.svg +3 -0
  286. package/src/icons/Eye.svg +3 -0
  287. package/src/icons/EyeClose.svg +3 -0
  288. package/src/icons/Gift.svg +3 -0
  289. package/src/icons/GiftCard.svg +3 -0
  290. package/src/icons/Heart.svg +3 -0
  291. package/src/icons/HeartFilled.svg +3 -0
  292. package/src/icons/InfoFilled.svg +3 -0
  293. package/src/icons/Locker.svg +11 -0
  294. package/src/icons/Minus.svg +3 -0
  295. package/src/icons/Order.svg +6 -0
  296. package/src/icons/OrderError.svg +15 -0
  297. package/src/icons/OrderSuccess.svg +15 -0
  298. package/src/icons/PaymentError.svg +16 -0
  299. package/src/icons/Placeholder.svg +3 -0
  300. package/src/icons/PlaceholderFilled.svg +4 -0
  301. package/src/icons/Search.svg +9 -0
  302. package/src/icons/SearchFilled.svg +10 -0
  303. package/src/icons/Sort.svg +12 -0
  304. package/src/icons/Star.svg +8 -0
  305. package/src/icons/Trash.svg +7 -0
  306. package/src/icons/User.svg +5 -0
  307. package/src/icons/View.svg +14 -0
  308. package/src/icons/Wallet.svg +6 -0
  309. package/src/icons/Warning.svg +12 -0
  310. package/src/icons/WarningFilled.svg +3 -0
  311. package/src/icons/WarningWithCircle.svg +4 -0
  312. package/src/icons/index.ts +42 -0
  313. package/src/lib/classes.ts +34 -0
  314. package/src/lib/config.ts +24 -0
  315. package/src/lib/debounce.ts +16 -0
  316. package/src/lib/deepmerge.ts +45 -0
  317. package/src/lib/deviceUtils.ts +16 -0
  318. package/src/lib/form-values.ts +31 -0
  319. package/src/lib/i18n.ts +18 -0
  320. package/src/lib/image-params-keymap.ts +36 -0
  321. package/src/lib/index.ts +24 -0
  322. package/src/lib/initializer.ts +134 -0
  323. package/src/lib/is-number.ts +12 -0
  324. package/src/lib/render.tsx +138 -0
  325. package/src/lib/resolve-image.ts +101 -0
  326. package/src/lib/signals.ts +11 -0
  327. package/src/lib/slot.tsx +434 -0
  328. package/src/lib/tests.tsx +47 -0
  329. package/src/lib/types.ts +16 -0
  330. package/src/lib/vcomponent.tsx +42 -0
  331. package/static/assets/images/Card.png +0 -0
  332. package/static/assets/images/example.jpg +0 -0
  333. package/static/assets/images/index.ts +11 -0
  334. package/static/dropin.png +0 -0
  335. package/static/favicon.svg +14 -0
  336. package/storybook-stories.js +21 -0
  337. package/tests/__mocks__/browserMocks.ts +28 -0
  338. package/tests/__mocks__/fileMocks.ts +12 -0
  339. package/tests/__mocks__/styleMock.ts +0 -0
  340. package/types/icons.d.ts +18 -0
@@ -0,0 +1,177 @@
1
+ /********************************************************************
2
+ * Copyright 2024 Adobe
3
+ * All Rights Reserved.
4
+ *
5
+ * NOTICE: Adobe permits you to use, modify, and distribute this
6
+ * file in accordance with the terms of the Adobe license agreement
7
+ * accompanying it.
8
+ *******************************************************************/
9
+
10
+ import { FunctionComponent, VNode } from 'preact';
11
+ import { HTMLAttributes, useState, useEffect } from 'preact/compat';
12
+ import { classes } from '@adobe-commerce/elsie/lib';
13
+ import { Divider, Icon, IconNode } from '@adobe-commerce/elsie/components';
14
+ import { Add, Minus } from '@adobe-commerce/elsie/icons';
15
+ import { useText } from '@adobe-commerce/elsie/i18n';
16
+ import '@adobe-commerce/elsie/components/Accordion/Accordion.css';
17
+ export interface AccordionSectionProps
18
+ extends Omit<HTMLAttributes<HTMLDivElement>, 'icon'> {
19
+ defaultOpen?: boolean;
20
+ actionIconPosition?: 'left' | 'right';
21
+ ariaLabelTitle: string;
22
+ iconOpen?: IconNode;
23
+ iconClose?: IconNode;
24
+ iconLeft?: IconNode;
25
+ showIconLeft?: boolean;
26
+ secondaryText?: string | VNode<HTMLAttributes<HTMLSpanElement>>;
27
+ renderContentWhenClosed?: boolean;
28
+ onStateChange?: (open: boolean) => void;
29
+ }
30
+
31
+ export const AccordionSection: FunctionComponent<AccordionSectionProps> = ({
32
+ className,
33
+ children,
34
+ title,
35
+ ariaLabelTitle,
36
+ secondaryText,
37
+ actionIconPosition = 'left',
38
+ iconOpen = Add,
39
+ iconClose = Minus,
40
+ iconLeft = Add,
41
+ showIconLeft = false,
42
+ renderContentWhenClosed = true,
43
+ defaultOpen,
44
+ onStateChange,
45
+ ...props
46
+ }) => {
47
+ const [open, setOpen] = useState<boolean>(false);
48
+ const onClickHandler = (e: { stopImmediatePropagation: () => void }) => {
49
+ e.stopImmediatePropagation();
50
+
51
+ const next = !open;
52
+ setOpen(next);
53
+ onStateChange?.(next);
54
+ };
55
+
56
+ useEffect(() => {
57
+ if (typeof defaultOpen !== 'undefined') {
58
+ setOpen(defaultOpen);
59
+ }
60
+ }, [defaultOpen]);
61
+
62
+ const buttonLabel = useText(
63
+ `Dropin.Accordion.${open ? 'close' : 'open'}.label`
64
+ ).label;
65
+
66
+ const openIcon = (
67
+ <Icon
68
+ source={iconOpen}
69
+ size="24"
70
+ onClick={onClickHandler}
71
+ onKeyPress={onClickHandler}
72
+ className={'dropin-accordion-section__open-icon'}
73
+ />
74
+ );
75
+
76
+ const closeIcon = (
77
+ <Icon
78
+ source={iconClose}
79
+ size="24"
80
+ onClick={onClickHandler}
81
+ onKeyPress={onClickHandler}
82
+ className={'dropin-accordion-section__close-icon'}
83
+ />
84
+ );
85
+
86
+ const leftIcon = <Icon source={iconLeft} size="24" />;
87
+
88
+ return (
89
+ <div
90
+ {...props}
91
+ className={classes(['dropin-accordion-section', className])}
92
+ >
93
+ <div className={'dropin-accordion-section__heading'}>
94
+ <div
95
+ className={'dropin-accordion-section__flex'}
96
+ onClick={onClickHandler}
97
+ onKeyPress={onClickHandler}
98
+ role="button"
99
+ aria-label={`${buttonLabel} ${ariaLabelTitle ?? title}`}
100
+ tabIndex={0}
101
+ >
102
+ <div className={'dropin-accordion-section__title-container'}>
103
+ {actionIconPosition === 'left' && (open ? closeIcon : openIcon)}
104
+
105
+ {showIconLeft && leftIcon}
106
+
107
+ <h3 className={'dropin-accordion-section__title'}>{title}</h3>
108
+ </div>
109
+ </div>
110
+
111
+ <div className={'dropin-accordion-section__secondary-text-container'}>
112
+ {secondaryText && (
113
+ <h4 className={'dropin-accordion-section__secondary-text'}>
114
+ {secondaryText}
115
+ </h4>
116
+ )}
117
+
118
+ {actionIconPosition === 'right' && (open ? closeIcon : openIcon)}
119
+ </div>
120
+ </div>
121
+
122
+ <div
123
+ className={'dropin-accordion-section__content-container'}
124
+ style={{ display: open ? 'grid' : 'none' }}
125
+ >
126
+ {(open || (renderContentWhenClosed && !open)) && children}
127
+ </div>
128
+ </div>
129
+ );
130
+ };
131
+
132
+ export interface AccordionProps
133
+ extends Omit<HTMLAttributes<HTMLDivElement>, 'icon'> {
134
+ actionIconPosition?: 'left' | 'right';
135
+ iconOpen?: IconNode;
136
+ iconClose?: IconNode;
137
+ iconLeft?: IconNode;
138
+ showIconLeft?: boolean;
139
+ secondaryText?: string | VNode<HTMLAttributes<HTMLSpanElement>>;
140
+ children: VNode<AccordionSectionProps>[] | VNode<AccordionSectionProps>;
141
+ }
142
+
143
+ export const Accordion: FunctionComponent<AccordionProps> = ({
144
+ className,
145
+ children,
146
+ actionIconPosition = 'left',
147
+ iconOpen = Add,
148
+ iconClose = Minus,
149
+ ...props
150
+ }) => {
151
+ const divider = <Divider variant="secondary" />;
152
+
153
+ const renderAccordionSection = (child: VNode<AccordionSectionProps>) => (
154
+ <>
155
+ <AccordionSection
156
+ {...child.props}
157
+ actionIconPosition={actionIconPosition}
158
+ iconOpen={iconOpen}
159
+ iconClose={iconClose}
160
+ />
161
+ {divider}
162
+ </>
163
+ );
164
+
165
+ return (
166
+ <div {...props} className={classes(['dropin-accordion', className])}>
167
+ {[
168
+ divider,
169
+ ...(
170
+ (Array.isArray(children)
171
+ ? children
172
+ : [children]) as VNode<AccordionSectionProps>[]
173
+ ).map(renderAccordionSection),
174
+ ]}
175
+ </div>
176
+ );
177
+ };
@@ -0,0 +1,11 @@
1
+ /********************************************************************
2
+ * Copyright 2024 Adobe
3
+ * All Rights Reserved.
4
+ *
5
+ * NOTICE: Adobe permits you to use, modify, and distribute this
6
+ * file in accordance with the terms of the Adobe license agreement
7
+ * accompanying it.
8
+ *******************************************************************/
9
+
10
+ export * from '@adobe-commerce/elsie/components/Accordion/Accordion';
11
+ export { Accordion as default } from '@adobe-commerce/elsie/components/Accordion/Accordion';
@@ -0,0 +1,100 @@
1
+ /********************************************************************
2
+ * Copyright 2024 Adobe
3
+ * All Rights Reserved.
4
+ *
5
+ * NOTICE: Adobe permits you to use, modify, and distribute this
6
+ * file in accordance with the terms of the Adobe license agreement
7
+ * accompanying it.
8
+ *******************************************************************/
9
+
10
+ /* https://cssguidelin.es/#bem-like-naming */
11
+
12
+ .dropin-action-button {
13
+ --bgColor: var(--color-neutral-200);
14
+ --textColor: var(--color-neutral-800);
15
+ --borderColor: var(--color-neutral-400);
16
+ display: inline-flex;
17
+ box-sizing: border-box;
18
+ row-gap: var(--spacing-small);
19
+ white-space: normal;
20
+ align-items: center;
21
+ justify-content: center;
22
+ font: var(--type-body-2-strong-font);
23
+ padding: 6px var(--spacing-small);
24
+ background: var(--bgColor);
25
+ color: var(--textColor);
26
+ border: var(--shape-border-width-1) solid var(--borderColor);
27
+ border-radius: var(--shape-border-radius-1);
28
+ word-wrap: break-word;
29
+ text-align: left;
30
+ }
31
+
32
+ .dropin-action-button:hover,
33
+ .dropin-action-button:focus:hover {
34
+ --textColor: var(--color-neutral-900);
35
+ }
36
+
37
+ .dropin-action-button:active:focus {
38
+ --borderColor: var(--color-neutral-500);
39
+ }
40
+
41
+ .dropin-action-button:focus {
42
+ outline: none;
43
+ }
44
+
45
+ .dropin-action-button:focus-visible {
46
+ --borderColor: var(--color-neutral-800);
47
+ outline: solid var(--shape-border-width-4) var(--color-neutral-400);
48
+ }
49
+
50
+ .dropin-action-button--active {
51
+ --bgColor: var(--color-action-button-active);
52
+ --borderColor: var(--color-neutral-400);
53
+ --textColor: var(--color-neutral-900);
54
+ }
55
+
56
+ .dropin-action-button--active:hover,
57
+ .dropin-action-button--active:focus:hover {
58
+ --bgColor: var(--color-action-button-active);
59
+ --textColor: var(--color-neutral-800);
60
+ }
61
+
62
+ .dropin-action-button--active:active:focus {
63
+ --bgColor: var(--color-action-button-active);
64
+ --textColor: var(--color-neutral-700);
65
+ }
66
+
67
+ .dropin-action-button--disabled,
68
+ .dropin-action-button:disabled,
69
+ .dropin-action-button--disabled:focus-visible {
70
+ --bgColor: var(--color-neutral-300);
71
+ --textColor: var(--color-neutral-500);
72
+ pointer-events: none;
73
+ }
74
+
75
+ .dropin-action-button:not(:disabled) {
76
+ cursor: pointer;
77
+ }
78
+
79
+ .dropin-action-button-icon {
80
+ display: inline-flex;
81
+ justify-content: center;
82
+ align-items: center;
83
+ height: 16px;
84
+ }
85
+
86
+ .dropin-action-button-icon:first-child:not(:last-child) {
87
+ margin-right: var(--spacing-xsmall);
88
+ }
89
+
90
+ /* Medium (portrait tablets and large phones, 768px and up) */
91
+ /* @media only screen and (min-width: 768px) { } */
92
+
93
+ /* Large (landscape tablets, 1024px and up) */
94
+ /* @media only screen and (min-width: 1024px) { } */
95
+
96
+ /* XLarge (laptops/desktops, 1366px and up) */
97
+ /* @media only screen and (min-width: 1366px) { } */
98
+
99
+ /* XXlarge (large laptops and desktops, 1920px and up) */
100
+ /* @media only screen and (min-width: 1920px) { } */
@@ -0,0 +1,169 @@
1
+ /********************************************************************
2
+ * Copyright 2024 Adobe
3
+ * All Rights Reserved.
4
+ *
5
+ * NOTICE: Adobe permits you to use, modify, and distribute this
6
+ * file in accordance with the terms of the Adobe license agreement
7
+ * accompanying it.
8
+ *******************************************************************/
9
+
10
+ // https://storybook.js.org/docs/7.0/preact/writing-stories/introduction
11
+ import type { Meta, StoryObj } from '@storybook/preact';
12
+ import {
13
+ ActionButton as component,
14
+ ActionButtonProps,
15
+ } from '@adobe-commerce/elsie/components/ActionButton';
16
+ import { Add } from '@adobe-commerce/elsie/icons';
17
+ import { Icon } from '@adobe-commerce/elsie/components/Icon';
18
+ import { IconsList } from '@adobe-commerce/elsie/components/Icon/Icon.stories.helpers';
19
+ import { expect, within } from '@storybook/test';
20
+
21
+ /**
22
+ * Use Action Buttons to let users complete actions or select items in a workflow.
23
+ */
24
+ const meta: Meta<ActionButtonProps> = {
25
+ title: 'Components/ActionButton',
26
+ component,
27
+ argTypes: {
28
+ icon: {
29
+ options: Object.keys(IconsList),
30
+ mapping: IconsList,
31
+ control: {
32
+ type: 'select',
33
+ },
34
+ },
35
+ },
36
+ };
37
+
38
+ export default meta;
39
+
40
+ type Story = StoryObj<ActionButtonProps>;
41
+
42
+ export const Default: Story = {
43
+ name: 'Action Button',
44
+ args: {
45
+ children: 'Action',
46
+ active: false,
47
+ disabled: false,
48
+ },
49
+ play: async ({ canvasElement }) => {
50
+ const canvas = within(canvasElement);
51
+ await expect(await canvas.findByRole('button')).toBeVisible();
52
+ await expect(await canvas.findByRole('button')).toHaveClass(
53
+ 'dropin-action-button'
54
+ );
55
+ },
56
+ };
57
+
58
+ export const IconOnly: Story = {
59
+ name: 'Icon Action Button',
60
+ args: {
61
+ ...Default.args,
62
+ children: '',
63
+ 'aria-label': 'Action Button',
64
+ icon: (
65
+ <Icon
66
+ source={Add}
67
+ size="32"
68
+ className="storybook_icon"
69
+ stroke="1"
70
+ viewBox="0 0 24 24"
71
+ />
72
+ ),
73
+ },
74
+ play: async ({ canvasElement }) => {
75
+ const canvas = within(canvasElement);
76
+ const buttonIcon = document.querySelector(
77
+ '.dropin-action-button-icon'
78
+ ) as HTMLElement;
79
+ const addIcon = document.querySelector(
80
+ 'g[data-name="Add icon"]'
81
+ ) as HTMLElement;
82
+ await expect(await canvas.findByRole('button')).toBeVisible();
83
+ await expect(await buttonIcon).toBeVisible();
84
+ await expect(await addIcon).toBeVisible();
85
+ },
86
+ };
87
+
88
+ export const WithIcon: Story = {
89
+ name: 'Action Button With Icon',
90
+ args: {
91
+ ...Default.args,
92
+ icon: (
93
+ <Icon
94
+ source={Add}
95
+ size="32"
96
+ className="storybook_icon"
97
+ stroke="1"
98
+ viewBox="0 0 24 24"
99
+ />
100
+ ),
101
+ },
102
+ play: async ({ canvasElement }) => {
103
+ const canvas = within(canvasElement);
104
+ const buttonIcon = document.querySelector(
105
+ '.dropin-action-button-icon'
106
+ ) as HTMLElement;
107
+ const addIcon = document.querySelector(
108
+ 'g[data-name="Add icon"]'
109
+ ) as HTMLElement;
110
+ await expect(await canvas.findByRole('button')).toBeVisible();
111
+ await expect(await buttonIcon).toBeVisible();
112
+ await expect(await addIcon).toBeVisible();
113
+ await expect(await canvas.getByText('Action')).toBeVisible();
114
+ },
115
+ };
116
+
117
+ export const Disabled: Story = {
118
+ name: 'Disabled Action Button',
119
+ parameters: {
120
+ a11y: {
121
+ config: {
122
+ rules: [{ id: 'color-contrast', enabled: false }],
123
+ },
124
+ },
125
+ },
126
+ args: {
127
+ ...Default.args,
128
+ disabled: true,
129
+ },
130
+ play: async ({ canvasElement }) => {
131
+ const canvas = within(canvasElement);
132
+ await expect(await canvas.findByRole('button')).toBeDisabled();
133
+ },
134
+ };
135
+
136
+ export const Active: Story = {
137
+ name: 'Active Action Button',
138
+ args: {
139
+ ...Default.args,
140
+ active: true,
141
+ },
142
+ };
143
+
144
+ export const DisabledIcon: Story = {
145
+ name: 'Disabled Action Button With Icon',
146
+ parameters: {
147
+ a11y: {
148
+ config: {
149
+ rules: [{ id: 'color-contrast', enabled: false }],
150
+ },
151
+ },
152
+ },
153
+ args: {
154
+ ...WithIcon.args,
155
+ disabled: true,
156
+ },
157
+ play: async ({ canvasElement }) => {
158
+ const canvas = within(canvasElement);
159
+ await expect(await canvas.findByRole('button')).toBeDisabled();
160
+ },
161
+ };
162
+
163
+ export const ActiveIcon: Story = {
164
+ name: 'Active Action Button With Icon',
165
+ args: {
166
+ ...WithIcon.args,
167
+ active: true,
168
+ },
169
+ };
@@ -0,0 +1,53 @@
1
+ /********************************************************************
2
+ * Copyright 2024 Adobe
3
+ * All Rights Reserved.
4
+ *
5
+ * NOTICE: Adobe permits you to use, modify, and distribute this
6
+ * file in accordance with the terms of the Adobe license agreement
7
+ * accompanying it.
8
+ *******************************************************************/
9
+
10
+ import { ComponentChildren, FunctionComponent, VNode } from 'preact';
11
+ import { HTMLAttributes } from 'preact/compat';
12
+ import { VComponent, classes } from '@adobe-commerce/elsie/lib';
13
+ import '@adobe-commerce/elsie/components/ActionButton/ActionButton.css';
14
+
15
+ export interface ActionButtonProps
16
+ extends Omit<HTMLAttributes<HTMLButtonElement>, 'icon'> {
17
+ children?: ComponentChildren;
18
+ icon?: VNode<HTMLAttributes<SVGSVGElement>>;
19
+ active?: boolean;
20
+ disabled?: boolean;
21
+ }
22
+
23
+ export const ActionButton: FunctionComponent<ActionButtonProps> = ({
24
+ icon,
25
+ className,
26
+ children,
27
+ active = false,
28
+ disabled = false,
29
+ ...props
30
+ }) => {
31
+ return (
32
+ <button
33
+ role="button"
34
+ disabled={disabled}
35
+ {...props}
36
+ className={classes([
37
+ 'dropin-action-button',
38
+ ['dropin-action-button--active', active],
39
+ ['dropin-action-button--disabled', disabled],
40
+ className,
41
+ ])}
42
+ >
43
+ {icon && (
44
+ <VComponent
45
+ node={icon}
46
+ className={classes(['dropin-action-button-icon'])}
47
+ />
48
+ )}
49
+ {children &&
50
+ (typeof children === 'string' ? <span>{children}</span> : children)}
51
+ </button>
52
+ );
53
+ };
@@ -0,0 +1,10 @@
1
+ /********************************************************************
2
+ * Copyright 2024 Adobe
3
+ * All Rights Reserved.
4
+ *
5
+ * NOTICE: Adobe permits you to use, modify, and distribute this
6
+ * file in accordance with the terms of the Adobe license agreement
7
+ * accompanying it.
8
+ *******************************************************************/
9
+
10
+ export * from '@adobe-commerce/elsie/components/ActionButton/ActionButton';
@@ -0,0 +1,77 @@
1
+ /********************************************************************
2
+ * Copyright 2024 Adobe
3
+ * All Rights Reserved.
4
+ *
5
+ * NOTICE: Adobe permits you to use, modify, and distribute this
6
+ * file in accordance with the terms of the Adobe license agreement
7
+ * accompanying it.
8
+ *******************************************************************/
9
+
10
+ /* https://cssguidelin.es/#bem-like-naming */
11
+
12
+ .dropin-action-button-group {
13
+ display: inline-flex;
14
+ align-items: center;
15
+ justify-content: center;
16
+ border-radius: var(--shape-border-radius-1);
17
+ border: var(--shape-border-width-1) solid var(--color-neutral-400);
18
+ }
19
+
20
+ .dropin-action-button-group__option {
21
+ border: none;
22
+ border-radius: 0;
23
+ align-self: stretch;
24
+ --borderRadiusValue: calc(
25
+ var(--shape-border-radius-1) - var(--shape-border-width-1)
26
+ );
27
+ }
28
+
29
+ .dropin-action-button-group__option:first-child {
30
+ border-radius: var(--borderRadiusValue) 0 0 var(--borderRadiusValue);
31
+ }
32
+
33
+ .dropin-action-button-group__option:last-child {
34
+ border-radius: 0 var(--borderRadiusValue) var(--borderRadiusValue) 0;
35
+ }
36
+
37
+ .dropin-action-button-group__option:only-child {
38
+ border-radius: var(--borderRadiusValue);
39
+ }
40
+
41
+ .dropin-action-button-group__option--with-dividers {
42
+ border-right: var(--shape-border-width-1) solid var(--color-neutral-400);
43
+ }
44
+
45
+ .dropin-action-button-group__option--with-dividers:last-child {
46
+ border-right: none;
47
+ }
48
+
49
+ .dropin-action-button-group__option--active:not(:disabled) {
50
+ background: var(--color-neutral-50);
51
+ }
52
+
53
+ .dropin-action-button-group--secondary {
54
+ border: none;
55
+ }
56
+
57
+ .dropin-action-button-group__option--secondary {
58
+ background: var(--color-neutral-100);
59
+ }
60
+
61
+ .dropin-action-button-group__option:focus-visible {
62
+ outline: solid var(--shape-border-width-4) var(--color-neutral-400);
63
+ border-radius: var(--shape-border-radius-1);
64
+ z-index: 1;
65
+ }
66
+
67
+ /* Medium (portrait tablets and large phones, 768px and up) */
68
+ /* @media only screen and (min-width: 768px) { } */
69
+
70
+ /* Large (landscape tablets, 1024px and up) */
71
+ /* @media only screen and (min-width: 1024px) { } */
72
+
73
+ /* XLarge (laptops/desktops, 1366px and up) */
74
+ /* @media only screen and (min-width: 1366px) { } */
75
+
76
+ /* XXlarge (large laptops and desktops, 1920px and up) */
77
+ /* @media only screen and (min-width: 1920px) { } */
@@ -0,0 +1,97 @@
1
+ /********************************************************************
2
+ * Copyright 2024 Adobe
3
+ * All Rights Reserved.
4
+ *
5
+ * NOTICE: Adobe permits you to use, modify, and distribute this
6
+ * file in accordance with the terms of the Adobe license agreement
7
+ * accompanying it.
8
+ *******************************************************************/
9
+
10
+ // https://storybook.js.org/docs/7.0/preact/writing-stories/introduction
11
+ import type { Meta, StoryObj } from '@storybook/preact';
12
+ import { ActionButton } from '..';
13
+ import {
14
+ ActionButtonGroup as component,
15
+ ActionButtonGroupProps,
16
+ } from '@adobe-commerce/elsie/components/ActionButtonGroup';
17
+ import { Cart, Heart, Star } from '@adobe-commerce/elsie/icons';
18
+ import { Icon } from '../Icon';
19
+
20
+ /**
21
+ * Use Action Button Groups to group related actions.
22
+ */
23
+ const meta: Meta<ActionButtonGroupProps> = {
24
+ title: 'Components/ActionButtonGroup',
25
+ component,
26
+ argTypes: {
27
+ variant: {
28
+ description: 'Action Button Group variant',
29
+ options: ['primary', 'secondary'],
30
+ control: { type: 'radio' },
31
+ },
32
+ disabled: {
33
+ description: 'Whether or not the field is disabled',
34
+ type: { name: 'boolean', required: false },
35
+ defaultValue: false,
36
+ },
37
+ dividers: {
38
+ description: 'Whether or not to show dividers between options',
39
+ type: { name: 'boolean', required: false },
40
+ defaultValue: true,
41
+ },
42
+ handleSelect: {
43
+ description: 'Callback function for when an option is selected',
44
+ type: 'function',
45
+ defaultValue: {
46
+ summary: '() => {}',
47
+ },
48
+ action: 'Value Selected',
49
+ },
50
+ },
51
+ };
52
+
53
+ export default meta;
54
+
55
+ type Story = StoryObj<ActionButtonGroupProps>;
56
+
57
+ /**
58
+ * ```ts
59
+ * import { ActionButtonGroup } from '@adobe-commerce/elsie/components/ActionButtonGroup';
60
+ * ```
61
+ */
62
+
63
+ export const Primary: Story = {
64
+ args: {
65
+ variant: 'primary',
66
+ children: [
67
+ <ActionButton key="option1" value="option1">
68
+ Option1
69
+ </ActionButton>,
70
+ <ActionButton key="option2" value="option2">
71
+ Option2
72
+ </ActionButton>,
73
+ ],
74
+ },
75
+ };
76
+
77
+ export const Secondary: Story = {
78
+ args: {
79
+ variant: 'secondary',
80
+ activeOption: 'option2',
81
+ children: [
82
+ <ActionButton
83
+ key="option1"
84
+ value="option1"
85
+ icon={<Icon source={Heart} />}
86
+ >
87
+ Option1
88
+ </ActionButton>,
89
+ <ActionButton key="option2" value="option2" icon={<Icon source={Star} />}>
90
+ Option2
91
+ </ActionButton>,
92
+ <ActionButton key="option3" value="option3" icon={<Icon source={Cart} />}>
93
+ Option3
94
+ </ActionButton>,
95
+ ],
96
+ },
97
+ };