Skip to content

Commit

Permalink
Merge pull request #317 from 10up/refactor/migrate-post-author-compon…
Browse files Browse the repository at this point in the history
…ents-to-ts

Migrate post author components to ts
  • Loading branch information
fabiankaegy authored May 3, 2024
2 parents 90e8e64 + d04376c commit 5374b80
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 163 deletions.
3 changes: 0 additions & 3 deletions components/author/context.js

This file was deleted.

35 changes: 35 additions & 0 deletions components/author/context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { createContext, useContext } from '@wordpress/element';

export type Author = {
avatar_urls: Record<string, string>;
description: string;
email: string;
first_name: string;
id: number;
last_name: string;
link: string;
name: string;
nickname: string;
registered_date: string;
slug: string;
url: string;
};

export const AuthorContext = createContext<Author>({
avatar_urls: {},
description: '',
email: '',
first_name: '',
id: 0,
last_name: '',
link: '',
name: '',
nickname: '',
registered_date: '',
slug: '',
url: '',
});

export const useAuthor = () => {
return useContext(AuthorContext);
}
144 changes: 0 additions & 144 deletions components/author/index.js

This file was deleted.

97 changes: 97 additions & 0 deletions components/author/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { useSelect } from '@wordpress/data';
import { store as blockEditorStore } from '@wordpress/block-editor';

Check failure on line 2 in components/author/index.tsx

View workflow job for this annotation

GitHub Actions / Cypress

Could not find a declaration file for module '@wordpress/block-editor'. '/home/runner/work/block-components/block-components/node_modules/@wordpress/block-editor/build/index.js' implicitly has an 'any' type.
import { useAuthor } from './context';

interface NameProps {
tagName?: keyof JSX.IntrinsicElements;
[key: string]: any;
}

export const Name: React.FC<NameProps> = (props) => {
const { tagName: TagName = 'span', ...rest } = props;
const { name, link } = useAuthor();

const wrapperProps = { ...rest };

if (TagName === 'a' && link) {
wrapperProps.href = link;
}

return <TagName {...wrapperProps}>{name}</TagName>;
};

interface FirstNameProps {
tagName?: keyof JSX.IntrinsicElements;
[key: string]: any;
}

export const FirstName: React.FC<FirstNameProps> = (props) => {
const { tagName: TagName = 'span', ...rest } = props;
const { first_name: firstName } = useAuthor();

return <TagName {...rest}>{firstName}</TagName>;
};

interface LastNameProps {
tagName?: keyof JSX.IntrinsicElements;
[key: string]: any;
}

export const LastName: React.FC<LastNameProps> = (props) => {
const { tagName: TagName = 'span', ...rest } = props;
const { last_name: lastName } = useAuthor();

return <TagName {...rest}>{lastName}</TagName>;
};

function useDefaultAvatar() {
const { avatarURL: defaultAvatarUrl } = useSelect((select) => {
const { getSettings } = select(blockEditorStore);

Check failure on line 49 in components/author/index.tsx

View workflow job for this annotation

GitHub Actions / Cypress

Property 'getSettings' does not exist on type '{}'.
const { __experimentalDiscussionSettings } = getSettings();
return __experimentalDiscussionSettings;
}, []);
return defaultAvatarUrl;
}

interface AvatarProps {
[key: string]: any;
}

export const Avatar: React.FC<AvatarProps> = (props) => {
const { ...rest } = props;
const authorDetails = useAuthor();

const avatarUrls = authorDetails?.avatar_urls ? Object.values(authorDetails.avatar_urls) : null;
const defaultAvatar = useDefaultAvatar();

const avatarSourceUrl = avatarUrls ? avatarUrls[avatarUrls.length - 1] : defaultAvatar;

return <img src={avatarSourceUrl} {...rest} />;
};

interface BioProps {
tagName?: keyof JSX.IntrinsicElements;
[key: string]: any;
}

export const Bio: React.FC<BioProps> = (props) => {
const { tagName: TagName = 'p', ...rest } = props;
const { description } = useAuthor();

return <TagName {...rest}>{description}</TagName>;
};

interface EmailProps {
[key: string]: any;
}

export const Email: React.FC<EmailProps> = (props) => {
const { ...rest } = props;
const { email } = useAuthor();

return (
<a href={`mailto:${email}`} {...rest}>
{email}
</a>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,33 @@ import { Children } from '@wordpress/element';
import { store as coreStore } from '@wordpress/core-data';
import { Spinner } from '@wordpress/components';
import { useSelect } from '@wordpress/data';
import PropTypes from 'prop-types';
import { usePost } from '../../hooks';
import { Name, FirstName, LastName, Avatar, Bio, Email } from '../author';

import { AuthorContext } from '../author/context';

export const PostAuthor = (props) => {
import type { Author } from '../author/context';

interface PostAuthorProps {
children?: React.ReactNode | ((author: Author) => React.ReactNode);
[key: string]: any;
}

export const PostAuthor: React.FC<PostAuthorProps> & {
Name: typeof Name;
FirstName: typeof FirstName;
LastName: typeof LastName;
Avatar: typeof Avatar;
Bio: typeof Bio;
Email: typeof Email;
} = (props) => {
const { children, ...rest } = props;
const { postId, postType } = usePost();

const [author, hasResolved] = useSelect(
(select) => {
const { getEditedEntityRecord, getUser, hasFinishedResolution } = select(coreStore);

const postQuery = ['postType', postType, postId];
const postQuery = ['postType', postType, postId as number] as const;

const post = getEditedEntityRecord(...postQuery);
const hasResolvedPost = hasFinishedResolution('getEditedEntityRecord', postQuery);
Expand Down Expand Up @@ -54,18 +66,6 @@ export const PostAuthor = (props) => {
return <Name {...rest} />;
};

PostAuthor.propTypes = {
children: PropTypes.oneOfType([
PropTypes.func,
PropTypes.node,
PropTypes.arrayOf(PropTypes.node),
]),
};

PostAuthor.defaultProps = {
children: null,
};

PostAuthor.Name = Name;
PostAuthor.FirstName = FirstName;
PostAuthor.LastName = LastName;
Expand Down

0 comments on commit 5374b80

Please sign in to comment.