@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,16 @@
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 const isIOSMobileDevice = () => {
11
+ const userAgent = navigator.userAgent.toLowerCase();
12
+ const isIOS = /ipad|iphone|ipod/.test(userAgent);
13
+ const isMacWithTouch = userAgent.includes('mac') && 'ontouchend' in document;
14
+
15
+ return isIOS || isMacWithTouch;
16
+ };
@@ -0,0 +1,31 @@
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 const getFormValues = (form: HTMLFormElement) => {
11
+ const formData: any = new FormData(form);
12
+ const result = Object.fromEntries(formData);
13
+ return result;
14
+ };
15
+
16
+ export const getFormErrors = (form: HTMLFormElement) => {
17
+ const formData: any = new FormData(form);
18
+
19
+ const data = Object.fromEntries(formData);
20
+
21
+ const result = Object.entries(data).reduce((result, [key]) => {
22
+ // @ts-ignore
23
+ const field = form.elements[key];
24
+
25
+ return field?.validationMessage
26
+ ? { ...result, [key]: field.validationMessage }
27
+ : { ...result };
28
+ }, {});
29
+
30
+ return result;
31
+ };
@@ -0,0 +1,18 @@
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
+ /**
11
+ * Convert locale from Magento standard to react-intl BCP 47 language tag
12
+ *
13
+ * @param {string} locale - A locale (e.g. `fr_FR`).
14
+ * @returns {string} A BCP 47 language tag (e.g. `fr-FR`).
15
+ */
16
+ export const toLanguageTag = (locale: string) => {
17
+ return locale.replace('_', '-');
18
+ };
@@ -0,0 +1,36 @@
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
+ class ImageParamsKeyMap {
11
+ private _map:
12
+ | { [key: string]: string | ((data: any) => [string, string]) }
13
+ | undefined;
14
+
15
+ get map() {
16
+ return this._map;
17
+ }
18
+
19
+ set map(value: typeof this._map) {
20
+ this._map = value;
21
+ }
22
+
23
+ public getMethods() {
24
+ return {
25
+ setMap: (value: typeof this._map) => {
26
+ this.map = value;
27
+ },
28
+ getMap: () => this.map,
29
+ };
30
+ }
31
+ }
32
+
33
+ const keyMap = new ImageParamsKeyMap();
34
+
35
+ export const { setMap: setImageParamsKeyMap, getMap: getImageParamsKeyMap } =
36
+ keyMap.getMethods();
@@ -0,0 +1,24 @@
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/lib/form-values';
11
+ export * from '@adobe-commerce/elsie/lib/classes';
12
+ export * from '@adobe-commerce/elsie/lib/deepmerge';
13
+ export * from '@adobe-commerce/elsie/lib/debounce';
14
+ export * from '@adobe-commerce/elsie/lib/resolve-image';
15
+ export * from '@adobe-commerce/elsie/lib/render';
16
+ export * from '@adobe-commerce/elsie/lib/i18n';
17
+ export * from '@adobe-commerce/elsie/lib/initializer';
18
+ export * from '@adobe-commerce/elsie/lib/config';
19
+ export * from '@adobe-commerce/elsie/lib/types';
20
+ export * from '@adobe-commerce/elsie/lib/slot';
21
+ export * from '@adobe-commerce/elsie/lib/vcomponent';
22
+ export * from '@adobe-commerce/elsie/lib/image-params-keymap';
23
+ export * from '@adobe-commerce/elsie/lib/is-number';
24
+ export * from '@adobe-commerce/elsie/lib/deviceUtils';
@@ -0,0 +1,134 @@
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 {
11
+ Config,
12
+ setImageParamsKeyMap,
13
+ } from '@adobe-commerce/elsie/lib';
14
+
15
+ type Listener = { off(): void };
16
+
17
+ type Listeners<T> = (config?: T) => Array<Listener | undefined>;
18
+
19
+ type Init<T> = (config?: T) => Promise<void>;
20
+
21
+ type Options<T> = { init: Init<T>; listeners: Listeners<T> };
22
+
23
+ export type Model<T = any, D = any> = {
24
+ transformer?: (data: D) => T & { [key: string]: any };
25
+ };
26
+
27
+ /**
28
+ * The `Initializer` class is responsible for setting up event listeners and initializing a module with the given configuration.
29
+ *
30
+ * @template T - The type of the configuration object.
31
+ * @class
32
+ */
33
+ export class Initializer<T> {
34
+ private _listeners: Listener[] = [];
35
+ listeners: Listeners<T>;
36
+ init: Init<T>;
37
+ config = new Config<T>({} as T);
38
+
39
+ /**
40
+ * Creates an instance of Initializer.
41
+ * @param options - The initialization options.
42
+ * @param options.init - A function that initializes the module.
43
+ * @param options.listeners - A function that sets up event listeners.
44
+ */
45
+ constructor({ init, listeners }: Options<T>) {
46
+ this.listeners = (config) => {
47
+ // Unbind existing listeners
48
+ this._listeners.forEach((listener) => listener.off());
49
+ // Bind new listeners
50
+ return (this._listeners = listeners(config) as Listener[]);
51
+ };
52
+
53
+ this.init = (options) => {
54
+ const { imageParamsKeyMap, ...rest } =
55
+ options as any;
56
+ this.config.setConfig({ ...this.config.getConfig(), ...rest });
57
+ setImageParamsKeyMap(imageParamsKeyMap);
58
+ return init(options);
59
+ };
60
+ }
61
+ }
62
+
63
+ type Initializers = [Initializer<any>, { [key: string]: any } | undefined][];
64
+
65
+ /**
66
+ * The Initializers class provides methods to register, mount, and configure initializers.
67
+ *
68
+ * @class
69
+ *
70
+ * @method register - Registers a new initializer. If the initializers have already been mounted, it immediately binds the event listeners and initializes the API for the new initializer.
71
+ * @method mount - Mounts all registered initializers. This involves binding the event listeners and initializing the APIs for each initializer, in that order.
72
+ * @method setImageParamKeys - Sets the image parameter keys. These keys are used when initializing the APIs for the initializers.
73
+ */
74
+ export class initializers {
75
+ static _initializers: Initializers = [];
76
+ static _mounted: boolean = false;
77
+ static _imageParamsKeyMap: { [key: string]: string } | undefined = undefined;
78
+ /**
79
+ * Registers a new initializer. If the initializers have already been mounted,it immediately binds the event listeners and initializes the API for the new initializer.
80
+ * @param initializer - The initializer to register.
81
+ * @param options - Optional configuration for the initializer.
82
+ */
83
+ static register(
84
+ initializer: Initializer<any>,
85
+ options?: { [key: string]: any }
86
+ ) {
87
+ if (initializers._mounted) {
88
+ initializer.listeners?.(options);
89
+ initializer.init?.(options);
90
+ }
91
+ initializers._initializers.push([initializer, options]);
92
+ }
93
+
94
+ /**
95
+ * Mounts the provided initializer immediately. This involves binding the event listeners and initializing the API for the initializer.
96
+ */
97
+ static async mountImmediately(
98
+ initializer: Initializer<any>,
99
+ options?: { [key: string]: any }
100
+ ) {
101
+ initializer.listeners?.(options);
102
+ await initializer.init?.({
103
+ imageParamsKeyMap: initializers._imageParamsKeyMap,
104
+ ...options,
105
+ });
106
+ }
107
+
108
+ /**
109
+ * Mounts all registered initializers. This involves binding the event listeners and initializing the APIs for each initializer, in that order.
110
+ */
111
+ static mount() {
112
+ initializers._mounted = true;
113
+ // In this specific order
114
+ // 1. Bind events
115
+ initializers._initializers?.forEach(([initializer, options]) => {
116
+ initializer.listeners?.(options);
117
+ });
118
+
119
+ // 2. Initialize APIs
120
+ initializers._initializers?.forEach(([initializer, options]) => {
121
+ initializer.init?.({
122
+ imageParamsKeyMap: initializers._imageParamsKeyMap,
123
+ ...options,
124
+ });
125
+ });
126
+ }
127
+ /**
128
+ * Sets the image parameter keys. These keys are used when initializing the APIs for the initializers.
129
+ * @param params - The image parameter keys.
130
+ */
131
+ static setImageParamKeys(params: { [key: string]: any }) {
132
+ initializers._imageParamsKeyMap = params;
133
+ }
134
+ }
@@ -0,0 +1,12 @@
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 const isNumber = (value: number | string): value is number => {
11
+ return typeof value === 'number';
12
+ };
@@ -0,0 +1,138 @@
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 { render, VNode, createContext } from 'preact';
11
+ import renderToString from 'preact-render-to-string';
12
+ import { Container, VComponent } from '@adobe-commerce/elsie/lib';
13
+ import { Signal, signal } from '@adobe-commerce/elsie/lib/signals';
14
+
15
+ export const SlotQueueContext = createContext<Signal<Set<string>> | null>(null);
16
+
17
+ type RenderAPI = {
18
+ remove: () => void;
19
+ setProps: (cb: (prev: any) => any) => void;
20
+ };
21
+
22
+ /**
23
+ * The `Render` class provides methods to render and unmount components, as well as to render components to a string.
24
+ * @class
25
+ *
26
+ * @property {Function} render - Renders a component to a root element.
27
+ * @property {Function} toString - Renders a component to a string.
28
+ */
29
+ export class Render {
30
+ private _provider: VNode<any>;
31
+
32
+ constructor(provider: VNode<any>) {
33
+ this._provider = provider;
34
+ }
35
+
36
+ /**
37
+ * Renders a container to a root element.
38
+ * @param Container - The container to render.
39
+ * @param props - The container parameters.
40
+ * @returns A function to render the component to a root element.
41
+ */
42
+ render<T>(Component: Container<T>, props: T) {
43
+ /**
44
+ * Renders a component to a root element.
45
+ * @param rootElement - The root element to render the component to.
46
+ * @returns A promise that resolves to an object with methods to control the rendered component.
47
+ */
48
+ return async (rootElement: HTMLElement): Promise<RenderAPI> => {
49
+ if (!Component) throw new Error('Component is not defined');
50
+ if (!rootElement) throw new Error('Root element is not defined');
51
+
52
+ const initialData = (await Component.getInitialData?.(props)) ?? {};
53
+
54
+ const state = signal<T>({ ...props });
55
+
56
+ const queue = signal<Set<string>>(new Set());
57
+
58
+ const provider = this._provider;
59
+
60
+ const Root = ({ next }: { next: Signal<T> }) => {
61
+ return (
62
+ <SlotQueueContext.Provider value={queue}>
63
+ <VComponent node={provider} {...provider.props}>
64
+ <Component {...next.value} initialData={initialData} />
65
+ </VComponent>
66
+ </SlotQueueContext.Provider>
67
+ );
68
+ };
69
+
70
+ // clear the root element
71
+ rootElement.innerHTML = '';
72
+
73
+ // clone the root element to initialize rendering on the background
74
+ const tmp = document.createElement('div');
75
+
76
+ // apply base design tokens and global styles to the root element
77
+ rootElement.classList.add('dropin-design');
78
+
79
+ render(<Root next={state} />, tmp);
80
+
81
+ // API object to control the rendered component
82
+ const API: RenderAPI = {
83
+ remove: () => {
84
+ render(null, tmp);
85
+ },
86
+ setProps: (cb: (prev: T) => T) => {
87
+ const next = cb(state.peek());
88
+ state.value = next;
89
+ },
90
+ };
91
+
92
+ // wait for all slots to be resolved
93
+ return new Promise((resolve) => {
94
+ queue.subscribe((pending) => {
95
+ if (pending.size === 0) {
96
+ // apply base design tokens and global styles to the root element
97
+ rootElement.classList.add('dropin-design');
98
+
99
+ // append the rendered component to the DOM only when all slots are resolved
100
+ rootElement.appendChild(tmp.firstChild ?? tmp);
101
+
102
+ return resolve(API);
103
+ }
104
+ });
105
+ });
106
+ };
107
+ }
108
+
109
+ /**
110
+ * UnRenders a component from a root element.
111
+ * @param rootElement - The root element to unmount the component from.
112
+ * @deprecated Use `remove` method from the returned object of the `mount` method instead.
113
+ */
114
+ unmount(rootElement: HTMLElement) {
115
+ if (!rootElement) throw new Error('Root element is not defined');
116
+ rootElement.firstChild?.remove();
117
+ }
118
+
119
+ /**
120
+ * Renders a component to a string.
121
+ * @param Component - The component to render.
122
+ * @param props - The component props.
123
+ * @param options - Optional rendering options.
124
+ */
125
+ async toString<T>(Component: Container<T>, props: T, options?: T) {
126
+ if (!Component) throw new Error('Component is not defined');
127
+
128
+ const initialData = (await Component.getInitialData?.(props)) ?? {};
129
+
130
+ return renderToString(
131
+ <VComponent node={this._provider} {...this._provider.props}>
132
+ <Component {...props} initialData={initialData} />
133
+ </VComponent>,
134
+ {},
135
+ { ...options }
136
+ );
137
+ }
138
+ }
@@ -0,0 +1,101 @@
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 { getImageParamsKeyMap } from '@adobe-commerce/elsie/lib/';
11
+
12
+ const BREAKPOINTS = {
13
+ medium: 768,
14
+ large: 1024,
15
+ xlarge: 1366,
16
+ xxlarge: 1920,
17
+ };
18
+
19
+ export interface ResolveImageUrlOptions {
20
+ width: number;
21
+ height?: number;
22
+ auto?: string;
23
+ quality?: number;
24
+ crop?: boolean;
25
+ fit?: string;
26
+ }
27
+
28
+ const resolveImageUrl = (url: string, _opts?: ResolveImageUrlOptions) => {
29
+ const [base, query] = url.split('?');
30
+ const params = new URLSearchParams(query);
31
+
32
+ const keyMapping = getImageParamsKeyMap();
33
+ const keyMappingKeys = (keyMapping && Object.keys(keyMapping)) || [];
34
+
35
+ let opts: any = {};
36
+ let unusedMapping = { ...keyMapping };
37
+
38
+ if (keyMappingKeys?.length > 0 && _opts) {
39
+ opts = Object.entries(_opts).reduce((acc, [key, value]) => {
40
+ const newKey = keyMapping![key];
41
+ if (typeof newKey === 'string') {
42
+ acc[newKey] = value;
43
+ } else if (typeof newKey === 'function') {
44
+ const [newKeyString, newValue] = newKey(value);
45
+ acc[newKeyString] = newValue;
46
+ }
47
+ delete unusedMapping![key];
48
+ return acc;
49
+ }, {} as { [key: string]: any });
50
+ } else {
51
+ opts = {
52
+ auto: 'webp',
53
+ quality: 80,
54
+ crop: false,
55
+ fit: 'cover',
56
+ ..._opts,
57
+ };
58
+ }
59
+
60
+ // Set unused mapping as default params
61
+ Object.entries(unusedMapping).forEach(([, value]) => {
62
+ if (typeof value === 'function') {
63
+ const [newKeyString, newValue] = value(undefined);
64
+ opts[newKeyString] = newValue;
65
+ }
66
+ });
67
+
68
+ // Append image optimization parameters
69
+ Object.entries(opts).forEach(([key, value]) => {
70
+ if (value !== undefined && value !== null) {
71
+ params.set(key, String(value));
72
+ }
73
+ });
74
+
75
+ return `${base}?${params.toString()}`;
76
+ };
77
+
78
+ export const generateSrcset = (
79
+ imageURL: string,
80
+ options: ResolveImageUrlOptions
81
+ ) => {
82
+ if (!imageURL || !options?.width) return;
83
+
84
+ const generateSrcsetUrl = (options: ResolveImageUrlOptions) => {
85
+ return resolveImageUrl(imageURL, {
86
+ ...options,
87
+ });
88
+ };
89
+
90
+ return Object.entries(BREAKPOINTS)
91
+ .map(([, value]) => {
92
+ // calculate breakpoints width
93
+ const relativeWidth = (options.width * value) / BREAKPOINTS.xxlarge;
94
+
95
+ return `${generateSrcsetUrl({
96
+ ...options,
97
+ width: relativeWidth,
98
+ })} ${value}w`;
99
+ })
100
+ .join(',\n');
101
+ };
@@ -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
+ // eslint-disable-next-line no-restricted-imports
11
+ export * from '@preact/signals';