Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
23 changed files
with
461 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
--- | ||
'@twilio-paste/meter': major | ||
'@twilio-paste/core': minor | ||
--- | ||
|
||
[Meter] Create Meter package. Meter is a visual representation of a numerical value within a known range. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@twilio-paste/codemods': minor | ||
--- | ||
|
||
[Codemods] New addition of Meter package. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
--- | ||
'@twilio-paste/base-radio-checkbox': patch | ||
'@twilio-paste/file-uploader': patch | ||
'@twilio-paste/label': patch | ||
'@twilio-paste/core': patch | ||
--- | ||
|
||
Slightly improved Label component types |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
53 changes: 53 additions & 0 deletions
53
packages/paste-core/components/meter/__tests__/index.spec.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import * as React from 'react'; | ||
import {render, screen} from '@testing-library/react'; | ||
import {Theme} from '@twilio-paste/theme'; | ||
import type {RenderOptions} from '@testing-library/react'; | ||
|
||
import {Default, HiddenValueLabelAriaLabel, Customized} from '../stories/index.stories'; | ||
|
||
const ThemeWrapper: RenderOptions['wrapper'] = ({children}) => ( | ||
<Theme.Provider theme="default">{children}</Theme.Provider> | ||
); | ||
|
||
const elementAttr = 'data-paste-element'; | ||
|
||
describe('Meter', () => { | ||
describe('base usage', () => { | ||
it('should render correctly', () => { | ||
render(<Default />, {wrapper: ThemeWrapper}); | ||
const meter = screen.getByRole('meter'); | ||
expect(meter).toBeInTheDocument(); | ||
expect(meter).toHaveAttribute('aria-valuemin', '0'); | ||
expect(meter).toHaveAttribute('aria-valuemax', '100'); | ||
expect(meter).toHaveAttribute('aria-valuenow', '75'); | ||
expect(meter).toHaveAttribute('aria-valuetext', '75%'); | ||
expect(meter).toHaveAttribute('id', 'meter'); | ||
expect(meter).toHaveAttribute('aria-labelledby', 'meterMETER_LABEL'); | ||
}); | ||
|
||
it('should apply aria-label correctly', () => { | ||
render(<HiddenValueLabelAriaLabel />, {wrapper: ThemeWrapper}); | ||
const meter = screen.getByRole('meter'); | ||
expect(meter).toHaveAttribute('aria-label', 'Fuel level'); | ||
expect(meter).not.toHaveAttribute('aria-labelledby'); | ||
}); | ||
}); | ||
|
||
describe('Customization', () => { | ||
it('should set default data-paste-element attribute on meter', () => { | ||
render(<Customized />); | ||
const meterOne = screen.getByTestId('meter_one'); | ||
expect(meterOne).toHaveAttribute(elementAttr, 'METER'); | ||
const meterLabelOne = screen.getByTestId('meter_label_one'); | ||
expect(meterLabelOne).toHaveAttribute(elementAttr, 'METER_LABEL'); | ||
}); | ||
|
||
it('should set custom data-paste-element attribute on meter', () => { | ||
render(<Customized />); | ||
const meterTwo = screen.getByTestId('meter_two'); | ||
expect(meterTwo).toHaveAttribute(elementAttr, 'FOO'); | ||
const meterLabelTwo = screen.getByTestId('meter_label_two'); | ||
expect(meterLabelTwo).toHaveAttribute(elementAttr, 'FOO_LABEL'); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
const {build} = require('../../../../tools/build/esbuild'); | ||
|
||
build(require('./package.json')); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
{ | ||
"name": "@twilio-paste/meter", | ||
"version": "0.0.0", | ||
"category": "data display", | ||
"status": "alpha", | ||
"description": "Meter is a visual representation of a numerical value within a known range.", | ||
"author": "Twilio Inc.", | ||
"license": "MIT", | ||
"main:dev": "src/index.tsx", | ||
"main": "dist/index.js", | ||
"module": "dist/index.es.js", | ||
"types": "dist/index.d.ts", | ||
"sideEffects": false, | ||
"publishConfig": { | ||
"access": "public" | ||
}, | ||
"files": [ | ||
"dist" | ||
], | ||
"scripts": { | ||
"build": "yarn clean && NODE_ENV=production node build.js && tsc", | ||
"build:js": "NODE_ENV=development node build.js", | ||
"clean": "rm -rf ./dist", | ||
"tsc": "tsc" | ||
}, | ||
"peerDependencies": { | ||
"@twilio-paste/animation-library": "^2.0.0", | ||
"@twilio-paste/box": "^10.0.0", | ||
"@twilio-paste/color-contrast-utils": "^5.0.0", | ||
"@twilio-paste/customization": "^8.0.0", | ||
"@twilio-paste/design-tokens": "^10.0.0", | ||
"@twilio-paste/icons": "^12.0.0", | ||
"@twilio-paste/label": "^13.0.0", | ||
"@twilio-paste/media-object": "^10.0.0", | ||
"@twilio-paste/react-spectrum-library": "^2.0.0", | ||
"@twilio-paste/screen-reader-only": "^13.0.0", | ||
"@twilio-paste/style-props": "^9.0.0", | ||
"@twilio-paste/styling-library": "^3.0.0", | ||
"@twilio-paste/text": "^10.0.0", | ||
"@twilio-paste/theme": "^11.0.0", | ||
"@twilio-paste/types": "^6.0.0", | ||
"@twilio-paste/uid-library": "^2.0.0", | ||
"@types/react": "^16.8.6 || ^17.0.2 || ^18.0.27", | ||
"@types/react-dom": "^16.8.6 || ^17.0.2 || ^18.0.10", | ||
"prop-types": "^15.7.2", | ||
"react": "^16.8.6 || ^17.0.2 || ^18.0.0", | ||
"react-dom": "^16.8.6 || ^17.0.2 || ^18.0.0" | ||
}, | ||
"devDependencies": { | ||
"@twilio-paste/animation-library": "^2.0.0", | ||
"@twilio-paste/box": "^10.0.0", | ||
"@twilio-paste/color-contrast-utils": "^5.0.0", | ||
"@twilio-paste/customization": "^8.0.0", | ||
"@twilio-paste/design-tokens": "^10.0.0", | ||
"@twilio-paste/icons": "^12.0.0", | ||
"@twilio-paste/label": "^13.0.0", | ||
"@twilio-paste/media-object": "^10.0.0", | ||
"@twilio-paste/react-spectrum-library": "^2.0.0", | ||
"@twilio-paste/screen-reader-only": "^13.0.0", | ||
"@twilio-paste/style-props": "^9.0.0", | ||
"@twilio-paste/styling-library": "^3.0.0", | ||
"@twilio-paste/text": "^10.0.0", | ||
"@twilio-paste/theme": "^11.0.0", | ||
"@twilio-paste/types": "^6.0.0", | ||
"@twilio-paste/uid-library": "^2.0.0", | ||
"@types/react": "^18.0.27", | ||
"@types/react-dom": "^18.0.10", | ||
"prop-types": "^15.7.2", | ||
"react": "^18.0.0", | ||
"react-dom": "^18.0.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import * as React from 'react'; | ||
import {type BoxProps, Box} from '@twilio-paste/box'; | ||
import {Text} from '@twilio-paste/text'; | ||
import type {HTMLPasteProps} from '@twilio-paste/types'; | ||
import {useMeter} from '@twilio-paste/react-spectrum-library'; | ||
|
||
import {LABEL_SUFFIX} from './constants'; | ||
|
||
export interface MeterProps extends HTMLPasteProps<'meter'>, Pick<BoxProps, 'element'> { | ||
minValue?: number; | ||
maxValue?: number; | ||
value?: number; | ||
id: string; | ||
showValueLabel?: boolean; | ||
formatOptions?: Intl.NumberFormatOptions; // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat#options | ||
valueLabel?: string; | ||
'aria-label'?: string; | ||
'aria-describedby'?: string; | ||
'aria-labelledby'?: string; | ||
/* | ||
* The following props don't exist on the react-aria useMeter hook but do exist on the HTML meter element. | ||
* They can be added back into the Paste Meter API depending on the finalized spec & designs. | ||
* | ||
* low?: number; | ||
* high?: number; | ||
* optimum?: number; | ||
*/ | ||
} | ||
|
||
const Meter = React.forwardRef<HTMLMeterElement, MeterProps>(({element = 'METER', id, ...props}, ref) => { | ||
const {value = 0, minValue = 0, maxValue = 100, showValueLabel = true} = props; | ||
const {meterProps} = useMeter(props); | ||
|
||
// Calculate the width of the bar as a percentage | ||
const percentage = (value - minValue) / (maxValue - minValue); | ||
const fillWidth = `${Math.round(percentage * 100)}%`; | ||
|
||
/* | ||
* Since ProgressBar isn't a form element, we cannot use htmlFor from the regular label | ||
* so we create a ProgressBarLabel component that behaves like a regular form Label | ||
* but leverages aria-labelledby instead of htmlFor transparently. | ||
*/ | ||
let labelledBy = props['aria-labelledby']; | ||
if (labelledBy == null && props['aria-label'] == null && id != null) { | ||
labelledBy = `${id}${LABEL_SUFFIX}`; | ||
} | ||
|
||
return ( | ||
<Box | ||
as="div" | ||
{...meterProps} | ||
role="meter" | ||
id={id} | ||
maxWidth="size30" | ||
position="relative" | ||
element={element} | ||
aria-labelledby={labelledBy} | ||
> | ||
<Box | ||
display="flex" | ||
width="fit-content" | ||
position="absolute" | ||
right="0" | ||
top="spaceNegative70" | ||
element={`${element}_VALUE_LABEL_WRAPPER`} | ||
> | ||
{showValueLabel && ( | ||
<Text as="span" element={`${element}_VALUE_LABEL`}> | ||
{meterProps['aria-valuetext']} | ||
</Text> | ||
)} | ||
</Box> | ||
<Box height="10px" backgroundColor="colorBackground" element={`${element}_BAR`} ref={ref}> | ||
<Box width={fillWidth} height="10px" backgroundColor="colorBackgroundAvailable" element={`${element}_FILL`} /> | ||
</Box> | ||
</Box> | ||
); | ||
}); | ||
|
||
Meter.displayName = 'Meter'; | ||
|
||
export {Meter}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import * as React from 'react'; | ||
import {type BoxProps} from '@twilio-paste/box'; | ||
import {Label} from '@twilio-paste/label'; | ||
import type {HTMLPasteProps} from '@twilio-paste/types'; | ||
|
||
import {LABEL_SUFFIX} from './constants'; | ||
|
||
export interface MeterLabelProps extends HTMLPasteProps<'div'>, Pick<BoxProps, 'element'> { | ||
children: string; | ||
htmlFor: string; | ||
} | ||
|
||
const MeterLabel = React.forwardRef<HTMLLabelElement, MeterLabelProps>( | ||
({element = 'METER_LABEL', children, htmlFor, ...labelProps}, ref) => { | ||
return ( | ||
<Label {...labelProps} as="div" element={element} id={`${htmlFor}${LABEL_SUFFIX}`} ref={ref}> | ||
{children} | ||
</Label> | ||
); | ||
} | ||
); | ||
|
||
MeterLabel.displayName = 'MeterLabel'; | ||
|
||
export {MeterLabel}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export const LABEL_SUFFIX = 'METER_LABEL'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './Meter'; | ||
export * from './MeterLabel'; |
Oops, something went wrong.