Skip to content

Commit

Permalink
feat: add jsDoc at react, react-query-4
Browse files Browse the repository at this point in the history
  • Loading branch information
kangju2000 committed Nov 19, 2024
1 parent fbb937b commit b1b1193
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 5 deletions.
6 changes: 6 additions & 0 deletions packages/react-query-4/src/queryOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ export type UnSelectedQueryOptions<
select?: undefined
}

/**
* Creates a reusable query options object that can be used across different query hooks.
* Provides better type inference and easier query key management.
*
* @see {@link https://suspensive.org/en/docs/react-query/queryOptions Suspensive Docs}
*/
export function queryOptions<
TQueryFnData = unknown,
TError = unknown,
Expand Down
4 changes: 4 additions & 0 deletions packages/react/src/ClientOnly.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,8 @@ export interface ClientOnlyProps {
fallback?: ReactNode
}

/**
* This component ensures its children are only rendered on the client-side.
* @see {@link https://suspensive.org/docs/react/ClientOnly Suspensive Docs}
*/
export const ClientOnly = ({ children, fallback }: ClientOnlyProps) => <>{useIsClient() ? children : fallback}</>
46 changes: 46 additions & 0 deletions packages/react/src/DefaultProps.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,23 @@ import { type ContextType, type PropsWithChildren } from 'react'
import { DelayDefaultPropsContext, SuspenseDefaultPropsContext } from './contexts'
import { Message_DefaultProp_delay_ms_should_be_greater_than_0, SuspensiveError } from './models/SuspensiveError'

