@openedx/frontend-base 1.0.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (356) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +112 -0
  3. package/config/babel/babel.config.js +28 -0
  4. package/config/config-helpers/createConfig.js +13 -0
  5. package/config/config-helpers/createLintConfig.js +16 -0
  6. package/config/config-helpers/getBaseConfig.js +12 -0
  7. package/config/defaultConfigPaths.js +35 -0
  8. package/config/eslint/base.eslint.config.js +113 -0
  9. package/config/index.js +12 -0
  10. package/config/jest/jest.config.js +30 -0
  11. package/config/tsconfig.json +32 -0
  12. package/config/types.js +25 -0
  13. package/config/webpack/common-config/all/getCodeRules.js +52 -0
  14. package/config/webpack/common-config/all/getFileLoaderRules.js +26 -0
  15. package/config/webpack/common-config/all/getIgnoreWarnings.js +14 -0
  16. package/config/webpack/common-config/all/getImageMinimizer.js +25 -0
  17. package/config/webpack/common-config/all/getStylesheetRule.js +112 -0
  18. package/config/webpack/common-config/dev/getDevServer.js +38 -0
  19. package/config/webpack/common-config/index.js +18 -0
  20. package/config/webpack/common-config/site/getHtmlWebpackPlugin.js +16 -0
  21. package/config/webpack/plugins/html-webpack-new-relic-plugin/HtmlWebpackNewRelicPlugin.js +91 -0
  22. package/config/webpack/plugins/html-webpack-new-relic-plugin/index.js +7 -0
  23. package/config/webpack/plugins/html-webpack-new-relic-plugin/test/fixtures/entry.js +3 -0
  24. package/config/webpack/plugins/paragon-webpack-plugin/ParagonWebpackPlugin.js +108 -0
  25. package/config/webpack/plugins/paragon-webpack-plugin/index.js +7 -0
  26. package/config/webpack/plugins/paragon-webpack-plugin/utils/assetUtils.js +64 -0
  27. package/config/webpack/plugins/paragon-webpack-plugin/utils/htmlUtils.js +53 -0
  28. package/config/webpack/plugins/paragon-webpack-plugin/utils/index.js +9 -0
  29. package/config/webpack/plugins/paragon-webpack-plugin/utils/paragonStylesheetUtils.js +114 -0
  30. package/config/webpack/plugins/paragon-webpack-plugin/utils/scriptUtils.js +146 -0
  31. package/config/webpack/plugins/paragon-webpack-plugin/utils/stylesheetUtils.js +126 -0
  32. package/config/webpack/plugins/paragon-webpack-plugin/utils/tagUtils.js +57 -0
  33. package/config/webpack/types.js +2 -0
  34. package/config/webpack/utils/getLocalAliases.js +65 -0
  35. package/config/webpack/utils/getPublicPath.js +6 -0
  36. package/config/webpack/utils/getResolvedSiteConfigPath.js +32 -0
  37. package/config/webpack/utils/paragonUtils.js +138 -0
  38. package/config/webpack/webpack.config.build.js +80 -0
  39. package/config/webpack/webpack.config.dev.js +76 -0
  40. package/config/webpack/webpack.config.dev.shell.js +110 -0
  41. package/eslint.config.js +18 -0
  42. package/frontend-base.d.ts +8 -0
  43. package/index.ts +7 -0
  44. package/jest.config.js +7 -0
  45. package/openedx-frontend-base.tgz +0 -0
  46. package/package.json +149 -0
  47. package/runtime/analytics/MockAnalyticsService.js +71 -0
  48. package/runtime/analytics/SegmentAnalyticsService.js +243 -0
  49. package/runtime/analytics/index.ts +12 -0
  50. package/runtime/analytics/interface.js +145 -0
  51. package/runtime/auth/AxiosCsrfTokenService.js +60 -0
  52. package/runtime/auth/AxiosJwtAuthService.js +363 -0
  53. package/runtime/auth/AxiosJwtTokenService.js +134 -0
  54. package/runtime/auth/LocalForageCache.js +76 -0
  55. package/runtime/auth/MockAuthService.js +278 -0
  56. package/runtime/auth/index.ts +19 -0
  57. package/runtime/auth/interceptors/createCsrfTokenProviderInterceptor.js +36 -0
  58. package/runtime/auth/interceptors/createJwtTokenProviderInterceptor.js +37 -0
  59. package/runtime/auth/interceptors/createProcessAxiosRequestErrorInterceptor.js +20 -0
  60. package/runtime/auth/interceptors/createRetryInterceptor.js +74 -0
  61. package/runtime/auth/interface.js +309 -0
  62. package/runtime/auth/utils.js +105 -0
  63. package/runtime/babel.config.js +3 -0
  64. package/runtime/config/index.ts +295 -0
  65. package/runtime/constants.ts +68 -0
  66. package/runtime/i18n/index.js +118 -0
  67. package/runtime/i18n/injectIntlWithShim.jsx +48 -0
  68. package/runtime/i18n/lib.ts +272 -0
  69. package/runtime/index.ts +134 -0
  70. package/runtime/initialize.js +352 -0
  71. package/runtime/jest.config.js +32 -0
  72. package/runtime/logging/MockLoggingService.js +31 -0
  73. package/runtime/logging/NewRelicLoggingService.js +184 -0
  74. package/runtime/logging/index.ts +9 -0
  75. package/runtime/logging/interface.js +109 -0
  76. package/runtime/logging/types.ts +4 -0
  77. package/runtime/react/AuthenticatedPageRoute.jsx +43 -0
  78. package/runtime/react/CombinedAppProvider.tsx +46 -0
  79. package/runtime/react/CurrentAppContext.tsx +25 -0
  80. package/runtime/react/CurrentAppProvider.tsx +46 -0
  81. package/runtime/react/Divider.tsx +5 -0
  82. package/runtime/react/ErrorBoundary.jsx +47 -0
  83. package/runtime/react/ErrorPage.jsx +72 -0
  84. package/runtime/react/LoginRedirect.jsx +16 -0
  85. package/runtime/react/PageWrap.jsx +24 -0
  86. package/runtime/react/SiteContext.tsx +32 -0
  87. package/runtime/react/SiteProvider.tsx +78 -0
  88. package/runtime/react/hooks.ts +106 -0
  89. package/runtime/react/index.ts +19 -0
  90. package/runtime/routing/index.ts +1 -0
  91. package/runtime/routing/utils.ts +34 -0
  92. package/runtime/scripts/GoogleAnalyticsLoader.ts +59 -0
  93. package/runtime/scripts/index.ts +1 -0
  94. package/runtime/setupTest.js +49 -0
  95. package/runtime/slots/Slot.tsx +32 -0
  96. package/runtime/slots/SlotContext.tsx +8 -0
  97. package/runtime/slots/hooks.ts +35 -0
  98. package/runtime/slots/index.ts +7 -0
  99. package/runtime/slots/layout/DefaultSlotLayout.tsx +9 -0
  100. package/runtime/slots/layout/hooks.ts +65 -0
  101. package/runtime/slots/layout/index.ts +5 -0
  102. package/runtime/slots/layout/types.ts +45 -0
  103. package/runtime/slots/layout/utils.ts +14 -0
  104. package/runtime/slots/types.ts +23 -0
  105. package/runtime/slots/utils.ts +59 -0
  106. package/runtime/slots/widget/WidgetContext.tsx +9 -0
  107. package/runtime/slots/widget/WidgetProvider.tsx +30 -0
  108. package/runtime/slots/widget/hooks.ts +105 -0
  109. package/runtime/slots/widget/iframe/IFrameContentWrapper.messages.tsx +16 -0
  110. package/runtime/slots/widget/iframe/IFrameContentWrapper.tsx +84 -0
  111. package/runtime/slots/widget/iframe/IFrameWidget.tsx +59 -0
  112. package/runtime/slots/widget/iframe/constants.ts +19 -0
  113. package/runtime/slots/widget/iframe/hooks.ts +179 -0
  114. package/runtime/slots/widget/iframe/index.ts +6 -0
  115. package/runtime/slots/widget/iframe/types.ts +7 -0
  116. package/runtime/slots/widget/index.ts +6 -0
  117. package/runtime/slots/widget/types.ts +134 -0
  118. package/runtime/slots/widget/utils.tsx +201 -0
  119. package/runtime/subscriptions.ts +60 -0
  120. package/runtime/testing/index.ts +9 -0
  121. package/runtime/testing/initializeMockApp.ts +81 -0
  122. package/runtime/testing/mockMessages.ts +23 -0
  123. package/runtime/utils.js +178 -0
  124. package/shell/DefaultLayout.tsx +18 -0
  125. package/shell/DefaultMain.tsx +7 -0
  126. package/shell/Logo.tsx +28 -0
  127. package/shell/Shell.messages.ts +61 -0
  128. package/shell/Shell.tsx +18 -0
  129. package/shell/app.scss +149 -0
  130. package/shell/app.ts +24 -0
  131. package/shell/babel.config.js +3 -0
  132. package/shell/dev/devFooter/app.tsx +43 -0
  133. package/shell/dev/devFooter/index.ts +1 -0
  134. package/shell/dev/devHeader/BarContext.tsx +13 -0
  135. package/shell/dev/devHeader/BarLink.tsx +16 -0
  136. package/shell/dev/devHeader/BarProvider.tsx +25 -0
  137. package/shell/dev/devHeader/CoursesLink.tsx +16 -0
  138. package/shell/dev/devHeader/FooContext.tsx +13 -0
  139. package/shell/dev/devHeader/FooLink.tsx +16 -0
  140. package/shell/dev/devHeader/FooProvider.tsx +25 -0
  141. package/shell/dev/devHeader/app.tsx +53 -0
  142. package/shell/dev/devHeader/index.ts +1 -0
  143. package/shell/dev/devHeader/providers.tsx +11 -0
  144. package/shell/dev/devHome/HomePage.tsx +28 -0
  145. package/shell/dev/devHome/app.ts +18 -0
  146. package/shell/dev/devHome/i18n/index.ts +27 -0
  147. package/shell/dev/devHome/index.ts +1 -0
  148. package/shell/dev/devHome/messages.ts +11 -0
  149. package/shell/dev/devUser/app.tsx +24 -0
  150. package/shell/dev/devUser/index.ts +1 -0
  151. package/shell/dev/index.ts +5 -0
  152. package/shell/dev/slotShowcase/HorizontalSlotLayout.tsx +11 -0
  153. package/shell/dev/slotShowcase/LayoutWithOptions.tsx +17 -0
  154. package/shell/dev/slotShowcase/SlotShowcasePage.tsx +66 -0
  155. package/shell/dev/slotShowcase/WidgetWithOptions.tsx +11 -0
  156. package/shell/dev/slotShowcase/app.tsx +373 -0
  157. package/shell/dev/slotShowcase/index.ts +1 -0
  158. package/shell/footer/CenterLinks.tsx +11 -0
  159. package/shell/footer/CopyrightNotice.tsx +36 -0
  160. package/shell/footer/Footer.tsx +34 -0
  161. package/shell/footer/LabeledLinkColumn.tsx +19 -0
  162. package/shell/footer/LanguageMenu.tsx +35 -0
  163. package/shell/footer/LanguageMenuItem.tsx +23 -0
  164. package/shell/footer/LeftLinks.tsx +11 -0
  165. package/shell/footer/LegalNotices.tsx +17 -0
  166. package/shell/footer/PoweredBy.tsx +17 -0
  167. package/shell/footer/RevealLinks.tsx +43 -0
  168. package/shell/footer/RightLinks.tsx +11 -0
  169. package/shell/footer/app.tsx +73 -0
  170. package/shell/footer/data/api.ts +48 -0
  171. package/shell/footer/index.ts +2 -0
  172. package/shell/header/AuthenticatedMenu.tsx +32 -0
  173. package/shell/header/Header.tsx +17 -0
  174. package/shell/header/anonymous-menu/AnonymousMenu.tsx +14 -0
  175. package/shell/header/anonymous-menu/LoginButton.tsx +14 -0
  176. package/shell/header/anonymous-menu/RegisterButton.tsx +15 -0
  177. package/shell/header/app.tsx +142 -0
  178. package/shell/header/desktop/DesktopLayout.tsx +22 -0
  179. package/shell/header/desktop/PrimaryNavLinks.tsx +10 -0
  180. package/shell/header/desktop/SecondaryNavLinks.tsx +10 -0
  181. package/shell/header/index.ts +2 -0
  182. package/shell/header/mobile/MobileLayout.tsx +47 -0
  183. package/shell/header/mobile/MobileNavLinks.tsx +10 -0
  184. package/shell/i18n/index.ts +25 -0
  185. package/shell/index.ts +7 -0
  186. package/shell/jest.config.js +30 -0
  187. package/shell/menus/LinkMenuItem.tsx +64 -0
  188. package/shell/menus/NavDropdownMenuSlot.tsx +29 -0
  189. package/shell/menus/ProfileLinkMenuItem.tsx +33 -0
  190. package/shell/menus/data/utils.ts +19 -0
  191. package/shell/public/index.html +10 -0
  192. package/shell/router/createRouter.ts +17 -0
  193. package/shell/router/getAppRoutes.ts +21 -0
  194. package/shell/setupTest.js +48 -0
  195. package/shell/site.config.dev.tsx +49 -0
  196. package/shell/site.tsx +41 -0
  197. package/test-site/app.d.ts +15 -0
  198. package/test-site/dist/176.436443549ebb858db483.js +2 -0
  199. package/test-site/dist/176.436443549ebb858db483.js.map +1 -0
  200. package/test-site/dist/362.536eff787d2380fe246c.js +2 -0
  201. package/test-site/dist/362.536eff787d2380fe246c.js.map +1 -0
  202. package/test-site/dist/653.486966b108d224551296.js +2 -0
  203. package/test-site/dist/653.486966b108d224551296.js.map +1 -0
  204. package/test-site/dist/74e025d3fe9a7b7f8503054e2563b353.jpg +0 -0
  205. package/test-site/dist/806.323cf6496ad0a7fe73a7.js +3 -0
  206. package/test-site/dist/806.323cf6496ad0a7fe73a7.js.LICENSE.txt +106 -0
  207. package/test-site/dist/806.323cf6496ad0a7fe73a7.js.map +1 -0
  208. package/test-site/dist/95ec738c0b7faac5b5c9126794446bbd.svg +4 -0
  209. package/test-site/dist/app.612058b36c74787759ac.css +61 -0
  210. package/test-site/dist/app.612058b36c74787759ac.css.map +1 -0
  211. package/test-site/dist/app.612058b36c74787759ac.js +2 -0
  212. package/test-site/dist/app.612058b36c74787759ac.js.map +1 -0
  213. package/test-site/dist/cb28cdb1468c915e27e5cec9af64f22f.svg +1 -0
  214. package/test-site/dist/index.html +1 -0
  215. package/test-site/dist/report.html +39 -0
  216. package/test-site/dist/runtime.c7aeaf7b967496cb076f.js +2 -0
  217. package/test-site/dist/runtime.c7aeaf7b967496cb076f.js.map +1 -0
  218. package/test-site/eslint.config.js +12 -0
  219. package/test-site/package-lock.json +19226 -0
  220. package/test-site/package.json +29 -0
  221. package/test-site/public/index.html +10 -0
  222. package/test-site/site.config.build.tsx +27 -0
  223. package/test-site/site.config.dev.tsx +27 -0
  224. package/test-site/src/authenticated-page/AuthenticatedPage.tsx +18 -0
  225. package/test-site/src/authenticated-page/i18n/index.ts +27 -0
  226. package/test-site/src/authenticated-page/index.tsx +28 -0
  227. package/test-site/src/example-page/ExamplePage.tsx +79 -0
  228. package/test-site/src/example-page/Image.tsx +11 -0
  229. package/test-site/src/example-page/ParagonPreview.jsx +66 -0
  230. package/test-site/src/example-page/apple.jpg +0 -0
  231. package/test-site/src/example-page/apple.svg +1 -0
  232. package/test-site/src/example-page/index.ts +16 -0
  233. package/test-site/src/i18n/README.md +3 -0
  234. package/test-site/src/i18n/messages/frontend-app-sample/ar.json +4 -0
  235. package/test-site/src/i18n/messages/frontend-app-sample/eo.json +1 -0
  236. package/test-site/src/i18n/messages/frontend-app-sample/es_419.json +4 -0
  237. package/test-site/src/i18n/messages/frontend-component-emptylangs/ar.json +1 -0
  238. package/test-site/src/i18n/messages/frontend-component-singlelang/ar.json +3 -0
  239. package/test-site/src/iframe-widget/IframeWidget.tsx +14 -0
  240. package/test-site/src/iframe-widget/index.ts +16 -0
  241. package/test-site/src/index.tsx +3 -0
  242. package/test-site/src/messages.js +11 -0
  243. package/test-site/src/site.scss +11 -0
  244. package/test-site/tsconfig.json +14 -0
  245. package/tools/babel/babel.config.js +27 -0
  246. package/tools/babel.config.js +3 -0
  247. package/tools/cli/README.md +29 -0
  248. package/tools/cli/commands/pack.ts +9 -0
  249. package/tools/cli/commands/release.ts +27 -0
  250. package/tools/cli/commands/serve.ts +43 -0
  251. package/tools/cli/intl-imports.ts +274 -0
  252. package/tools/cli/openedx.ts +101 -0
  253. package/tools/cli/transifex-utils.ts +75 -0
  254. package/tools/cli/utils/ensureConfigFilenameOption.ts +40 -0
  255. package/tools/cli/utils/formatter.ts +10 -0
  256. package/tools/cli/utils/getResolvedConfigPath.ts +23 -0
  257. package/tools/cli/utils/prettyPrintTitle.ts +15 -0
  258. package/tools/cli/utils/printUsage.ts +53 -0
  259. package/tools/config-helpers/createConfig.ts +8 -0
  260. package/tools/config-helpers/createLintConfig.ts +14 -0
  261. package/tools/config-helpers/getBaseConfig.ts +11 -0
  262. package/tools/defaultConfigPaths.ts +30 -0
  263. package/tools/dist/babel/babel.config.js +28 -0
  264. package/tools/dist/cli/commands/pack.js +14 -0
  265. package/tools/dist/cli/commands/release.js +28 -0
  266. package/tools/dist/cli/commands/serve.js +44 -0
  267. package/tools/dist/cli/intl-imports.js +233 -0
  268. package/tools/dist/cli/openedx.js +100 -0
  269. package/tools/dist/cli/transifex-utils.js +68 -0
  270. package/tools/dist/cli/utils/ensureConfigFilenameOption.js +42 -0
  271. package/tools/dist/cli/utils/formatter.js +10 -0
  272. package/tools/dist/cli/utils/getResolvedConfigPath.js +28 -0
  273. package/tools/dist/cli/utils/prettyPrintTitle.js +17 -0
  274. package/tools/dist/cli/utils/printUsage.js +48 -0
  275. package/tools/dist/config-helpers/createConfig.js +13 -0
  276. package/tools/dist/config-helpers/createLintConfig.js +16 -0
  277. package/tools/dist/config-helpers/getBaseConfig.js +12 -0
  278. package/tools/dist/defaultConfigPaths.js +35 -0
  279. package/tools/dist/eslint/base.eslint.config.js +113 -0
  280. package/tools/dist/eslint.config.js +11 -0
  281. package/tools/dist/index.js +12 -0
  282. package/tools/dist/jest/jest.config.js +30 -0
  283. package/tools/dist/jest.config.js +20 -0
  284. package/tools/dist/types.js +25 -0
  285. package/tools/dist/typescript/tsconfig.json +32 -0
  286. package/tools/dist/webpack/common-config/all/getCodeRules.js +52 -0
  287. package/tools/dist/webpack/common-config/all/getFileLoaderRules.js +26 -0
  288. package/tools/dist/webpack/common-config/all/getIgnoreWarnings.js +14 -0
  289. package/tools/dist/webpack/common-config/all/getImageMinimizer.js +25 -0
  290. package/tools/dist/webpack/common-config/all/getStylesheetRule.js +112 -0
  291. package/tools/dist/webpack/common-config/dev/getDevServer.js +38 -0
  292. package/tools/dist/webpack/common-config/index.js +18 -0
  293. package/tools/dist/webpack/common-config/site/getHtmlWebpackPlugin.js +16 -0
  294. package/tools/dist/webpack/plugins/html-webpack-new-relic-plugin/HtmlWebpackNewRelicPlugin.js +91 -0
  295. package/tools/dist/webpack/plugins/html-webpack-new-relic-plugin/index.js +7 -0
  296. package/tools/dist/webpack/plugins/html-webpack-new-relic-plugin/test/fixtures/entry.js +3 -0
  297. package/tools/dist/webpack/plugins/paragon-webpack-plugin/ParagonWebpackPlugin.js +108 -0
  298. package/tools/dist/webpack/plugins/paragon-webpack-plugin/index.js +7 -0
  299. package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/assetUtils.js +64 -0
  300. package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/htmlUtils.js +53 -0
  301. package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/index.js +9 -0
  302. package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/paragonStylesheetUtils.js +114 -0
  303. package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/scriptUtils.js +146 -0
  304. package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/stylesheetUtils.js +126 -0
  305. package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/tagUtils.js +57 -0
  306. package/tools/dist/webpack/types.js +2 -0
  307. package/tools/dist/webpack/utils/getLocalAliases.js +65 -0
  308. package/tools/dist/webpack/utils/getPublicPath.js +6 -0
  309. package/tools/dist/webpack/utils/getResolvedSiteConfigPath.js +32 -0
  310. package/tools/dist/webpack/utils/paragonUtils.js +138 -0
  311. package/tools/dist/webpack/webpack.config.build.js +80 -0
  312. package/tools/dist/webpack/webpack.config.dev.js +76 -0
  313. package/tools/dist/webpack/webpack.config.dev.shell.js +110 -0
  314. package/tools/eslint/base.eslint.config.js +124 -0
  315. package/tools/eslint/modules.d.ts +5 -0
  316. package/tools/eslint.config.js +15 -0
  317. package/tools/index.ts +3 -0
  318. package/tools/jest/jest.config.js +30 -0
  319. package/tools/jest.config.js +19 -0
  320. package/tools/tsconfig.json +24 -0
  321. package/tools/types.ts +21 -0
  322. package/tools/typescript/tsconfig.json +32 -0
  323. package/tools/webpack/common-config/README.md +15 -0
  324. package/tools/webpack/common-config/all/getCodeRules.ts +51 -0
  325. package/tools/webpack/common-config/all/getFileLoaderRules.ts +23 -0
  326. package/tools/webpack/common-config/all/getIgnoreWarnings.ts +13 -0
  327. package/tools/webpack/common-config/all/getImageMinimizer.ts +26 -0
  328. package/tools/webpack/common-config/all/getStylesheetRule.ts +111 -0
  329. package/tools/webpack/common-config/dev/getDevServer.ts +35 -0
  330. package/tools/webpack/common-config/index.ts +6 -0
  331. package/tools/webpack/common-config/site/getHtmlWebpackPlugin.ts +11 -0
  332. package/tools/webpack/modules.d.ts +6 -0
  333. package/tools/webpack/plugins/html-webpack-new-relic-plugin/HtmlWebpackNewRelicPlugin.ts +102 -0
  334. package/tools/webpack/plugins/html-webpack-new-relic-plugin/LICENSE +21 -0
  335. package/tools/webpack/plugins/html-webpack-new-relic-plugin/README.md +7 -0
  336. package/tools/webpack/plugins/html-webpack-new-relic-plugin/index.js +3 -0
  337. package/tools/webpack/plugins/html-webpack-new-relic-plugin/test/fixtures/entry.js +1 -0
  338. package/tools/webpack/plugins/paragon-webpack-plugin/ParagonWebpackPlugin.ts +134 -0
  339. package/tools/webpack/plugins/paragon-webpack-plugin/index.ts +3 -0
  340. package/tools/webpack/plugins/paragon-webpack-plugin/utils/assetUtils.ts +71 -0
  341. package/tools/webpack/plugins/paragon-webpack-plugin/utils/htmlUtils.ts +72 -0
  342. package/tools/webpack/plugins/paragon-webpack-plugin/utils/index.ts +6 -0
  343. package/tools/webpack/plugins/paragon-webpack-plugin/utils/paragonStylesheetUtils.ts +131 -0
  344. package/tools/webpack/plugins/paragon-webpack-plugin/utils/scriptUtils.ts +144 -0
  345. package/tools/webpack/plugins/paragon-webpack-plugin/utils/stylesheetUtils.ts +106 -0
  346. package/tools/webpack/plugins/paragon-webpack-plugin/utils/tagUtils.ts +54 -0
  347. package/tools/webpack/types.ts +69 -0
  348. package/tools/webpack/utils/getLocalAliases.ts +65 -0
  349. package/tools/webpack/utils/getPublicPath.ts +3 -0
  350. package/tools/webpack/utils/getResolvedSiteConfigPath.ts +28 -0
  351. package/tools/webpack/utils/paragonUtils.ts +152 -0
  352. package/tools/webpack/webpack.config.build.ts +93 -0
  353. package/tools/webpack/webpack.config.dev.shell.ts +122 -0
  354. package/tools/webpack/webpack.config.dev.ts +90 -0
  355. package/tsconfig.json +23 -0
  356. package/types.ts +99 -0
