From 2483e749f5e26909b633ccb21d67a68b896eca7f Mon Sep 17 00:00:00 2001 From: Preston Bourne Date: Tue, 20 Jun 2023 09:02:20 -0400 Subject: [PATCH 1/5] add tree sorting func --- examples/basic/components/accordion/docs.mdx | 5 ++++ examples/basic/components/accordion/index.tsx | 10 ++++++++ packages/swingset/src/get-nav-tree.ts | 25 +++++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 examples/basic/components/accordion/docs.mdx create mode 100644 examples/basic/components/accordion/index.tsx diff --git a/examples/basic/components/accordion/docs.mdx b/examples/basic/components/accordion/docs.mdx new file mode 100644 index 0000000..8cd8d38 --- /dev/null +++ b/examples/basic/components/accordion/docs.mdx @@ -0,0 +1,5 @@ +--- +title: 'Accordion' +description: 'UI component named after a funky instrument 🪗' +path: 'Content/Accordion' +--- \ No newline at end of file diff --git a/examples/basic/components/accordion/index.tsx b/examples/basic/components/accordion/index.tsx new file mode 100644 index 0000000..55723f8 --- /dev/null +++ b/examples/basic/components/accordion/index.tsx @@ -0,0 +1,10 @@ +import { ReactElement } from 'react' + +interface ButtonProps { + color?: string + children: ReactElement +} + +export function Button({ children }: ButtonProps) { + return +} diff --git a/packages/swingset/src/get-nav-tree.ts b/packages/swingset/src/get-nav-tree.ts index 47a5273..053c2bf 100644 --- a/packages/swingset/src/get-nav-tree.ts +++ b/packages/swingset/src/get-nav-tree.ts @@ -4,6 +4,7 @@ import { ComponentNode, CategoryNode, NavigationTree, + NavigationNode, } from './types.js' export function getNavigationTree( @@ -83,5 +84,29 @@ export function getNavigationTree( } const tree = Array.from(categories.values()) + + tree.sort(compareTitleSort) + return tree } + +function compareTitleSort( + a: T, + b: T +): -1 | 0 | 1 { + const aHasChildren = 'children' in a && a.children.length > 0 + const bHasChildren = 'children' in b && b.children.length > 0 + if (aHasChildren) { + a.children.sort(compareTitleSort) + } + if (bHasChildren) { + b.children.sort(compareTitleSort) + } + if (a.title > b.title) { + return 1 + } + if (b.title > a.title) { + return -1 + } + return 0 +} From 344f49118fbe89a9dab5f1251d2e6a70a432f25b Mon Sep 17 00:00:00 2001 From: Preston Bourne Date: Tue, 20 Jun 2023 09:49:36 -0400 Subject: [PATCH 2/5] add accordion --- examples/basic/components/accordion/docs.mdx | 5 ++++- examples/basic/components/accordion/index.tsx | 11 ++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/examples/basic/components/accordion/docs.mdx b/examples/basic/components/accordion/docs.mdx index 8cd8d38..2f96977 100644 --- a/examples/basic/components/accordion/docs.mdx +++ b/examples/basic/components/accordion/docs.mdx @@ -2,4 +2,7 @@ title: 'Accordion' description: 'UI component named after a funky instrument 🪗' path: 'Content/Accordion' ---- \ No newline at end of file +--- +import {Accordion} from '.' + + \ No newline at end of file diff --git a/examples/basic/components/accordion/index.tsx b/examples/basic/components/accordion/index.tsx index 55723f8..dbb5e9d 100644 --- a/examples/basic/components/accordion/index.tsx +++ b/examples/basic/components/accordion/index.tsx @@ -1,10 +1,15 @@ import { ReactElement } from 'react' -interface ButtonProps { +interface AccordionProps { color?: string children: ReactElement } -export function Button({ children }: ButtonProps) { - return +export function Accordion({ children }: AccordionProps) { + return ( +
+ Hello 👋 + Nice meeting you! How's everything going? +
+ ) } From 5ea8f6610095a14672b68969fdb5b12315373528 Mon Sep 17 00:00:00 2001 From: Preston Bourne <90055250+prestonbourne@users.noreply.github.com> Date: Wed, 21 Jun 2023 09:02:08 -0400 Subject: [PATCH 3/5] Tests for `getNavigationTree` (#110) 1. Rewrote the test for `parseComponentPath` 2. Added test for `getNavigationTree` 3. renamed `get-nav-tree.ts` to `get-navigation-tree.ts` Co-authored-by: Preston Bourne <90055250+Saintpreston@users.noreply.github.com> --- package.json | 2 +- .../__tests__/get-navigation-tree.test.ts | 101 ++++++++++++++++++ packages/swingset/__tests__/index.test.ts | 7 -- .../__tests__/parse-component-path.test.ts | 21 ++-- ...get-nav-tree.ts => get-navigation-tree.ts} | 0 packages/swingset/src/loader.ts | 2 +- 6 files changed, 116 insertions(+), 17 deletions(-) create mode 100644 packages/swingset/__tests__/get-navigation-tree.test.ts delete mode 100644 packages/swingset/__tests__/index.test.ts rename packages/swingset/src/{get-nav-tree.ts => get-navigation-tree.ts} (100%) diff --git a/package.json b/package.json index 5a18e5a..d01d81b 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,6 @@ "prerelease:canary": "turbo build", "release": "changeset publish", "release:canary": "changeset publish --tag canary", - "test": "jest" + "test": "npx turbo run test --concurrency 1 --continue" } } diff --git a/packages/swingset/__tests__/get-navigation-tree.test.ts b/packages/swingset/__tests__/get-navigation-tree.test.ts new file mode 100644 index 0000000..4143d3f --- /dev/null +++ b/packages/swingset/__tests__/get-navigation-tree.test.ts @@ -0,0 +1,101 @@ +import { describe, it } from 'vitest' +import { getNavigationTree } from '../src/get-navigation-tree' +import { ComponentEntity, NavigationTree } from '../src/types' + +describe(getNavigationTree.name, () => { + it('Builds the Navigation Tree', ({ expect }) => { + const input: ComponentEntity[] = [ + { + __type: 'component', + category: 'default', + componentPath: '../../..', + filepath: '../../..', + frontmatter: {}, + normalizedPath: '', + relativePath: '', + slug: '', + title: '', + load: '', + }, + ] + + const expectation: NavigationTree = [ + { + children: [ + { + __type: 'component', + componentPath: '../../..', + slug: '', + title: '', + }, + ], + title: 'default', + __type: 'category', + }, + ] + + const result = getNavigationTree(input) + + expect(result).toEqual(expectation) + }) + it('Supports duplicate entities', ({ expect }) => { + const input: ComponentEntity[] = [ + { + __type: 'component', + category: 'default', + componentPath: '../../..', + filepath: '../../..', + frontmatter: {}, + normalizedPath: '', + relativePath: '', + slug: '', + title: '', + load: '', + }, + { + __type: 'component', + category: 'default', + componentPath: '../../..', + filepath: '../../..', + frontmatter: {}, + normalizedPath: '', + relativePath: '', + slug: '', + title: '', + load: '', + }, + ] + + const expectation: NavigationTree = [ + { + children: [ + { + __type: 'component', + componentPath: '../../..', + slug: '', + title: '', + }, + { + __type: 'component', + componentPath: '../../..', + slug: '', + title: '', + }, + ], + title: 'default', + __type: 'category', + }, + ] + + const result = getNavigationTree(input) + + expect(result).toEqual(expectation) + }) + it('Returns an empty array if it receives one', ({ expect }) => { + const input: ComponentEntity[] = [] + const expectation: NavigationTree = [] + const result = getNavigationTree(input) + + expect(result).toEqual(expectation) + }) +}) diff --git a/packages/swingset/__tests__/index.test.ts b/packages/swingset/__tests__/index.test.ts deleted file mode 100644 index 8173b17..0000000 --- a/packages/swingset/__tests__/index.test.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { describe, it } from 'vitest' - -describe('tests', () => { - it('works', ({ expect }) => { - expect(true).toBe(true) - }) -}) diff --git a/packages/swingset/__tests__/parse-component-path.test.ts b/packages/swingset/__tests__/parse-component-path.test.ts index 8df8f6c..4aa356a 100644 --- a/packages/swingset/__tests__/parse-component-path.test.ts +++ b/packages/swingset/__tests__/parse-component-path.test.ts @@ -1,8 +1,8 @@ import { describe, it } from 'vitest' import { parseComponentPath } from '../src/parse-component-path' -describe('parseComponentPath', () => { - it('converts the front matter string to an object', ({ expect }) => { +describe(parseComponentPath.name, () => { + it('Converts a 3 segment path to a navigationData object', ({ expect }) => { const expectation = { category: 'Components', folder: 'Forms', @@ -13,7 +13,7 @@ describe('parseComponentPath', () => { expect(result).toEqual(expectation) }) - it('converts the front matter string to an object', ({ expect }) => { + it('Converts a 2 segment path to a navigationData object', ({ expect }) => { const expectation = { category: 'Components', page: 'Button', @@ -23,8 +23,9 @@ describe('parseComponentPath', () => { expect(result).toEqual(expectation) }) - it('converts the front matter string to an object', ({ expect }) => { + it('Converts a 1 segment path to a navigationData object', ({ expect }) => { const expectation = { + category: 'default', page: 'Button', } @@ -32,10 +33,14 @@ describe('parseComponentPath', () => { expect(result).toEqual(expectation) }) - it('Throws an error when invalid input is received', ({expect}) => { + it('Throws an error when too many segments are received', ({ expect }) => { + const input = 'edibles/fruits/berries/blueberries' - expect(() => parseComponentPath('edibles/fruits/berries/blueberries')).toThrowError() - - + const errorSnapshot = + "\"Received Component path with more than 3 segments: 'edibles/fruits/berries/blueberries'. Remove the extra segments. Expected format: '[Category]/[Folder]/[Page]'\"" + + expect(() => parseComponentPath(input)).toThrowErrorMatchingInlineSnapshot( + errorSnapshot + ) }) }) diff --git a/packages/swingset/src/get-nav-tree.ts b/packages/swingset/src/get-navigation-tree.ts similarity index 100% rename from packages/swingset/src/get-nav-tree.ts rename to packages/swingset/src/get-navigation-tree.ts diff --git a/packages/swingset/src/loader.ts b/packages/swingset/src/loader.ts index 95542e7..40b6a0a 100644 --- a/packages/swingset/src/loader.ts +++ b/packages/swingset/src/loader.ts @@ -5,7 +5,7 @@ import { matter } from 'vfile-matter' import { type LoaderContext } from 'webpack' import { resolveComponents } from './resolvers/component.js' import { stringifyEntity } from './resolvers/stringify-entity.js' -import { getNavigationTree } from './get-nav-tree.js' +import { getNavigationTree } from './get-navigation-tree.js' import { resolveDocs } from './resolvers/doc.js' import { NEXT_MDX_COMPONENTS_ALIAS } from './constants.js' import { type SwingsetConfig } from './config.js' From 1bb7a015a2afef6c96ee86c93edebab1ccd6d952 Mon Sep 17 00:00:00 2001 From: Preston Bourne Date: Wed, 21 Jun 2023 09:35:32 -0400 Subject: [PATCH 4/5] rewrite sort --- packages/swingset/src/get-navigation-tree.ts | 25 +++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/packages/swingset/src/get-navigation-tree.ts b/packages/swingset/src/get-navigation-tree.ts index 2f35909..43d25cb 100644 --- a/packages/swingset/src/get-navigation-tree.ts +++ b/packages/swingset/src/get-navigation-tree.ts @@ -85,23 +85,30 @@ export function getNavigationTree( const tree = Array.from(categories.values()) - tree.sort(compareTitleSort) + deepSort(tree) return tree } +/** + * + * Sorts tree alphabetically + */ +function deepSort(nodes: (CategoryNode | NavigationNode)[]) { + nodes.sort(compareTitleSort) + + for (const node of nodes) { + const hasChildren = 'children' in node + + if (hasChildren) { + deepSort(node.children) + } + } +} function compareTitleSort( a: T, b: T ): -1 | 0 | 1 { - const aHasChildren = 'children' in a && a.children.length > 0 - const bHasChildren = 'children' in b && b.children.length > 0 - if (aHasChildren) { - a.children.sort(compareTitleSort) - } - if (bHasChildren) { - b.children.sort(compareTitleSort) - } if (a.title > b.title) { return 1 } From fce23a91e39f6b889336cc60f5bedbd93683e9a2 Mon Sep 17 00:00:00 2001 From: Preston Bourne Date: Wed, 21 Jun 2023 09:35:39 -0400 Subject: [PATCH 5/5] new line --- packages/swingset/src/get-navigation-tree.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/swingset/src/get-navigation-tree.ts b/packages/swingset/src/get-navigation-tree.ts index 43d25cb..9c2579b 100644 --- a/packages/swingset/src/get-navigation-tree.ts +++ b/packages/swingset/src/get-navigation-tree.ts @@ -89,6 +89,7 @@ export function getNavigationTree( return tree } + /** * * Sorts tree alphabetically