@patternfly/patternfly-doc-core 1.0.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 (111) hide show
  1. package/.astro/collections/dir.schema.json +28 -0
  2. package/.astro/collections/textContent.schema.json +28 -0
  3. package/.astro/content-assets.mjs +1 -0
  4. package/.astro/content-modules.mjs +1 -0
  5. package/.astro/content.d.ts +171 -0
  6. package/.astro/types.d.ts +2 -0
  7. package/.github/workflows/build.yml +61 -0
  8. package/.history/package_20250227163130.json +97 -0
  9. package/.history/package_20250227163527.json +97 -0
  10. package/.history/package_20250227163646.json +97 -0
  11. package/.history/package_20250227163651.json +97 -0
  12. package/.history/package_20250227163654.json +97 -0
  13. package/.history/package_20250227163657.json +97 -0
  14. package/.history/package_20250227163659.json +97 -0
  15. package/.history/package_20250227164608.json +97 -0
  16. package/.history/package_20250227164611.json +97 -0
  17. package/.history/package_20250227164616.json +98 -0
  18. package/.vscode/extensions.json +4 -0
  19. package/.vscode/launch.json +11 -0
  20. package/README.md +49 -0
  21. package/astro.config.mjs +18 -0
  22. package/babel.config.cjs +4 -0
  23. package/cli/cli.ts +81 -0
  24. package/cli/createCollectionContent.ts +31 -0
  25. package/cli/createConfigFile.ts +36 -0
  26. package/cli/getConfig.ts +28 -0
  27. package/cli/setFsRootDir.ts +29 -0
  28. package/cli/templates/package.json +19 -0
  29. package/cli/templates/pf-docs.config.mjs +20 -0
  30. package/cli/testData/good.config.js +12 -0
  31. package/cli/tsconfig.json +9 -0
  32. package/cli/updatePackageFile.ts +55 -0
  33. package/dist/PF-HorizontalLogo-Color.svg +29 -0
  34. package/dist/PF-HorizontalLogo-Reverse.svg +28 -0
  35. package/dist/_astro/ClientRouter.astro_astro_type_script_index_0_lang.BScVxmeO.js +1 -0
  36. package/dist/_astro/Navigation.BoL0fVlO.js +1 -0
  37. package/dist/_astro/PageContext.CGSBAxAd.js +9 -0
  38. package/dist/_astro/PageToggle.jHn9PsTr.js +1 -0
  39. package/dist/_astro/RedHatDisplayVF-Italic.CRpusWc8.woff2 +0 -0
  40. package/dist/_astro/RedHatDisplayVF.CYDHf1NI.woff2 +0 -0
  41. package/dist/_astro/RedHatMonoVF-Italic.DGQo2ogW.woff2 +0 -0
  42. package/dist/_astro/RedHatMonoVF.C4fMH6Vz.woff2 +0 -0
  43. package/dist/_astro/RedHatTextVF-Italic.Dkj_WqbA.woff2 +0 -0
  44. package/dist/_astro/RedHatTextVF.wYvZ7prR.woff2 +0 -0
  45. package/dist/_astro/Toolbar.BI0orElX.js +1 -0
  46. package/dist/_astro/_id_.DZfGTTvw.css +1 -0
  47. package/dist/_astro/_id_.EhyPoRav.css +1 -0
  48. package/dist/_astro/client.DBe4QnD_.js +1 -0
  49. package/dist/_astro/divider.DrQDtXS2.js +1 -0
  50. package/dist/_astro/fa-solid-900.DguXoeIz.woff2 +0 -0
  51. package/dist/_astro/index.IDjx8w0N.js +32 -0
  52. package/dist/_astro/navStore.br_igkhP.js +1 -0
  53. package/dist/_astro/pf-v6-pficon.Dy6oiu9u.woff2 +0 -0
  54. package/dist/avatarImg.svg +18 -0
  55. package/dist/avatarImgDark.svg +16 -0
  56. package/dist/cli/cli.js +57 -0
  57. package/dist/cli/createCollectionContent.js +26 -0
  58. package/dist/cli/createConfigFile.js +22 -0
  59. package/dist/cli/getConfig.js +14 -0
  60. package/dist/cli/setFsRootDir.js +20 -0
  61. package/dist/cli/templates/pf-docs.config.mjs +20 -0
  62. package/dist/cli/tsconfig.tsbuildinfo +1 -0
  63. package/dist/cli/updatePackageFile.js +35 -0
  64. package/dist/content/typography/line-height.png +0 -0
  65. package/dist/design-foundations/typography/index.html +193 -0
  66. package/dist/design-foundations/usage-and-behavior/index.html +342 -0
  67. package/dist/favicon.svg +9 -0
  68. package/dist/get-started/contribute/index.html +89 -0
  69. package/dist/index.html +42 -0
  70. package/eslint.config.mjs +131 -0
  71. package/jest.config.ts +27 -0
  72. package/package.json +98 -0
  73. package/public/PF-HorizontalLogo-Color.svg +29 -0
  74. package/public/PF-HorizontalLogo-Reverse.svg +28 -0
  75. package/public/avatarImg.svg +18 -0
  76. package/public/avatarImgDark.svg +16 -0
  77. package/public/content/typography/line-height.png +0 -0
  78. package/public/favicon.svg +9 -0
  79. package/release.config.mjs +16 -0
  80. package/src/__mocks__/styleMock.ts +2 -0
  81. package/src/components/Breadcrumbs.astro +10 -0
  82. package/src/components/KebabDropdownItems.astro +14 -0
  83. package/src/components/KebabDropdownItems.tsx +15 -0
  84. package/src/components/Masthead.astro +30 -0
  85. package/src/components/NavEntry.tsx +26 -0
  86. package/src/components/NavSection.tsx +38 -0
  87. package/src/components/Navigation.astro +13 -0
  88. package/src/components/Navigation.tsx +58 -0
  89. package/src/components/Page.astro +19 -0
  90. package/src/components/PageToggle.tsx +47 -0
  91. package/src/components/Toolbar.astro +5 -0
  92. package/src/components/Toolbar.tsx +173 -0
  93. package/src/components/UserDropdownItems.astro +9 -0
  94. package/src/components/UserDropdownItems.tsx +10 -0
  95. package/src/content.config.ts +36 -0
  96. package/src/content.ts +1 -0
  97. package/src/env.d.ts +1 -0
  98. package/src/layouts/Main.astro +26 -0
  99. package/src/pages/[section]/[...id].astro +31 -0
  100. package/src/pages/index.astro +17 -0
  101. package/src/stores/navStore.ts +3 -0
  102. package/src/styles/global.scss +1 -0
  103. package/src/utils/capitalize.ts +3 -0
  104. package/src/utils/index.ts +1 -0
  105. package/test.setup.ts +2 -0
  106. package/textContent/contribute.md +71 -0
  107. package/textContent/typography.md +95 -0
  108. package/textContent/usage-and-behavior.md +139 -0
  109. package/tsconfig.jest.json +8 -0
  110. package/tsconfig.json +14 -0
  111. package/tsconfig.vitest.json +6 -0
