Skip to content
Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/ui-components/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@node-core/ui-components",
"version": "1.6.0",
"version": "1.6.1",
"type": "module",
"exports": {
"./*": {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
@reference "../../../styles/index.css";

.header {
@apply flex
items-start
gap-1;
}

.attribute {
@apply font-ibm-plex-mono
inline-flex
flex-wrap
items-center
gap-1
text-sm
font-semibold;

.longName {
@apply break-all
sm:break-keep;
}

&.return {
@apply font-open-sans
shrink-0;

svg {
@apply size-4;
}
}
}

.type {
@apply font-ibm-plex-mono
inline-flex
flex-wrap
gap-0.5
text-sm
break-all;

a {
@apply text-green-700
dark:text-green-400;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { ArrowTurnDownLeftIcon } from '@heroicons/react/24/outline';
import classNames from 'classnames';

import type Signature from '#ui/Common/Signature';
import type { ComponentProps, FC } from 'react';

import styles from './index.module.css';

type SignatureHeaderProps = { isReturn?: boolean } & Omit<
ComponentProps<typeof Signature>,
Comment thread
canerakdas marked this conversation as resolved.
'title' | 'description'
>;

const SignatureHeader: FC<SignatureHeaderProps> = ({
name,
type,
optional,
isReturn = false,
}) => (
<div className={styles.header}>
{name && (
<span
className={classNames(styles.attribute, {
[styles.return]: isReturn,
})}
>
{isReturn && <ArrowTurnDownLeftIcon />}
<span
className={classNames(styles.name, {
[styles.longName]: name.length > 16,
})}
>
{name}:
{optional && (
<span
className={styles.optional}
role="img"
aria-label="Optional"
data-tooltip="Optional"
tabIndex={0}
>
?
</span>
)}
Comment thread
canerakdas marked this conversation as resolved.
</span>
</span>
)}
{type && <span className={styles.type}>{type}</span>}
</div>
);

export default SignatureHeader;
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
@reference "../../../styles/index.css";

.item {
@apply flex
flex-col
gap-1;
}

.return {
@apply rounded-sm
bg-green-100
px-4
py-3
dark:bg-neutral-900/40;
}

.children {
@apply relative
flex
flex-col
rounded-sm
border
border-neutral-200
dark:border-neutral-900;

&:has(> .return:only-child) {
@apply border-0;
}

&:not(:has(.return:only-child)) .return {
@apply mx-4
mb-3;
}

.item:not(.return) {
@apply mx-4
py-3;
}

.item:not(:last-child, :has(+ .return)) {
@apply border-b
border-neutral-200
dark:border-neutral-900;
}
}

.description {
@apply text-sm
break-all;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import classNames from 'classnames';

import SignatureHeader from '#ui/Common/Signature/SignatureHeader';

import type Signature from '#ui/Common/Signature';
import type { ComponentProps, FC, PropsWithChildren } from 'react';

import styles from './index.module.css';

type SignatureItemProps = Omit<ComponentProps<typeof Signature>, 'title'>;
Comment thread
canerakdas marked this conversation as resolved.

const SignatureItem: FC<PropsWithChildren<SignatureItemProps>> = ({
kind = 'default',
name,
type,
description,
optional,
children,
}) => (
<div
className={classNames(styles.item, {
[styles.return]: kind === 'return',
})}
>
<SignatureHeader
name={name}
type={type}
optional={optional}
isReturn={kind === 'return'}
/>
{description && <div className={styles.description}>{description}</div>}
{children && <div className={styles.children}>{children}</div>}
</div>
);

export default SignatureItem;
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
@reference "../../../styles/index.css";

.container {
@apply flex
flex-col
gap-3;
}

.title {
@apply text-base
font-semibold;
}

.root {
@apply flex
flex-col
gap-4
rounded-sm
border
border-neutral-200
px-4
py-3
dark:border-neutral-900;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { useId } from 'react';

import type Signature from '#ui/Common/Signature';
import type { ComponentProps, FC, PropsWithChildren } from 'react';

import styles from './index.module.css';

type SignatureRootProps = Pick<ComponentProps<typeof Signature>, 'title'>;
Comment thread
canerakdas marked this conversation as resolved.

const SignatureRoot: FC<PropsWithChildren<SignatureRootProps>> = ({
title,
children,
}) => {
const titleId = useId();

return (
<section className={styles.container} aria-labelledby={titleId}>
<div className={styles.title} id={titleId}>
{title}
</div>
<div className={styles.root}>{children}</div>
</section>
);
};

export default SignatureRoot;
106 changes: 106 additions & 0 deletions packages/ui-components/src/Common/Signature/index.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import FunctionDefinition from '#ui/Common/Signature';

import type { Meta as MetaObj, StoryObj } from '@storybook/react-webpack5';

type Story = StoryObj<typeof FunctionDefinition>;
type Meta = MetaObj<typeof FunctionDefinition>;
Comment thread
canerakdas marked this conversation as resolved.
Outdated

export const Default: Story = {
args: {
title: 'Attributes',
children: (
<>
<FunctionDefinition
name="attribute1"
type={
<>
<a href="#">&lt;Type1&gt;</a>|<a href="#">&lt;Type2&gt;</a>
</>
}
/>
<FunctionDefinition
name="attribute2"
optional
type={<a href="#">&lt;Object&gt;</a>}
description="An optional attribute."
>
<FunctionDefinition
name="option1"
type={<a href="#">&lt;Type3&gt;</a>}
/>
<FunctionDefinition
name="option2"
type={<a href="#">&lt;Type3&gt;</a>}
/>
<FunctionDefinition
name="option3"
type={<a href="#">&lt;Type3&gt;</a>}
description="One of the available options."
/>
</FunctionDefinition>
<FunctionDefinition
name="Returns"
type={<a href="#">&lt;Type4&gt;</a>}
description="Returns the result of the function."
kind="return"
/>
</>
),
},
};

export const WithLongAttributeNames: Story = {
args: {
title: 'Attributes',
children: (
<>
<FunctionDefinition
name="thisIsAnAttributeWithAnExcessivelyLongNameToTestTextWrapping"
type={
<>
<a href="#">&lt;Type1&gt;</a>|<a href="#">&lt;Type2&gt;</a>
</>
}
/>
</>
),
},
};

export const WithLongTypeAndAttributeNames: Story = {
args: {
title: 'Attributes',
children: (
<>
<FunctionDefinition
name="attribute1"
type={
<>
<a href="#">
&lt;ThisIsATypeWithAnExcessivelyLongNameToTestTextWrapping&gt;
</a>
</>
}
/>
</>
),
},
};

export const OptionalAttribute: Story = {
args: {
title: 'Attributes',
children: (
<FunctionDefinition
name="optionalAttribute"
optional
type={<a href="#">&lt;Object&gt;</a>}
description="An optional attribute."
/>
),
},
};

export default {
component: FunctionDefinition,
} as Meta;
41 changes: 41 additions & 0 deletions packages/ui-components/src/Common/Signature/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import SignatureItem from '#ui/Common/Signature/SignatureItem';
import SignatureRoot from '#ui/Common/Signature/SignatureRoot';

import type { FC, PropsWithChildren, ReactNode } from 'react';

export type SignatureProps = {
title?: string;
kind?: 'default' | 'return';
name?: string;
type?: ReactNode;
description?: ReactNode;
optional?: boolean;
};

const Signature: FC<PropsWithChildren<SignatureProps>> = ({
kind = 'default',
name,
type,
description,
optional,
title,
children,
}) => {
if (title) {
return <SignatureRoot title={title}>{children}</SignatureRoot>;
}

return (
<SignatureItem
kind={kind}
name={name}
type={type}
description={description}
optional={optional}
>
{children}
</SignatureItem>
);
};

export default Signature;
Loading
Loading