feat(docs): Add TOC to supported hardware page.

This commit is contained in:
Peter Johanson 2022-04-17 14:30:22 +00:00 committed by Pete Johanson
parent 158ac27207
commit c8c273d83b
4 changed files with 151 additions and 96 deletions

View File

@ -6,12 +6,48 @@ sidebar_label: Supported Hardware
import HardwareList from "@site/src/components/hardware-list";
import Metadata from "@site/src/data/hardware-metadata.json";
import Heading from "@theme/Heading";
import { groupedMetadata } from "@site/src/components/hardware-utils";
export const toc = [
{
value: "Onboard Controller Keyboards",
id: "onboard",
level: 2,
},
{
value: "Composite Keyboards",
id: "composite",
level: 2,
},
...Object.values(groupedMetadata(Metadata).interconnects).map(
({ interconnect }) => ({
value: `${interconnect.name} Interconnect`,
id: interconnect.id,
level: 3,
})
),
{
value: "Other Hardware",
id: "other-hardware",
level: 2,
},
{
value: "Contributing",
id: "contributing",
level: 2,
},
];
With the solid technical foundation of Zephyr™ RTOS, ZMK can support a wide diversity of hardware targets.
That being said, there are currently only a few specific [boards](/docs/faq#what-is-a-board)/[shields](faq.md#what-is-a-shield) that have been implemented and tested by the ZMK contributors.
<HardwareList items={Metadata} />
## Other Hardware
<Heading as="h2" id="other-hardware">
Other Hardware
</Heading>
In addition to the basic keyboard functionality, there is some initial support for additional keyboard hardware:
@ -22,6 +58,8 @@ In addition to the basic keyboard functionality, there is some initial support f
Until detailed documentation is available, feel free to ask questions about how these are supported in the [Discord server](https://zmk.dev/community/discord/invite).
## Contributing
<Heading as="h2" id="contributing">
Contributing
</Heading>
If you'd like to add support for a new keyboard shield, head over to the [New Keyboard Shield](development/new-shield.md) documentation.

View File

@ -1,11 +1,9 @@
import React from "react";
import {
Board,
HardwareMetadata,
Interconnect,
Shield,
} from "../hardware-metadata";
import Heading from "@theme/Heading";
import { HardwareMetadata } from "../hardware-metadata";
import { groupedMetadata, InterconnectDetails } from "./hardware-utils";
interface HardwareListProps {
items: HardwareMetadata[];
@ -53,12 +51,6 @@ function HardwareLineItem({ item }: { item: HardwareMetadata }) {
);
}
interface InterconnectDetails {
interconnect?: Interconnect;
boards: Board[];
shields: Shield[];
}
function mapInterconnect({
interconnect,
boards,
@ -70,15 +62,17 @@ function mapInterconnect({
return (
<div key={interconnect.id}>
<h4>{interconnect.name} Interconnect</h4>
<Heading as="h3" id={interconnect.id}>
{interconnect.name} Interconnect
</Heading>
{interconnect.description && <p>{interconnect.description}</p>}
<h5>Boards</h5>
<Heading as="h4">Boards</Heading>
<ul>
{boards.map((s) => (
<HardwareLineItem key={s.id} item={s} />
))}
</ul>
<h5>Shields</h5>
<Heading as="h4">Shields</Heading>
<ul>
{shields.map((s) => (
<HardwareLineItem key={s.id} item={s} />
@ -88,88 +82,41 @@ function mapInterconnect({
);
}
interface GroupedMetadata {
onboard: Board[];
interconnects: Record<string, InterconnectDetails>;
}
function groupedBoard(agg: GroupedMetadata, board: Board) {
if (board.features?.includes("keys")) {
agg.onboard.push(board);
} else if (board.exposes) {
board.exposes.forEach((element) => {
let ic = agg.interconnects[element] ?? {
boards: [],
shields: [],
};
ic.boards.push(board);
agg.interconnects[element] = ic;
});
} else {
console.error("Board without keys or interconnect");
}
return agg;
}
function groupedShield(agg: GroupedMetadata, shield: Shield) {
shield.requires.forEach((id) => {
let ic = agg.interconnects[id] ?? { boards: [], shields: [] };
ic.shields.push(shield);
agg.interconnects[id] = ic;
});
return agg;
}
function groupedInterconnect(agg: GroupedMetadata, item: Interconnect) {
let ic = agg.interconnects[item.id] ?? { boards: [], shields: [] };
ic.interconnect = item;
agg.interconnects[item.id] = ic;
return agg;
}
function HardwareList({ items }: HardwareListProps) {
let grouped = items.reduce<GroupedMetadata>(
(agg, hm) => {
switch (hm.type) {
case "board":
return groupedBoard(agg, hm);
case "shield":
return groupedShield(agg, hm);
case "interconnect":
return groupedInterconnect(agg, hm);
}
},
{ onboard: [] as Board[], interconnects: {} }
);
let grouped = groupedMetadata(items);
return (
<>
<h2>Keyboards</h2>
<h3>Onboard Controller Keyboards</h3>
<p>
Keyboards with onboard controllers are single PCBs that contain all the
components of a keyboard, including the controller chip, switch
footprints, etc.
</p>
<ul>
{grouped["onboard"]
.sort((a, b) => a.name.localeCompare(b.name))
.map((s) => (
<HardwareLineItem key={s.id} item={s} />
))}
</ul>
<h3>Composite Keyboards</h3>
<p>
Composite keyboards are composed of two main PCBs: a small controller
board with exposed pads, and a larger keyboard PCB (a shield, in ZMK
lingo) with switch footprints and a location where the controller is
added. This location is called an interconnect. Multiple interconnects
can be found below.
</p>
{Object.values(grouped.interconnects).map(mapInterconnect)}
<section>
<Heading as="h2" id="onboard">
Onboard Controller Keyboards
</Heading>
<p>
Keyboards with onboard controllers are single PCBs that contain all
the components of a keyboard, including the controller chip, switch
footprints, etc.
</p>
<ul>
{grouped["onboard"]
.sort((a, b) => a.name.localeCompare(b.name))
.map((s) => (
<HardwareLineItem key={s.id} item={s} />
))}
</ul>
</section>
<section>
<Heading as="h2" id="composite">
Composite Keyboards
</Heading>
<p>
Composite keyboards are composed of two main PCBs: a small controller
board with exposed pads, and a larger keyboard PCB (a shield, in ZMK
lingo) with switch footprints and a location where the controller is
added. This location is called an interconnect. Multiple interconnects
can be found below.
</p>
{Object.values(grouped.interconnects).map(mapInterconnect)}
</section>
</>
);
}

View File

@ -0,0 +1,70 @@
import {
Board,
HardwareMetadata,
Interconnect,
Shield,
} from "../hardware-metadata";
export interface InterconnectDetails {
interconnect?: Interconnect;
boards: Board[];
shields: Shield[];
}
export interface GroupedMetadata {
onboard: Board[];
interconnects: Record<string, InterconnectDetails>;
}
function groupedBoard(agg: GroupedMetadata, board: Board) {
if (board.features?.includes("keys")) {
agg.onboard.push(board);
} else if (board.exposes) {
board.exposes.forEach((element) => {
let ic = agg.interconnects[element] ?? {
boards: [],
shields: [],
};
ic.boards.push(board);
agg.interconnects[element] = ic;
});
} else {
console.error("Board without keys or interconnect");
}
return agg;
}
function groupedShield(agg: GroupedMetadata, shield: Shield) {
shield.requires.forEach((id) => {
let ic = agg.interconnects[id] ?? { boards: [], shields: [] };
ic.shields.push(shield);
agg.interconnects[id] = ic;
});
return agg;
}
function groupedInterconnect(agg: GroupedMetadata, item: Interconnect) {
let ic = agg.interconnects[item.id] ?? { boards: [], shields: [] };
ic.interconnect = item;
agg.interconnects[item.id] = ic;
return agg;
}
export function groupedMetadata(items: HardwareMetadata[]) {
return items.reduce<GroupedMetadata>(
(agg, hm) => {
switch (hm.type) {
case "board":
return groupedBoard(agg, hm);
case "shield":
return groupedShield(agg, hm);
case "interconnect":
return groupedInterconnect(agg, hm);
}
},
{ onboard: [] as Board[], interconnects: {} }
);
}

View File

@ -2,7 +2,7 @@
"extends": "@tsconfig/docusaurus/tsconfig.json",
"include": ["src/"],
"compilerOptions": {
"jsx": "react",
"types": ["node", "@docusaurus/theme-classic"],
"moduleResolution": "Node",
"esModuleInterop": true,
"resolveJsonModule": true,