@@ -0,0 +1,18 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!-- Generator: Adobe Illustrator 24.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
+ <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
4
+ viewBox="0 0 36 36" style="enable-background:new 0 0 36 36;" xml:space="preserve">
5
+ <style type="text/css">
6
+ .st0{fill-rule:evenodd;clip-rule:evenodd;fill:#F0F0F0;}
7
+ .st1{fill-rule:evenodd;clip-rule:evenodd;fill:#D2D2D2;}
8
+ .st2{fill:#B8BBBE;}
9
+ .st3{fill:#D2D2D2;}
10
+ </style>
11
+ <rect class="st0" width="36" height="36"/>
12
+ <path class="st1" d="M17.7,20.1c-3.5,0-6.4-2.9-6.4-6.4s2.9-6.4,6.4-6.4s6.4,2.9,6.4,6.4S21.3,20.1,17.7,20.1z"/>
13
+ <path class="st2" d="M13.3,36l0-6.7c-2,0.4-2.9,1.4-3.1,3.5L10.1,36H13.3z"/>
14
+ <path class="st3" d="M10.1,36l0.1-3.2c0.2-2.1,1.1-3.1,3.1-3.5l0,6.7h9.4l0-6.7c2,0.4,2.9,1.4,3.1,3.5l0.1,3.2h4.7
15
+ c-0.4-3.9-1.3-9-2.9-11c-1.1-1.4-2.3-2.2-3.5-2.6s-1.8-0.6-6.3-0.6s-6.1,0.7-6.1,0.7c-1.2,0.4-2.4,1.2-3.4,2.6
16
+ C6.7,27,5.8,32.2,5.4,36H10.1z"/>
17
+ <path class="st2" d="M25.9,36l-0.1-3.2c-0.2-2.1-1.1-3.1-3.1-3.5l0,6.7H25.9z"/>
18
+ </svg>
@@ -0,0 +1,16 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!-- Generator: Adobe Illustrator 24.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
+ <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
4
+ viewBox="0 0 36 36" style="enable-background:new 0 0 36 36;" xml:space="preserve">
5
+ <style type="text/css">
6
+ .st0{fill:#212427;}
7
+ .st1{fill-rule:evenodd;clip-rule:evenodd;fill:#6A6E73;}
8
+ .st2{fill-rule:evenodd;clip-rule:evenodd;fill:#4F5255;}
9
+ </style>
10
+ <rect class="st0" width="36" height="36"/>
11
+ <path class="st1" d="M30.5,36c-0.4-3.9-1.3-9-2.9-11c-1.1-1.4-2.3-2.2-3.5-2.6s-1.8-0.6-6.3-0.6s-6.1,0.7-6.1,0.7
12
+ c-1.2,0.4-2.4,1.2-3.4,2.6C6.7,27,5.8,32.2,5.4,36H30.5z"/>
13
+ <path class="st1" d="M17.7,20.1c-3.5,0-6.4-2.9-6.4-6.4s2.9-6.4,6.4-6.4s6.4,2.9,6.4,6.4S21.3,20.1,17.7,20.1z"/>
14
+ <path class="st2" d="M13.3,36l0-6.7c-2,0.4-2.9,1.4-3.1,3.5L10.1,36H13.3z"/>
15
+ <path class="st2" d="M22.7,36l0-6.7c2,0.4,2.9,1.4,3.1,3.5l0.1,3.2H22.7z"/>
16
+ </svg>
@@ -0,0 +1,9 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 128 128">
2
+ <path d="M50.4 78.5a75.1 75.1 0 0 0-28.5 6.9l24.2-65.7c.7-2 1.9-3.2 3.4-3.2h29c1.5 0 2.7 1.2 3.4 3.2l24.2 65.7s-11.6-7-28.5-7L67 45.5c-.4-1.7-1.6-2.8-2.9-2.8-1.3 0-2.5 1.1-2.9 2.7L50.4 78.5Zm-1.1 28.2Zm-4.2-20.2c-2 6.6-.6 15.8 4.2 20.2a17.5 17.5 0 0 1 .2-.7 5.5 5.5 0 0 1 5.7-4.5c2.8.1 4.3 1.5 4.7 4.7.2 1.1.2 2.3.2 3.5v.4c0 2.7.7 5.2 2.2 7.4a13 13 0 0 0 5.7 4.9v-.3l-.2-.3c-1.8-5.6-.5-9.5 4.4-12.8l1.5-1a73 73 0 0 0 3.2-2.2 16 16 0 0 0 6.8-11.4c.3-2 .1-4-.6-6l-.8.6-1.6 1a37 37 0 0 1-22.4 2.7c-5-.7-9.7-2-13.2-6.2Z" />
3
+ <style>
4
+ path { fill: #000; }
5
+ @media (prefers-color-scheme: dark) {
6
+ path { fill: #FFF; }
7
+ }
8
+ </style>
9
+ </svg>
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @type {import('semantic-release').GlobalConfig}
3
+ */
4
+ export default {
5
+ branches: ['main'],
6
+ analyzeCommits: {
7
+ preset: 'angular'
8
+ },
9
+ plugins: [
10
+ '@semantic-release/commit-analyzer',
11
+ '@semantic-release/release-notes-generator',
12
+ '@semantic-release/npm',
13
+ '@semantic-release/github',
14
+ ],
15
+ dryRun: false
16
+ };
@@ -0,0 +1,2 @@
1
+ // We aren't actually using CSS modules, so we don't need to mock what `require('@patternfly/react-styles/css/whatever')` would do
2
+ module.exports = {}
@@ -0,0 +1,10 @@
1
+ ---
2
+ import { Breadcrumb, BreadcrumbItem } from '@patternfly/react-core'
3
+ ---
4
+
5
+ <Breadcrumb>
6
+ <BreadcrumbItem>Section home</BreadcrumbItem>
7
+ <BreadcrumbItem to="#">Section title</BreadcrumbItem>
8
+ <BreadcrumbItem to="#">Section title</BreadcrumbItem>
9
+ <BreadcrumbItem to="#" isActive> Section landing </BreadcrumbItem>
10
+ </Breadcrumb>
@@ -0,0 +1,14 @@
1
+ ---
2
+ import { DropdownItem } from '@patternfly/react-core'
3
+ import CogIcon from '@patternfly/react-icons/dist/esm/icons/cog-icon'
4
+ import HelpIcon from '@patternfly/react-icons/dist/esm/icons/help-icon'
5
+ ---
6
+
7
+ <>
8
+ <DropdownItem>
9
+ <CogIcon /> Settings
10
+ </DropdownItem>
11
+ <DropdownItem>
12
+ <HelpIcon /> Help
13
+ </DropdownItem>
14
+ </>
@@ -0,0 +1,15 @@
1
+ import React from 'react'
2
+ import { DropdownItem } from '@patternfly/react-core'
3
+ import CogIcon from '@patternfly/react-icons/dist/esm/icons/cog-icon'
4
+ import HelpIcon from '@patternfly/react-icons/dist/esm/icons/help-icon'
5
+
6
+ export const KebabDropdownItems: React.FunctionComponent = () => (
7
+ <>
8
+ <DropdownItem>
9
+ <CogIcon /> Settings
10
+ </DropdownItem>
11
+ <DropdownItem>
12
+ <HelpIcon /> Help
13
+ </DropdownItem>
14
+ </>
15
+ )
@@ -0,0 +1,30 @@
1
+ ---
2
+ import {
3
+ Brand,
4
+ Masthead as PFMasthead,
5
+ MastheadMain,
6
+ MastheadToggle,
7
+ MastheadBrand,
8
+ MastheadLogo,
9
+ MastheadContent,
10
+ } from '@patternfly/react-core'
11
+ import pfLogo from '/PF-HorizontalLogo-Color.svg?url'
12
+ import Toolbar from './Toolbar.astro'
13
+ import { PageToggle } from './PageToggle'
14
+ ---
15
+
16
+ <PFMasthead>
17
+ <MastheadMain>
18
+ <MastheadToggle>
19
+ <PageToggle client:idle />
20
+ </MastheadToggle>
21
+ <MastheadBrand>
22
+ <MastheadLogo component="a" href="/">
23
+ <Brand src={pfLogo} alt="PatternFly" heights={{ default: '36px' }} />
24
+ </MastheadLogo>
25
+ </MastheadBrand>
26
+ </MastheadMain>
27
+ <MastheadContent>
28
+ <Toolbar />
29
+ </MastheadContent>
30
+ </PFMasthead>
@@ -0,0 +1,26 @@
1
+ import { NavItem } from '@patternfly/react-core'
2
+
3
+ export interface TextContentEntry {
4
+ id: string
5
+ data: {
6
+ id: string
7
+ section: string
8
+ }
9
+ collection: string
10
+ }
11
+
12
+ interface NavEntryProps {
13
+ entry: TextContentEntry
14
+ isActive: boolean
15
+ }
16
+
17
+ export const NavEntry = ({ entry, isActive }: NavEntryProps) => {
18
+ const { id } = entry
19
+ const { id: entryTitle, section } = entry.data
20
+
21
+ return (
22
+ <NavItem itemId={id} to={`/${section}/${id}`} isActive={isActive} id={`nav-entry-${id}`}>
23
+ {entryTitle}
24
+ </NavItem>
25
+ )
26
+ }
@@ -0,0 +1,38 @@
1
+ import { NavExpandable } from '@patternfly/react-core'
2
+ import { sentenceCase } from 'change-case'
3
+ import { NavEntry, type TextContentEntry } from './NavEntry'
4
+
5
+ interface NavSectionProps {
6
+ entries: TextContentEntry[]
7
+ sectionId: string
8
+ activeItem: string
9
+ }
10
+
11
+ export const NavSection = ({
12
+ entries,
13
+ sectionId,
14
+ activeItem,
15
+ }: NavSectionProps) => {
16
+ const isExpanded = window.location.pathname.includes(sectionId)
17
+
18
+ const sortedNavEntries = entries.sort((a, b) =>
19
+ a.data.id.localeCompare(b.data.id),
20
+ )
21
+
22
+ const isActive = sortedNavEntries.some((entry) => entry.id === activeItem)
23
+
24
+ const items = sortedNavEntries.map((entry) => (
25
+ <NavEntry key={entry.id} entry={entry} isActive={activeItem === entry.id} />
26
+ ))
27
+
28
+ return (
29
+ <NavExpandable
30
+ title={sentenceCase(sectionId)}
31
+ isActive={isActive}
32
+ isExpanded={isExpanded}
33
+ id={`nav-section-${sectionId}`}
34
+ >
35
+ {items}
36
+ </NavExpandable>
37
+ )
38
+ }
@@ -0,0 +1,13 @@
1
+ ---
2
+ import { getCollection } from 'astro:content'
3
+
4
+ import { Navigation as ReactNav } from './Navigation.tsx'
5
+
6
+ import { content } from "../content"
7
+
8
+ const collections = await Promise.all(content.map(async (entry) => await getCollection(entry.name as 'textContent')))
9
+
10
+ const navEntries = collections.flat();
11
+ ---
12
+
13
+ <ReactNav client:only="react" navEntries={navEntries} transition:animate="fade" />
@@ -0,0 +1,58 @@
1
+ import { useEffect, useState } from 'react'
2
+ import {
3
+ Nav,
4
+ NavList,
5
+ PageSidebar,
6
+ PageSidebarBody,
7
+ } from '@patternfly/react-core'
8
+ import { useStore } from '@nanostores/react'
9
+ import { isNavOpen } from '../stores/navStore'
10
+ import { NavSection } from './NavSection'
11
+ import { type TextContentEntry } from './NavEntry'
12
+
13
+ interface NavigationProps {
14
+ navEntries: TextContentEntry[]
15
+ }
16
+
17
+ export const Navigation: React.FunctionComponent<NavigationProps> = ({
18
+ navEntries,
19
+ }: NavigationProps) => {
20
+ const $isNavOpen = useStore(isNavOpen)
21
+ const [activeItem, setActiveItem] = useState('')
22
+
23
+ useEffect(() => {
24
+ setActiveItem(window.location.pathname.split('/').reverse()[0])
25
+ }, [])
26
+
27
+ const onNavSelect = (
28
+ _event: React.FormEvent<HTMLInputElement>,
29
+ selectedItem: { itemId: string | number },
30
+ ) => {
31
+ setActiveItem(selectedItem.itemId.toString())
32
+ }
33
+
34
+ const sections = new Set(navEntries.map((entry) => entry.data.section))
35
+
36
+ const navSections = Array.from(sections).map((section) => {
37
+ const entries = navEntries.filter((entry) => entry.data.section === section)
38
+
39
+ return (
40
+ <NavSection
41
+ key={section}
42
+ entries={entries}
43
+ sectionId={section}
44
+ activeItem={activeItem}
45
+ />
46
+ )
47
+ })
48
+
49
+ return (
50
+ <PageSidebar isSidebarOpen={$isNavOpen}>
51
+ <PageSidebarBody>
52
+ <Nav onSelect={onNavSelect}>
53
+ <NavList>{navSections}</NavList>
54
+ </Nav>
55
+ </PageSidebarBody>
56
+ </PageSidebar>
57
+ )
58
+ }
@@ -0,0 +1,19 @@
1
+ ---
2
+ import styles from '@patternfly/react-styles/css/components/Page/page'
3
+ import { Content, PageSection } from '@patternfly/react-core'
4
+ ---
5
+
6
+ <div class={styles.page}>
7
+ <slot name="skipToContent" />
8
+ <slot name="masthead" />
9
+ <slot name="sidebar" />
10
+ <div class={styles.pageMainContainer}>
11
+ <main class={styles.pageMain}>
12
+ <PageSection transition:animate="none">
13
+ <Content>
14
+ <slot />
15
+ </Content>
16
+ </PageSection>
17
+ </main>
18
+ </div>
19
+ </div>
@@ -0,0 +1,47 @@
1
+ import type React from 'react'
2
+ import { PageToggleButton } from '@patternfly/react-core'
3
+ import BarsIcon from '@patternfly/react-icons/dist/esm/icons/bars-icon'
4
+ import { useStore } from '@nanostores/react'
5
+ import { isNavOpen } from '../stores/navStore'
6
+ import { useEffect } from 'react'
7
+
8
+ export const PageToggle: React.FunctionComponent = () => {
9
+ const $isNavOpen = useStore(isNavOpen)
10
+
11
+ /** Applies sidebar styles to the island element astro creates as a wrapper for the sidebar.
12
+ * Without it the page content will not expand to fill the space left by the sidebar when it is collapsed.
13
+ */
14
+ function applySidebarStylesToIsland() {
15
+ const isClientSide = typeof window !== 'undefined'
16
+ const sideBarIsland = document.getElementById('page-sidebar')?.parentElement
17
+
18
+ if (!isClientSide || !sideBarIsland) {
19
+ return
20
+ }
21
+
22
+ if (!sideBarIsland.classList.contains('pf-v6-c-page__sidebar')) {
23
+ sideBarIsland.classList.add('pf-v6-c-page__sidebar', 'pf-m-expanded')
24
+ } else {
25
+ sideBarIsland.classList.toggle('pf-m-expanded')
26
+ sideBarIsland.classList.toggle('pf-m-collapsed')
27
+ }
28
+ }
29
+
30
+ function onToggle() {
31
+ isNavOpen.set(!$isNavOpen)
32
+ }
33
+
34
+ useEffect(() => {
35
+ applySidebarStylesToIsland()
36
+ }, [$isNavOpen])
37
+
38
+ return (
39
+ <PageToggleButton
40
+ variant="plain"
41
+ aria-label="Global navigation"
42
+ onSidebarToggle={onToggle}
43
+ >
44
+ <BarsIcon />
45
+ </PageToggleButton>
46
+ )
47
+ }
@@ -0,0 +1,5 @@
1
+ ---
2
+ import { Toolbar as ReactToolbar } from './Toolbar.tsx'
3
+ ---
4
+
5
+ <ReactToolbar client:idle />
@@ -0,0 +1,173 @@
1
+ import * as React from 'react'
2
+ import { useState } from 'react'
3
+ import {
4
+ Avatar,
5
+ Button,
6
+ ButtonVariant,
7
+ Divider,
8
+ Dropdown,
9
+ DropdownGroup,
10
+ DropdownList,
11
+ MenuToggle,
12
+ type MenuToggleElement,
13
+ Toolbar as PFToolbar,
14
+ ToolbarContent,
15
+ ToolbarGroup,
16
+ ToolbarItem,
17
+ } from '@patternfly/react-core'
18
+ import BellIcon from '@patternfly/react-icons/dist/esm/icons/bell-icon'
19
+ import CogIcon from '@patternfly/react-icons/dist/esm/icons/cog-icon'
20
+ import QuestionCircleIcon from '@patternfly/react-icons/dist/esm/icons/question-circle-icon'
21
+ import EllipsisVIcon from '@patternfly/react-icons/dist/esm/icons/ellipsis-v-icon'
22
+
23
+ import imgAvatar from '/avatarImg.svg?url'
24
+
25
+ import { KebabDropdownItems } from './KebabDropdownItems'
26
+ import { UserDropdownItems } from './UserDropdownItems'
27
+
28
+ export const Toolbar: React.FunctionComponent = () => {
29
+ const [isDropdownOpen, setIsDropdownOpen] = useState(false)
30
+ const [isKebabDropdownOpen, setIsKebabDropdownOpen] = useState(false)
31
+ const [isFullKebabDropdownOpen, setIsFullKebabDropdownOpen] = useState(false)
32
+
33
+ const onDropdownToggle = () => {
34
+ setIsDropdownOpen(!isDropdownOpen)
35
+ }
36
+
37
+ const onDropdownSelect = () => {
38
+ setIsDropdownOpen(false)
39
+ }
40
+
41
+ const onKebabDropdownToggle = () => {
42
+ setIsKebabDropdownOpen(!isKebabDropdownOpen)
43
+ }
44
+
45
+ const onKebabDropdownSelect = () => {
46
+ setIsKebabDropdownOpen(false)
47
+ }
48
+
49
+ const onFullKebabDropdownToggle = () => {
50
+ setIsFullKebabDropdownOpen(!isFullKebabDropdownOpen)
51
+ }
52
+
53
+ const onFullKebabDropdownSelect = () => {
54
+ setIsFullKebabDropdownOpen(false)
55
+ }
56
+
57
+ return (
58
+ <PFToolbar id="toolbar" isStatic>
59
+ <ToolbarContent>
60
+ <ToolbarGroup
61
+ variant="action-group-plain"
62
+ align={{ default: 'alignEnd' }}
63
+ gap={{ default: 'gapNone', md: 'gapMd' }}
64
+ >
65
+ <ToolbarItem>
66
+ <Button
67
+ aria-label="Notifications"
68
+ variant={ButtonVariant.plain}
69
+ icon={<BellIcon />}
70
+ />
71
+ </ToolbarItem>
72
+ <ToolbarGroup
73
+ variant="action-group-plain"
74
+ visibility={{ default: 'hidden', lg: 'visible' }}
75
+ >
76
+ <ToolbarItem>
77
+ <Button
78
+ aria-label="Settings"
79
+ variant={ButtonVariant.plain}
80
+ icon={<CogIcon />}
81
+ />
82
+ </ToolbarItem>
83
+ <ToolbarItem>
84
+ <Button
85
+ aria-label="Help"
86
+ variant={ButtonVariant.plain}
87
+ icon={<QuestionCircleIcon />}
88
+ />
89
+ </ToolbarItem>
90
+ </ToolbarGroup>
91
+ <ToolbarItem
92
+ visibility={{ default: 'hidden', md: 'visible', lg: 'hidden' }}
93
+ >
94
+ <Dropdown
95
+ isOpen={isKebabDropdownOpen}
96
+ onSelect={onKebabDropdownSelect}
97
+ onOpenChange={(isOpen: boolean) => setIsKebabDropdownOpen(isOpen)}
98
+ popperProps={{ position: 'right' }}
99
+ toggle={(toggleRef: React.Ref<MenuToggleElement>) => (
100
+ <MenuToggle
101
+ ref={toggleRef}
102
+ onClick={onKebabDropdownToggle}
103
+ isExpanded={isKebabDropdownOpen}
104
+ variant="plain"
105
+ aria-label="Settings and help"
106
+ >
107
+ <EllipsisVIcon aria-hidden="true" />
108
+ </MenuToggle>
109
+ )}
110
+ >
111
+ <DropdownList>
112
+ <KebabDropdownItems />
113
+ </DropdownList>
114
+ </Dropdown>
115
+ </ToolbarItem>
116
+ <ToolbarItem visibility={{ md: 'hidden' }}>
117
+ <Dropdown
118
+ isOpen={isFullKebabDropdownOpen}
119
+ onSelect={onFullKebabDropdownSelect}
120
+ onOpenChange={(isOpen: boolean) =>
121
+ setIsFullKebabDropdownOpen(isOpen)
122
+ }
123
+ popperProps={{ position: 'right' }}
124
+ toggle={(toggleRef: React.Ref<MenuToggleElement>) => (
125
+ <MenuToggle
126
+ ref={toggleRef}
127
+ onClick={onFullKebabDropdownToggle}
128
+ isExpanded={isFullKebabDropdownOpen}
129
+ variant="plain"
130
+ aria-label="Toolbar menu"
131
+ >
132
+ <EllipsisVIcon aria-hidden="true" />
133
+ </MenuToggle>
134
+ )}
135
+ >
136
+ <DropdownGroup key="group 2" aria-label="User actions">
137
+ <DropdownList>
138
+ <UserDropdownItems />
139
+ </DropdownList>
140
+ </DropdownGroup>
141
+ <Divider />
142
+ <DropdownList>
143
+ <KebabDropdownItems />
144
+ </DropdownList>
145
+ </Dropdown>
146
+ </ToolbarItem>
147
+ </ToolbarGroup>
148
+ <ToolbarItem visibility={{ default: 'hidden', md: 'visible' }}>
149
+ <Dropdown
150
+ isOpen={isDropdownOpen}
151
+ onSelect={onDropdownSelect}
152
+ onOpenChange={(isOpen: boolean) => setIsDropdownOpen(isOpen)}
153
+ popperProps={{ position: 'right' }}
154
+ toggle={(toggleRef: React.Ref<MenuToggleElement>) => (
155
+ <MenuToggle
156
+ ref={toggleRef}
157
+ onClick={onDropdownToggle}
158
+ isExpanded={isDropdownOpen}
159
+ icon={<Avatar src={imgAvatar} alt="" size="sm" />}
160
+ >
161
+ Ned Username
162
+ </MenuToggle>
163
+ )}
164
+ >
165
+ <DropdownList>
166
+ <UserDropdownItems />
167
+ </DropdownList>
168
+ </Dropdown>
169
+ </ToolbarItem>
170
+ </ToolbarContent>
171
+ </PFToolbar>
172
+ )
173
+ }
@@ -0,0 +1,9 @@
1
+ ---
2
+ import { DropdownItem } from '@patternfly/react-core'
3
+ ---
4
+
5
+ <>
6
+ <DropdownItem key="group 2 profile">My profile</DropdownItem>
7
+ <DropdownItem key="group 2 user">User management</DropdownItem>
8
+ <DropdownItem key="group 2 logout">Logout</DropdownItem>
9
+ </>
@@ -0,0 +1,10 @@
1
+ import React from 'react'
2
+ import { DropdownItem } from '@patternfly/react-core'
3
+
4
+ export const UserDropdownItems: React.FunctionComponent = () => (
5
+ <>
6
+ <DropdownItem key="group 2 profile">My profile</DropdownItem>
7
+ <DropdownItem key="group 2 user">User management</DropdownItem>
8
+ <DropdownItem key="group 2 logout">Logout</DropdownItem>
9
+ </>
10
+ )
@@ -0,0 +1,36 @@
1
+ import { defineCollection, z } from 'astro:content'
2
+ import { glob } from 'astro/loaders'
3
+
4
+ import { content } from './content'
5
+ import type { CollectionDefinition } from '../cli/getConfig'
6
+
7
+ function defineContent(contentObj: CollectionDefinition) {
8
+ const { base, packageName, pattern, name } = contentObj
9
+ const dir = `${process.cwd()}/${base || `node_modules/${packageName}`}`
10
+
11
+ if (!base && !packageName) {
12
+ // eslint-disable-next-line no-console
13
+ console.error('Either a base or packageName must be defined for ', name)
14
+ return
15
+ }
16
+
17
+ return defineCollection({
18
+ loader: glob({ base: dir, pattern }),
19
+ schema: z.object({
20
+ id: z.string(),
21
+ section: z.string(),
22
+ title: z.string().optional(),
23
+ }),
24
+ })
25
+ }
26
+
27
+ export const collections = content.reduce(
28
+ (acc, contentObj) => {
29
+ const def = defineContent(contentObj)
30
+ if (def) {
31
+ acc[contentObj.name] = def
32
+ }
33
+ return acc
34
+ },
35
+ {} as Record<string, ReturnType<typeof defineContent>>,
36
+ )
package/src/content.ts ADDED
@@ -0,0 +1 @@
1
+ export const content = [{ base: 'textContent', pattern: '*.md', name: "textContent" }, { base: 'dir', pattern: '*.md', name: "dir" }]
package/src/env.d.ts ADDED
@@ -0,0 +1 @@
1
+ /// <reference path="../.astro/types.d.ts" />
@@ -0,0 +1,26 @@
1
+ ---
2
+ import '@patternfly/patternfly/patternfly.css'
3
+ import { ClientRouter } from 'astro:transitions'
4
+
5
+ import Page from '../components/Page.astro'
6
+ import Masthead from '../components/Masthead.astro'
7
+ import Navigation from '../components/Navigation.astro'
8
+ ---
9
+
10
+ <html lang="en" transition:animate="none">
11
+ <head>
12
+ <meta charset="utf-8" />
13
+ <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
14
+ <meta name="viewport" content="width=device-width" />
15
+ <meta name="generator" content={Astro.generator} />
16
+ <title>Astro</title>
17
+ <ClientRouter />
18
+ </head>
19
+ <body>
20
+ <Page>
21
+ <Masthead slot="masthead" />
22
+ <Navigation slot="sidebar" />
23
+ <slot />
24
+ </Page>
25
+ </body>
26
+ </html>
@@ -0,0 +1,31 @@
1
+ ---
2
+ import { getCollection, render } from 'astro:content'
3
+ import { Title } from '@patternfly/react-core'
4
+ import MainLayout from '../../layouts/Main.astro'
5
+ import { content } from "../../content"
6
+
7
+ export async function getStaticPaths() {
8
+ const collections = await Promise.all(content.map(async (entry) => await getCollection(entry.name as 'textContent')))
9
+
10
+ return collections.flat().map((entry) => ({
11
+ params: { id: entry.id, section: entry.data.section },
12
+ props: { entry, title: entry.data.title },
13
+ })
14
+ )
15
+ }
16
+
17
+ const { entry } = Astro.props
18
+ const { title } = entry.data
19
+ const { Content } = await render(entry)
20
+ ---
21
+
22
+ <MainLayout>
23
+ {
24
+ title && (
25
+ <Title headingLevel="h1" size="4xl">
26
+ {title}
27
+ </Title>
28
+ )
29
+ }
30
+ <Content />
31
+ </MainLayout>