From 0ac88d2d030b28b2df78ce4a5ddc04798e5e758d Mon Sep 17 00:00:00 2001 From: Joshua Graber Date: Thu, 6 Jun 2024 19:39:35 -0400 Subject: [PATCH 1/4] docs(components): update component docs split docs into separate component READMEs, write script to collect links to all component docs in directory --- .husky/pre-push | 2 +- package.json | 5 +- scripts/update-docs.sh | 30 ++++ .../Breadcrumbs/PdapBreadcrumbs.vue | 15 ++ src/components/Breadcrumbs/README.md | 14 ++ src/components/Breadcrumbs/index.ts | 4 +- src/components/Button/PdapButton.vue | 15 ++ src/components/Button/README.md | 31 ++++ src/components/Button/index.ts | 4 +- src/components/Dropdown/PdapDropdown.vue | 16 ++ src/components/Dropdown/README.md | 103 +++++++++++++ .../ErrorBoundary/PdapErrorBoundary.vue | 18 +++ src/components/ErrorBoundary/README.md | 38 +++++ src/components/Footer/PdapFooter.vue | 14 ++ src/components/Footer/README.md | 71 +++++++++ src/components/Form/PdapForm.vue | 114 +++++++++++++- src/components/Form/README.md | 145 ++++++++++++++++++ src/components/Header/PdapHeader.vue | 17 ++ src/components/Header/README.md | 40 +++++ src/components/Input/README.md | 3 + src/components/Nav/PdapNav.vue | 43 ++++++ src/components/Nav/README.md | 37 +++++ .../QuickSearchForm/QuickSearchForm.vue | 20 +++ src/components/QuickSearchForm/README.md | 18 +++ src/components/TileIcon/TileIcon.vue | 9 ++ 25 files changed, 814 insertions(+), 12 deletions(-) create mode 100644 scripts/update-docs.sh create mode 100644 src/components/Breadcrumbs/README.md create mode 100644 src/components/Button/README.md create mode 100644 src/components/Dropdown/README.md create mode 100644 src/components/ErrorBoundary/README.md create mode 100644 src/components/Footer/README.md create mode 100644 src/components/Form/README.md create mode 100644 src/components/Header/README.md create mode 100644 src/components/Input/README.md create mode 100644 src/components/Nav/README.md create mode 100644 src/components/QuickSearchForm/README.md diff --git a/.husky/pre-push b/.husky/pre-push index 115cd65..858630c 100755 --- a/.husky/pre-push +++ b/.husky/pre-push @@ -1,4 +1,4 @@ #!/usr/bin/env sh . "$(dirname -- "$0")/_/husky.sh" -npm run test:ci +npm run docs && npm run test:ci diff --git a/package.json b/package.json index 3d65af0..76dec75 100644 --- a/package.json +++ b/package.json @@ -113,7 +113,8 @@ "test:badge": "vitest run --coverage.enabled --coverage.reporter='text-summary'", "test:ci": "npm run test -- --silent", "typecheck": "vue-tsc", - "dev": "vite" + "dev": "vite", + "docs": "bash ./scripts/update-docs.sh" }, "workspaces": [ "eslint-config" @@ -134,4 +135,4 @@ "path": "./node_modules/cz-conventional-changelog" } } -} +} \ No newline at end of file diff --git a/scripts/update-docs.sh b/scripts/update-docs.sh new file mode 100644 index 0000000..b7331d3 --- /dev/null +++ b/scripts/update-docs.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +# Edit these vars at your peril +base_dir=./src/components +output_file="components.md" + +echo "# Component Documentation" > "docs/$output_file" +echo -e "\n" >> "docs/$output_file" + +for dir in $base_dir/*/; do + dir_name=$(basename "$dir") + dir_normalized=.$dir + + # Check if a README.md file exists in the directory + if [ -f "$dir/README.md" ]; then + # If so, write the link to the output file + echo "- [$dir_name]($dir_normalized/README.md)" >> "docs/$output_file" + fi +done + +# create a commit, only if there are changes +if git diff --quiet docs/$output_file; then + echo "No component documentation changes detected" + exit 0 +else + commit_msg="chore(docs): auto-update to component docs" + + echo "Changes detected, committing updated docs/$output_file file..." + git add docs/$output_file && git commit -m "$commit_msg" --no-verify && echo "Commit finished, proceeding with push" +fi diff --git a/src/components/Breadcrumbs/PdapBreadcrumbs.vue b/src/components/Breadcrumbs/PdapBreadcrumbs.vue index 955148d..e7e32e2 100644 --- a/src/components/Breadcrumbs/PdapBreadcrumbs.vue +++ b/src/components/Breadcrumbs/PdapBreadcrumbs.vue @@ -25,6 +25,21 @@ const route = useRoute(); const breadcrumbs = computed(() => getBreadcrumbs(route)); + + --> diff --git a/src/components/FlexContainer/__snapshots__/flex-container.spec.ts.snap b/src/components/FlexContainer/__snapshots__/flex-container.spec.ts.snap deleted file mode 100644 index 5555488..0000000 --- a/src/components/FlexContainer/__snapshots__/flex-container.spec.ts.snap +++ /dev/null @@ -1,3 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[`Renders container component > Renders a container 1`] = `
Container Content
`; diff --git a/src/components/FlexContainer/flex-container.spec.ts b/src/components/FlexContainer/flex-container.spec.ts deleted file mode 100644 index 8aefe5a..0000000 --- a/src/components/FlexContainer/flex-container.spec.ts +++ /dev/null @@ -1,37 +0,0 @@ -// Component -import FlexContainer from './FlexContainer.vue'; - -// Utils -import { mount } from '@vue/test-utils'; -import { describe, expect, test } from 'vitest'; - -// Test -describe('Renders container component', () => { - // Render - test('Renders a container', () => { - const wrapper = mount(FlexContainer, { - slots: { - default: 'Container Content', - }, - }); - - expect(wrapper.find('.pdap-flex-container').exists()).toBe(true); - expect(wrapper.classes()).toContain('pdap-flex-container'); - expect(wrapper.html()).toContain('Container Content'); - expect(wrapper.html()).toMatchSnapshot(); - }); - - // Props - // Props - align - test('Renders start aligned container', () => { - const wrapper = mount(FlexContainer, { props: { alignment: 'start' } }); - expect(wrapper.props().alignment).toBe('start'); - expect(wrapper.classes()).toContain('pdap-flex-container-start'); - }); - - test('Renders center aligned container', () => { - const wrapper = mount(FlexContainer, { props: { alignment: 'center' } }); - expect(wrapper.props().alignment).toBe('center'); - expect(wrapper.classes()).toContain('pdap-flex-container-center'); - }); -}); diff --git a/src/components/FlexContainer/index.ts b/src/components/FlexContainer/index.ts deleted file mode 100644 index 785e98b..0000000 --- a/src/components/FlexContainer/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import FlexContainer from './FlexContainer.vue'; - -export { FlexContainer }; diff --git a/src/components/FlexContainer/types.ts b/src/components/FlexContainer/types.ts deleted file mode 100644 index e1d831c..0000000 --- a/src/components/FlexContainer/types.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface PdapFlexContainerProps { - alignment?: 'center' | 'start'; - component?: string; -} diff --git a/src/components/GridContainer/GridContainer.vue b/src/components/GridContainer/GridContainer.vue deleted file mode 100644 index 58865d7..0000000 --- a/src/components/GridContainer/GridContainer.vue +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - diff --git a/src/components/GridContainer/__snapshots__/grid.spec.ts.snap b/src/components/GridContainer/__snapshots__/grid.spec.ts.snap deleted file mode 100644 index 7b991e4..0000000 --- a/src/components/GridContainer/__snapshots__/grid.spec.ts.snap +++ /dev/null @@ -1,9 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[`Renders container component > Renders a container 1`] = ` -
-
  • - - -
    -`; diff --git a/src/components/GridContainer/grid.spec.ts b/src/components/GridContainer/grid.spec.ts deleted file mode 100644 index b8ee539..0000000 --- a/src/components/GridContainer/grid.spec.ts +++ /dev/null @@ -1,136 +0,0 @@ -/* eslint-disable vue/one-component-per-file */ -// Component -import GridContainer from './GridContainer.vue'; -import GridItem, { PdapGridItemProps } from '../GridItem/GridItem.vue'; - -// Utils -import { defineComponent } from 'vue'; -import { mount } from '@vue/test-utils'; -import { describe, expect, test, vi } from 'vitest'; - -type TestSlotProps = T; - -const data = [ - { component: 'li' }, - { component: 'img', src: 'https://mock.test.com' }, - { component: 'card', spanColumn: 3, spanRow: 2 }, -]; -const template = - ''; - -const expectComponents = new Set(['li', 'img', 'card']); - -const MultipleItems = defineComponent({ - components: { - GridItem, - }, - props: { - data: { - type: Array, - default: data, - }, - }, - template, -}); - -const SingleItem = defineComponent({ - components: { - GridItem, - }, - props: { - data: { - type: Array, - default: data, - }, - }, - template: '', -}); - -const getComputedStyle = vi.fn((el) => el.getComputedStyle()); -getComputedStyle.mockReturnValue({ - gridTemplateRows: 'repeat(3, minmax(20px, 1fr))', - gridTemplateColumns: 'repeat(2, auto)', - gridRow: 'span 2 / span 2', -}); -vi.stubGlobal('getComputedStyle', getComputedStyle); - -// Test -describe('Renders container component', () => { - // Render - test('Renders a container', () => { - const wrapper = mount(GridContainer, { - slots: { - default: MultipleItems, - }, - }); - - const container = wrapper.find('.pdap-grid-container'); - const items = container.findAll('.pdap-grid-item'); - - // Container - expect(container.exists()).toBe(true); - expect(wrapper.classes()).toContain('pdap-grid-container'); - - // Renders all items passed - expect(items.length).toBe(3); - - // Renders fall-through prop conditionally for img element - expect(container.find('[src="https://mock.test.com"]').exists()).toBe(true); - - // Renders each type of component passed - expect( - items.every((item) => - item.getRootNodes().some((node) => expectComponents.has(node.localName)) - ) - ).toBe(true); - - // Snapshot - expect(wrapper.html()).toMatchSnapshot(); - }); - - test('Renders a container with template props passed', () => { - const wrapper = mount(GridContainer, { - slots: { - default: MultipleItems, - }, - props: { - templateColumns: 'repeat(2, auto)', - templateRows: 'repeat(3, minmax(20px, 1fr))', - }, - }); - - expect(window.getComputedStyle(wrapper.vm.$el).gridTemplateColumns).toBe( - 'repeat(2, auto)' - ); - expect(window.getComputedStyle(wrapper.vm.$el).gridTemplateRows).toBe( - 'repeat(3, minmax(20px, 1fr))' - ); - }); - - test('Renders a container with columns and rows props passed', () => { - const wrapper = mount(GridContainer, { - slots: { - default: MultipleItems, - }, - props: { - rows: 2, - columns: 3, - }, - }); - - expect(wrapper.vm.$props.rows).toBe(2); - expect(wrapper.vm.$props.columns).toBe(3); - }); - - test('Renders a grid item with custom row span prop', () => { - const wrapper = mount(GridContainer, { - slots: { - default: SingleItem, - }, - }); - - expect( - window.getComputedStyle(wrapper.find('.pdap-grid-item').element).gridRow - ).toBe('span 2 / span 2'); - }); -}); diff --git a/src/components/GridContainer/index.ts b/src/components/GridContainer/index.ts deleted file mode 100644 index e407d59..0000000 --- a/src/components/GridContainer/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import GridContainer from './GridContainer.vue'; - -export { GridContainer }; diff --git a/src/components/GridContainer/types.ts b/src/components/GridContainer/types.ts deleted file mode 100644 index 54eabca..0000000 --- a/src/components/GridContainer/types.ts +++ /dev/null @@ -1,7 +0,0 @@ -export interface PdapGridContainerProps { - columns?: 1 | 2 | 3 | 'auto'; - component?: string; - rows?: number | 'auto'; - templateColumns?: string; - templateRows?: string; -} diff --git a/src/components/GridItem/GridItem.vue b/src/components/GridItem/GridItem.vue deleted file mode 100644 index 79dd56a..0000000 --- a/src/components/GridItem/GridItem.vue +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - diff --git a/src/components/GridItem/index.ts b/src/components/GridItem/index.ts deleted file mode 100644 index 2e0be61..0000000 --- a/src/components/GridItem/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import GridItem from './GridItem.vue'; - -export { GridItem }; diff --git a/src/components/GridItem/types.ts b/src/components/GridItem/types.ts deleted file mode 100644 index 70d1cd8..0000000 --- a/src/components/GridItem/types.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface PdapGridItemProps { - component?: string; - spanColumn?: 1 | 2 | 3; - spanRow?: number; -} diff --git a/src/components/index.ts b/src/components/index.ts index 4e6d2f6..4d15c5f 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -1,9 +1,7 @@ export { Button } from './Button'; -export { FlexContainer } from './FlexContainer'; +export { ErrorBoundary } from './ErrorBoundary'; export { Footer } from './Footer'; export { Form } from './Form'; -export { GridContainer } from './GridContainer'; -export { GridItem } from './GridItem'; export { Input } from './Input'; export { Header } from './Header'; export { Nav } from './Nav'; diff --git a/src/demo/pages/ComponentDemo.vue b/src/demo/pages/ComponentDemo.vue index b98a3d2..3e4935d 100644 --- a/src/demo/pages/ComponentDemo.vue +++ b/src/demo/pages/ComponentDemo.vue @@ -144,7 +144,7 @@ -

    Here is a form using the Form component directly

    +

    Form

    Say hello
    -

    And here is the Quick Search Form component

    +

    Quick Search Form

    + +

    Error Boundary

    + +
    +

    + This is the content that will render inside the error boundary if + there is no error +

    + +
    +
    @@ -166,6 +181,7 @@ import { Breadcrumbs, Button, Dropdown, + ErrorBoundary, Form, QuickSearchForm, } from '../../components'; @@ -234,6 +250,10 @@ function buttonAlert(msg: string) { alert(msg); } +function triggerError() { + throw new Error('Trigger error fallback'); +} + function submit(values: Record<'firstName' | 'lastName' | 'iceCream', string>) { console.debug({ values }); const alertString = `Howdy, ${values.firstName} ${values.lastName}\n${ diff --git a/src/index.ts b/src/index.ts index eb83c74..cf2bcaf 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,17 +1,15 @@ // Components export * from './components'; -// Styles +// Styles - compiled automatically import './styles/styles.css'; // Types export * from './components/Button/types'; export * from './components/Dropdown/types'; -export * from './components/FlexContainer/types'; +export * from './components/ErrorBoundary/types'; export * from './components/Footer/types'; export * from './components/Form/types'; -export * from './components/GridContainer/types'; -export * from './components/GridItem/types'; export * from './components/Header/types'; export * from './components/Input/types'; export * from './components/Nav/types';