Skip to content

Commit

Permalink
feat: support custom colors for audio player
Browse files Browse the repository at this point in the history
This commit adds block supports for color customization.

The block editor color palette is used to select the colors. The colors
are stored in the block attributes, though are applied using inline
styles of custom CSS properties. This allows the custom colors to be
applied to the shadow DOM of the `media-chrome` web components.

Fixes: #11
  • Loading branch information
johnhooks committed May 27, 2024
1 parent b1655b1 commit abd7204
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 5 deletions.
5 changes: 5 additions & 0 deletions docs/planning.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ Replicate the functionality of the audio block. Using the `audio` element.

Add a custom UI that replicates the features of the standard `audio` element.

### Color Supports

- [Block Supports - Color](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-supports/#color)
- [Theme Supports - Color Palettes](https://developer.wordpress.org/block-editor/how-to-guides/themes/theme-support/#block-color-palettes)

## Step Three

Incrementally add features to expand the functionality.
Expand Down
5 changes: 5 additions & 0 deletions src/audio/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@
"supports": {
"anchor": true,
"align": true,
"color": {
"background": true,
"text": true,
"link": false
},
"spacing": {
"margin": true,
"padding": true
Expand Down
10 changes: 9 additions & 1 deletion src/audio/edit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import './editor.scss';
import Caption from './edit/caption.js';
import { Player } from './player/index.js';
import type { Attributes } from './types';
import useStyle from './use-style.js';

const ALLOWED_MEDIA_TYPES = ['audio'];

Expand Down Expand Up @@ -114,6 +115,8 @@ function VinylEdit({
className: classes,
});

const style = useStyle(attributes);

if (!src) {
return (
<div {...blockProps}>
Expand Down Expand Up @@ -196,7 +199,12 @@ function VinylEdit({
*/}

<Disabled isDisabled={!isSingleSelected}>
<Player loop={loop} preload={preload} src={src} />
<Player
loop={loop}
preload={preload}
src={src}
style={style}
/>
</Disabled>

{isTemporaryAudio && <Spinner />}
Expand Down
13 changes: 10 additions & 3 deletions src/audio/player/player.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,18 @@ import {
} from '../../react/index.js';
import type { Attributes } from '../types';

type Props = Omit<Attributes, 'caption' | 'id'>;
type Props = Omit<Attributes, 'caption' | 'id'> & {
style?: React.CSSProperties;
};

export default function Player({ loop, preload, src }: Props) {
export default function Player({ loop, preload, src, style }: Props) {
return (
<VinylController audio={true} autohide="-1" className="vinyl__player">
<VinylController
audio={true}
autohide="-1"
className="vinyl__player"
style={style}
>
<audio slot="media" src={src} preload={preload} loop={loop} />
<VinylControlBar className="vinyl__control-bar">
<div className="vinyl__media-controls">
Expand Down
9 changes: 8 additions & 1 deletion src/audio/save.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,24 @@ import {
} from '../react/index.js';

import type { Attributes } from './types';
import { computeStyle } from './use-style.js';

export default function Save({ attributes }: BlockSaveProps<Attributes>) {
const { loop, preload, src } = attributes;

const blockProps = useBlockProps.save();

// Not using a hook here because the save function should be static.
const style = computeStyle(attributes);

return (
src && (
<figure {...useBlockProps.save()}>
<figure {...blockProps}>
<VinylController
audio={true}
autohide="-1"
className="vinyl__player"
style={style}
>
<audio
slot="media"
Expand Down
12 changes: 12 additions & 0 deletions src/audio/style.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
.wp-block-vinyl-audio {
--vinyl-background-color: var(--wp--preset--color--base, transparent);
--vinyl-text-color: var(--wp--preset--color--contrast, #000);

/* This block has customizable padding, border-box makes that more predictable. */
box-sizing: border-box;

Expand All @@ -11,6 +14,15 @@
margin-top: 0.5em;
}

vinyl-controller {
--media-background-color: var(--vinyl-background-color);
--media-control-background: var(--vinyl-background-color);
--media-control-hover-background: transparent;

/* The primary color is used for --media-text-color and --media-icon-color. */
--media-primary-color: var(--vinyl-text-color);
}

/* Show full-width when not aligned. */
.vinyl__player {
width: 100%;
Expand Down
16 changes: 16 additions & 0 deletions src/audio/types.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,27 @@
import type { Transform } from '@wordpress/blocks';
import type { Style } from '@wordpress/style-engine/build-types/types';

export interface Attributes {
caption?: string;
id?: number;
loop?: boolean;
src?: string;
preload?: string;

/**
* Set by the color block support, if a text color is set.
*/
textColor?: string;

/**
* Set by the color block support, if a background color is set.
*/
backgroundColor?: string;

/**
* The block's style settings.
*/
style?: Style;
}

/**
Expand Down
36 changes: 36 additions & 0 deletions src/audio/use-style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { useMemo } from '@wordpress/element';

import { Attributes } from './types';

/**
* @param attributes The audio block attributes.
*/
export default function useStyle(attributes: Attributes): React.CSSProperties {
const style = useMemo(
() => computeStyle(attributes),
// eslint-disable-next-line react-hooks/exhaustive-deps
[attributes.textColor, attributes.backgroundColor, attributes.style]
);

return style;
}

export function computeStyle(attributes: Attributes) {
const result: React.CSSProperties = {};

if (attributes.backgroundColor) {
result['--vinyl-background-color'] =
`var(--wp--preset--color--${attributes.backgroundColor})`;
} else if (attributes.style?.color?.background) {
result['--vinyl-background-color'] = attributes.style.color.background;
}

if (attributes.textColor) {
result['--vinyl-text-color'] =
`var(--wp--preset--color--${attributes.textColor})`;
} else if (attributes.style?.color?.text) {
result['--vinyl-text-color'] = attributes.style.color.text;
}

return result;
}

0 comments on commit abd7204

Please sign in to comment.