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

New Block: Implement progress bar block #68652

Draft
wants to merge 2 commits into
base: trunk
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions docs/reference-guides/core-blocks.md
Original file line number Diff line number Diff line change
Expand Up @@ -700,6 +700,15 @@ Add text that respects your spacing and tabs, and also allows styling. ([Source]
- **Supports:** anchor, color (background, gradients, text), interactivity (clientNavigation), spacing (margin, padding), typography (fontSize, lineHeight)
- **Attributes:** content

## Progress Bar

Display a progress bar. Useful for tracking progress on a task or project. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/progress-bar))

- **Name:** core/progress-bar
- **Category:** design
- **Supports:** align, ~~html~~
- **Attributes:** backgroundColor, label, max, progressColor, value

## Pullquote

Give special visual emphasis to a quote from your text. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/pullquote))
Expand Down
22 changes: 12 additions & 10 deletions packages/block-library/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
import {
setDefaultBlockName,
setFreeformContentHandlerName,
setUnregisteredTypeHandlerName,
setGroupingBlockName,
setUnregisteredTypeHandlerName,
} from '@wordpress/blocks';

/**
Expand All @@ -21,37 +21,39 @@ import {
//
// See https://github.com/WordPress/gutenberg/pull/40655 for more context.
import * as archives from './archives';
import * as avatar from './avatar';
import * as audio from './audio';
import * as avatar from './avatar';
import * as reusableBlock from './block';
import * as button from './button';
import * as buttons from './buttons';
import * as calendar from './calendar';
import * as categories from './categories';
import * as classic from './freeform';
import * as code from './code';
import * as column from './column';
import * as columns from './columns';
import * as comments from './comments';
import * as commentAuthorAvatar from './comment-author-avatar';
import * as commentAuthorName from './comment-author-name';
import * as commentContent from './comment-content';
import * as commentDate from './comment-date';
import * as commentEditLink from './comment-edit-link';
import * as commentReplyLink from './comment-reply-link';
import * as commentTemplate from './comment-template';
import * as commentsPaginationPrevious from './comments-pagination-previous';
import * as comments from './comments';
import * as commentsPagination from './comments-pagination';
import * as commentsPaginationNext from './comments-pagination-next';
import * as commentsPaginationNumbers from './comments-pagination-numbers';
import * as commentsPaginationPrevious from './comments-pagination-previous';
import * as commentsTitle from './comments-title';
import * as cover from './cover';
import * as details from './details';
import * as embed from './embed';
import * as file from './file';
import * as footnotes from './footnotes';
import * as form from './form';
import * as formInput from './form-input';
import * as formSubmitButton from './form-submit-button';
import * as formSubmissionNotification from './form-submission-notification';
import * as formSubmitButton from './form-submit-button';
import * as classic from './freeform';
import * as gallery from './gallery';
import * as group from './group';
import * as heading from './heading';
Expand All @@ -70,13 +72,13 @@ import * as navigation from './navigation';
import * as navigationLink from './navigation-link';
import * as navigationSubmenu from './navigation-submenu';
import * as nextpage from './nextpage';
import * as pattern from './pattern';
import * as pageList from './page-list';
import * as pageListItem from './page-list-item';
import * as paragraph from './paragraph';
import * as pattern from './pattern';
import * as postAuthor from './post-author';
import * as postAuthorName from './post-author-name';
import * as postAuthorBiography from './post-author-biography';
import * as postAuthorName from './post-author-name';
import * as postComment from './post-comment';
import * as postCommentsCount from './post-comments-count';
import * as postCommentsForm from './post-comments-form';
Expand All @@ -91,6 +93,7 @@ import * as postTerms from './post-terms';
import * as postTimeToRead from './post-time-to-read';
import * as postTitle from './post-title';
import * as preformatted from './preformatted';
import * as progressBar from './progress-bar';
import * as pullquote from './pullquote';
import * as query from './query';
import * as queryNoResults from './query-no-results';
Expand All @@ -101,7 +104,6 @@ import * as queryPaginationPrevious from './query-pagination-previous';
import * as queryTitle from './query-title';
import * as queryTotal from './query-total';
import * as quote from './quote';
import * as reusableBlock from './block';
import * as readMore from './read-more';
import * as rss from './rss';
import * as search from './search';
Expand All @@ -121,7 +123,6 @@ import * as termDescription from './term-description';
import * as textColumns from './text-columns';
import * as verse from './verse';
import * as video from './video';
import * as footnotes from './footnotes';

import isBlockMetadataExperimental from './utils/is-block-metadata-experimental';

Expand Down Expand Up @@ -182,6 +183,7 @@ const getAllBlocks = () => {
verse,
video,
footnotes,
progressBar,

// theme blocks
navigation,
Expand Down
34 changes: 34 additions & 0 deletions packages/block-library/src/progress-bar/block.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "core/progress-bar",
"category": "design",
"title": "Progress Bar",
"description": "Display a progress bar. Useful for tracking progress on a task or project.",
"textdomain": "default",
"attributes": {
"label": {
"type": "string",
"default": "Progress"
},
"value": {
"type": "number",
"default": 50
},
"max": {
"type": "number",
"default": 100
},
"backgroundColor": {
"type": "string"
},
"progressColor": {
"type": "string"
}
},
"supports": {
"align": true,
"html": false
},
"style": "wp-block-progress-bar"
}
120 changes: 120 additions & 0 deletions packages/block-library/src/progress-bar/edit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/**
* WordPress dependencies
*/
import {
InspectorControls,
PanelColorSettings,
useBlockProps,
} from '@wordpress/block-editor';
import { PanelBody, RangeControl, TextControl } from '@wordpress/components';
import { __ } from '@wordpress/i18n';

