chore(ui): added API reference comments for Toast component (#7129)

This commit is contained in:
Shahed Nasser authored and GitHub committed 2024-04-23 13:25:06 +02:00
1 parent 14748755ee
commit cfd765bece
5 files changed
+139 -9

No files matched your search

@@ -154,10 +154,10 @@ export default class TypedocManager {
// push a prop into the `propsToRemove` set. // push a prop into the `propsToRemove` set.
Object.entries(spec.props!).forEach(([propName, propDetails]) => { Object.entries(spec.props!).forEach(([propName, propDetails]) => {
// retrieve the reflection of the prop // retrieve the reflection of the prop
const reflectionPropType = props.find( const reflectionProp = props.find(
(propType) => propType.name === propName (propType) => propType.name === propName
) )
if (!reflectionPropType) { if (!reflectionProp) {
// if the reflection doesn't exist and the // if the reflection doesn't exist and the
// prop doesn't have a description, it should // prop doesn't have a description, it should
// be removed. // be removed.
@@ -172,7 +172,7 @@ export default class TypedocManager {
if ( if (
this.shouldExcludeExternal({ this.shouldExcludeExternal({
parentReflection: reflection, parentReflection: reflection,
childReflection: reflectionPropType, childReflection: reflectionProp,
propDescription: propDetails.description, propDescription: propDetails.description,
signature, signature,
}) })
@@ -180,9 +180,18 @@ export default class TypedocManager {
propsToRemove.add(propName) propsToRemove.add(propName)
return return
} }
// if the prop doesn't have a default value, try to retrieve it
if (!propDetails.defaultValue) {
propDetails.defaultValue = this.getReflectionDefaultValue(
reflectionProp,
propDetails.description
)
}
// if the prop doesn't have description, retrieve it using Typedoc // if the prop doesn't have description, retrieve it using Typedoc
propDetails.description = propDetails.description =
propDetails.description || this.getDescription(reflectionPropType) propDetails.description || this.getDescription(reflectionProp)
// if the prop still doesn't have description, remove it. // if the prop still doesn't have description, remove it.
if (!propDetails.description) { if (!propDetails.description) {
propsToRemove.add(propName) propsToRemove.add(propName)
@@ -218,15 +227,15 @@ export default class TypedocManager {
.forEach((prop) => { .forEach((prop) => {
// If the prop has description (retrieved) // If the prop has description (retrieved)
// through Typedoc, it's added into the spec. // through Typedoc, it's added into the spec.
const description = this.normalizeDescription( const rawDescription = this.getDescription(prop)
this.getDescription(prop) const description = this.normalizeDescription(rawDescription)
)
if (!description) { if (!description) {
return return
} }
spec.props![prop.name] = { spec.props![prop.name] = {
description, description,
required: !prop.flags.isOptional, required: !prop.flags.isOptional,
defaultValue: this.getReflectionDefaultValue(prop, rawDescription),
tsType: prop.type tsType: prop.type
? this.getTsType(prop.type) ? this.getTsType(prop.type)
: prop.signatures?.length : prop.signatures?.length
@@ -379,11 +388,29 @@ export default class TypedocManager {
// prop or component's description. These aren't removed // prop or component's description. These aren't removed
// by React Docgen. // by React Docgen.
normalizeDescription(description: string): string { normalizeDescription(description: string): string {
return description let normalizedDescription = description
.replace("@keep", "") .replace("@keep", "")
.replace("@ignore", "") .replace("@ignore", "")
.replace("@excludeExternal", "") .replace("@excludeExternal", "")
.trim() .trim()
// check if `@defaultValue` tag is in the description and remove it
const defaultValueIndex = normalizedDescription.indexOf("@defaultValue")
if (defaultValueIndex !== -1) {
// if there are tags after the default value, keep them and only
// remove the default value.
const possibleEndIndex = normalizedDescription.indexOf(
"@",
defaultValueIndex + "@defaultValue".length
)
normalizedDescription =
normalizedDescription.slice(0, defaultValueIndex) +
(possibleEndIndex === -1
? ""
: normalizedDescription.slice(possibleEndIndex))
}
return normalizedDescription
} }
// Retrieve the description of a reflection (component or prop) // Retrieve the description of a reflection (component or prop)
@@ -610,4 +637,41 @@ export default class TypedocManager {
}) as DeclarationReflection) }) as DeclarationReflection)
: undefined : undefined
} }
getReflectionDefaultValue(
reflection: DeclarationReflection,
description?: string
):
| {
value: string
computed: boolean
}
| undefined {
let value: string | undefined
if (!reflection.defaultValue) {
// try to infer default value from description
const valueIndexInDescription = description
? description.indexOf("@defaultValue")
: -1
if (valueIndexInDescription !== -1) {
const sliceStart = valueIndexInDescription + "@defaultValue ".length
// the default value ends either at the end of the description or
// until the next tag.
const sliceEnd = description!.indexOf("@", sliceStart)
value = description!.slice(
sliceStart,
sliceEnd !== -1 ? sliceEnd : undefined
)
}
} else {
value = JSON.stringify(reflection.defaultValue)
}
return value
? {
value,
computed: false,
}
: undefined
}
} }
+1 -1
View File
@@ -36,7 +36,7 @@
### Installation ### Installation
```sh ```sh
yarn add @medusajs/medusa-ui yarn add @medusajs/ui
``` ```
### Usage ### Usage
@@ -14,13 +14,49 @@ interface ToastComponentProps {
dismissLabel?: string dismissLabel?: string
} }
/**
* This component is based on the [Sonner](https://sonner.emilkowal.ski/toast) toast library.
*/
export const Toast = ({ export const Toast = ({
/**
* Optional ID of the toast.
*/
id, id,
/**
* @ignore
*
* @privateRemarks
* As the Toast component is created using
* the `toast` utility functions, the variant is inferred
* from the utility function.
*/
variant = "info", variant = "info",
/**
* @ignore
*
* @privateRemarks
* The `toast` utility functions accept this as a parameter.
*/
title, title,
/**
* The toast's text.
*/
description, description,
/**
* The toast's action buttons.
*/
action, action,
/**
* @ignore
*
* @privateRemarks
* The `toast` utility functions don't allow
* passing this prop.
*/
onDismiss, onDismiss,
/**
* The label of the dismiss button, if available.
*/
dismissLabel = "Close", dismissLabel = "Close",
}: ToastComponentProps) => { }: ToastComponentProps) => {
const hasActionables = !!action || onDismiss const hasActionables = !!action || onDismiss
@@ -18,10 +18,28 @@ interface ToasterProps
| "toastOptions" | "toastOptions"
> {} > {}
/**
* This component is based on the [Toaster component of the Sonner library](https://sonner.emilkowal.ski/toaster).
*/
const Toaster = ({ const Toaster = ({
/**
* The position of the created toasts.
*/
position = "bottom-right", position = "bottom-right",
/**
* The gap between the toast components.
*/
gap = 12, gap = 12,
/**
* The space from the edges of the screen.
*/
offset = 24, offset = 24,
/**
* The time in milliseconds that a toast is shown before it's
* automatically dismissed.
*
* @defaultValue 4000
*/
duration, duration,
...props ...props
}: ToasterProps) => { }: ToasterProps) => {
+12
View File
@@ -36,8 +36,20 @@ export type ToastVariant =
export type ToastActionVariant = "default" | "destructive" export type ToastActionVariant = "default" | "destructive"
export type ToastAction = { export type ToastAction = {
/**
* The button's text.
*/
label: string label: string
/**
* The button's alt text.
*/
altText: string altText: string
/**
* The function to execute when the button is clicked.
*/
onClick: () => void | Promise<void> onClick: () => void | Promise<void>
/**
* The button's variant.
*/
variant?: ToastActionVariant variant?: ToastActionVariant
} }