@openedx/frontend-base 1.0.0-alpha.26 → 1.0.0-alpha.27

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.
@@ -1,4 +1,8 @@
1
1
  header {
2
+ .container-fluid {
3
+ min-height: 65px;
4
+ }
5
+
2
6
  .nav-link {
3
7
  padding: 1.125rem 1rem;
4
8
 
@@ -4,7 +4,7 @@ import { Link, matchPath, useLocation, useParams } from 'react-router-dom';
4
4
  import { useQuery } from '@tanstack/react-query';
5
5
  import { Slot, useIntl } from '../../../runtime';
6
6
  import { getCourseHomeCourseMetadata } from './data/service';
7
- import { Nav, Navbar, Skeleton } from '@openedx/paragon';
7
+ import { Container, Nav, Navbar, Skeleton } from '@openedx/paragon';
8
8
  import messages from './messages';
9
9
  import { isClientRoute } from './utils';
10
10
  import './course-tabs-navigation.scss';
@@ -54,9 +54,9 @@ const CourseTabsNavigation = () => {
54
54
  if (!courseId || resolvedTabs.length === 0) {
55
55
  return null;
56
56
  }
57
- return (_jsx(Navbar, { expand: "sm", className: "course-tabs-navigation pb-0", "aria-label": intl.formatMessage(messages.courseMaterial), children: _jsxs(Nav, { variant: "tabs", activeKey: currentTab, children: [_jsx(Navbar.Toggle, { "aria-controls": "course-nav" }), _jsx(Navbar.Collapse, { id: "course-nav", children: resolvedTabs.map(tab => (_jsx(Nav.Item, { children: _jsx(Nav.Link, Object.assign({}, (tab.clientPath
58
- ? { to: tab.clientPath, as: Link }
59
- : { href: tab.url }), { active: tab.tabId === currentTab, children: tab.title })) }, tab.tabId))) }), _jsx(Slot, { id: "org.openedx.frontend.slot.header.courseNavigationBar.extraContent.v1" })] }) }));
57
+ return (_jsx(Navbar, { expand: "sm", className: "course-tabs-navigation pb-0", "aria-label": intl.formatMessage(messages.courseMaterial), children: _jsx(Container, { fluid: true, size: "xl", children: _jsxs(Nav, { variant: "tabs", activeKey: currentTab, children: [_jsx(Navbar.Toggle, { "aria-controls": "course-nav" }), _jsx(Navbar.Collapse, { id: "course-nav", children: resolvedTabs.map(tab => (_jsx(Nav.Item, { children: _jsx(Nav.Link, Object.assign({}, (tab.clientPath
58
+ ? { to: tab.clientPath, as: Link }
59
+ : { href: tab.url }), { active: tab.tabId === currentTab, children: tab.title })) }, tab.tabId))) }), _jsx(Slot, { id: "org.openedx.frontend.slot.header.courseNavigationBar.extraContent.v1" })] }) }) }));
60
60
  };
61
61
  export default CourseTabsNavigation;
62
62
  //# sourceMappingURL=CourseTabsNavigation.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CourseTabsNavigation.js","sourceRoot":"","sources":["../../../../shell/header/course-navigation-bar/CourseTabsNavigation.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useMemo } from 'react';\nimport { Link, matchPath, useLocation, useParams } from 'react-router-dom';\nimport { useQuery } from '@tanstack/react-query';\nimport { Slot, useIntl } from '../../../runtime';\nimport { CourseTab, getCourseHomeCourseMetadata } from './data/service';\nimport { Nav, Navbar, Skeleton } from '@openedx/paragon';\nimport messages from './messages';\nimport { isClientRoute } from './utils';\nimport './course-tabs-navigation.scss';\n\ninterface ResolvedTab extends CourseTab {\n pathname: string,\n clientPath: string | null,\n}\n\n/*\n * Returns the tabId of the tab whose pathname is the longest prefix match\n * against the current path. Uses react-router's matchPath for segment-aware\n * matching.\n *\n * For example, given tabs with paths /course/ (tabId: \"outline\")\n * and /course/dates/ (tabId: \"dates\"):\n *\n * /course/dates/foo -> \"dates\" (longest prefix match)\n * /course/outline -> \"outline\"\n * /courseware -> null (not a segment boundary)\n */\nconst getActiveTabId = (currentPath: string, tabs: ResolvedTab[]): string | null => {\n let best: ResolvedTab | null = null;\n for (const tab of tabs) {\n const match = matchPath({ path: `${tab.pathname}/*`, end: false }, currentPath);\n if (match && (!best || tab.pathname.length > best.pathname.length)) {\n best = tab;\n }\n }\n return best?.tabId ?? null;\n};\n\nconst CourseTabsNavigation = () => {\n const location = useLocation();\n const { courseId = '' } = useParams();\n const intl = useIntl();\n\n const { data = { tabs: [] }, isLoading } = useQuery({\n queryKey: ['org.openedx.frontend.app.header.course-meta', courseId],\n queryFn: () => getCourseHomeCourseMetadata(courseId),\n retry: 2,\n enabled: !!courseId,\n });\n\n const { tabs } = data;\n\n const resolvedTabs: ResolvedTab[] = useMemo(\n () => tabs.map(tab => {\n // Tab URLs from the course_home API are always absolute.\n const pathname = new URL(tab.url).pathname;\n return { ...tab, pathname, clientPath: isClientRoute(pathname) ? pathname : null };\n }),\n [tabs]\n );\n\n const currentTab = useMemo(\n () => resolvedTabs.length > 0 ? getActiveTabId(location.pathname, resolvedTabs) : null,\n [location.pathname, resolvedTabs]\n );\n\n if (isLoading) {\n return <Skeleton className=\"lead mt-3\" />;\n }\n\n if (!courseId || resolvedTabs.length === 0) {\n return null;\n }\n\n return (\n <Navbar expand=\"sm\" className=\"course-tabs-navigation pb-0\" aria-label={intl.formatMessage(messages.courseMaterial)}>\n <Nav\n variant=\"tabs\"\n activeKey={currentTab}\n >\n <Navbar.Toggle aria-controls=\"course-nav\" />\n <Navbar.Collapse id=\"course-nav\">\n {\n resolvedTabs.map(tab => (\n <Nav.Item key={tab.tabId}>\n <Nav.Link\n {...(tab.clientPath\n ? { to: tab.clientPath, as: Link }\n : { href: tab.url }\n )}\n active={tab.tabId === currentTab}\n >\n {tab.title}\n </Nav.Link>\n </Nav.Item>\n ))\n }\n </Navbar.Collapse>\n <Slot id=\"org.openedx.frontend.slot.header.courseNavigationBar.extraContent.v1\" />\n </Nav>\n </Navbar>\n );\n};\n\nexport default CourseTabsNavigation;\n"]}
1
+ {"version":3,"file":"CourseTabsNavigation.js","sourceRoot":"","sources":["../../../../shell/header/course-navigation-bar/CourseTabsNavigation.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useMemo } from 'react';\nimport { Link, matchPath, useLocation, useParams } from 'react-router-dom';\nimport { useQuery } from '@tanstack/react-query';\nimport { Slot, useIntl } from '../../../runtime';\nimport { CourseTab, getCourseHomeCourseMetadata } from './data/service';\nimport { Container, Nav, Navbar, Skeleton } from '@openedx/paragon';\nimport messages from './messages';\nimport { isClientRoute } from './utils';\nimport './course-tabs-navigation.scss';\n\ninterface ResolvedTab extends CourseTab {\n pathname: string,\n clientPath: string | null,\n}\n\n/*\n * Returns the tabId of the tab whose pathname is the longest prefix match\n * against the current path. Uses react-router's matchPath for segment-aware\n * matching.\n *\n * For example, given tabs with paths /course/ (tabId: \"outline\")\n * and /course/dates/ (tabId: \"dates\"):\n *\n * /course/dates/foo -> \"dates\" (longest prefix match)\n * /course/outline -> \"outline\"\n * /courseware -> null (not a segment boundary)\n */\nconst getActiveTabId = (currentPath: string, tabs: ResolvedTab[]): string | null => {\n let best: ResolvedTab | null = null;\n for (const tab of tabs) {\n const match = matchPath({ path: `${tab.pathname}/*`, end: false }, currentPath);\n if (match && (!best || tab.pathname.length > best.pathname.length)) {\n best = tab;\n }\n }\n return best?.tabId ?? null;\n};\n\nconst CourseTabsNavigation = () => {\n const location = useLocation();\n const { courseId = '' } = useParams();\n const intl = useIntl();\n\n const { data = { tabs: [] }, isLoading } = useQuery({\n queryKey: ['org.openedx.frontend.app.header.course-meta', courseId],\n queryFn: () => getCourseHomeCourseMetadata(courseId),\n retry: 2,\n enabled: !!courseId,\n });\n\n const { tabs } = data;\n\n const resolvedTabs: ResolvedTab[] = useMemo(\n () => tabs.map(tab => {\n // Tab URLs from the course_home API are always absolute.\n const pathname = new URL(tab.url).pathname;\n return { ...tab, pathname, clientPath: isClientRoute(pathname) ? pathname : null };\n }),\n [tabs]\n );\n\n const currentTab = useMemo(\n () => resolvedTabs.length > 0 ? getActiveTabId(location.pathname, resolvedTabs) : null,\n [location.pathname, resolvedTabs]\n );\n\n if (isLoading) {\n return <Skeleton className=\"lead mt-3\" />;\n }\n\n if (!courseId || resolvedTabs.length === 0) {\n return null;\n }\n\n return (\n <Navbar expand=\"sm\" className=\"course-tabs-navigation pb-0\" aria-label={intl.formatMessage(messages.courseMaterial)}>\n <Container fluid size=\"xl\">\n <Nav\n variant=\"tabs\"\n activeKey={currentTab}\n >\n <Navbar.Toggle aria-controls=\"course-nav\" />\n <Navbar.Collapse id=\"course-nav\">\n {\n resolvedTabs.map(tab => (\n <Nav.Item key={tab.tabId}>\n <Nav.Link\n {...(tab.clientPath\n ? { to: tab.clientPath, as: Link }\n : { href: tab.url }\n )}\n active={tab.tabId === currentTab}\n >\n {tab.title}\n </Nav.Link>\n </Nav.Item>\n ))\n }\n </Navbar.Collapse>\n <Slot id=\"org.openedx.frontend.slot.header.courseNavigationBar.extraContent.v1\" />\n </Nav>\n </Container>\n </Navbar>\n );\n};\n\nexport default CourseTabsNavigation;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openedx/frontend-base",
3
- "version": "1.0.0-alpha.26",
3
+ "version": "1.0.0-alpha.27",
4
4
  "description": "Build tools, setup and config for frontend apps",
5
5
  "publishConfig": {
6
6
  "access": "public"