export default function Edit( { attributes, setAttributes } ) {
const {
label,
value,
max = 100,
backgroundColor,
progressColor,
} = attributes;

const blockProps = useBlockProps( {
className: 'wp-block-progress-bar',
} );

// Custom styles for the progress bar
const progressBarStyle = {
backgroundColor: backgroundColor || '#f0f0f0',
borderRadius: '4px',
overflow: 'hidden',
height: '24px',
position: 'relative',
};

const progressStyle = {
backgroundColor: progressColor || '#4CAF50',
width: `${ ( value / max ) * 100 }%`,
height: '100%',
transition: 'width 0.3s ease',
};

return (
<div { ...blockProps }>
<InspectorControls>
<PanelBody title={ __( 'Progress Bar Settings' ) }>
<TextControl
__next40pxDefaultSize
__nextHasNoMarginBottom
label={ __( 'Label' ) }
value={ label || '' }
onChange={ ( labelText ) =>
setAttributes( { label: labelText } )
}
/>
<RangeControl
__next40pxDefaultSize
__nextHasNoMarginBottom
label={ __( 'Progress Value' ) }
value={ value }
onChange={ ( currentValue ) =>
setAttributes( { value: currentValue } )
}
min={ 0 }
max={ max }
/>
<RangeControl
__next40pxDefaultSize
__nextHasNoMarginBottom
label={ __( 'Maximum Value' ) }
value={ max }
onChange={ ( maxValue ) =>
setAttributes( { max: maxValue } )
}
min={ 1 }
max={ 1000 }
/>
</PanelBody>
<PanelColorSettings
title={ __( 'Color Settings' ) }
colorSettings={ [
{
value: backgroundColor,
onChange: ( bgColor ) =>
setAttributes( { backgroundColor: bgColor } ),
label: __( 'Background Color' ),
},
{
value: progressColor,
onChange: ( progressBarColor ) =>
setAttributes( {
progressColor: progressBarColor,
} ),
label: __( 'Progress Color' ),
},
] }
/>
</InspectorControls>

<div className="wp-block-progress-bar__container">
{ label && (
<div className="wp-block-progress-bar__label">
{ label }
</div>
) }
<div
style={ progressBarStyle }
className="wp-block-progress-bar__bar"
>
<div
style={ progressStyle }
className="wp-block-progress-bar__progress"
>
<span className="wp-block-progress-bar__value">
{ value }%
</span>
</div>
</div>
</div>
</div>
);
}
30 changes: 30 additions & 0 deletions packages/block-library/src/progress-bar/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* WordPress dependencies
*/
import { _x } from '@wordpress/i18n';
import { home } from '@wordpress/icons';

/**
* Internal dependencies
*/
import initBlock from '../utils/init-block';
import metadata from './block.json';
import edit from './edit';
import save from './save';

const { name } = metadata;

export { metadata, name };

export const settings = {
icon: home,
edit,
save,
example: {
attributes: {
label: _x( 'Progress Bar', 'block example' ),
},
},
};

export const init = () => initBlock( { name, metadata, settings } );
6 changes: 6 additions & 0 deletions packages/block-library/src/progress-bar/init.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* Internal dependencies
*/
import { init } from '.';

export default init();
74 changes: 74 additions & 0 deletions packages/block-library/src/progress-bar/save.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/**
* WordPress dependencies
*/
import { useBlockProps } from '@wordpress/block-editor';

export default function save( { attributes } ) {
const {
label,
value,
max = 100,
backgroundColor,
progressColor,
} = attributes;

const blockProps = useBlockProps.save( {
className: 'wp-block-progress-bar',
} );

// Calculate the percentage
const percentage = Math.min( Math.max( ( value / max ) * 100, 0 ), 100 );

// Custom styles for the progress bar
const progressBarStyle = {
backgroundColor: backgroundColor || '#f0f0f0',
borderRadius: '4px',
overflow: 'hidden',
height: '24px',
position: 'relative',
};

const progressStyle = {
backgroundColor: progressColor || '#4CAF50',
width: `${ percentage }%`,
height: '100%',
transition: 'width 0.3s ease',
};

return (
<div { ...blockProps }>
<div className="wp-block-progress-bar__container">
{ label && (
<div className="wp-block-progress-bar__label">
{ label }
</div>
) }
<div
style={ progressBarStyle }
className="wp-block-progress-bar__bar"
>
<meter
className="wp-block-progress-bar__meter"
value={ value }
max={ max }
style={ {
display: 'block',
width: '100%',
height: '100%',
...progressStyle,
} }
>
<div
style={ progressStyle }
className="wp-block-progress-bar__progress"
>
<span className="wp-block-progress-bar__value">
{ percentage.toFixed( 1 ) }%
</span>
</div>
</meter>
</div>
</div>
</div>
);
}
Loading