From 95d9fcec7f317e4fbd053bbd6e203a511e1a26ca Mon Sep 17 00:00:00 2001 From: Joshua Graber <68428039+joshuagraber@users.noreply.github.com> Date: Fri, 7 Jun 2024 10:24:39 -0400 Subject: [PATCH] docs(components): update component documentation (#83) --- .husky/pre-push | 2 +- README.md | 37 +- docs/components.md | 546 +----------------- 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 | 63 +- src/components/ErrorBoundary/README.md | 40 ++ .../ErrorBoundary/error-boundary.spec.ts | 6 +- src/components/ErrorBoundary/types.ts | 10 +- 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 + src/demo/pages/ComponentDemo.vue | 6 +- 30 files changed, 894 insertions(+), 584 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/README.md b/README.md index a7f4514..cf546fd 100644 --- a/README.md +++ b/README.md @@ -120,24 +120,25 @@ Use these [brand assets](https://docs.pdap.io/meta/about/staff/brand-assets). Us ## Scripts reference -Script | What it does --------------- | ------------------------------------------------------- -`_commit` | Create conventional commits -`build` | Builds the library -`build:watch` | Builds the library and watches for file changes -`ci` | Remove all generated files and re-installs deps -`clean` | Remove all generated files (except `package-lock.json`) -`clean:deps` | Remove node_modules directory -`clean:build` | Remove dist directory -`clean:test` | Remove testing coverage reports -`lint` | Lint everything -`lint:es` | Lint `ts` and `vue` with `eslint` -`lint:css` | Lint `css` and `vue` with `stylelint` -`lint:ts` | Lint `ts` with `tsc` -`test` | Run all test suites -`test:changed` | Run only test suites affected by changed files -`typecheck` | Run type check on all `ts` and `vue` files -`dev` | Run demo app to check visual changes to components +| Script | What it does | +| -------------- | ----------------------------------------------------------------------- | +| `_commit` | Create conventional commits | +| `build` | Builds the library | +| `build:watch` | Builds the library and watches for file changes | +| `ci` | Remove all generated files and re-installs deps | +| `clean` | Remove all generated files (except `package-lock.json`) | +| `clean:deps` | Remove node_modules directory | +| `clean:build` | Remove dist directory | +| `clean:test` | Remove testing coverage reports | +| `lint` | Lint everything | +| `lint:es` | Lint `ts` and `vue` with `eslint` | +| `lint:css` | Lint `css` and `vue` with `stylelint` | +| `lint:ts` | Lint `ts` with `tsc` | +| `test` | Run all test suites | +| `test:changed` | Run only test suites affected by changed files | +| `typecheck` | Run type check on all `ts` and `vue` files | +| `dev` | Run demo app to check visual changes to components | +| `docs` | Run script to automatically aggregate links to component `README` files | _n.b. There are some other scripts defined in the `package.json` `"scripts"` field, but they are mostly for CI or cleanup post-build, etc. You shouldn't need them._ diff --git a/docs/components.md b/docs/components.md index f1d9cc8..460784c 100644 --- a/docs/components.md +++ b/docs/components.md @@ -1,533 +1,13 @@ -# PDAP Component Documentation - -Documentation for PDAP component usage - -## Table of Contents - -- [Breadcrumbs](#breadcrumbs) - - - [Props](#props) - - [Example](#example) - -- [Button](#button) - - - [Props](#props-1) - - - [Example](#example-1) - -- [FlexContainer](#flexcontainer) - -- [Props](#props-2) - -- [Example](#example-2) - -- [Footer](#footer) - -- [Props](#props-3) - -- [Example](#example-3) - -- [Form](#form) - -- [Props](#props-4) - -- [Example](#example-4) - -- [GridContainer](#gridcontainer) - -- [Props](#props-5) - -- [Example](#example-5) - -- [GridItem](#griditem) - -- [Props](#props-6) - -- [Example](#example-6) - -- [Header](#header) - - - [Props](#props-7) - - [Example](#example-7) - -- [Input](#input) - -- [Nav](#nav) - -- [Example](#example-8) - -- [QuickSearchForm](#quicksearchform) - -- [Props](#props-8) - -- [TileIcon](#tileicon) - -- [Props](#props-9) - -- [Example](#example-9) - -- [Dropdown](#dropdown) - - - [Props](#props-9) - - - [Example](#example-9) - -## Button - -### _Props_ - -None - -### _Example_ - -See the Demo application [page](../src/demo/pages/ComponentDemo.vue) and [router](../src/demo/router.js) - -... - -## Footer - -### _Props_ - -name | required? | types | description | default ---------------------- | --------- | -------- | ---------------------- | ----------------------------------------------------------- -`logoImageSrc` | no | `string` | Source of logo image | `'node_modules/pdap-design-system/dist/images/acronym.svg'` -`logoImageAnchorPath` | no | `string` | Flex alignment presets | `/` - -### _Notes_ - -The `Footer` component provides support for overriding the default social links. The `links` variable is `inject`ed by the component, using the following defaults: - -``` -export default { - ... - inject: { - footerLinks: { - default: [ - { - to: 'https://github.com/orgs/Police-Data-Accessibility-Project', - text: 'Github', - }, - { - to: 'ttps://discord.gg/wMqex8nKZJ', - text: 'Discord', - }, - { - to: 'https://www.linkedin.com/company/pdap', - text: 'LinkedIn', - }, - ] - } - }, - data() { - return { - links: this.footerLinks; - } - } -} -``` - -If we desire different links somewhere that `Footer` is rendered, simply `provide` an overriding array from a parent component, like so: - -### _Example_ - -``` - - -... - - -``` - -## Form - -The `Form` component is powerful. All you need to do is pass a few props, and the component will generate inputs and render them in the UI, complete with customizable form validation and both form-level and input-level error states. - -### _Props_ - -name | required? | types | description | default --------- | --------- | ---------------- | ---------------------------------- | ------- -`error` | no | `string` \ | `undefined` \ | `null` | Error state | `undefined` -`id` | yes | `string` | Form id | none -`name` | yes | `string` | Form name | none -`schema` | yes | `PdapFormSchema` | Array of schema entries for inputs | none - -### _Notes_ - -- Form schema entries can look different depending on the type of input. We currently only use text inputs, so the example only displays these. -- To properly submit the form, you must render a button with `type="submit"` _inside_ of the `Form` component. -- `Form` emits a `submit` event and passes all values to the handler you pass to `on-submit` -- Currently available form validations are defined by the `PdapFormValidators` interface: - -``` -PdapFormValidators { - maxLength: { - message?: string; - value: number; - }; - minLength: { - message?: string; - value: number; - }; - required: { - message?: string; - value: boolean; - }; -} -``` - -- The `message` property is optional. If it is not passed, Vuelidate will default to a generic error message. The `value` property is the value you want to validate against. (i.e. for a required field with a max length of 12 characters, we might pass: - -``` -// For a custom message -{ - ..., - validators: { - maxLength: { - message: 'No more than twelve characters, please!', - value: 12 - }, - required: { - message: 'Pretty please enter this field.', - value: true - } - } -} - -// For the default Vuelidate message -{ - ..., - validators: { - maxLength: { - value: 12 - }, - required: { - value: true - } - } -} -``` - -) - -### _Example_ - -``` - - -... - - -``` - -## GridContainer - -_DEPRECATED_ All container components are designed to be dynamic and take any `HTMLElement` tag as the component to be rendered. It also works with the `GridItem` component (see example below). `GridContainer` and `GridItem` could both be passed as the element type for `FlexContainer`, for example, or vice versa, allowing us to easily compose complex layouts. - -### _Props_ - -name | required? | types | description | default ------------------ | --------- | ---------- | ----------------------------------- | --------------------------------------------------- -`columns` | no | `1` \ | `2` \ | `3` \ | `'auto'` | Number of grid columns | `'auto'` -`component` | no | `string` | HTML Element to render as container | `'div'` -`rows` | no | `number` \ | `'auto'` | Number of grid rows | `'auto'` -`templateColumns` | no | `string` \ | `undefined` | Custom `grid-template-columns` value, passed inline | `undefined` (no-op) -`templateRows` | no | `string` \ | `undefined` | Custom `grid-template-rows` value, passed inline | `undefined` (no-op) - -### _Notes_ - -- Grid layouts max out at 3 columns, and responsiveness is baked in. - - - i.e. When you render a 3-column grid layout, it automatically resizes to 2 columns, then 1 column, as screen widths decrease. - - In this case, it is a best practice to leave the `rows` prop as its default `'auto'` value, to ensure that the layout fills as many rows as are needed when the number of columns decreases - -### _Example_ - -``` - - -... - - -``` - -## GridItem - -_DEPRECATED_ - -### _Props_ - -name | required? | types | description | default ------------- | --------- | -------- | ----------------------------------- | ------- -`component` | no | `string` | HTML Element to render as grid item | `'div'` -`spanColumn` | no | `1` \ | `2` \ | `3` | Columns grid item should span | `1` -`spanRow` | no | `number` | Rows grid item should span | `1` - -### _Notes_ - -- Grid layouts max out at 3 columns, and responsiveness is baked in. - - - i.e. When you render a 3-column grid layout, it automatically resizes to 2 columns, then 1 column, as screen widths decrease. - - In this case, it is a best practice to leave the `rows` prop as its default `'auto'` value, to ensure that the layout fills as many rows as are needed when the number of columns decreases - -### _Example_ - -See `GridContainer` above. - -## Header - -### _Props_ - -name | required? | types | description | default ---------------------- | --------- | -------- | ---------------------- | ---------------------------------------------------------- -`logoImageSrc` | no | `string` | Source of logo image | `'node_modules/pdap-design-system/dist/images/lockup.svg'` -`logoImageAnchorPath` | no | `string` | Flex alignment presets | `/` - -### _Notes_ - -The `Header` component does not require any props to be passed. But keep in mind that it is responsible for rendering the `Nav` component. Consuming applications will need to `provide` an array of nav links -- **there are no defaults for this**, you must `provide` these links either 1\. in a layout component (see example below), at the route level, or at the app level. This allows for flexibility in which links are rendered on which routes - -### _Example_ - -``` - - -... - - -``` - -## Input - -Inputs are rendered by the `Form` component via a schema. Please see `Form` for more details - -## Nav - -You do not need to render `Nav` directly. `Header` takes care of that. But you do need to `provide` nav link data from a parent component. This allows for nav links to be dynamic depending on where `Header` is rendered. - -### _Example_ - -``` - - -... - - -``` - -## Dropdown - -The Dropdown component is an accessible dropdown menu that can be triggered by click or hover and positioned in various placements. It provides keyboard accessibility features such as toggling the dropdown on enter/space and closing on escape. - -### _Props_ - -name | required? | types | description | default -------------- | --------- | ------------------------- | -------------------------------------------------- | ------------------------------- -`defaultOpen` | no | `boolean` | Whether the dropdown is initially open | `false` -`disabled` | no | `boolean` | Whether the dropdown should be disabled | `false` -`triggerType` | no | `PdapDropdownTriggerType` | The type of event that should trigger the dropdown | `PdapDropdownTriggerType.PRESS` - -### _Example_ - -See [Component demo](../src/demo/pages/ComponentDemo.vue) +# Component Documentation + + +- [Breadcrumbs](../src/components/Breadcrumbs//README.md) +- [Button](../src/components/Button//README.md) +- [Dropdown](../src/components/Dropdown//README.md) +- [ErrorBoundary](../src/components/ErrorBoundary//README.md) +- [Footer](../src/components/Footer//README.md) +- [Form](../src/components/Form//README.md) +- [Header](../src/components/Header//README.md) +- [Input](../src/components/Input//README.md) +- [Nav](../src/components/Nav//README.md) +- [QuickSearchForm](../src/components/QuickSearchForm//README.md) 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)); + +