diff --git a/src/course-tabs/CourseTabsNavigation.tsx b/src/course-tabs/CourseTabsNavigation.tsx index 87a1b92c4a..d9d315c1dd 100644 --- a/src/course-tabs/CourseTabsNavigation.tsx +++ b/src/course-tabs/CourseTabsNavigation.tsx @@ -1,16 +1,14 @@ import React from 'react'; -import classNames from 'classnames'; import { useIntl } from '@edx/frontend-platform/i18n'; -import { CourseTabLinksSlot } from '../plugin-slots/CourseTabLinksSlot'; -import { CoursewareSearch, CoursewareSearchToggle } from '../course-home/courseware-search'; -import { useCoursewareSearchState } from '../course-home/courseware-search/hooks'; -import Tabs from '../generic/tabs/Tabs'; +import { CoursewareSearch, CoursewareSearchToggle } from '@src/course-home/courseware-search'; +import { useCoursewareSearchState } from '@src/course-home/courseware-search/hooks'; +import { CourseTabLinksSlot } from '@src/plugin-slots/CourseTabLinksSlot'; +import Tabs from '@src/generic/tabs/Tabs'; import messages from './messages'; -interface CourseTabsNavigationProps { +export interface CourseTabsNavigationProps { activeTabSlug?: string; - className?: string | null; tabs: Array<{ title: string; slug: string; @@ -20,14 +18,13 @@ interface CourseTabsNavigationProps { const CourseTabsNavigation = ({ activeTabSlug = undefined, - className = null, tabs, }:CourseTabsNavigationProps) => { const intl = useIntl(); const { show } = useCoursewareSearchState(); return ( -
+
diff --git a/src/course-tabs/index.js b/src/course-tabs/index.ts similarity index 50% rename from src/course-tabs/index.js rename to src/course-tabs/index.ts index e2236ee726..801de27856 100644 --- a/src/course-tabs/index.js +++ b/src/course-tabs/index.ts @@ -1,2 +1,2 @@ -/* eslint-disable import/prefer-default-export */ export { default as CourseTabsNavigation } from './CourseTabsNavigation'; +export type { CourseTabsNavigationProps } from './CourseTabsNavigation'; diff --git a/src/plugin-slots/CourseTabsNavigationSlot/README.md b/src/plugin-slots/CourseTabsNavigationSlot/README.md new file mode 100644 index 0000000000..084bf07b02 --- /dev/null +++ b/src/plugin-slots/CourseTabsNavigationSlot/README.md @@ -0,0 +1,38 @@ +# Course Tab Navigation Slot + +### Slot ID: `org.openedx.frontend.learning.course_tabs_navigation.v1` + +### Props: +NONE + +## Description + +This slot is used to replace/modify/hide the entire course tab navigation. + +## Example + +### Added a drop shadow to Course Tabs bar +![Added a drop shadow to Course Tabs bar](./course-tabs-navigation-shadow.png) + +The following `env.config.jsx` will add a new course tab call "Custom Tab". + +```js +import { DIRECT_PLUGIN, PLUGIN_OPERATIONS } from '@openedx/frontend-plugin-framework'; + +const config = { + pluginSlots: { + "org.openedx.frontend.learning.course_tab_navigation.v1": { + keepDefault: true, + plugins: [ + { + op: PLUGIN_OPERATIONS.Wrap, + widgetId: 'default_contents', + wrapper: ({component}) => (
{component}
) + }, + ], + }, + }, +} + +export default config; +``` diff --git a/src/plugin-slots/CourseTabsNavigationSlot/course-tabs-navigation-shadow.png b/src/plugin-slots/CourseTabsNavigationSlot/course-tabs-navigation-shadow.png new file mode 100644 index 0000000000..eb3c6617be Binary files /dev/null and b/src/plugin-slots/CourseTabsNavigationSlot/course-tabs-navigation-shadow.png differ diff --git a/src/plugin-slots/CourseTabsNavigationSlot/index.tsx b/src/plugin-slots/CourseTabsNavigationSlot/index.tsx new file mode 100644 index 0000000000..eda1e470b2 --- /dev/null +++ b/src/plugin-slots/CourseTabsNavigationSlot/index.tsx @@ -0,0 +1,8 @@ +import { CourseTabsNavigation, type CourseTabsNavigationProps } from '@src/course-tabs'; +import { PluginSlot } from '@openedx/frontend-plugin-framework'; + +export const CourseTabsNavigationSlot = ({ tabs, activeTabSlug }: CourseTabsNavigationProps) => ( + + + +); diff --git a/src/tab-page/LoadedTabPage.jsx b/src/tab-page/LoadedTabPage.tsx similarity index 73% rename from src/tab-page/LoadedTabPage.jsx rename to src/tab-page/LoadedTabPage.tsx index 67a1b86595..f1c3e8271f 100644 --- a/src/tab-page/LoadedTabPage.jsx +++ b/src/tab-page/LoadedTabPage.tsx @@ -1,27 +1,35 @@ import React from 'react'; -import PropTypes from 'prop-types'; import { Helmet } from 'react-helmet'; import { getConfig } from '@edx/frontend-platform'; import { useToggle } from '@openedx/paragon'; -import { CourseTabsNavigation } from '../course-tabs'; -import { useModel } from '../generic/model-store'; -import { AlertList } from '../generic/user-messages'; -import StreakModal from '../shared/streak-celebration'; -import InstructorToolbar from '../instructor-toolbar'; -import useEnrollmentAlert from '../alerts/enrollment-alert'; -import useLogistrationAlert from '../alerts/logistration-alert'; +import { CourseTabsNavigationSlot } from '@src/plugin-slots/CourseTabsNavigationSlot'; + +import { useModel } from '@src/generic/model-store'; +import { AlertList } from '@src/generic/user-messages'; +import useEnrollmentAlert from '@src/alerts/enrollment-alert'; +import useLogistrationAlert from '@src/alerts/logistration-alert'; +import StreakModal from '@src/shared/streak-celebration'; +import InstructorToolbar from '@src/instructor-toolbar'; import ProductTours from '../product-tours/ProductTours'; +interface LoadedTabPageProps { + activeTabSlug: string; + children?: React.ReactNode; + courseId: string; + metadataModel: string; + unitId?: string | null; +} + const LoadedTabPage = ({ activeTabSlug, - children, + children = null, courseId, metadataModel, - unitId, -}) => { + unitId = null, +}: LoadedTabPageProps) => { const { celebrations, org, @@ -80,7 +88,7 @@ const LoadedTabPage = ({ ...logistrationAlert, }} /> - +
{children}
@@ -89,18 +97,4 @@ const LoadedTabPage = ({ ); }; -LoadedTabPage.propTypes = { - activeTabSlug: PropTypes.string.isRequired, - children: PropTypes.node, - courseId: PropTypes.string.isRequired, - metadataModel: PropTypes.string, - unitId: PropTypes.string, -}; - -LoadedTabPage.defaultProps = { - children: null, - metadataModel: 'courseHomeMeta', - unitId: null, -}; - export default LoadedTabPage;