Skip to content

Commit fa04cce

Browse files
Merge pull request #37 from thatblindgeye/propsTable
feat: Created PropsTable component structure
2 parents 14320b8 + 4f75441 commit fa04cce

File tree

5 files changed

+674
-28
lines changed

5 files changed

+674
-28
lines changed

package-lock.json

Lines changed: 40 additions & 28 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
"@nanostores/react": "^0.8.0",
4545
"@patternfly/patternfly": "^6.0.0",
4646
"@patternfly/react-core": "^6.0.0",
47+
"@patternfly/react-table": "^6.0.0",
4748
"@types/react": "^18.3.12",
4849
"@types/react-dom": "^18.3.1",
4950
"astro": "^5.4.1",

src/components/PropsTable.tsx

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
import { Label, Stack } from '@patternfly/react-core'
2+
import {
3+
Table,
4+
Thead,
5+
Th,
6+
Tr,
7+
Tbody,
8+
Td,
9+
TableText,
10+
} from '@patternfly/react-table'
11+
import { css } from '@patternfly/react-styles'
12+
import accessibleStyles from '@patternfly/react-styles/css/utilities/Accessibility/accessibility'
13+
import textStyles from '@patternfly/react-styles/css/utilities/Text/text'
14+
15+
export type ComponentProp = {
16+
name: string
17+
isRequired?: boolean
18+
isBeta?: boolean
19+
isHidden?: boolean
20+
isDeprecated?: boolean
21+
type?: string
22+
defaultValue?: string
23+
description?: string
24+
}
25+
26+
type PropsTableProps = {
27+
componentName: string
28+
headingLevel?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'
29+
componentDescription?: string
30+
componentProps?: ComponentProp[]
31+
}
32+
33+
export const PropsTable: React.FunctionComponent<PropsTableProps> = ({
34+
componentName,
35+
headingLevel = 'h3',
36+
componentDescription,
37+
componentProps,
38+
}) => {
39+
const SectionHeading = headingLevel
40+
const publicProps = componentProps?.filter((prop) => !prop.isHidden)
41+
const hasPropsToRender = !!publicProps?.length
42+
43+
const renderTagLabel = (componentProp: ComponentProp) => {
44+
const { name, isBeta, isDeprecated } = componentProp
45+
if (!isBeta && !isDeprecated) {
46+
return null
47+
}
48+
49+
if (isBeta && isDeprecated) {
50+
// eslint-disable-next-line no-console
51+
console.error(
52+
`The ${name} prop for ${componentName} has both the isBeta and isDeprecated tag.`,
53+
)
54+
}
55+
56+
return (
57+
<Label color={`${isBeta ? 'blue' : 'grey'}`} isCompact>
58+
{isBeta ? 'Beta' : 'Deprecated'}
59+
</Label>
60+
)
61+
}
62+
63+
const renderRequiredDescription = (isRequired: boolean | undefined) => {
64+
if (!isRequired) {
65+
return null
66+
}
67+
68+
return (
69+
<>
70+
<span aria-hidden="true" className={css(textStyles.textColorRequired)}>
71+
*
72+
</span>
73+
<span className={css(accessibleStyles.screenReader)}>required</span>
74+
</>
75+
)
76+
}
77+
78+
return (
79+
<>
80+
<SectionHeading>{componentName}</SectionHeading>
81+
<Stack hasGutter>
82+
{componentDescription && (
83+
<div
84+
data-testid="component-description"
85+
className={css(textStyles.textColorSubtle)}
86+
>
87+
{componentDescription}
88+
</div>
89+
)}
90+
{hasPropsToRender && (
91+
<>
92+
<div id={`${componentName}-required-description`}>
93+
<span className={css(textStyles.textColorRequired)}>*</span>{' '}
94+
<span className={css(textStyles.textColorSubtle)}>
95+
indicates a required prop
96+
</span>
97+
</div>
98+
<Table
99+
variant="compact"
100+
aria-label={`Props for ${componentName}`}
101+
aria-describedby={`${componentName}-required-description`}
102+
gridBreakPoint="grid-lg"
103+
>
104+
<Thead>
105+
<Tr>
106+
<Th width={20}>Name</Th>
107+
<Th width={20}>Type</Th>
108+
<Th width={10}>Default</Th>
109+
<Th>Description</Th>
110+
</Tr>
111+
</Thead>
112+
<Tbody>
113+
{publicProps.map((prop: ComponentProp) => (
114+
<Tr key={prop.name}>
115+
<Td>
116+
<TableText wrapModifier="breakWord">
117+
{prop.name}
118+
{renderRequiredDescription(prop.isRequired)}{' '}
119+
{renderTagLabel(prop)}
120+
</TableText>
121+
</Td>
122+
<Td>
123+
<TableText wrapModifier="breakWord">
124+
{prop.type || 'No type info available'}
125+
</TableText>
126+
</Td>
127+
<Td>
128+
<TableText wrapModifier="breakWord">
129+
{prop.defaultValue || '-'}
130+
</TableText>
131+
</Td>
132+
<Td>
133+
<TableText wrapModifier="breakWord">
134+
{prop.description || 'No description available.'}
135+
</TableText>
136+
</Td>
137+
</Tr>
138+
))}
139+
</Tbody>
140+
</Table>
141+
</>
142+
)}
143+
</Stack>
144+
</>
145+
)
146+
}

0 commit comments

Comments
 (0)