Skip to content

Commit

Permalink
feat: link component
Browse files Browse the repository at this point in the history
  • Loading branch information
nicholasio committed Oct 29, 2024
1 parent e8a7c95 commit 686ea35
Show file tree
Hide file tree
Showing 12 changed files with 534 additions and 152 deletions.
521 changes: 388 additions & 133 deletions package-lock.json

Large diffs are not rendered by default.

8 changes: 7 additions & 1 deletion packages/block-primitives/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@
"types": "./dist/primitives/image.d.ts",
"default": "./dist/primitives/image.js"
},
"./link": {
"block-editor": "./dist/block-editor/link.js",
"types": "./dist/primitives/link.d.ts",
"default": "./dist/primitives/link.js"
},
"./block": {
"block-editor": "./dist/block-editor/block.js",
"types": "./dist/primitives/block.d.ts",
Expand Down Expand Up @@ -60,6 +65,7 @@
"@testing-library/react": "^14.2.1",
"@testing-library/user-event": "^14.5.2",
"dts-bundle-generator": "^9.5.1",
"@10up/block-components": "^1.19.3",
"@types/jest": "^29.0.3",
"jest": "^29.0.3",
"ts-jest": "^29.0.1",
Expand All @@ -71,7 +77,7 @@
"@wordpress/block-editor": "^12.21.0",
"@wordpress/data": "^9.23.0",
"@wordpress/components": "^27.1.0",
"@10up/block-components" : "^1.18.0",
"@10up/block-components": "^1.19.3",
"@wordpress/blob": "^3.53.0"
},
"peerDependenciesMeta": {
Expand Down
31 changes: 17 additions & 14 deletions packages/block-primitives/src/block-editor/image.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,26 @@ import { Placeholder, Spinner, ToolbarGroup } from '@wordpress/components';
import { isBlobURL } from '@wordpress/blob';
import { ImagePrimitive, ImagePrimitiveValue } from '../shared/types.js';
import { useBlockPrimitiveProps } from './block.js';
import FrontEndImagePrimitive from '../primitives/image.js';

/**

Check warning on line 9 in packages/block-primitives/src/block-editor/image.tsx

View workflow job for this annotation

GitHub Actions / eslint (20.x)

Missing JSDoc @param "props" declaration

Check warning on line 9 in packages/block-primitives/src/block-editor/image.tsx

View workflow job for this annotation

GitHub Actions / eslint (20.x)

Missing JSDoc @returns declaration
* The Image Block Editor Primitive
*
* Expects an attribute of type {@link ImagePrimitiveValue}
*/
const Image = ({
name,
onPrimitiveSelect,
mediaURL,
mediaId,
title = 'Edit Media',
value,
accept = 'image/*,video/*',
allowedTypes = ['image'],
...rest
}: ImagePrimitive) => {
const Image = (props: ImagePrimitive) => {
const {
name,
onPrimitiveSelect,
mediaURL,
mediaId,
title = 'Edit Media',
value,
accept = 'image/*,video/*',
allowedTypes = ['image'],
...rest
} = props;

const { attributes, setAttributes } = useBlockPrimitiveProps();

const defaultOnPrimitive: ImagePrimitive['onPrimitiveSelect'] = (
Expand All @@ -35,7 +38,7 @@ const Image = ({
};

const attribute: ImagePrimitiveValue = attributes[name] ?? value ?? {};
const { id, url, alt } = attribute;
const { id, url } = attribute;

const isUploading = !id && isBlobURL(url);

Expand Down Expand Up @@ -68,8 +71,8 @@ const Image = ({
)}
</Placeholder>
) : null}
{/* TOOD: Maybe just use the front-end primitive here */}
{!isUploading && id ? <img src={url} alt={alt ?? ''} /> : null}

{!isUploading && id ? <FrontEndImagePrimitive {...props} value={attribute} /> : null}

Check warning on line 75 in packages/block-primitives/src/block-editor/image.tsx

View workflow job for this annotation

GitHub Actions / eslint (20.x)

Prop spreading is forbidden
</>
);
};
Expand Down
50 changes: 50 additions & 0 deletions packages/block-primitives/src/block-editor/link.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { FC } from 'react';
import { Link as LinkBlockComponent } from '@10up/block-components';
import { useBlockProps } from '@wordpress/block-editor';
import { LinkPrimitiveValue, LinkProps } from '#shared/types.js';
import { useBlockPrimitiveProps } from './block.js';

const Link: FC<LinkProps> = ({
name,
value,
className,
placeholder = 'Enter Link Text here...',
}) => {
const blockProps = useBlockProps();
const { attributes, setAttributes } = useBlockPrimitiveProps();

const attribute: LinkPrimitiveValue = attributes[name] ?? value ?? {};
const { url, opensInNewTab, title } = attribute;

const defaultOnPrimitiveChange = (_name, _value: LinkPrimitiveValue, _setAttributes) =>
_setAttributes({ [_name]: _value });

const _onPrimitiveChange = defaultOnPrimitiveChange;

return (
<div {...blockProps}>

Check warning on line 25 in packages/block-primitives/src/block-editor/link.tsx

View workflow job for this annotation

GitHub Actions / eslint (20.x)

Prop spreading is forbidden
<LinkBlockComponent
value={title}
url={url}
opensInNewTab={opensInNewTab}
onTextChange={(text) =>
_onPrimitiveChange(name, { ...attribute, text }, setAttributes)
}
onLinkChange={(link) =>
_onPrimitiveChange(name, { ...attribute, ...link }, setAttributes)
}
onLinkRemove={() => {
_onPrimitiveChange(
name,
{ url: '', text: '', title: '', opensInNewTab: false },
setAttributes,
);
}}
className={className}
placeholder={placeholder}
/>
</div>
);
};

export default Link;
22 changes: 22 additions & 0 deletions packages/block-primitives/src/primitives/link.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { FC } from 'react';
import { LinkProps } from '#shared/types.js';

const Link: FC<LinkProps> = ({ className, value }) => {
if (typeof value === 'undefined') {
return null;
}

return (
<a
href={value.url}
className={className}
title={value.title}
target={value.opensInNewTab ? '_blank' : '_self'}
rel="noreferrer"
>
{value.text ?? value.text}
</a>
);
};

export default Link;
18 changes: 18 additions & 0 deletions packages/block-primitives/src/shared/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,24 @@ export interface RichTextPrimitive<T extends keyof HTMLElementTagNameMap>
) => void;
}

