Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Composite: fix Storybook docgen #64682

Merged
merged 12 commits into from
Aug 22, 2024
4 changes: 4 additions & 0 deletions packages/components/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### Internal

- `Composite` V2: fix Storybook docgen ([#64682](https://github.com/WordPress/gutenberg/pull/64682)).

## 28.6.0 (2024-08-21)

### Deprecations
Expand Down
58 changes: 39 additions & 19 deletions packages/components/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ To meet the above requirements, we recommend:

- using `Object.assign()` to add subcomponents as properties of the top-level component;
- using named functions for all components;
- using a separate file for each component, context and hook;
- setting explicitly the `displayName` on all subcomponents;
- adding the top-level JSDoc to the result of the `Object.assign` call;
- adding inline subcomponent JSDocs inside the `Object.assign` call.
Expand All @@ -256,36 +257,55 @@ The following example implements all of the above recommendations.

```tsx
//=======================
// Component.tsx
// subcomponent.tsx
//=======================
import { forwardRef, createContext } from '@wordpress/element';
import { forwardRef } from '@wordpress/element';

function UnforwardedTopLevelComponent( props, ref ) {
/* ... */
}
const TopLevelComponent = forwardRef( UnforwardedTopLevelComponent );

function UnforwardedSubComponent( props, ref ) {
/* ... */
}
const SubComponent = forwardRef( UnforwardedSubComponent );
export const SubComponent = forwardRef(
function UnforwardedSubComponent( props, ref ) {
/* ... */
}
);
SubComponent.displayName = 'Component.SubComponent';

const Context = createContext();
//=======================
// context.ts
//=======================
import { createContext } from '@wordpress/element';

/** The top-level component's JSDoc. */
export const Component = Object.assign( TopLevelComponent, {
/** The subcomponent's JSDoc. */
SubComponent,
/** The context's JSDoc. */
Context,
} );
export const Context = createContext();

//=======================
// hook.ts
//=======================

/** The hook's JSDoc. */
export function useComponent() {
/* ... */
}

//=======================
// component.tsx
//=======================
import { forwardRef } from '@wordpress/element';
import { SubComponent } from './subcomponent';
import { Context } from './context';

/** The top-level component's JSDoc. */
export const Component = Object.assign(
forwardRef( function UnforwardedTopLevelComponent( props, ref ) {
/* ... */
} ),
{
/** The subcomponent's JSDoc. */
SubComponent,
/** The context's JSDoc. */
Context,
}
);

export default Component;

//=======================
// App.tsx
//=======================
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import { useInstanceId } from '@wordpress/compose';
* Internal dependencies
*/
import Cell from './cell';
import { Composite, useCompositeStore } from '../composite';
import { Composite } from '../composite';
import { useCompositeStore } from '../composite/store';
import { Root, Row } from './styles/alignment-matrix-control-styles';
import AlignmentMatrixControlIcon from './icon';
import { GRID, getItemId, getItemValue } from './utils';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import { isRTL } from '@wordpress/i18n';
* Internal dependencies
*/
import { CircularOptionPickerContext } from './circular-option-picker-context';
import { Composite, useCompositeStore } from '../composite';
import { Composite } from '../composite';
import { useCompositeStore } from '../composite/store';
import type {
CircularOptionPickerProps,
ListboxCircularOptionPickerProps,
Expand Down
31 changes: 31 additions & 0 deletions packages/components/src/composite/group-label.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* External dependencies
*/
import * as Ariakit from '@ariakit/react';

/**
* WordPress dependencies
*/
import { forwardRef } from '@wordpress/element';

/**
* Internal dependencies
*/
import type { WordPressComponentProps } from '../context';
import { useCompositeContext } from './context';
import type { CompositeGroupLabelProps } from './types';

export const CompositeGroupLabel = forwardRef<
HTMLDivElement,
WordPressComponentProps< CompositeGroupLabelProps, 'div', false >
>( function CompositeGroupLabel( props, ref ) {
const context = useCompositeContext();
return (
<Ariakit.CompositeGroupLabel
store={ context?.store }
{ ...props }
ref={ ref }
/>
);
} );
CompositeGroupLabel.displayName = 'Composite.GroupLabel';
31 changes: 31 additions & 0 deletions packages/components/src/composite/group.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* External dependencies
*/
import * as Ariakit from '@ariakit/react';

/**
* WordPress dependencies
*/
import { forwardRef } from '@wordpress/element';

/**
* Internal dependencies
*/
import type { WordPressComponentProps } from '../context';
import { useCompositeContext } from './context';
import type { CompositeGroupProps } from './types';

export const CompositeGroup = forwardRef<
HTMLDivElement,
WordPressComponentProps< CompositeGroupProps, 'div', false >
>( function CompositeGroup( props, ref ) {
const context = useCompositeContext();
return (
<Ariakit.CompositeGroup
store={ context?.store }
{ ...props }
ref={ ref }
/>
);
} );
CompositeGroup.displayName = 'Composite.Group';
31 changes: 31 additions & 0 deletions packages/components/src/composite/hover.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* External dependencies
*/
import * as Ariakit from '@ariakit/react';

/**
* WordPress dependencies
*/
import { forwardRef } from '@wordpress/element';

/**
* Internal dependencies
*/
import type { WordPressComponentProps } from '../context';
import { useCompositeContext } from './context';
import type { CompositeHoverProps } from './types';

export const CompositeHover = forwardRef<
HTMLDivElement,
WordPressComponentProps< CompositeHoverProps, 'div', false >
>( function CompositeHover( props, ref ) {
const context = useCompositeContext();
return (
<Ariakit.CompositeHover
store={ context?.store }
{ ...props }
ref={ ref }
/>
);
} );
CompositeHover.displayName = 'Composite.Hover';
Loading
Loading