Skip to content
This repository has been archived by the owner on Jun 5, 2023. It is now read-only.

Commit

Permalink
feat: New Duration component
Browse files Browse the repository at this point in the history
  • Loading branch information
diondiondion committed Sep 25, 2019
1 parent 3b6db45 commit 0506256
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 0 deletions.
27 changes: 27 additions & 0 deletions src/Duration/README.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
name: Duration
menu: Components
---

import {Playground, Props} from 'docz';
import Duration from './';

# Duration

A simple component for rendering a duration (e.g. of a video) in the format `m:s` or `h:m:s` with an accessible label.

This comment has been minimized.

Copy link
@ikhemissi

ikhemissi Sep 25, 2019

Contributor

Can you please add a line here to say that the component accepts a numerical value (number of seconds) as input ?


## Examples

<Playground>
<Duration value={27} />
<br />
<Duration value={523} />
<br />
<Duration value={1104} />
<br />
<Duration value={7329} />
</Playground>

## Props

<Props of={Duration} />
21 changes: 21 additions & 0 deletions src/Duration/getDuration.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
function getZeroPaddedRest(value, base) {
const remaining = value % base;
if (remaining < 10) {
return String(remaining).padStart(2, '0');
} else return remaining;
}

function getDuration(durationInSeconds) {
const hours = parseInt(durationInSeconds / (60 * 60));
let minutes = parseInt(durationInSeconds / 60);
minutes = hours ? getZeroPaddedRest(minutes, 60) : minutes;
const seconds = getZeroPaddedRest(durationInSeconds, 60);

return {
hours,
minutes,
seconds,
};
}

export default getDuration;
46 changes: 46 additions & 0 deletions src/Duration/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import React from 'react';
import PropTypes from 'prop-types';
import getDuration from './getDuration';

function getDefaultLabel(minutes, hours) {
const addPluralS = count => (count === 1 ? '' : 's');

const readableMins = `${minutes} minute${addPluralS(minutes)}`;

This comment has been minimized.

Copy link
@ikhemissi

ikhemissi Sep 25, 2019

Contributor

I am wondering if there is a browser API that we can use to show a localised duration for the duration

if (hours) {
return `${hours} hour${addPluralS(minutes)}, ${readableMins}`;
} else return readableMins;
}

function Duration(props) {
const {value, getLabel, as: Component, ...otherProps} = props;
const {hours, minutes, seconds} = getDuration(value);

const duration = hours ? [hours, minutes, seconds] : [minutes, seconds];

return (
<Component
{...otherProps}
aria-label={getLabel(Number(minutes), Number(hours))}
>
{duration.join(':')}
</Component>
);
}

Duration.defaultProps = {
as: 'span',
getLabel: getDefaultLabel,
};

Duration.propTypes = {
/** Change the element rendered by the component */
as: PropTypes.oneOfType([PropTypes.string, PropTypes.elementType]),
/** Customise the accessible label, i.e. for localisation */
getLabel: PropTypes.func,
/** Duration in seconds */
value: PropTypes.number.isRequired,
};

export {getDuration};

export default Duration;
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export {default as Box} from './Box';
export {default as Button} from './Button';
export {default as ButtonCore} from './ButtonCore';
export {default as CenterContent} from './CenterContent';
export {default as Duration} from './Duration';
export {default as Flex} from './Flex';
export {default as Icon} from './Icon';
export {default as InlineList} from './InlineList';
Expand Down

0 comments on commit 0506256

Please sign in to comment.