diff --git a/.gitignore b/.gitignore
index 33c49961..0cbbfc84 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,6 +13,9 @@ node_modules
*/**/dist
*/**/build
+# SDS docs
+@stellar/design-system/docs
+
# misc
.DS_Store
.env
diff --git a/@stellar/design-system-website/docs/intro.md b/@stellar/design-system-website/docs/intro.mdx
similarity index 83%
rename from @stellar/design-system-website/docs/intro.md
rename to @stellar/design-system-website/docs/intro.mdx
index 351b1b29..da637c1d 100644
--- a/@stellar/design-system-website/docs/intro.md
+++ b/@stellar/design-system-website/docs/intro.mdx
@@ -5,6 +5,12 @@ sidebar_position: 1
# Intro
+Let's discover **Docusaurus in less than 5 minutes**.
+
+## SDS Button component
+
+
+
```tsx live
```
-Let's discover **Docusaurus in less than 5 minutes**.
+
+
+## SDS Link component
+
+
+
+```tsx live
+
+ Test link
+
+```
+
+
## Getting Started
diff --git a/@stellar/design-system-website/src/components/ComponentDescription/index.tsx b/@stellar/design-system-website/src/components/ComponentDescription/index.tsx
new file mode 100644
index 00000000..80a0eae4
--- /dev/null
+++ b/@stellar/design-system-website/src/components/ComponentDescription/index.tsx
@@ -0,0 +1,24 @@
+import React from "react";
+import SdsDocs from "@stellar/design-system/docs/components.json";
+import { Element } from "@site/src/components/Element";
+
+export const ComponentDescription = ({
+ componentName,
+}: {
+ componentName: string;
+}) => {
+ const component = SdsDocs?.children?.find(
+ (c) => c.name === componentName && c.variant === "declaration",
+ );
+
+ if (!component) {
+ throw Error(`Component "${componentName}" description not found.`);
+ }
+
+ // TODO: split paragraphs /n/n
+ const description = component.comment.summary.map((s) => (
+
+ ));
+
+ return
{description}
;
+};
diff --git a/@stellar/design-system-website/src/components/ComponentProps/index.tsx b/@stellar/design-system-website/src/components/ComponentProps/index.tsx
new file mode 100644
index 00000000..b6d5aad6
--- /dev/null
+++ b/@stellar/design-system-website/src/components/ComponentProps/index.tsx
@@ -0,0 +1,82 @@
+import React from "react";
+import SdsDocs from "@stellar/design-system/docs/components.json";
+import { Element } from "@site/src/components/Element";
+
+export const ComponentProps = ({
+ componentName,
+}: {
+ componentName: string;
+}) => {
+ const component = SdsDocs?.children?.find(
+ (c) => c.name === `${componentName}Props` && c.variant === "declaration",
+ );
+
+ if (!component) {
+ throw Error(`Component "${componentName}" props not found.`);
+ }
+
+ // TODO: reusable component
+ // TODO: split paragraphs /n/n
+ const description = component.comment.summary.map((s) => (
+
+ ));
+
+ const props = component.children.map((p) => {
+ // TODO: handle this properly
+ const defaultVal = p.comment?.blockTags?.[0]?.content?.[0];
+
+ return (
+
+
+ {p.name}
+ |
+
+
+ |
+
+ {defaultVal ? (
+
+ ) : null}
+ |
+ {p?.flags?.isOptional ? "Yes" : ""} |
+ {/* TODO: render summary properly */}
+ {p.comment.summary[0].text} |
+
+ );
+ });
+
+ return (
+
+
+
+
+ Prop |
+ Type |
+ Default |
+ Optional |
+ Description |
+
+
+ {props}
+
+
{description}
+
+ );
+};
+
+// TODO: move to its own file
+// TODO: might be combined with Element?
+const PropType = ({ type }: { type: any }) => {
+ // TODO: handle all types
+ switch (type.type) {
+ case "union":
+ return type.types.map((t) => (
+ <>
+ {t.value}
{" "}
+ >
+ ));
+ default:
+ // reference
+ return {type.name || ""}
;
+ }
+};
diff --git a/@stellar/design-system-website/src/components/Element.tsx b/@stellar/design-system-website/src/components/Element.tsx
new file mode 100644
index 00000000..daee1142
--- /dev/null
+++ b/@stellar/design-system-website/src/components/Element.tsx
@@ -0,0 +1,24 @@
+import React from "react";
+
+export type ElementKind = "text" | "code" | "inline-tag";
+
+export const Element = ({
+ text,
+ kind,
+}: {
+ text: string;
+ kind: ElementKind;
+}) => {
+ switch (kind) {
+ case "code":
+ // Remove ``
+ return {text.slice(1, -1)}
;
+ case "inline-tag":
+ // TODO: link to inner component
+ return {text};
+ // text is default
+ default:
+ // TODO: how to handle md links
+ return <>{text}>;
+ }
+};
diff --git a/@stellar/design-system-website/src/theme/MDXComponents.js b/@stellar/design-system-website/src/theme/MDXComponents.js
new file mode 100644
index 00000000..7e803989
--- /dev/null
+++ b/@stellar/design-system-website/src/theme/MDXComponents.js
@@ -0,0 +1,9 @@
+import MDXComponents from "@theme-original/MDXComponents";
+import { ComponentDescription } from "@site/src/components/ComponentDescription";
+import { ComponentProps } from "@site/src/components/ComponentProps";
+
+export default {
+ ...MDXComponents,
+ ComponentDescription,
+ ComponentProps,
+};
diff --git a/@stellar/design-system-website/tsconfig.json b/@stellar/design-system-website/tsconfig.json
index 6f475698..aea83c96 100644
--- a/@stellar/design-system-website/tsconfig.json
+++ b/@stellar/design-system-website/tsconfig.json
@@ -2,6 +2,7 @@
// This file is not used in compilation. It is here just for a nice editor experience.
"extends": "@tsconfig/docusaurus/tsconfig.json",
"compilerOptions": {
- "baseUrl": "."
+ "baseUrl": ".",
+ "resolveJsonModule": true
}
}
diff --git a/@stellar/design-system/package.json b/@stellar/design-system/package.json
index eb67cee7..71ec6e3a 100755
--- a/@stellar/design-system/package.json
+++ b/@stellar/design-system/package.json
@@ -21,7 +21,8 @@
"watch:dev": "webpack --watch --mode development",
"clean": "rimraf ./build",
"start": "run-p clean watch:tsc watch:dev",
- "lint-tsc": "tsc --noEmit"
+ "lint-tsc": "tsc --noEmit",
+ "typedoc": "typedoc --options typedoc.json"
},
"peerDependencies": {
"react": ">=18.0.0",
@@ -64,6 +65,7 @@
"sass-loader": "^13.2.0",
"style-loader": "^3.3.1",
"ts-loader": "^9.4.2",
+ "typedoc": "^0.24.8",
"typescript": "^4.9.5",
"webpack": "^5.75.0",
"webpack-cli": "^5.0.1"
diff --git a/@stellar/design-system/src/components/Button/index.tsx b/@stellar/design-system/src/components/Button/index.tsx
index c498ca92..2f368878 100644
--- a/@stellar/design-system/src/components/Button/index.tsx
+++ b/@stellar/design-system/src/components/Button/index.tsx
@@ -2,7 +2,11 @@ import React from "react";
import { Loader } from "../Loader";
import "./styles.scss";
-interface ButtonProps extends React.ButtonHTMLAttributes {
+/**
+ * Including all valid [button attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attributes)
+ */
+export interface ButtonProps {
+ /** Variant of the button */
variant:
| "primary"
| "secondary"
@@ -10,18 +14,35 @@ interface ButtonProps extends React.ButtonHTMLAttributes {
| "destructive"
| "error"
| "success";
+ /** Size of the button */
size: "md" | "sm" | "xs";
+ /** Label of the button */
children?: string | React.ReactNode;
+ /** Icon element */
icon?: React.ReactNode;
+ /** Position of the icon @defaultValue `right` */
iconPosition?: "left" | "right";
+ /** Loading state indicator */
isLoading?: boolean;
+ /** Make label uppercase */
isUppercase?: boolean;
+ /** Sets width of the button to match the parent container */
isFullWidth?: boolean;
+ /** Pill shaped button */
isPill?: boolean;
+ /** Button with extra padding */
isExtraPadding?: boolean;
}
-export const Button = ({
+interface Props
+ extends ButtonProps,
+ React.ButtonHTMLAttributes {}
+
+/**
+ * `Button` is used to trigger an action that is not opening a link (use {@link Link}
+ * instead).
+ */
+export const Button: React.FC = ({
variant,
size,
children,
@@ -33,7 +54,7 @@ export const Button = ({
isPill,
isExtraPadding,
...props
-}: ButtonProps): JSX.Element => {
+}) => {
const additionalClasses = [
`Button--${variant}`,
`Button--${size}`,
diff --git a/@stellar/design-system/src/components/Link/index.tsx b/@stellar/design-system/src/components/Link/index.tsx
index 0667ba90..de22a065 100644
--- a/@stellar/design-system/src/components/Link/index.tsx
+++ b/@stellar/design-system/src/components/Link/index.tsx
@@ -1,18 +1,38 @@
import React from "react";
import "./styles.scss";
-interface LinkProps extends React.AnchorHTMLAttributes {
- children: string | React.ReactNode;
+/**
+ * Including all valid [anchor element attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attributes)
+ */
+export interface LinkProps {
+ /** Content of the link */
+ children?: string | React.ReactNode;
+ /** Variant of the link @defaultValue `primary` */
variant?: "primary" | "secondary";
+ /** Size of the link, will inherit parent size if not set */
size?: "md" | "sm" | "xs";
+ /** Icon element */
icon?: React.ReactNode;
+ /** Position of the icon @defaultValue `right` */
iconPosition?: "left" | "right";
+ /** Disable the link */
isDisabled?: boolean;
+ /** Underline the link */
isUnderline?: boolean;
+ /** Make the link uppercase */
isUppercase?: boolean;
}
-export const Link: React.FC = ({
+interface Props
+ extends LinkProps,
+ React.AnchorHTMLAttributes {}
+
+/**
+ * `Link` component is a styled HTML anchor (`a`) element. Use `Link` to open links or to navigate to other pages.
+ *
+ * `Link` with external `href` (starting with `http(s)` or `//`) will have attributes `rel="noreferrer noopener"` and `target="_blank"` automatically added.
+ */
+export const Link: React.FC = ({
children,
variant = "primary",
size,
diff --git a/@stellar/design-system/typedoc.json b/@stellar/design-system/typedoc.json
new file mode 100644
index 00000000..3fef5eec
--- /dev/null
+++ b/@stellar/design-system/typedoc.json
@@ -0,0 +1,6 @@
+{
+ "$schema": "https://typedoc.org/schema.json",
+ "entryPoints": ["src"],
+ "json": "./docs/components.json",
+ "excludeNotDocumented": true
+}
diff --git a/package.json b/package.json
index ce43e5c3..03489c4d 100755
--- a/package.json
+++ b/package.json
@@ -12,9 +12,10 @@
"scripts": {
"build:sds": "yarn workspace @stellar/design-system build",
"build:sds-web": "yarn workspace @stellar/design-system-website build",
- "build": "run-s build:sds build:sds-web",
+ "build": "run-s build:sds docs:sds build:sds-web",
"start:sds": "yarn workspace @stellar/design-system start",
"start:sds-web": "yarn workspace @stellar/design-system-website start",
+ "docs:sds": "yarn workspace @stellar/design-system typedoc",
"tsc:sds": "yarn workspace @stellar/design-system lint-tsc",
"tsc:sds-web": "yarn workspace @stellar/design-system-website lint-tsc",
"clean": "rm -rf node_modules && rm -rf */**/node_modules && rm -rf */**/build",
diff --git a/yarn.lock b/yarn.lock
index ab4bcb76..3795f8bf 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2988,6 +2988,11 @@ ansi-regex@^6.0.1:
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a"
integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==
+ansi-sequence-parser@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/ansi-sequence-parser/-/ansi-sequence-parser-1.1.0.tgz#4d790f31236ac20366b23b3916b789e1bde39aed"
+ integrity sha512-lEm8mt52to2fT8GhciPCGeCXACSz2UwIN4X2e2LJSnZ5uAbn2/dsYdOmUXq0AtWS5cpAupysIneExOgH0Vd2TQ==
+
ansi-styles@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
@@ -6598,6 +6603,11 @@ json5@^2.1.2, json5@^2.2.2:
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283"
integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==
+jsonc-parser@^3.2.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76"
+ integrity sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==
+
jsonfile@^6.0.1:
version "6.1.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae"
@@ -6879,6 +6889,11 @@ lru-cache@^6.0.0:
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.0.tgz#b9e2a6a72a129d81ab317202d93c7691df727e61"
integrity sha512-svTf/fzsKHffP42sujkO/Rjs37BCIsQVRCeNYIm9WN8rgT7ffoUnRtZCqU+6BqcSBdv8gwJeTz8knJpgACeQMw==
+lunr@^2.3.9:
+ version "2.3.9"
+ resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1"
+ integrity sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==
+
magic-string@^0.25.1, magic-string@^0.25.2:
version "0.25.9"
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.9.tgz#de7f9faf91ef8a1c91d02c2e5314c8277dbcdd1c"
@@ -6898,6 +6913,11 @@ markdown-escapes@^1.0.0:
resolved "https://registry.yarnpkg.com/markdown-escapes/-/markdown-escapes-1.0.4.tgz#c95415ef451499d7602b91095f3c8e8975f78535"
integrity sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==
+marked@^4.3.0:
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/marked/-/marked-4.3.0.tgz#796362821b019f734054582038b116481b456cf3"
+ integrity sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==
+
mdast-squeeze-paragraphs@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/mdast-squeeze-paragraphs/-/mdast-squeeze-paragraphs-4.0.0.tgz#7c4c114679c3bee27ef10b58e2e015be79f1ef97"
@@ -9461,6 +9481,16 @@ shelljs@^0.8.5:
interpret "^1.0.0"
rechoir "^0.6.2"
+shiki@^0.14.1:
+ version "0.14.3"
+ resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.14.3.tgz#d1a93c463942bdafb9866d74d619a4347d0bbf64"
+ integrity sha512-U3S/a+b0KS+UkTyMjoNojvTgrBHjgp7L6ovhFVZsXmBGnVdQ4K4U9oK0z63w538S91ATngv1vXigHCSWOwnr+g==
+ dependencies:
+ ansi-sequence-parser "^1.1.0"
+ jsonc-parser "^3.2.0"
+ vscode-oniguruma "^1.7.0"
+ vscode-textmate "^8.0.0"
+
side-channel@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf"
@@ -10120,6 +10150,16 @@ typedarray@^0.0.6:
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==
+typedoc@^0.24.8:
+ version "0.24.8"
+ resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.24.8.tgz#cce9f47ba6a8d52389f5e583716a2b3b4335b63e"
+ integrity sha512-ahJ6Cpcvxwaxfu4KtjA8qZNqS43wYt6JL27wYiIgl1vd38WW/KWX11YuAeZhuz9v+ttrutSsgK+XO1CjL1kA3w==
+ dependencies:
+ lunr "^2.3.9"
+ marked "^4.3.0"
+ minimatch "^9.0.0"
+ shiki "^0.14.1"
+
typescript@^4.7.4, typescript@^4.9.5:
version "4.9.5"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a"
@@ -10585,6 +10625,16 @@ vlq@^1.0.0:
resolved "https://registry.yarnpkg.com/vlq/-/vlq-1.0.1.tgz#c003f6e7c0b4c1edd623fd6ee50bbc0d6a1de468"
integrity sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w==
+vscode-oniguruma@^1.7.0:
+ version "1.7.0"
+ resolved "https://registry.yarnpkg.com/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz#439bfad8fe71abd7798338d1cd3dc53a8beea94b"
+ integrity sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==
+
+vscode-textmate@^8.0.0:
+ version "8.0.0"
+ resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-8.0.0.tgz#2c7a3b1163ef0441097e0b5d6389cd5504b59e5d"
+ integrity sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==
+
wait-on@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-6.0.1.tgz#16bbc4d1e4ebdd41c5b4e63a2e16dbd1f4e5601e"