@@ -0,0 +1,18 @@
1
+ import {
2
+ SiteProvider,
3
+ Slot
4
+ } from '../runtime';
5
+ import { useActiveRouteRoleWatcher, useTrackColorSchemeChoice } from '../runtime/react/hooks';
6
+
7
+ import DefaultLayout from './DefaultLayout';
8
+
9
+ export default function Shell() {
10
+ useActiveRouteRoleWatcher();
11
+ useTrackColorSchemeChoice();
12
+
13
+ return (
14
+ <SiteProvider>
15
+ <Slot id="org.openedx.frontend.slot.layout.main.v1" layout={DefaultLayout} />
16
+ </SiteProvider>
17
+ );
18
+ }
package/shell/app.scss ADDED
@@ -0,0 +1,149 @@
1
+ @use "@openedx/paragon/scss/core/core.scss";
2
+
3
+ .flex-basis-0 {
4
+ flex-basis: 0 !important;
5
+ }
6
+
7
+ .gap-0 {
8
+ gap: 0px;
9
+ }
10
+
11
+ .gap-1 {
12
+ gap: 4px;
13
+ }
14
+
15
+ .gap-1\.5 {
16
+ gap: 6px;
17
+ }
18
+
19
+ .gap-2 {
20
+ gap: 8px;
21
+ }
22
+
23
+ .gap-2\.5 {
24
+ gap: 12px;
25
+ }
26
+
27
+ .gap-3 {
28
+ gap: 16px;
29
+ }
30
+
31
+ .gap-3\.5 {
32
+ gap: 20px;
33
+ }
34
+
35
+ .gap-4 {
36
+ gap: 24px;
37
+ }
38
+
39
+ .gap-4\.5 {
40
+ gap: 32px;
41
+ }
42
+
43
+ .gap-5 {
44
+ gap: 48px;
45
+ }
46
+
47
+ .gap-5\.5 {
48
+ gap: 64px;
49
+ }
50
+
51
+ .gap-6 {
52
+ gap: 80px;
53
+ }
54
+
55
+ .row-gap-0 {
56
+ row-gap: 0px;
57
+ }
58
+
59
+ .row-gap-1 {
60
+ row-gap: 4px;
61
+ }
62
+
63
+ .row-gap-1\.5 {
64
+ row-gap: 6px;
65
+ }
66
+
67
+ .row-gap-2 {
68
+ row-gap: 8px;
69
+ }
70
+
71
+ .row-gap-2\.5 {
72
+ row-gap: 12px;
73
+ }
74
+
75
+ .row-gap-3 {
76
+ row-gap: 16px;
77
+ }
78
+
79
+ .row-gap-3\.5 {
80
+ row-gap: 20px;
81
+ }
82
+
83
+ .row-gap-4 {
84
+ row-gap: 24px;
85
+ }
86
+
87
+ .row-gap-4\.5 {
88
+ row-gap: 32px;
89
+ }
90
+
91
+ .row-gap-5 {
92
+ row-gap: 48px;
93
+ }
94
+
95
+ .row-gap-5\.5 {
96
+ row-gap: 64px;
97
+ }
98
+
99
+ .row-gap-6 {
100
+ row-gap: 80px;
101
+ }
102
+
103
+ .column-gap-0 {
104
+ column-gap: 0px;
105
+ }
106
+
107
+ .column-gap-1 {
108
+ column-gap: 4px;
109
+ }
110
+
111
+ .column-gap-1\.5 {
112
+ column-gap: 6px;
113
+ }
114
+
115
+ .column-gap-2 {
116
+ column-gap: 8px;
117
+ }
118
+
119
+ .column-gap-2\.5 {
120
+ column-gap: 12px;
121
+ }
122
+
123
+ .column-gap-3 {
124
+ column-gap: 16px;
125
+ }
126
+
127
+ .column-gap-3\.5 {
128
+ column-gap: 20px;
129
+ }
130
+
131
+ .column-gap-4 {
132
+ column-gap: 24px;
133
+ }
134
+
135
+ .column-gap-4\.5 {
136
+ column-gap: 32px;
137
+ }
138
+
139
+ .column-gap-5 {
140
+ column-gap: 48px;
141
+ }
142
+
143
+ .column-gap-5\.5 {
144
+ column-gap: 64px;
145
+ }
146
+
147
+ .column-gap-6 {
148
+ column-gap: 80px;
149
+ }
package/shell/app.ts ADDED
@@ -0,0 +1,24 @@
1
+ import { WidgetOperationTypes } from '../runtime';
2
+ import { App } from '../types';
3
+ import { Footer } from './footer';
4
+ import { Header } from './header';
5
+
6
+ const app: App = {
7
+ appId: 'org.openedx.frontend.app.shell',
8
+ slots: [
9
+ {
10
+ slotId: 'org.openedx.frontend.slot.header.main.v1',
11
+ id: 'org.openedx.frontend.widget.header.main.v1',
12
+ op: WidgetOperationTypes.APPEND,
13
+ component: Header,
14
+ },
15
+ {
16
+ slotId: 'org.openedx.frontend.slot.footer.main.v1',
17
+ id: 'org.openedx.frontend.widget.footer.main.v1',
18
+ op: WidgetOperationTypes.APPEND,
19
+ component: Footer,
20
+ },
21
+ ]
22
+ };
23
+
24
+ export default app;
@@ -0,0 +1,3 @@
1
+ const config = require('../tools/babel/babel.config');
2
+
3
+ module.exports = config;
@@ -0,0 +1,43 @@
1
+ import { Button } from '@openedx/paragon';
2
+ import { LayoutOperationTypes, WidgetOperationTypes } from '../../../runtime';
3
+ import { App, } from '../../../types';
4
+ import LinkMenuItem from '../../menus/LinkMenuItem';
5
+
6
+ const app: App = {
7
+ appId: 'org.openedx.frontend.app.dev.footer',
8
+ slots: [
9
+ {
10
+ slotId: 'org.openedx.frontend.slot.footer.desktopTop.v1',
11
+ id: 'footer.booyah.revealed',
12
+ op: WidgetOperationTypes.APPEND,
13
+ element: (
14
+ <Button>I are button</Button>
15
+ )
16
+ },
17
+ {
18
+ slotId: 'org.openedx.frontend.slot.footer.desktopTop.v1',
19
+ op: LayoutOperationTypes.OPTIONS,
20
+ options: {
21
+ label: 'I Reveal Buttons',
22
+ }
23
+ },
24
+ {
25
+ slotId: 'org.openedx.frontend.slot.footer.desktopTop.v1',
26
+ id: 'footer.booyah.revealed.linky',
27
+ op: WidgetOperationTypes.APPEND,
28
+ element: (
29
+ <Button>I Are Another Button</Button>
30
+ )
31
+ },
32
+ {
33
+ slotId: 'org.openedx.frontend.slot.footer.desktopCenterLink1.v1',
34
+ id: 'footer.booyah.centerLinks.first.1',
35
+ op: WidgetOperationTypes.APPEND,
36
+ element: (
37
+ <LinkMenuItem label="Link 1" url="#" />
38
+ )
39
+ },
40
+ ]
41
+ };
42
+
43
+ export default app;
@@ -0,0 +1 @@
1
+ export { default as devFooterApp } from './app';
@@ -0,0 +1,13 @@
1
+ import { createContext, Dispatch, SetStateAction } from 'react';
2
+
3
+ interface BarContextInterface {
4
+ bar: string,
5
+ setBar: Dispatch<SetStateAction<string>>,
6
+ };
7
+
8
+ const BarContext = createContext<BarContextInterface>({
9
+ bar: '',
10
+ setBar: () => { }
11
+ });
12
+
13
+ export default BarContext;
@@ -0,0 +1,16 @@
1
+ import { useContext } from 'react';
2
+ import { Icon } from '@openedx/paragon';
3
+ import { CrisisAlert } from '@openedx/paragon/icons';
4
+
5
+ import BarContext from './BarContext';
6
+
7
+ export default function BarLink() {
8
+ const { bar } = useContext(BarContext);
9
+
10
+ return (
11
+ <div className="d-flex">
12
+ <Icon src={CrisisAlert} className="mr-2" />
13
+ <span>{bar}</span>
14
+ </div>
15
+ );
16
+ }
@@ -0,0 +1,25 @@
1
+ import { ReactNode, useMemo, useState } from 'react';
2
+ import BarContext from './BarContext';
3
+
4
+ function getBar() {
5
+ return 'Bar';
6
+ }
7
+
8
+ interface BarProviderProps {
9
+ children?: ReactNode,
10
+ }
11
+
12
+ export default function BarProvider({ children }: BarProviderProps) {
13
+ const [bar, setBar] = useState(getBar());
14
+
15
+ const barContextValue = useMemo(() => ({
16
+ bar,
17
+ setBar,
18
+ }), [bar, setBar]);
19
+
20
+ return (
21
+ <BarContext.Provider value={barContextValue}>
22
+ {children}
23
+ </BarContext.Provider>
24
+ );
25
+ };
@@ -0,0 +1,16 @@
1
+ import { Icon } from '@openedx/paragon';
2
+ import { BookOpen } from '@openedx/paragon/icons';
3
+
4
+ import { useWidgetOptions } from '../../../runtime';
5
+
6
+ export default function CoursesLink() {
7
+ const options = useWidgetOptions();
8
+ const title = typeof options.title === 'string' ? options.title : 'Courses';
9
+
10
+ return (
11
+ <div className="d-flex">
12
+ <Icon src={BookOpen} className="mr-2" />
13
+ <span>{title}</span>
14
+ </div>
15
+ );
16
+ }
@@ -0,0 +1,13 @@
1
+ import { createContext, Dispatch, SetStateAction } from 'react';
2
+
3
+ interface FooContextInterface {
4
+ foo: string,
5
+ setFoo: Dispatch<SetStateAction<string>>,
6
+ };
7
+
8
+ const FooContext = createContext<FooContextInterface>({
9
+ foo: '',
10
+ setFoo: () => { }
11
+ });
12
+
13
+ export default FooContext;
@@ -0,0 +1,16 @@
1
+ import { useContext } from 'react';
2
+ import { Icon } from '@openedx/paragon';
3
+ import { Kitesurfing } from '@openedx/paragon/icons';
4
+
5
+ import FooContext from './FooContext';
6
+
7
+ export default function FooLink() {
8
+ const { foo } = useContext(FooContext);
9
+
10
+ return (
11
+ <div className="d-flex">
12
+ <Icon src={Kitesurfing} className="mr-2" />
13
+ <span>{foo}</span>
14
+ </div>
15
+ );
16
+ }
@@ -0,0 +1,25 @@
1
+ import { ReactNode, useMemo, useState } from 'react';
2
+ import FooContext from './FooContext';
3
+
4
+ function getFoo() {
5
+ return 'Foo';
6
+ }
7
+
8
+ interface FooProviderProps {
9
+ children?: ReactNode,
10
+ }
11
+
12
+ export default function FooProvider({ children }: FooProviderProps) {
13
+ const [foo, setFoo] = useState(getFoo());
14
+
15
+ const fooContextValue = useMemo(() => ({
16
+ foo,
17
+ setFoo,
18
+ }), [foo, setFoo]);
19
+
20
+ return (
21
+ <FooContext.Provider value={fooContextValue}>
22
+ {children}
23
+ </FooContext.Provider>
24
+ );
25
+ };
@@ -0,0 +1,53 @@
1
+ import { WidgetOperationTypes } from '../../../runtime';
2
+ import { App } from '../../../types';
3
+ import LinkMenuItem from '../../menus/LinkMenuItem';
4
+ import CoursesLink from './CoursesLink';
5
+ import FooLink from './FooLink';
6
+ import BarLink from './BarLink';
7
+ import providers from './providers';
8
+
9
+ const app: App = {
10
+ appId: 'org.openedx.frontend.app.dev.header',
11
+ slots: [
12
+ {
13
+ slotId: 'org.openedx.frontend.slot.header.primaryLinks.v1',
14
+ id: 'org.openedx.frontend.widget.slotShowcase.headerLink',
15
+ op: WidgetOperationTypes.APPEND,
16
+ element: (
17
+ <LinkMenuItem
18
+ label={<CoursesLink />}
19
+ url="#"
20
+ variant="navLink"
21
+ />
22
+ )
23
+ },
24
+ {
25
+ slotId: 'org.openedx.frontend.slot.header.primaryLinks.v1',
26
+ id: 'org.openedx.frontend.widget.slotShowcase.headerLink2a',
27
+ op: WidgetOperationTypes.APPEND,
28
+ element: (
29
+ <LinkMenuItem
30
+ label={<FooLink />}
31
+ url="#"
32
+ variant="navLink"
33
+ />
34
+ )
35
+ },
36
+ {
37
+ slotId: 'org.openedx.frontend.slot.header.primaryLinks.v1',
38
+ id: 'org.openedx.frontend.widget.slotShowcase.headerLink2b',
39
+ op: WidgetOperationTypes.APPEND,
40
+ condition: { authenticated: true },
41
+ element: (
42
+ <LinkMenuItem
43
+ label={<BarLink />}
44
+ url="#"
45
+ variant="navLink"
46
+ />
47
+ )
48
+ },
49
+ ],
50
+ providers
51
+ };
52
+
53
+ export default app;
@@ -0,0 +1 @@
1
+ export { default as devHeaderApp } from './app';
@@ -0,0 +1,11 @@
1
+ import { AppProvider } from '../../../types';
2
+
3
+ import FooProvider from './FooProvider';
4
+ import BarProvider from './BarProvider';
5
+
6
+ const providers: AppProvider[] = [
7
+ FooProvider,
8
+ BarProvider,
9
+ ];
10
+
11
+ export default providers;
@@ -0,0 +1,28 @@
1
+ import { Link } from 'react-router-dom';
2
+ import { useIntl } from '../../../runtime';
3
+ import { getUrlByRouteRole } from '../../../runtime/routing';
4
+ import messages from './messages';
5
+
6
+ export default function HomePage() {
7
+ const coursewareUrl = getUrlByRouteRole('courseware');
8
+ const dashboardUrl = getUrlByRouteRole('learnerDashboard');
9
+ const slotShowcaseUrl = getUrlByRouteRole('slotShowcase');
10
+ const intl = useIntl();
11
+
12
+ return (
13
+ <div className="p-3">
14
+ <p>{intl.formatMessage(messages.homeContent)}</p>
15
+ <ul>
16
+ {coursewareUrl !== null && (
17
+ <li><Link to={coursewareUrl}>Go to courseware page</Link></li>
18
+ )}
19
+ {dashboardUrl !== null && (
20
+ <li><Link to={dashboardUrl}>Go to dashboard page</Link></li>
21
+ )}
22
+ {slotShowcaseUrl !== null && (
23
+ <li><Link to={slotShowcaseUrl}>Go to slot showcase page</Link></li>
24
+ )}
25
+ </ul>
26
+ </div>
27
+ );
28
+ }
@@ -0,0 +1,18 @@
1
+ import { App } from '../../../types';
2
+ import HomePage from './HomePage';
3
+ import messages from './i18n';
4
+
5
+ const app: App = {
6
+ appId: 'org.openedx.frontend.app.dev.home',
7
+ routes: [{
8
+ path: '/',
9
+ id: 'dev.home',
10
+ Component: HomePage,
11
+ handle: {
12
+ role: 'home'
13
+ }
14
+ }],
15
+ messages,
16
+ };
17
+
18
+ export default app;
@@ -0,0 +1,27 @@
1
+ // Placeholder be overridden by `make pull_translations`
2
+ export default {
3
+ ar: {},
4
+ 'zh-hk': {},
5
+ 'zh-cn': {},
6
+ uk: {},
7
+ 'tr-tr': {},
8
+ th: {},
9
+ te: {},
10
+ ru: {},
11
+ 'pt-pt': {},
12
+ 'pt-br': {},
13
+ 'it-it': {},
14
+ id: {},
15
+ hi: {},
16
+ he: {},
17
+ 'fr-ca': {
18
+ 'home.content': 'Home content in French.'
19
+ },
20
+ fa: {},
21
+ 'es-es': {},
22
+ 'es-419': {},
23
+ el: {},
24
+ 'de-de': {},
25
+ da: {},
26
+ bo: {},
27
+ };
@@ -0,0 +1 @@
1
+ export { default as devHomeApp } from './app';
@@ -0,0 +1,11 @@
1
+ import { defineMessages } from '../../../runtime';
2
+
3
+ const messages = defineMessages({
4
+ homeContent: {
5
+ id: 'home.content',
6
+ defaultMessage: 'Home page content.',
7
+ description: 'Content for the dev project home page.',
8
+ },
9
+ });
10
+
11
+ export default messages;
@@ -0,0 +1,24 @@
1
+ import { WidgetOperationTypes } from '../../../runtime';
2
+ import { App } from '../../../types';
3
+ import LoginButton from '../../header/anonymous-menu/LoginButton';
4
+ import RegisterButton from '../../header/anonymous-menu/RegisterButton';
5
+
6
+ const app: App = {
7
+ appId: 'org.openedx.frontend.app.dev.user',
8
+ slots: [
9
+ {
10
+ slotId: 'org.openedx.frontend.slot.header.anonymousMenu.v1',
11
+ id: 'user.anonymousMenu.loginButton',
12
+ op: WidgetOperationTypes.APPEND,
13
+ component: LoginButton,
14
+ },
15
+ {
16
+ slotId: 'org.openedx.frontend.slot.header.anonymousMenu.v1',
17
+ id: 'user.anonymousMenu.registerButton',
18
+ op: WidgetOperationTypes.APPEND,
19
+ component: RegisterButton,
20
+ },
21
+ ]
22
+ };
23
+
24
+ export default app;
@@ -0,0 +1 @@
1
+ export { default as devUserApp } from './app';
@@ -0,0 +1,5 @@
1
+ export { devFooterApp } from './devFooter';
2
+ export { devHeaderApp } from './devHeader';
3
+ export { devHomeApp } from './devHome';
4
+ export { devUserApp } from './devUser';
5
+ export { slotShowcaseApp } from './slotShowcase';
@@ -0,0 +1,11 @@
1
+ import { useWidgets } from '../../../runtime';
2
+
3
+ export default function HorizontalSlotLayout() {
4
+ const widgets = useWidgets();
5
+
6
+ return (
7
+ <div className="d-flex gap-3">
8
+ {widgets}
9
+ </div>
10
+ );
11
+ }
@@ -0,0 +1,17 @@
1
+ import { useLayoutOptions, useWidgets } from '../../../runtime';
2
+
3
+ export default function LayoutWithOptions() {
4
+ const widgets = useWidgets();
5
+ const options = useLayoutOptions();
6
+
7
+ const title = typeof options.title === 'string' ? options.title : 'Foo';
8
+
9
+ return (
10
+ <>
11
+ <div>Layout Title: <strong>{title}</strong></div>
12
+ <div>
13
+ {widgets}
14
+ </div>
15
+ </>
16
+ );
17
+ }
@@ -0,0 +1,66 @@
1
+ import { Slot } from '../../../runtime';
2
+ import HorizontalSlotLayout from './HorizontalSlotLayout';
3
+ import LayoutWithOptions from './LayoutWithOptions';
4
+
5
+ export default function SlotShowcasePage() {
6
+ return (
7
+ <div className="p-3">
8
+ <h1>Slot Showcase</h1>
9
+
10
+ <p>As a best practice, widgets should pass additional props (<code>...props</code>) to their rendered HTMLElement. This accomplishes two things:</p>
11
+ <ul>
12
+ <li>It allows custom layouts to add <code>className</code> and <code>style</code> props as necessary for the layout.</li>
13
+ <li>It allows widgets to be effectively &quot;wrapped&quot; by a parent component to alter their behavior.</li>
14
+ </ul>
15
+
16
+ <h3>Simple slot with default layout</h3>
17
+ <p>This slot has no opinionated layout, it just renders its children.</p>
18
+ <Slot id="org.openedx.frontend.slot.dev.slotShowcaseSimple" />
19
+
20
+ <h3>Simple slot with default content and props</h3>
21
+ <p>This slot has default content, and it exposes a slot prop to widgets.</p>
22
+ <Slot id="org.openedx.frontend.slot.dev.slotShowcaseSimpleWithDefaultContent" aSlotProp="hello!">
23
+ <div>Look, I&apos;m default content!</div>
24
+ </Slot>
25
+
26
+ <h2>UI Layout Operations</h2>
27
+
28
+ <h3>Slot with custom layout</h3>
29
+ <p>This slot uses a horizontal flexbox layout from a component.</p>
30
+ <Slot id="org.openedx.frontend.slot.dev.slotShowcaseCustom" layout={HorizontalSlotLayout} />
31
+ <p>This slot uses a horizontal flexbox layout from a JSX element.</p>
32
+ <Slot id="org.openedx.frontend.slot.dev.slotShowcaseCustom" layout={<HorizontalSlotLayout />} />
33
+
34
+ <h3>Slot with override custom layout</h3>
35
+ <p>This slot uses a horizontal flexbox layout, but it was added by a layout replace operation.</p>
36
+ <Slot id="org.openedx.frontend.slot.dev.slotShowcaseCustomConfig" />
37
+
38
+ <h3>Slot with layout options</h3>
39
+ <p>These slots use a custom layout that takes options. The first shows the default title, the second shows it set to &quot;Bar&quot;</p>
40
+ <Slot id="org.openedx.frontend.slot.dev.slotShowcaseLayoutWithOptionsDefault" layout={LayoutWithOptions} />
41
+ <Slot id="org.openedx.frontend.slot.dev.slotShowcaseLayoutWithOptions" layout={LayoutWithOptions} />
42
+
43
+ <h2>UI Widget Operations</h2>
44
+
45
+ <h3>Slot with prepended element</h3>
46
+ <p>This slot has a prepended element (and two appended elements).</p>
47
+ <Slot id="org.openedx.frontend.slot.dev.slotShowcasePrepending" />
48
+
49
+ <h3>Slot with inserted elements</h3>
50
+ <p>This slot has elements inserted before and after the second element. Also note that the insert operations are declared <em>before</em> the related element is declared, but can still insert themselves relative to it.</p>
51
+ <Slot id="org.openedx.frontend.slot.dev.slotShowcaseInserting" />
52
+
53
+ <h3>Slot with replaced element</h3>
54
+ <p>This slot has an element replacing element two.</p>
55
+ <Slot id="org.openedx.frontend.slot.dev.slotShowcaseReplacing" />
56
+
57
+ <h3>Slot with removed element</h3>
58
+ <p>This slot has removed element two (<code>WidgetOperationTypes.REMOVE</code>).</p>
59
+ <Slot id="org.openedx.frontend.slot.dev.slotShowcaseRemoving" />
60
+
61
+ <h3>Slot with widget with options.</h3>
62
+ <p>Both widgets accept options. The first shows the default title, the second shows it set to &quot;Bar&quot;</p>
63
+ <Slot id="org.openedx.frontend.slot.dev.slotShowcaseWidgetOptions" />
64
+ </div>
65
+ );
66
+ }