// copied from 10up block components

export interface LinkPrimitiveValue {
url: string;
opensInNewTab?: boolean;
title?: string;
text?: string;
type?: string;
kind?: string;
}

export interface LinkProps {
name: string;
value?: LinkPrimitiveValue;
placeholder?: string;
className?: string;
}

export interface GutenbergBlock<T extends Record<string, unknown>> {
attributes: {
[k in keyof T]: T[k];
Expand Down
6 changes: 6 additions & 0 deletions projects/component-library/src/hero/Hero.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ export const Primary: Story = {
url: 'https://placehold.co/600x400',
alt: 'Hero Image',
},
link: {
url: 'https://example.com',
text: 'Read more',
title: 'Read more',
opensInNewTab: true,
},
},
},
};
13 changes: 11 additions & 2 deletions projects/component-library/src/hero/Hero.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import type { GutenbergBlock, ImagePrimitiveValue } from '@headstartwp/block-primitives';
import type {
GutenbergBlock,
ImagePrimitiveValue,
LinkPrimitiveValue,
} from '@headstartwp/block-primitives';
import Image from '@headstartwp/block-primitives/image';
import RichText from '@headstartwp/block-primitives/rich-text';
import { containerStyle, titleStyle } from './style.css';
import Link from '@headstartwp/block-primitives/link';
import { containerStyle, titleStyle, linkStyle } from './style.css';

export type HeroAttributes = {
title: string;
content: string;
image: ImagePrimitiveValue;
link: LinkPrimitiveValue;
};

export const Hero = ({ attributes }: GutenbergBlock<HeroAttributes>) => {
Expand Down Expand Up @@ -34,6 +40,9 @@ export const Hero = ({ attributes }: GutenbergBlock<HeroAttributes>) => {
mediaURL={attributes?.image?.url ?? ''}
allowedTypes={['image/jpg']}
/>

{/* eslint-disable-next-line jsx-a11y/anchor-is-valid */}
<Link name="link" value={attributes.link} className={linkStyle} />
</div>
);
};
9 changes: 9 additions & 0 deletions projects/component-library/src/hero/style.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,12 @@ export const titleStyle = style({
fontSize: '2rem',
fontWeight: 'bold',
});

export const linkStyle = style({
color: 'red',
textDecoration: 'none',
display: 'block',
':hover': {
textDecoration: 'underline',
},
});
3 changes: 3 additions & 0 deletions wp/10up-theme/includes/blocks/example-block/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
},
"image": {
"type": "object"
},
"link": {
"type": "object"
}
},
"example": {
Expand Down
3 changes: 2 additions & 1 deletion wp/10up-theme/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
"dependencies": {
"modern-normalize": "^2.0.0",
"@headstartwp/block-primitives": "*",
"@headstartwp/component-library": "*"
"@headstartwp/component-library": "*",
"@10up/block-components": "^1.19.3"
},
"10up-toolkit": {
"useBlockAssets": true,
Expand Down
2 changes: 1 addition & 1 deletion wp/10up-theme/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const config = require('10up-toolkit/config/webpack.config');

config.resolve = {
...config.resolve,
conditionNames: ['block-editor'],
conditionNames: ['block-editor', 'require'],
};

module.exports = config;

0 comments on commit 686ea35

Please sign in to comment.