{"id":31718676,"url":"https://github.com/speakeasy-api/docs-md-public","last_synced_at":"2025-10-09T02:54:47.683Z","repository":{"id":315138335,"uuid":"1057550506","full_name":"speakeasy-api/docs-md-public","owner":"speakeasy-api","description":"Public repository of React components used with DocsMD","archived":false,"fork":false,"pushed_at":"2025-10-07T22:41:51.000Z","size":301339,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-10-08T00:26:34.982Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/speakeasy-api.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-15T22:14:17.000Z","updated_at":"2025-10-07T22:41:46.000Z","dependencies_parsed_at":"2025-10-08T00:16:57.047Z","dependency_job_id":"e56dd0fa-6f5a-4459-90b0-6734772c5f05","html_url":"https://github.com/speakeasy-api/docs-md-public","commit_stats":null,"previous_names":["speakeasy-api/docs-md-public","speakeasy-api/docs-md-react"],"tags_count":63,"template":false,"template_full_name":null,"purl":"pkg:github/speakeasy-api/docs-md-public","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/speakeasy-api%2Fdocs-md-public","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/speakeasy-api%2Fdocs-md-public/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/speakeasy-api%2Fdocs-md-public/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/speakeasy-api%2Fdocs-md-public/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/speakeasy-api","download_url":"https://codeload.github.com/speakeasy-api/docs-md-public/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/speakeasy-api%2Fdocs-md-public/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279000723,"owners_count":26082894,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-08T02:00:06.501Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-10-09T02:54:47.002Z","updated_at":"2025-10-09T02:54:47.676Z","avatar_url":"https://github.com/speakeasy-api.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# DocsMD React Components\n\nThis repository contains React components used with Speakeasy's Docs product. We\nprovide these components under an open source license, and are provided as a\nreference for customers that wish to implement custom components.\n\n## Component Philosophy\n\nA core philosophy of DocsMD is that any meaningful content should _always_ be\nrendered inside of MDX, not as properties to a component. This way, search\nindexers and the like can index the content properly, and any styling that a\nsite may provide for markdown will be applied. These behaviors usually don't\nhappen when content is not present as markdown.\n\nThis presents some unique constraints when designing components. Notably, we\ncan't do this:\n\n```md\n\u003cMyCustomHeading title=\"My Heading\" /\u003e\n```\n\nIn this case, anything the markdown parser does to stylize headings, such as\nadding a copy-link icon, will ignore this heading. That means we _must_ instead\nwrite this as:\n\n```md\n\u003cMyCustomHeading\u003e\n\n### My Heading\n\n\u003c/MyCustomHeading\u003e\n```\n\nSo if you're wondering why our components don't follow standard React component\nconventions, this is why. Most notably, we see this pattern with slots,\ndescribed below.\n\n### Slots\n\nMany DocsMD components take in a heterogenous set of children that need to be\n\"assembled\" into a specific structure. For example, the TabbedSection component\ntakes in a set of children that are one of:\n\n- A single [`SectionTitle`](src/components/SectionTitle/SectionTitle.tsx)\n  component that contains the title, aka the \"Responses\" heading, with\n  `slot=\"title\"`\n- A set of [`SectionTab`](src/components/SectionTab/SectionTab.tsx) components\n  that contains the contents of each tab, aka the status code, with `slot=\"tab\"`\n- A set of [`SectionContent`](src/components/SectionContent/SectionContent.tsx)\n  components that contains the contents of each section, aka the response body,\n  with `slot=\"section\"`\n\nEach section tab is correlated with a section component by way of \"id\".\nAdmittedly we're abusing the concept of an `id` here, and for historical reasons\nthe _actual_ id on a DOM nodes comes from the `headingId` property (we have a\ntask to fix that some day).\n\nTo support sorting of this \"grab bag\" of children, we borrow a concept from web\ncomponents: slots. Each child is assigned a \"slot\" that is used to determine its\nposition in the final output.\n\nThere are two hooks that are used to get components assigned to slots:\n\n- [`useUniqueChild`](src/util/hooks.ts): gets exactly one child with the given\n  slot, and errors if there are no children with that slot or if there are\n  multiple children with that slot.\n- [`useChildren`](src/util/hooks.ts): gets all children with the given slot,\n  returned as an array\n\nIt's a little convoluted, and slightly hacky in the React world, but has proven\npowerful so far.\n\n### Internal vs External Components\n\nComponents are informally divided into two categories:\n\n- External components: These components are directly referenced by compiled MDX\n  code.\n- Internal components: These components are used by other components in the\n  library, and not directly referenced in compiled MDX code.\n\nBoth types of components are designed such that they can be overridden. To\nsupport overriding internal components, any other component that references\ninternal components takes a prop with a component implementation, that defaults\nto the internal component implementation.\n\nFor example, the\n[`ExpandableCell`](src/components/ExpandableCell/ExpandableCell.tsx) component\ntakes an\n[`ExpandableCellIcon`](src/components/ExpandableCell/types.ts)\nprop that defaults to the\n[`ExpandableCellIcon`](src/components/ExpandableCellIcon/ExpandableCellIcon.tsx)\ncomponent. If you wish to provide a custom icon, you can pass in a custom\ncomponent to this prop.\n\nMost components are external components, a few are internal components, and\n[`Pill`](src/components/Pill/Pill.tsx) is used both internally and externally.\n\n### Component-Specific Documentation\n\nSee the source code for each component in the [src/components](src/components)\ndirectory for documentation each component. Property types are always defined\nin a file called `types.ts`, and includes documentation for each property.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspeakeasy-api%2Fdocs-md-public","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fspeakeasy-api%2Fdocs-md-public","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspeakeasy-api%2Fdocs-md-public/lists"}