Skip to content

feat(props): add props data gathering and table rendering support#40

Merged
dlabaj merged 8 commits intomainfrom
add-props-data-gathering
May 1, 2025
Merged

feat(props): add props data gathering and table rendering support#40
dlabaj merged 8 commits intomainfrom
add-props-data-gathering

Conversation

@wise-king-sullyman
Copy link
Contributor

@wise-king-sullyman wise-king-sullyman commented Apr 9, 2025

Closes #41

To test this PR:

  1. pull this branch
  2. install the deps
  3. run build:props (this will happen automatically when the server is started via the CLI)
  4. start the dev server
  5. go to http://localhost:4321/get-started/contribute
  6. verify that the props table renders
  7. go to the contribute.md file in textContent
  8. add other components to the propComponents array (or add that entry to other files)
  9. verify that those other components start showing too.

@thatblindgeye thatblindgeye self-requested a review April 9, 2025 16:49

adapter: node({
mode: 'standalone'
})
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes enable astro to run a node server for the custom endpoint below in props.json.ts

@@ -0,0 +1,94 @@
/* eslint-disable no-console */
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file ingests the files which should have their props parsed, parses the props out using tsDocGen, compiles that data into a single object, then writes that object to a json file.

Comment on lines +48 to +59
try {
astroRoot = import.meta
.resolve('@patternfly/patternfly-doc-core')
.replace('dist/cli/cli.js', '')
.replace('file://', '')
} catch (e) {
if (e.code === 'ERR_MODULE_NOT_FOUND') {
astroRoot = process.cwd()
} else {
console.error('Error resolving astroRoot', e)
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change just makes it so that we can run the docs-core locally more easily

@@ -0,0 +1,207 @@
import { readFile } from 'fs/promises'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is 99% just tsDocGen from the current docs framework. I'd like us to clean this up at some point, but that that is best left for further down the road.

@@ -0,0 +1,31 @@
export const config = {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This top level config files is also something that I just added to make running this repo locally easier.

}

type PropsTableProps = {
interface PropsTableProps extends React.HTMLProps<HTMLDivElement> {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I needed to make this change so that we could pass a key prop to the tables without TS throwing an error.

Comment on lines +25 to +35
async function getPropsData(propComponents: string[]) {
if (!propComponents.length) {
return []
}

const url = new URL(`/props?components=${propComponents}`, Astro.url)
const response = await fetch(url)
const propsData = await response.json()

return propsData
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At its root the new process works by the frontend hitting the backend /props route with its propComponents value as a query param. The backend then returns only the requested components prop data in json.

Comment on lines +1 to +17
import { readFileSync } from 'fs'
import { join } from 'path'

const propsFilePath = join(process.cwd(), 'dist', 'props.json')
const propsData = readFileSync(propsFilePath)
const props = JSON.parse(propsData.toString())

export const prerender = false

export async function GET({ request }: { request: Request }) {
const queryParams = new URL(request.url).searchParams
const components = queryParams.get('components')
const componentsArray = components?.split(',')
const propsData = componentsArray?.map((component) => props[component])

return new Response(JSON.stringify(propsData))
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what creates the custom endpoint to get the props data from the frontend.

id: Contribute
title: Contribute to PatternFly
section: get-started
propComponents: ['Button', 'BadgeCountObject']
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just for testing/demo purposes.

.resolve('@patternfly/patternfly-doc-core')
.replace('dist/cli/cli.js', '')
.replace('file://', '')
async function generateProps(program: Command, forceProps: boolean = false) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious, what would the expected use case of forceProps be?

Copy link
Contributor Author

@wise-king-sullyman wise-king-sullyman Apr 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whenever we want to enforce the props being generated on the CLI internals side regardless of if the user passes the --props flag, such as for when doing a production build.

Comment on lines +21 to +29
// {
// include: ['*/@patternfly/react-core/src/**/*.tsx'],
// exclude: [
// '/**/examples/**',
// '/**/__mocks__/**',
// '/**/__tests__/**',
// '/**/*.test.tsx',
// ],
// },
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this expected to be removed or uncommented before merging?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope I was planning to leave it commented in the template file like the content entry, but I'm not dead set on that.

(type && type.name) ||
(type && (type.raw || type.name)) ||
(tsType && (tsType.raw || tsType.name)) ||
'No type info',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could either remove this or update the PropsTable since I had included a fallback there with a similar string.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah we can if you want, I just wasn't trying to mess with tsDocGen any more than I needed to at the moment.

Comment on lines +53 to +55
propsData
.filter((comp: any) => !!comp)
.map((component: any) => (
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be something in a future update, but wondering if we want to tweak the order the prop tables get rendered. Believe currently it's just based on whatever order the propComponents array in frontmatter is written, but would sorting alphabetically make more sense? Or some other way to dictate what the order should be rather than manually having to know "Component X should be rendered before Component C because Reasons"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I lean towards just letting the order be dictated by the propsData order? Just because it's the simplest solution and lets the order be dictated consumer side. But I'm not firmly against us sorting it some way theoretically.

@wise-king-sullyman wise-king-sullyman marked this pull request as ready for review April 16, 2025 20:45
@dlabaj dlabaj merged commit fb6a78e into main May 1, 2025
1 check passed
@github-actions
Copy link

github-actions bot commented May 1, 2025

🎉 This PR is included in version 1.3.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add backend support for displaying component prop data

3 participants