Skip to content

Commit

Permalink
Support undiscriminated unions (#168)
Browse files Browse the repository at this point in the history
* Support undiscriminated unions

* Sort undiscriminated union variants

* Add icons for undiscriminated union variant types

* Upgrade @fern-fern/registry-browser

* Use the real name of variant

* Improve icons
  • Loading branch information
kafkas authored Sep 29, 2023
1 parent 6cad570 commit 02201c1
Show file tree
Hide file tree
Showing 9 changed files with 167 additions and 18 deletions.
12 changes: 6 additions & 6 deletions .pnp.cjs

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

Binary file not shown.
2 changes: 1 addition & 1 deletion packages/commons/app-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"depcheck": "depcheck"
},
"dependencies": {
"@fern-fern/registry-browser": "0.23.1-6-gd18235e",
"@fern-fern/registry-browser": "0.26.0-1-g7cf6a78",
"@fern-ui/core-utils": "workspace:*",
"lodash-es": "^4.17.21",
"next-mdx-remote": "^4.4.1",
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"@blueprintjs/icons": "^4.4.0",
"@blueprintjs/popover2": "^1.8.0",
"@blueprintjs/select": "^4.4.2",
"@fern-fern/registry-browser": "0.23.1-6-gd18235e",
"@fern-fern/registry-browser": "0.26.0-1-g7cf6a78",
"@fern-ui/app-utils": "workspace:*",
"@fern-ui/core-utils": "workspace:*",
"@fern-ui/react-commons": "workspace:*",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
import { DiscriminatedUnionVariant } from "../discriminated-union/DiscriminatedUnionVariant";
import { EnumValue } from "../enum/EnumValue";
import { ObjectProperty } from "../object/ObjectProperty";
import { UndiscriminatedUnionVariant } from "../undiscriminated-union/UndiscriminatedUnionVariant";
import styles from "./InternalTypeDefinition.module.scss";
import { TypeDefinitionDetails } from "./TypeDefinitionDetails";

Expand Down Expand Up @@ -67,8 +68,25 @@ export const InternalTypeDefinition: React.FC<InternalTypeDefinition.Props> = ({
elementNameSingular: "property",
elementNamePlural: "properties",
}),
// TODO
undiscriminatedUnion: () => undefined,
undiscriminatedUnion: (union) => ({
elements: union.variants
.sort((v1, v2) => {
if (v1.type.type === "id") {
return v2.type.type === "id" ? 0 : -1;
}
return v2.type.type !== "id" ? 0 : 1;
})
.map((variant, variantIdx) => (
<UndiscriminatedUnionVariant
key={variantIdx}
unionVariant={variant}
anchorIdParts={anchorIdParts}
/>
)),
elementNameSingular: "variant",
elementNamePlural: "variants",
separatorText: "OR",
}),
discriminatedUnion: (union) => ({
elements: union.variants.map((variant) => (
<DiscriminatedUnionVariant
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import * as FernRegistryApiRead from "@fern-fern/registry-browser/api/resources/api/resources/v1/resources/read";
import classNames from "classnames";
import { useCallback } from "react";
import { ApiPageDescription } from "../../ApiPageDescription";
import {
TypeDefinitionContext,
TypeDefinitionContextValue,
useTypeDefinitionContext,
} from "../context/TypeDefinitionContext";
import { InternalTypeReferenceDefinitions } from "../type-reference/InternalTypeReferenceDefinitions";
import { TypeShorthand } from "../type-shorthand/TypeShorthand";

type IconInfo = {
content: string;
size: number;
};

function getIconInfoForPrimitiveType(type: FernRegistryApiRead.PrimitiveType): IconInfo {
switch (type.type) {
case "integer":
case "long":
case "double":
return type.type === "double"
? {
content: "1.2",
size: 6,
}
: {
content: "123",
size: 6,
};
case "boolean":
return { content: "true", size: 6 };
case "uuid":
case "date":
case "datetime":
case "base64":
case "string":
return { content: "abc", size: 6 };
}
}

function getIconInfoForTypeReference(typeRef: FernRegistryApiRead.TypeReference): IconInfo | null {
switch (typeRef.type) {
case "id":
return null;
case "primitive":
return getIconInfoForPrimitiveType(typeRef.value);
case "map":
return { content: "{}", size: 9 };
case "literal":
return { content: "!", size: 9 };
case "list":
case "set":
case "optional":
return getIconInfoForTypeReference(typeRef.itemType);
case "unknown":
return { content: "{}", size: 9 };
}
}

function getIconForTypeReference(typeRef: FernRegistryApiRead.TypeReference): JSX.Element | null {
const info = getIconInfoForTypeReference(typeRef);
if (info == null) {
return null;
}
const { content, size } = info;
return (
<div
className="border-border-default-light dark:border-border-default-dark flex h-6 w-6 items-center justify-center rounded border"
style={{ fontSize: size }}
>
{content}
</div>
);
}

export declare namespace UndiscriminatedUnionVariant {
export interface Props {
unionVariant: FernRegistryApiRead.UndiscriminatedUnionVariant;
anchorIdParts: string[];
}
}

export const UndiscriminatedUnionVariant: React.FC<UndiscriminatedUnionVariant.Props> = ({
unionVariant,
anchorIdParts,
}) => {
const { isRootTypeDefinition } = useTypeDefinitionContext();
const contextValue = useTypeDefinitionContext();
const newContextValue = useCallback(
(): TypeDefinitionContextValue => ({
...contextValue,
jsonPropertyPath: [...contextValue.jsonPropertyPath],
}),
[contextValue]
);

return (
<div
className={classNames("flex flex-col py-3", {
"px-3": !isRootTypeDefinition,
})}
>
<div className="flex flex-col">
<div className="t-muted flex items-center space-x-2.5">
{getIconForTypeReference(unionVariant.type)}
{unionVariant.displayName == null ? null : (
<span className="t-primary text-sm">{unionVariant.displayName}</span>
)}
<span className="t-muted text-xs">
<TypeShorthand type={unionVariant.type} plural={false} />
</span>
</div>
<ApiPageDescription className="mt-2" description={unionVariant.description} isMarkdown />
<TypeDefinitionContext.Provider value={newContextValue}>
<InternalTypeReferenceDefinitions
type={unionVariant.type}
anchorIdParts={anchorIdParts}
isCollapsible
/>
</TypeDefinitionContext.Provider>
</div>
</div>
);
};
5 changes: 5 additions & 0 deletions packages/ui/app/src/util/string.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { capitalize, snakeCase } from "lodash-es";

export function toTitleCase(str: string): string {
return snakeCase(str).split("_").map(capitalize).join(" ");
}
2 changes: 1 addition & 1 deletion packages/ui/fe-bundle/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"lint:fern-prod": "yarn compile && yarn env:fern-prod next lint"
},
"dependencies": {
"@fern-fern/registry-browser": "0.23.1-6-gd18235e",
"@fern-fern/registry-browser": "0.26.0-1-g7cf6a78",
"@fern-ui/app-utils": "workspace:*",
"@fern-ui/core-utils": "workspace:*",
"@fern-ui/theme": "workspace:*",
Expand Down
14 changes: 7 additions & 7 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1851,24 +1851,24 @@ __metadata:
languageName: node
linkType: hard

"@fern-fern/registry-browser@npm:0.23.1-6-gd18235e":
version: 0.23.1-6-gd18235e
resolution: "@fern-fern/registry-browser@npm:0.23.1-6-gd18235e"
"@fern-fern/registry-browser@npm:0.26.0-1-g7cf6a78":
version: 0.26.0-1-g7cf6a78
resolution: "@fern-fern/registry-browser@npm:0.26.0-1-g7cf6a78"
dependencies:
"@types/url-join": 4.0.1
"@ungap/url-search-params": 0.2.2
axios: 1.4.0
js-base64: 3.7.2
url-join: 4.0.1
checksum: 22f27c0fc4d5884087cf302493b6a462b04b95ab8a80872889489b1361293338dcb8c50ab6d29951b8b30230103af6c478ab093270db684100c8820f819270b2
checksum: 57d13218d2f7caa14185856d66853791c8040b82d7ab4c6bd90ad56d4e0cbce0b5ab8d65801d99109c56a3374fdca689a0c81fe64ad8ce1e2a9b83bd85ca27ae
languageName: node
linkType: hard

"@fern-ui/app-utils@workspace:*, @fern-ui/app-utils@workspace:packages/commons/app-utils":
version: 0.0.0-use.local
resolution: "@fern-ui/app-utils@workspace:packages/commons/app-utils"
dependencies:
"@fern-fern/registry-browser": 0.23.1-6-gd18235e
"@fern-fern/registry-browser": 0.26.0-1-g7cf6a78
"@fern-ui/core-utils": "workspace:*"
"@types/jest": ^29.0.3
"@types/lodash-es": 4.17.9
Expand Down Expand Up @@ -1961,7 +1961,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "@fern-ui/fe-bundle@workspace:packages/ui/fe-bundle"
dependencies:
"@fern-fern/registry-browser": 0.23.1-6-gd18235e
"@fern-fern/registry-browser": 0.26.0-1-g7cf6a78
"@fern-ui/app-utils": "workspace:*"
"@fern-ui/core-utils": "workspace:*"
"@fern-ui/theme": "workspace:*"
Expand Down Expand Up @@ -2200,7 +2200,7 @@ __metadata:
"@blueprintjs/icons": ^4.4.0
"@blueprintjs/popover2": ^1.8.0
"@blueprintjs/select": ^4.4.2
"@fern-fern/registry-browser": 0.23.1-6-gd18235e
"@fern-fern/registry-browser": 0.26.0-1-g7cf6a78
"@fern-ui/app-utils": "workspace:*"
"@fern-ui/core-utils": "workspace:*"
"@fern-ui/react-commons": "workspace:*"
Expand Down

1 comment on commit 02201c1

@vercel
Copy link

@vercel vercel bot commented on 02201c1 Sep 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

fern-dev – ./packages/ui/fe-bundle

devtest.buildwithfern.com
fern-dev-git-main-buildwithfern.vercel.app
app-dev.buildwithfern.com
fern-dev-buildwithfern.vercel.app

Please sign in to comment.