Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
jgroth committed Nov 11, 2024
1 parent 083f6b3 commit 2daac50
Show file tree
Hide file tree
Showing 7 changed files with 143 additions and 97 deletions.
32 changes: 1 addition & 31 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@
"@eslint/eslintrc": "^3.1.0",
"@eslint/js": "^9.8.0",
"@stencil/core": "^4.22.1",
"@stencil/router": "^1.0.1",
"@stencil/sass": "^3.0.12",
"@types/jest": "^29.5.13",
"@types/prismjs": "^1.16.5",
Expand All @@ -83,6 +82,7 @@
"puppeteer": "^23.5.1",
"rollup-plugin-node-polyfills": "^0.2.1",
"tmp": "^0.1.0",
"urlpattern-polyfill": "^10.0.0",
"yargs": "^15.4.0"
},
"dependencies": {
Expand Down
86 changes: 41 additions & 45 deletions src/components/app/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,46 @@ export class App {
);
}

const routes = [
{
path: '/',
name: 'kompendium-markdown',
props: { text: this.data.readme },
},
{
path: '/component/:name/:section?',
name: 'kompendium-component',
props: {
docs: this.data.docs,
schemas: this.data.schemas,
examplePropsFactory: this.examplePropsFactory,
},
},
{
path: '/type/:name',
name: 'kompendium-type',
props: {
types: this.data.types,
},
},
{
path: '/debug/:name',
name: 'kompendium-debug',
props: {
docs: this.data.docs,
schemas: this.data.schemas,
examplePropsFactory: this.examplePropsFactory,
},
},
{
path: '',
name: 'kompendium-guide',
props: {
data: this.data,
},
},
];

return (
<div class="kompendium-body">
<kompendium-navigation
Expand All @@ -104,51 +144,7 @@ export class App {
index={this.index}
/>
<main role="main">
<stencil-router historyType="hash">
<stencil-route-switch scrollTopOffset={0}>
<stencil-route
url="/"
component="kompendium-markdown"
componentProps={{
text: this.data.readme,
}}
exact={true}
/>
<stencil-route
url="/component/:name/:section?"
component="kompendium-component"
componentProps={{
docs: this.data.docs,
schemas: this.data.schemas,
examplePropsFactory:
this.examplePropsFactory,
}}
/>
<stencil-route
url="/type/:name"
component="kompendium-type"
componentProps={{
types: this.data.types,
}}
/>
<stencil-route
url="/debug/:name"
component="kompendium-debug"
componentProps={{
docs: this.data.docs,
schemas: this.data.schemas,
examplePropsFactory:
this.examplePropsFactory,
}}
/>
<stencil-route
component="kompendium-guide"
componentProps={{
data: this.data,
}}
/>
</stencil-route-switch>
</stencil-router>
<kompendium-router routes={routes} />
</main>
</div>
);
Expand Down
94 changes: 94 additions & 0 deletions src/components/app/router.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import { Component, FunctionalComponent, h, Prop, State } from '@stencil/core';
import { URLPattern } from 'urlpattern-polyfill';

type MatchedComponent = {
name: string;
props?: Record<string, string | number>;
};

type RoutedComponent = {
path: string;
name: string;
props?: Record<string, string | number>;
};

const ComponentTemplate: FunctionalComponent<MatchedComponent> = (
props,
children,
) => {
const Name = props.name;

return <Name {...props.props}>{children}</Name>;
};

@Component({
tag: 'kompendium-router',
shadow: true,
})
export class Router {
@Prop()
public routes: RoutedComponent[];

@State()
private matchedComponent: MatchedComponent | undefined;

public componentWillLoad() {
const location = window.location;
this.setMatchedComponent(location);
}

public render() {
if (!this.matchedComponent) {
return '404';
}

return <ComponentTemplate {...this.matchedComponent} />;
}

private setMatchedComponent(location: Location) {
const component = this.findComponent(location);

if (component !== this.matchedComponent) {
this.matchedComponent = component;
}
}

private findComponent(location: Location): MatchedComponent | undefined {
const matchedRoute = this.routes.find(this.isMatched(location));
if (!matchedRoute) {
return;
}

const path = matchedRoute.path;
const pattern = new URLPattern({ hash: path });
const match = pattern.exec(location.href);
const props = this.parseProps(match?.hash.groups);

return {
name: matchedRoute.name,
props: {
...props,
...matchedRoute.props,
},
};
}

private isMatched = (location: Location) => (route: RoutedComponent) => {
const pattern = new URLPattern({
hash: route.path,
});

return pattern.test(location.href);
};

private parseProps(
groups: Record<string, string | undefined> = {},
): Record<string, string | number | undefined> {
return Object.fromEntries(
Object.entries(groups).map(([key, value]) => [
key,
isNaN(Number(value)) ? value : Number(value),
]),
);
}
}
8 changes: 2 additions & 6 deletions src/components/component/component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {
JsonDocsComponent,
JsonDocsTag,
} from '@stencil/core/internal';
import { MatchResults } from '@stencil/router';
import { PropertyList } from './templates/props';
import { EventList } from './templates/events';
import { MethodList } from './templates/methods';
Expand Down Expand Up @@ -32,11 +31,8 @@ export class KompendiumComponent {
@Prop()
public schemas: Array<Record<string, any>>;

/**
* Matched route parameters
*/
@Prop()
public match: MatchResults;
public name: string;

/**
* Factory for creating props for example components
Expand Down Expand Up @@ -88,7 +84,7 @@ export class KompendiumComponent {
}

public render(): HTMLElement {
const tag = this.match.params.name;
const tag = this.name;
const component = findComponent(tag, this.docs);

return (
Expand Down
8 changes: 2 additions & 6 deletions src/components/debug/debug.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {
JsonDocsComponent,
JsonDocsTag,
} from '@stencil/core/internal';
import { MatchResults } from '@stencil/router';
import { PropsFactory } from '../playground/playground.types';

@Component({
Expand All @@ -24,11 +23,8 @@ export class KompendiumDebug {
@Prop()
public schemas: Array<Record<string, any>>;

/**
* Matched route parameters
*/
@Prop()
public match: MatchResults;
public name: string;

/**
* Factory for creating props for example components
Expand All @@ -38,7 +34,7 @@ export class KompendiumDebug {
public examplePropsFactory?: PropsFactory = () => ({});

public render(): HTMLElement {
const tag = this.match.params.name;
const tag = this.name;
const component = findComponent(tag, this.docs);

return (
Expand Down
10 changes: 2 additions & 8 deletions src/components/type/type.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Component, h, Prop, State } from '@stencil/core';
import { TypeDescription, TypeDescriptionType } from '../../types';
import { MatchResults } from '@stencil/router';
import { Interface } from './templates/interface';
import { Alias } from './templates/alias';
import { Enum } from './templates/enum';
Expand All @@ -16,11 +15,8 @@ export class Type {
@Prop()
public types: TypeDescription[];

/**
* Matched route parameters
*/
@Prop()
public match: MatchResults;
public name: string;

@State()
private type: TypeDescription;
Expand Down Expand Up @@ -53,9 +49,7 @@ export class Type {
}

private findType() {
const type = this.types.find(
(type) => type.name === this.match.params.name,
);
const type = this.types.find((type) => type.name === this.name);

if (type) {
this.type = type;
Expand Down

0 comments on commit 2daac50

Please sign in to comment.