/**
* A class for configuring default props for Suspensive components.
*
* @example
* ```tsx
* const defaultProps = new DefaultProps({
* Delay: {
* ms: 1200,
* fallback: <LoadingMessage>Loading additional content...</LoadingMessage>
* },
* Suspense: {
* fallback: <Spinner>Fetching data...</Spinner>,
* clientOnly: false,
* },
* })
* ```
*/
export class DefaultProps {
Suspense?: ContextType<typeof SuspenseDefaultPropsContext>
Delay?: ContextType<typeof DelayDefaultPropsContext>
Expand All @@ -18,6 +35,35 @@ export class DefaultProps {
interface DefaultPropsProviderProps extends PropsWithChildren {
defaultProps: DefaultProps
}

/**
* A provider component that controls the default settings of Suspensive components.
* Use this to configure default props for Suspense, Delay, and other Suspensive components globally.
*
* @example
* ```tsx
* const defaultProps = new DefaultProps({
* Delay: {
* ms: 1000,
* fallback: <LoadingSpinner />
* },
* Suspense: {
* fallback: <Skeleton />,
* clientOnly: false,
* },
* })
*
* function App() {
* return (
* <DefaultPropsProvider defaultProps={defaultProps}>
* <YourApp />
* </DefaultPropsProvider>
* )
* }
* ```
*
* @see {@link https://suspensive.org/en/docs/react/DefaultPropsProvider Suspensive Docs}
*/
export const DefaultPropsProvider = ({ defaultProps, children }: DefaultPropsProviderProps) => (
<DelayDefaultPropsContext.Provider value={defaultProps.Delay ?? {}}>
<SuspenseDefaultPropsContext.Provider value={defaultProps.Suspense ?? {}}>
Expand Down
7 changes: 7 additions & 0 deletions packages/react/src/Delay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ export type DelayProps =
children?: ReactNode
}

/**
* This component delays the rendering of its children for a specified duration.
*
* The Delay component provides a way to introduce intentional delays in rendering,
* which can be useful for loading states or animations.
* @see {@link https://suspensive.org/docs/react/Delay Suspensive Docs}
*/
export const Delay = (props: DelayProps) => {
if (process.env.NODE_ENV === 'development' && typeof props.ms === 'number') {
SuspensiveError.assert(props.ms >= 0, Message_Delay_ms_prop_should_be_greater_than_or_equal_to_0)
Expand Down
12 changes: 10 additions & 2 deletions packages/react/src/ErrorBoundary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,8 @@ class BaseErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState
}

/**
* This component provide a simple and reusable wrapper that you can use to wrap around your components. Any rendering errors in your components hierarchy can then be gracefully handled.
* @see {@link https://suspensive.org/docs/react/ErrorBoundary}
* This component provides a simple and reusable wrapper that you can use to wrap around your components. Any rendering errors in your components hierarchy can then be gracefully handled.
* @see {@link https://suspensive.org/docs/react/ErrorBoundary Suspensive Docs}
*/
export const ErrorBoundary = Object.assign(
(() => {
Expand Down Expand Up @@ -212,6 +212,10 @@ if (process.env.NODE_ENV === 'development') {
ErrorBoundaryContext.displayName = 'ErrorBoundaryContext'
}

/**
* This hook provides a simple and reusable wrapper that you can use to wrap around your components. Any rendering errors in your components hierarchy can then be gracefully handled.
* @see {@link https://suspensive.org/en/docs/react/ErrorBoundary#useerrorboundary Suspensive Docs}
*/
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters
export const useErrorBoundary = <TError extends Error = Error>() => {
const [state, setState] = useState<ErrorBoundaryState<TError>>({
Expand All @@ -236,6 +240,10 @@ export const useErrorBoundary = <TError extends Error = Error>() => {
)
}

/**
* This hook allows you to access the reset method and error objects without prop drilling.
* @see {@link https://suspensive.org/en/docs/react/ErrorBoundary#useerrorboundaryfallbackprops Suspensive Docs}
*/
export const useErrorBoundaryFallbackProps = <TError extends Error = Error>(): ErrorBoundaryFallbackProps<TError> => {
const errorBoundary = useContext(ErrorBoundaryContext)
SuspensiveError.assert(
Expand Down
12 changes: 9 additions & 3 deletions packages/react/src/ErrorBoundaryGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ export interface ErrorBoundaryGroupProps extends PropsWithChildren {
}

/**
* ErrorBoundaryGroup is Component to manage multiple ErrorBoundaries
* @see {@link https://suspensive.org/docs/react/ErrorBoundaryGroup}
* ErrorBoundaryGroup is a wrapper component that allows you to manage multiple ErrorBoundaries easily.
* ErrorBoundaries as children of nested ErrorBoundaryGroup will also be reset by parent ErrorBoundaryGroup.Consumer.
* @see {@link https://suspensive.org/docs/react/ErrorBoundaryGroup Suspensive Docs}
*/
export const ErrorBoundaryGroup = Object.assign(
(() => {
Expand Down Expand Up @@ -63,7 +64,12 @@ export const ErrorBoundaryGroup = Object.assign(
}
)

export const useErrorBoundaryGroup = () => {
/**
* This hook provides the reset method for the ErrorBoundaryGroup.
* Must be used within an ErrorBoundaryGroup component.
* @see {@link https://suspensive.org/docs/react/ErrorBoundaryGroup#useerrorboundarygroup Suspensive Docs}
*/
export const useErrorBoundaryGroup = (): { reset: () => void } => {
const group = useContext(ErrorBoundaryGroupContext)
SuspensiveError.assert(
group != null,
Expand Down
40 changes: 40 additions & 0 deletions packages/react/src/wrap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,46 @@ class Wrap {
}
}

/**
* A utility for wrapping components with Suspense, ErrorBoundary, ErrorBoundaryGroup, and Delay functionality.
* Provides a chainable API to compose multiple wrapper components.
*
* @example
* ```tsx
* // Basic usage
* const WrappedComponent = wrap
* .ErrorBoundary({
* fallback: ({ error }) => <ErrorDisplay message={error.message} />
* })
* .Suspense({ fallback: <LoadingSpinner /> })
* .on(YourComponent)
*
* // With TypeScript props
* const PostItem = wrap
* .ErrorBoundary({ fallback: ({ error }) => <div>{error.message}</div> })
* .Suspense({ fallback: <div>Loading...</div> })
* .on<{ id: number }>((props) => {
* // Component implementation
* })
*
* // With ErrorBoundaryGroup
* const Page = wrap
* .ErrorBoundaryGroup({ blockOutside: true })
* .ErrorBoundary({ fallback: ({ error }) => <PageError error={error} /> })
* .Suspense({ fallback: <PageSkeleton /> })
* .on(() => {
* // Page implementation
* })
* ```
*
* Each wrapper method returns a chainable instance that can be further composed
* with additional wrappers before finalizing with .on()
*
* @see {@link Suspense}
* @see {@link ErrorBoundary}
* @see {@link ErrorBoundaryGroup}
* @see {@link Delay}
*/
export const wrap = {
Suspense: (props: OmitKeyof<ComponentProps<typeof Suspense>, 'children'> = {}) => new Wrap([[Suspense, props]]),
ErrorBoundary: (props: OmitKeyof<ComponentProps<typeof ErrorBoundary>, 'children'>) =>
Expand Down

0 comments on commit b1b1193

Please sign in to comment.