Page header
diff --git a/packages/docs/src/components/content/AccordionItem.tsx b/packages/docs/src/components/content/AccordionItem.tsx
new file mode 100644
index 0000000000..5ac58bdb5f
--- /dev/null
+++ b/packages/docs/src/components/content/AccordionItem.tsx
@@ -0,0 +1,9 @@
+import { AccordionItem, MinusCircleIcon, PlusCircleIcon } from '@cmsgov/design-system';
+
+AccordionItem.defaultProps = {
+ ...AccordionItem.defaultProps,
+ closeIconComponent: MinusCircleIcon,
+ openIconComponent: PlusCircleIcon,
+};
+
+export default AccordionItem;
diff --git a/packages/docs/src/components/content/ContentRenderer.tsx b/packages/docs/src/components/content/ContentRenderer.tsx
index 1ced7ee8e0..d0d5d22293 100644
--- a/packages/docs/src/components/content/ContentRenderer.tsx
+++ b/packages/docs/src/components/content/ContentRenderer.tsx
@@ -8,6 +8,7 @@ import ButtonVariationsTable from './ButtonVariationsTable';
import ColorExampleList from './ColorExampleList';
import ColorRamps from './ColorRamps';
import ComponentThemeOptions from './ComponentThemeOptions';
+import DesignResourceLink from './DesignResourceLink';
import EmbeddedExample from './EmbeddedExample';
import MaturityChecklist from './MaturityChecklist';
import ResponsiveExample from './ResponsiveExample';
@@ -18,6 +19,7 @@ import TextColorList from './TextColorList';
import ThemeContent from './ThemeContent';
import ReactDocsLinks from './ReactDocsLinks';
import ReactDocsLink from './ReactDocsLink';
+import { FrontmatterInterface } from '../../helpers/graphQLTypes';
// adds DS styling to tables from markdown
const TableWithClassnames = (props) => {
@@ -65,13 +67,16 @@ const TextWithMaxWidth = (props: any, Component) => {
* A mapping of custom components for mdx syntax
* Each mapping has a key with the element name and a value of a functional component to be used for that element
*/
-const customComponents = (theme) => ({
+const customComponents = (frontmatter, theme) => ({
ButtonMigrationTable: (props) =>
,
ButtonVariationsTable: (props) =>
,
code: CodeWithSyntaxHighlighting,
ColorExampleList: (props) =>
,
ColorRamps,
ComponentThemeOptions: (props) =>
,
+ DesignResourceLink: (props) => (
+
+ ),
EmbeddedExample,
MaturityChecklist,
ol: (props) => TextWithMaxWidth(props, 'ol'),
@@ -95,6 +100,7 @@ interface ContentRendererProps {
* Usually the `data.body.mdx` property from a `mdx` graphQL query
*/
data: string;
+ frontmatter?: FrontmatterInterface;
/**
* Current theme
*/
@@ -105,9 +111,9 @@ interface ContentRendererProps {
* ContentRenderer - a component to standardize the steps needed to display MDX content as page content
* @see https://www.gatsbyjs.com/plugins/gatsby-plugin-mdx/#components for details
*/
-const ContentRenderer = ({ data, theme }: ContentRendererProps) => {
+const ContentRenderer = ({ data, frontmatter, theme }: ContentRendererProps) => {
return (
-
+
{data}
);
diff --git a/packages/docs/src/components/content/DesignResourceLink.tsx b/packages/docs/src/components/content/DesignResourceLink.tsx
new file mode 100644
index 0000000000..aaebe17db1
--- /dev/null
+++ b/packages/docs/src/components/content/DesignResourceLink.tsx
@@ -0,0 +1,37 @@
+import React from 'react';
+import { withPrefix } from 'gatsby';
+import { FrontmatterInterface } from '../../helpers/graphQLTypes';
+import { makeSketchUrl } from '../../helpers/urlUtils';
+
+interface DesignResourceLinkProps {
+ /**
+ * Current theme name.
+ */
+ theme: string;
+ frontmatter: FrontmatterInterface;
+}
+
+const DesignResourceLink = ({ theme, frontmatter }: DesignResourceLinkProps) => {
+ const themeLinks = frontmatter[theme];
+ const sketchId = themeLinks?.sketchLink || null;
+
+ return (
+
+ {sketchId ? (
+
+
+ Sketch symbol
+
+ ) : (
+ 'This theme does not have a Sketch symbol.'
+ )}
+
+ );
+};
+
+export default DesignResourceLink;
diff --git a/packages/docs/src/components/content/MaturityChecklist/MaturityChecklist.tsx b/packages/docs/src/components/content/MaturityChecklist/MaturityChecklist.tsx
index 590c73d5ce..44852bc5ee 100644
--- a/packages/docs/src/components/content/MaturityChecklist/MaturityChecklist.tsx
+++ b/packages/docs/src/components/content/MaturityChecklist/MaturityChecklist.tsx
@@ -1,92 +1,231 @@
import MaturityChecklistItem, { CheckStatus } from './MaturityChecklistItem';
+import { Accordion, SvgIcon } from '@cmsgov/design-system';
+import AccordionItem from '../AccordionItem';
interface MaturityChecklistProps {
- // Accessibility
- a11yStandards: CheckStatus;
- color: CheckStatus;
- forcedColors: CheckStatus;
- screenReaders: CheckStatus;
- keyboardNavigable: CheckStatus;
-
- // Code
- storybook: CheckStatus;
- responsive: CheckStatus;
- spanish: CheckStatus;
-
- // Design
- completeUiKit: CheckStatus;
- responsiveUiKit: CheckStatus;
-
- // Tokens
- tokensInCode: CheckStatus;
- tokensInSketch: CheckStatus;
+ children: string;
+
+ items: {
+ // Accessibility
+ a11yStandards: CheckStatus;
+ color: CheckStatus;
+ forcedColors: CheckStatus;
+ screenReaders: CheckStatus;
+ keyboardNavigable: CheckStatus;
+
+ // Code
+ storybook: CheckStatus;
+ responsive: CheckStatus;
+ spanish: CheckStatus;
+
+ // Design
+ completeUiKit: CheckStatus;
+ responsiveUiKit: CheckStatus;
+
+ // Tokens
+ tokensInCode: CheckStatus;
+ tokensInSketch: CheckStatus;
+ };
}
/**
*
*/
-const MaturityChecklist = (props: MaturityChecklistProps) => (
-
-
- For more information about how we tested and validated our work for each checklist item,{' '}
-
- read our component maturity documentation
-
- .
-
-
- Accessibility
-
-
- Meets AA color contrast standards for accessibility and color blindness.
-
-
- While using FCM the components text is legible and improves readability.
-
-
- All Axe checks for WCAG AA compliance have passed.
-
-
- VoiceOver, NVDA, and JAWS screen readers provide concise communication and interaction.
-
-
- Component is fully navigable with a keyboard.
-
-
-
- Code
-
-
- Component has stories to cover all defined props.
-
-
- Component designed to work in all responsive breakpoints.
-
-
- Includes Spanish translations for default text content.
-
-
-
- {/* Design
-
-
- Includes all Sketch symbols for defined options.
-
-
- All Sketch symbols designed for small and large breakpoints.
-
-
*/}
-
- Tokens
-
-
- Tokens implemented in code.
-
-
- Tokens implemented in the Sketch.
-
-
-
-);
+const MaturityChecklist = (props: MaturityChecklistProps) => {
+ const criteria = [
+ {
+ title: 'Accessibility',
+ items: [
+ {
+ title: 'Color',
+ description: 'Meets AA color contrast standards for accessibility and color blindness.',
+ status: props.items['color'],
+ },
+ {
+ title: 'Forced Colors Mode (FCM)',
+ description: 'While using FCM the components text is legible and improves readability.',
+ status: props.items['forcedColors'],
+ },
+ {
+ title: 'WCAG 2.1 Level AA Conformance',
+ description: 'All Axe checks for WCAG AA compliance have passed.',
+ status: props.items['a11yStandards'],
+ },
+ {
+ title: 'Screen readers',
+ description:
+ 'VoiceOver, NVDA, and JAWS screen readers provide concise communication and interaction.',
+ status: props.items['screenReaders'],
+ },
+ {
+ title: 'Keyboard navigation',
+ description: 'Component is fully navigable with a keyboard.',
+ status: props.items['keyboardNavigable'],
+ },
+ ],
+ },
+ {
+ title: 'Code',
+ items: [
+ {
+ title: 'Storybook',
+ description: 'Component has stories to cover all defined props.',
+ status: props.items['storybook'],
+ },
+ {
+ title: 'Responsive',
+ description: 'Component designed to work in all responsive breakpoints.',
+ status: props.items['responsive'],
+ },
+ {
+ title: 'Spanish translations',
+ description: 'Includes Spanish translations for default text content.',
+ status: props.items['spanish'],
+ },
+ ],
+ },
+ // {
+ // title: 'Design',
+ // items: [
+ // {
+ // title: 'Sketch UI-kit',
+ // description: 'Includes all Sketch symbols for defined options.',
+ // status: props.items['completeUiKit'],
+ // },
+ // {
+ // title: 'Responsive',
+ // description: 'All Sketch symbols designed for small and large breakpoints.',
+ // status: props.items['responsiveUiKit'],
+ // },
+ // ],
+ // },
+ {
+ title: 'Tokens',
+ items: [
+ {
+ title: 'Code',
+ description: 'Tokens implemented in code.',
+ status: props.items['tokensInCode'],
+ },
+ {
+ title: 'Design',
+ description: 'Tokens implemented in the Sketch.',
+ status: props.items['tokensInSketch'],
+ },
+ ],
+ },
+ ];
+
+ // Calculates percentage of completed criteria
+ const progress = () => {
+ let totalAvailableCriteria = 0;
+ let completedCriteria = 0;
+
+ criteria.forEach((criterion) => {
+ criterion.items.forEach((item) => {
+ if (item.status !== null) {
+ totalAvailableCriteria++;
+ if (item.status === true) {
+ completedCriteria++;
+ }
+ }
+ });
+ });
+
+ return Math.round((completedCriteria / totalAvailableCriteria) * 100);
+ };
+
+ // Creates list of incomplete criteria
+ const incompleteCriteria = criteria.map((criterion) => {
+ return criterion.items.map((item) => {
+ if (item.status === false) {
+ return (
+
+ {item.description}
+
+ );
+ }
+ });
+ });
+
+ return (
+
+
+ {props.children}
+
+
+ {progress() === 100 ? (
+
+
+
+ ) : (
+
+
+
+ )}
+
This component meets {progress()}% of our maturity criteria.
+
+
+ {progress() !== 100 && (
+
+ <>
+
Incomplete criteria
+
+ >
+
+ )}
+
+
+
What does this mean?
+
+
+ Each component is tested against the following items to gauge the component's
+ maturity. When using incomplete components, consider the unmet criteria as applied to
+ your product.
+
+
+
+ For more information about how we tested and validated our work for each checklist item,{' '}
+
+ read our component maturity documentation
+
+ .
+
+
+
+
+
+ {criteria.map((criterion) => {
+ return (
+
+ {criterion.title}
+ {criterion.items.map((item) => {
+ return (
+
+ {item.description}
+
+ );
+ })}
+
+ );
+ })}
+
+
+
+
+ );
+};
export default MaturityChecklist;
diff --git a/packages/docs/src/components/content/MaturityChecklist/MaturityChecklistItem.tsx b/packages/docs/src/components/content/MaturityChecklist/MaturityChecklistItem.tsx
index da9cd36320..3b49859612 100644
--- a/packages/docs/src/components/content/MaturityChecklist/MaturityChecklistItem.tsx
+++ b/packages/docs/src/components/content/MaturityChecklist/MaturityChecklistItem.tsx
@@ -15,15 +15,18 @@ interface MaturityChecklistItemProps {
*/
const MaturityChecklistItem = ({ status, title, children }: MaturityChecklistItemProps) => (
-
+
+ {title}:
+ {children}
+
);
diff --git a/packages/docs/src/components/content/MaturityChecklist/Status.tsx b/packages/docs/src/components/content/MaturityChecklist/Status.tsx
index 35128a4638..391b5a6804 100644
--- a/packages/docs/src/components/content/MaturityChecklist/Status.tsx
+++ b/packages/docs/src/components/content/MaturityChecklist/Status.tsx
@@ -12,7 +12,7 @@ const Status = ({ status }: StatusProps) => {
if (status === true) {
return (
<>
-
+
{
} else {
return (
<>
-
+
{
+}: SeeStorybookForGuidanceProps) => {
return (
- See Storybook for{' '}
- {tech === 'react' ? 'React' : 'Web Component'} guidance of this component.
+
+ {' '}
+ {tech === 'react' ? 'Preact/React' : 'Web component'} documentation for Storybook
+
);
};
diff --git a/packages/docs/src/components/content/StorybookExample.tsx b/packages/docs/src/components/content/StorybookExample.tsx
index 4b92d879bd..42e0cc2660 100644
--- a/packages/docs/src/components/content/StorybookExample.tsx
+++ b/packages/docs/src/components/content/StorybookExample.tsx
@@ -22,6 +22,7 @@ interface StorybookExampleProps {
* Current theme
*/
theme: string;
+ hideFooter?: boolean;
}
/**
@@ -31,7 +32,13 @@ interface StorybookExampleProps {
* If you need to show responsiveness, use the `ResponsiveExample`.
* If you don't need a story, but can use regular HTML or React components, use an Embedded example.
*/
-const StorybookExample = ({ theme, componentName, minHeight, storyId }: StorybookExampleProps) => {
+const StorybookExample = ({
+ theme,
+ componentName,
+ minHeight,
+ storyId,
+ hideFooter = false,
+}: StorybookExampleProps) => {
const [iframeHeight, setiFrameHeight] = useState(200);
const [isLoading, setIsLoading] = useState(true);
const iframeRef = useRef();
@@ -108,7 +115,7 @@ const StorybookExample = ({ theme, componentName, minHeight, storyId }: Storyboo
/>
>
);
};
diff --git a/packages/docs/src/components/content/StorybookExampleFooter.tsx b/packages/docs/src/components/content/StorybookExampleFooter.tsx
index 1529b8a41a..2dff990c7c 100644
--- a/packages/docs/src/components/content/StorybookExampleFooter.tsx
+++ b/packages/docs/src/components/content/StorybookExampleFooter.tsx
@@ -12,15 +12,16 @@ interface StorybookExampleFooterProps {
* Current theme
*/
theme: string;
+ hidden?: boolean;
}
/**
* Goes below storybook-based examples and allows people to click a link to go directly
* to the story within Storybook.
*/
-const StorybookExampleFooter = ({ theme, storyId }: StorybookExampleFooterProps) => {
+const StorybookExampleFooter = ({ theme, storyId, hidden }: StorybookExampleFooterProps) => {
return (
-