@patternfly/documentation-framework 1.2.70 → 1.3.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.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,17 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # 1.3.0 (2022-12-08)
7
+
8
+
9
+ ### Features
10
+
11
+ * **docs:** enabled tertiary nav in sidenav ([#3274](https://github.com/patternfly/patternfly-org/issues/3274)) ([b2a6804](https://github.com/patternfly/patternfly-org/commit/b2a6804d7d93026b3b3a7a7e06b53c51be998e1e))
12
+
13
+
14
+
15
+
16
+
6
17
  ## 1.2.70 (2022-12-07)
7
18
 
8
19
  **Note:** Version bump only for package @patternfly/documentation-framework
@@ -3,10 +3,15 @@ import { Link } from '../link/link';
3
3
  import { Nav, NavList, NavExpandable, PageContextConsumer, capitalize } from '@patternfly/react-core';
4
4
  import { css } from '@patternfly/react-styles';
5
5
  import { Location } from '@reach/router';
6
- import { slugger } from '../../helpers';
6
+ import { makeSlug } from '../../helpers';
7
7
  import globalBreakpointXl from "@patternfly/react-tokens/dist/esm/global_breakpoint_xl";
8
8
  import { trackEvent } from '../../helpers';
9
9
 
10
+ const getIsActive = (location, section, subsection = null) => {
11
+ const slug = makeSlug(null, section, null, null, subsection);
12
+ return location.pathname.startsWith(`${process.env.pathPrefix}${slug}`);
13
+ }
14
+
10
15
  const NavItem = ({ text, href }) => {
11
16
  const isMobileView = window.innerWidth < Number.parseInt(globalBreakpointXl.value, 10);
12
17
  return (
@@ -34,6 +39,46 @@ const NavItem = ({ text, href }) => {
34
39
  )
35
40
  };
36
41
 
42
+ const ExpandableNav = ({groupedRoutes, location, section, subsection = null}) => {
43
+ const isActive = getIsActive(location, section, subsection);
44
+ const isSubsection = subsection;
45
+ const routes = isSubsection
46
+ ? groupedRoutes[section][subsection]
47
+ : groupedRoutes[section];
48
+ const currentSection = isSubsection ? subsection : section;
49
+ const analyticsName = isSubsection ? `${section}/${subsection}` : section;
50
+
51
+ return (
52
+ <NavExpandable
53
+ title={capitalize(currentSection.replace(/-/g, ' '))}
54
+ key={capitalize(currentSection.replace(/-/g, ' '))}
55
+ isActive={isActive}
56
+ isExpanded={isActive}
57
+ className="ws-side-nav-group"
58
+ onClick={(event) => {
59
+ // Don't bubble click event up, avoids subsection triggering duplicate analtics
60
+ event.stopPropagation();
61
+ // Don't trigger for bubbled events from NavItems
62
+ if (!event.target.href) {
63
+ const isExpanded = event.currentTarget.classList.contains('pf-m-expanded');
64
+ // 1 === expand section, 0 === collapse section
65
+ trackEvent('sidenav_section_click', 'click_event', analyticsName, isExpanded ? 0 : 1);
66
+ }
67
+ }}
68
+ >
69
+ {Object.entries(routes || {})
70
+ .filter(([id, { hideNavItem }]) => !Boolean(hideNavItem) && (id !== 'isSubsection'))
71
+ .map(([id, { slug, isSubsection = false }]) => ({ text: id, href: slug, isSubsection }))
72
+ .sort(({ text: text1 }, { text: text2 }) => text1.localeCompare(text2))
73
+ .map(navObj => navObj.isSubsection
74
+ ? ExpandableNav({groupedRoutes, location, section, subsection: navObj.text})
75
+ : NavItem(navObj)
76
+ )
77
+ }
78
+ </NavExpandable>
79
+ );
80
+ }
81
+
37
82
  export const SideNav = ({ groupedRoutes = {}, navItems = [] }) => {
38
83
  React.useEffect(() => {
39
84
  if (typeof window === 'undefined') {
@@ -56,32 +101,7 @@ export const SideNav = ({ groupedRoutes = {}, navItems = [] }) => {
56
101
  {navItems.map(({ section, text, href }) => section
57
102
  ? (
58
103
  <Location key={section}>
59
- {({ location }) => {
60
- const isActive = location.pathname.startsWith(`${process.env.pathPrefix}/${slugger(section)}`);
61
- return (
62
- <NavExpandable
63
- title={capitalize(section.replace(/-/g, ' '))}
64
- isActive={isActive}
65
- isExpanded={isActive}
66
- className="ws-side-nav-group"
67
- onClick={(event) => {
68
- // Don't trigger for bubbled events from NavItems
69
- if (!event.target.href) {
70
- const isExpanded = event.currentTarget.classList.contains('pf-m-expanded');
71
- // 1 === expand section, 0 === collapse section
72
- trackEvent('sidenav_section_click', 'click_event', section, isExpanded ? 0 : 1);
73
- }
74
- }}
75
- >
76
- {Object.entries(groupedRoutes[section] || {})
77
- .filter(([, { hideNavItem }]) => !Boolean(hideNavItem))
78
- .map(([id, { slug }]) => ({ text: id, href: slug }))
79
- .sort(({ text: text1 }, { text: text2 }) => text1.localeCompare(text2))
80
- .map(NavItem)
81
- }
82
- </NavExpandable>
83
- );
84
- }}
104
+ {({ location }) => ExpandableNav({groupedRoutes, location, section})}
85
105
  </Location>
86
106
  )
87
107
  : NavItem({
@@ -11,11 +11,14 @@ const slugger = children => {
11
11
  .replace(/[^A-Za-z0-9.\-~]/g, '');
12
12
  }
13
13
 
14
- const makeSlug = (source, section, id, noSource) => {
14
+ const makeSlug = (source, section, id, noSource, subsection) => {
15
15
  let url = '';
16
16
 
17
17
  if (section) {
18
18
  url += `/${slugger(section)}`
19
+ if (subsection) {
20
+ url += `/${slugger(subsection)}`
21
+ }
19
22
  }
20
23
 
21
24
  if (id) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@patternfly/documentation-framework",
3
3
  "description": "A framework to build documentation for PatternFly.",
4
- "version": "1.2.70",
4
+ "version": "1.3.0",
5
5
  "author": "Red Hat",
6
6
  "license": "MIT",
7
7
  "private": false,
@@ -85,5 +85,5 @@
85
85
  "react": "^16.8.0 || ^17.0.0",
86
86
  "react-dom": "^16.8.0 || ^17.0.0"
87
87
  },
88
- "gitHead": "0f120199eeeb5b9fb70c857bcccf1e7c435ae7e9"
88
+ "gitHead": "6998dfbf1533b58368f42df145376da2611bf30c"
89
89
  }
package/routes.js CHANGED
@@ -28,20 +28,34 @@ const isNull = o => o === null || o === undefined;
28
28
  const groupedRoutes = Object.entries(routes)
29
29
  .filter(([_slug, { id, section }]) => !isNull(id) && !isNull(section))
30
30
  .reduce((accum, [slug, pageData]) => {
31
- const { section, id, title, source, katacodaLayout, hideNavItem } = pageData;
31
+ const { section, subsection = null, id, title, source, katacodaLayout, hideNavItem } = pageData;
32
+ pageData.slug = slug;
33
+ // add section to groupedRoutes obj if not yet created
32
34
  accum[section] = accum[section] || {};
33
- accum[section][id] = accum[section][id] || {
35
+ // define data for page to be added to groupedRoutes obj
36
+ const data = {
34
37
  id,
35
38
  section,
39
+ subsection,
36
40
  title,
37
- slug: makeSlug(source, section, id, true),
41
+ slug: makeSlug(source, section, id, true, subsection),
38
42
  sources: [],
39
43
  katacodaLayout,
40
44
  hideNavItem
41
- };
42
-
43
- pageData.slug = slug;
44
- accum[section][id].sources.push(pageData);
45
+ }
46
+ // add page to groupedRoutes obj section or subsection
47
+ if (subsection) {
48
+ // add subsection to section
49
+ accum[section][subsection] = accum[section][subsection] || {};
50
+ accum[section][subsection].isSubsection = true;
51
+ // add page to subsection
52
+ accum[section][subsection][id] = accum[section][subsection][id] || data;
53
+ accum[section][subsection][id].sources.push(pageData);
54
+ } else {
55
+ // add page to section
56
+ accum[section][id] = accum[section][id] || data;
57
+ accum[section][id].sources.push(pageData);
58
+ }
45
59
 
46
60
  return accum;
47
61
  }, {});
@@ -88,15 +102,28 @@ const getDefaultDesignGuidelines = ({ id, section, slug, title }) => {
88
102
  Object.entries(groupedRoutes)
89
103
  .forEach(([_section, ids]) => {
90
104
  Object.values(ids).forEach(pageData => {
91
- const { slug, section } = pageData;
92
- // Remove source routes for `app.js`
93
- pageData.sources.forEach(({ slug }) => {
94
- delete routes[slug];
105
+ let pageDataArr = [];
106
+ // Loop through each page in expandable subsection
107
+ if (pageData.isSubsection) {
108
+ Object.entries(pageData).map(([section, ids]) => {
109
+ if (section !== 'isSubsection') {
110
+ pageDataArr.push(ids);
111
+ }
112
+ })
113
+ } else {
114
+ pageDataArr = [pageData];
115
+ }
116
+ pageDataArr.forEach(pageDataObj => {
117
+ const { slug } = pageDataObj;
118
+ // Remove source routes for `app.js`
119
+ pageDataObj.sources.forEach(({ slug }) => {
120
+ delete routes[slug];
121
+ });
122
+ // Sort sources for tabs
123
+ pageDataObj.sources = pageDataObj.sources.sort(sortSources);
124
+ // Add grouped route
125
+ routes[slug] = pageDataObj;
95
126
  });
96
- // Sort sources for tabs
97
- pageData.sources = pageData.sources.sort(sortSources);
98
- // Add grouped route
99
- routes[slug] = pageData;
100
127
  })
101
128
  });
102
129
 
@@ -49,7 +49,7 @@ function toReactComponent(mdFilePath, source, buildMode) {
49
49
  file.fail('id attribute is required in frontmatter for PatternFly docs');
50
50
  }
51
51
  source = frontmatter.source || source;
52
- const slug = makeSlug(source, frontmatter.section, frontmatter.id);
52
+ const slug = makeSlug(source, frontmatter.section, frontmatter.id, false, frontmatter.subsection);
53
53
  outPath = path.join(outputBase, `${slug}.js`);
54
54
 
55
55
  let sourceRepo = 'patternfly-org';
@@ -80,6 +80,7 @@ function toReactComponent(mdFilePath, source, buildMode) {
80
80
  pageData = {
81
81
  id: frontmatter.id,
82
82
  section: frontmatter.section || '',
83
+ subsection: frontmatter.subsection || '',
83
84
  source,
84
85
  slug,
85
86
  sourceLink: `https://github.com/patternfly/${
@@ -92,7 +93,7 @@ function toReactComponent(mdFilePath, source, buildMode) {
92
93
  // Temporarily override section until https://github.com/patternfly/patternfly-react/pull/4862 is in react-docs
93
94
  pageData.section = 'components';
94
95
  pageData.source = `${source}-demos`;
95
- pageData.slug = makeSlug(pageData.source, pageData.section, pageData.id);
96
+ pageData.slug = makeSlug(pageData.source, pageData.section, pageData.id, false, pageData.subsection);
96
97
  outPath = path.join(outputBase, `${pageData.slug}.js`);
97
98
  }
98
99
  if (frontmatter.title) {
@@ -259,6 +260,7 @@ function sourceMDFile(file, source, buildMode) {
259
260
  ...(pageData.examples && { examples: pageData.examples }),
260
261
  ...(pageData.fullscreenExamples && { fullscreenExamples: pageData.fullscreenExamples }),
261
262
  section: pageData.section,
263
+ subsection: pageData.subsection,
262
264
  source: pageData.source,
263
265
  ...(pageData.katacodaLayout && { katacodaLayout: pageData.katacodaLayout }),
264
266
  ...(pageData.hideNavItem && { hideNavItem: pageData.hideNavItem })