From 554c2300695839c29fd17717ecddb3732e32e111 Mon Sep 17 00:00:00 2001
From: Nora Krantz <75342690+nkrantz@users.noreply.github.com>
Date: Thu, 7 Sep 2023 17:28:59 -0400
Subject: [PATCH] chore(meter): add docs, update designs (#3463)
---
.changeset/blue-phones-battle.md | 6 +
.changeset/olive-lizards-enjoy.md | 5 +
cypress/integration/sitemap-vrt/constants.ts | 1 +
.../components/meter/__tests__/index.spec.tsx | 32 ++-
.../paste-core/components/meter/package.json | 2 +-
.../paste-core/components/meter/src/Meter.tsx | 126 ++++++----
.../components/meter/src/MeterLabel.tsx | 33 ++-
.../meter/stories/index.stories.tsx | 186 +++++++++++---
packages/paste-website/package.json | 1 +
.../src/component-examples/MeterExamples.ts | 35 +++
.../src/pages/components/meter/index.mdx | 233 ++++++++++++++++++
.../src/pages/components/slider/index.mdx | 53 ++--
yarn.lock | 1 +
13 files changed, 571 insertions(+), 143 deletions(-)
create mode 100644 .changeset/blue-phones-battle.md
create mode 100644 .changeset/olive-lizards-enjoy.md
create mode 100644 packages/paste-website/src/component-examples/MeterExamples.ts
create mode 100644 packages/paste-website/src/pages/components/meter/index.mdx
diff --git a/.changeset/blue-phones-battle.md b/.changeset/blue-phones-battle.md
new file mode 100644
index 0000000000..416433d473
--- /dev/null
+++ b/.changeset/blue-phones-battle.md
@@ -0,0 +1,6 @@
+---
+'@twilio-paste/meter': patch
+'@twilio-paste/core': patch
+---
+
+[Meter] Finalize designs of Meter component, bump to Production status, and add documentation.
diff --git a/.changeset/olive-lizards-enjoy.md b/.changeset/olive-lizards-enjoy.md
new file mode 100644
index 0000000000..2c2322a319
--- /dev/null
+++ b/.changeset/olive-lizards-enjoy.md
@@ -0,0 +1,5 @@
+---
+'@twilio-paste/codemods': patch
+---
+
+[Codemods] New export from Meter package: MeterLabel
diff --git a/cypress/integration/sitemap-vrt/constants.ts b/cypress/integration/sitemap-vrt/constants.ts
index 24bbe3ed67..f4ffb42c6f 100644
--- a/cypress/integration/sitemap-vrt/constants.ts
+++ b/cypress/integration/sitemap-vrt/constants.ts
@@ -60,6 +60,7 @@ export const SITEMAP = [
'/components/list/',
'/components/minimizable-dialog/',
'/components/media-object/',
+ '/components/meter',
'/components/pagination/',
'/components/modal/',
'/components/menu/',
diff --git a/packages/paste-core/components/meter/__tests__/index.spec.tsx b/packages/paste-core/components/meter/__tests__/index.spec.tsx
index b6f1d08d51..7a91e382c5 100644
--- a/packages/paste-core/components/meter/__tests__/index.spec.tsx
+++ b/packages/paste-core/components/meter/__tests__/index.spec.tsx
@@ -3,7 +3,7 @@ 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';
+import {Default, AriaLabel, Customized} from '../stories/index.stories';
const ThemeWrapper: RenderOptions['wrapper'] = ({children}) => (
{children}
@@ -21,14 +21,14 @@ describe('Meter', () => {
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');
+ expect(meter).toHaveAttribute('id');
+ expect(meter).toHaveAttribute('aria-labelledby');
});
it('should apply aria-label correctly', () => {
- render(, {wrapper: ThemeWrapper});
+ render(, {wrapper: ThemeWrapper});
const meter = screen.getByRole('meter');
- expect(meter).toHaveAttribute('aria-label', 'Fuel level');
+ expect(meter).toHaveAttribute('aria-label', 'Storage space');
expect(meter).not.toHaveAttribute('aria-labelledby');
});
});
@@ -36,18 +36,32 @@ describe('Meter', () => {
describe('Customization', () => {
it('should set default data-paste-element attribute on meter', () => {
render();
- const meterOne = screen.getByTestId('meter_one');
- expect(meterOne).toHaveAttribute(elementAttr, 'METER');
const meterLabelOne = screen.getByTestId('meter_label_one');
expect(meterLabelOne).toHaveAttribute(elementAttr, 'METER_LABEL');
+ expect(meterLabelOne.parentElement).toHaveAttribute(elementAttr, 'METER_LABEL_WRAPPER');
+ expect(meterLabelOne.nextElementSibling).toHaveAttribute(elementAttr, 'METER_LABEL_VALUE_LABEL');
+ const meterOne = screen.getByTestId('meter_one');
+ expect(meterOne).toHaveAttribute(elementAttr, 'METER');
+ expect(meterOne.firstElementChild).toHaveAttribute(elementAttr, 'METER_BAR');
+ expect(meterOne.firstElementChild?.firstElementChild).toHaveAttribute(elementAttr, 'METER_FILL');
+ expect(meterOne.lastElementChild).toHaveAttribute(elementAttr, 'METER_MIN_MAX_WRAPPER');
+ expect(meterOne.lastElementChild?.firstElementChild).toHaveAttribute(elementAttr, 'METER_MIN');
+ expect(meterOne.lastElementChild?.lastElementChild).toHaveAttribute(elementAttr, 'METER_MAX');
});
it('should set custom data-paste-element attribute on meter', () => {
render();
- const meterTwo = screen.getByTestId('meter_two');
- expect(meterTwo).toHaveAttribute(elementAttr, 'FOO');
const meterLabelTwo = screen.getByTestId('meter_label_two');
expect(meterLabelTwo).toHaveAttribute(elementAttr, 'FOO_LABEL');
+ expect(meterLabelTwo.parentElement).toHaveAttribute(elementAttr, 'FOO_LABEL_WRAPPER');
+ expect(meterLabelTwo.nextElementSibling).toHaveAttribute(elementAttr, 'FOO_LABEL_VALUE_LABEL');
+ const meterTwo = screen.getByTestId('meter_two');
+ expect(meterTwo).toHaveAttribute(elementAttr, 'FOO');
+ expect(meterTwo.firstElementChild).toHaveAttribute(elementAttr, 'FOO_BAR');
+ expect(meterTwo.firstElementChild?.firstElementChild).toHaveAttribute(elementAttr, 'FOO_FILL');
+ expect(meterTwo.lastElementChild).toHaveAttribute(elementAttr, 'FOO_MIN_MAX_WRAPPER');
+ expect(meterTwo.lastElementChild?.firstElementChild).toHaveAttribute(elementAttr, 'FOO_MIN');
+ expect(meterTwo.lastElementChild?.lastElementChild).toHaveAttribute(elementAttr, 'FOO_MAX');
});
});
});
diff --git a/packages/paste-core/components/meter/package.json b/packages/paste-core/components/meter/package.json
index 00bc19dd31..578536ea37 100644
--- a/packages/paste-core/components/meter/package.json
+++ b/packages/paste-core/components/meter/package.json
@@ -2,7 +2,7 @@
"name": "@twilio-paste/meter",
"version": "1.0.0",
"category": "data display",
- "status": "alpha",
+ "status": "production",
"description": "Meter is a visual representation of a numerical value within a known range.",
"author": "Twilio Inc.",
"license": "MIT",
diff --git a/packages/paste-core/components/meter/src/Meter.tsx b/packages/paste-core/components/meter/src/Meter.tsx
index 8439ba73d7..348f6b3a36 100644
--- a/packages/paste-core/components/meter/src/Meter.tsx
+++ b/packages/paste-core/components/meter/src/Meter.tsx
@@ -9,73 +9,93 @@ import {LABEL_SUFFIX} from './constants';
export interface MeterProps extends HTMLPasteProps<'meter'>, Pick {
minValue?: number;
maxValue?: number;
+ minLabel?: string;
+ maxLabel?: string;
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(({element = 'METER', id, ...props}, ref) => {
- const {value = 0, minValue = 0, maxValue = 100, showValueLabel = true} = props;
- const {meterProps} = useMeter(props);
+const Meter = React.forwardRef(
+ ({element = 'METER', id, minLabel, maxLabel, ...props}, ref) => {
+ const {value = 0, minValue = 0, maxValue = 100} = 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)}%`;
+ // 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}`;
- }
+ /*
+ * Since Meter isn't a form element, we cannot use htmlFor from the regular Label
+ * so we created a MeterLabel component that behaves like a regular form Label
+ * but leverages aria-labelledby instead of htmlFor under the hood.
+ * `aria-labelledby` and `aria-label` can still be passed for custom labelling options.
+ */
+ let labelledBy = props['aria-labelledby'];
+ if (labelledBy == null && props['aria-label'] == null && id != null) {
+ labelledBy = `${id}${LABEL_SUFFIX}`;
+ }
- return (
-
+ return (
- {showValueLabel && (
-
- {meterProps['aria-valuetext']}
-
+
+
+
+ {(minLabel || maxLabel) && (
+
+ {minLabel ? (
+
+ {minLabel}
+
+ ) : (
+
+ )}
+ {maxLabel ? (
+
+ {maxLabel}
+
+ ) : (
+
+ )}
+
)}
-
-
-
-
- );
-});
+ );
+ }
+);
Meter.displayName = 'Meter';
diff --git a/packages/paste-core/components/meter/src/MeterLabel.tsx b/packages/paste-core/components/meter/src/MeterLabel.tsx
index 1f3a5100f4..7f8a3cb57b 100644
--- a/packages/paste-core/components/meter/src/MeterLabel.tsx
+++ b/packages/paste-core/components/meter/src/MeterLabel.tsx
@@ -1,6 +1,7 @@
import * as React from 'react';
-import {type BoxProps} from '@twilio-paste/box';
+import {type BoxProps, Box} from '@twilio-paste/box';
import {Label} from '@twilio-paste/label';
+import {Text} from '@twilio-paste/text';
import type {HTMLPasteProps} from '@twilio-paste/types';
import {LABEL_SUFFIX} from './constants';
@@ -8,14 +9,36 @@ import {LABEL_SUFFIX} from './constants';
export interface MeterLabelProps extends HTMLPasteProps<'div'>, Pick {
children: string;
htmlFor: string;
+ valueLabel?: string;
}
const MeterLabel = React.forwardRef(
- ({element = 'METER_LABEL', children, htmlFor, ...labelProps}, ref) => {
+ ({element = 'METER_LABEL', children, htmlFor, valueLabel, ...labelProps}, ref) => {
return (
-
+
+
+ {valueLabel && (
+
+ {valueLabel}
+
+ )}
+
);
}
);
diff --git a/packages/paste-core/components/meter/stories/index.stories.tsx b/packages/paste-core/components/meter/stories/index.stories.tsx
index 6f6368352c..ca1d60e9db 100644
--- a/packages/paste-core/components/meter/stories/index.stories.tsx
+++ b/packages/paste-core/components/meter/stories/index.stories.tsx
@@ -2,6 +2,7 @@ import {CustomizationProvider} from '@twilio-paste/customization';
import {useTheme} from '@twilio-paste/theme';
import {useUID} from '@twilio-paste/uid-library';
import {HelpText} from '@twilio-paste/help-text';
+import {Box} from '@twilio-paste/box';
import * as React from 'react';
import {Meter, MeterLabel} from '../src';
@@ -13,38 +14,94 @@ export default {
};
export const Default = (): React.ReactElement => {
- const meterId = 'meter';
+ const meterId = useUID();
return (
- <>
- Storage space
+
+
+ Storage used
+
- >
+
+ );
+};
+
+export const Full = (): React.ReactElement => {
+ const meterId = useUID();
+ return (
+
+
+ Storage used
+
+
+
+ );
+};
+
+export const Empty = (): React.ReactElement => {
+ const meterId = useUID();
+ return (
+
+
+ Storage used
+
+
+
);
};
-export const HiddenValueLabelAriaLabel = (): React.ReactElement => {
+export const MinMax = (): React.ReactElement => {
const meterId = useUID();
- return ;
+ return (
+
+
+ Storage space used
+
+
+
+ );
};
-export const FormattedValueLabel = (): React.ReactElement => {
+export const MinOnly = (): React.ReactElement => {
const meterId = useUID();
return (
- <>
- Account funds
-
- >
+
+
+ Storage space
+
+
+
);
};
-export const CustomValueLabelCustomLabel = (): React.ReactElement => {
+export const MaxOnly = (): React.ReactElement => {
+ const meterId = useUID();
+ return (
+
+
+ Storage space
+
+
+
+ );
+};
+
+export const AriaLabel = (): React.ReactElement => {
+ const meterId = useUID();
+ return (
+
+
+
+ );
+};
+
+export const CustomLabel = (): React.ReactElement => {
const labelId = useUID();
const meterId = useUID();
return (
- <>
+
-
- >
+
+
);
};
@@ -52,11 +109,35 @@ export const WithHelpText = (): React.ReactElement => {
const meterId = useUID();
const helpTextId = useUID();
return (
- <>
- Storage space used
-
+
+
+ Storage space used
+
+
+ Additional storage may be purchased on your account page.
+
+ );
+};
+
+export const Wrapped = (): React.ReactElement => {
+ const meterId = useUID();
+ const helpTextId = useUID();
+ return (
+
+
+ Storage space used on this account that belongs to you
+
+ Helpful text
- >
+
);
};
@@ -68,39 +149,70 @@ export const Customized = (): React.ReactElement => {
-
- Storage space
-
-
-
- Storage space
-
-
+
+
+
+ Storage space
+
+
+
+
+
+ Storage space
+
+
+
+
);
};
diff --git a/packages/paste-website/package.json b/packages/paste-website/package.json
index 47cbf867e8..03540aa86e 100644
--- a/packages/paste-website/package.json
+++ b/packages/paste-website/package.json
@@ -83,6 +83,7 @@
"@twilio-paste/media-object": "^10.0.0",
"@twilio-paste/menu": "^14.0.1",
"@twilio-paste/menu-primitive": "^2.0.0",
+ "@twilio-paste/meter": "^1.0.0",
"@twilio-paste/minimizable-dialog": "^4.0.0",
"@twilio-paste/modal": "^16.0.0",
"@twilio-paste/modal-dialog-primitive": "^2.0.0",
diff --git a/packages/paste-website/src/component-examples/MeterExamples.ts b/packages/paste-website/src/component-examples/MeterExamples.ts
new file mode 100644
index 0000000000..1792566ac5
--- /dev/null
+++ b/packages/paste-website/src/component-examples/MeterExamples.ts
@@ -0,0 +1,35 @@
+export const defaultMeter = `
+const DefaultMeterExample = () => {
+ const meterId = useUID()
+ const helpTextId = useUID()
+ return (
+
+ Emails delivered
+
+ Showing successful deliveries of June email campaign.
+
+ );
+};
+
+render(
+
+)
+`.trim();
+
+export const minMaxMeter = `
+const DefaultMeterExample = () => {
+ const meterId = useUID()
+ const helpTextId = useUID()
+ return (
+
+ Account balance paid
+
+ Remaining balance must be paid by the end of the billing period.
+
+ );
+};
+
+render(
+
+)
+`.trim();
diff --git a/packages/paste-website/src/pages/components/meter/index.mdx b/packages/paste-website/src/pages/components/meter/index.mdx
new file mode 100644
index 0000000000..e20f08fd61
--- /dev/null
+++ b/packages/paste-website/src/pages/components/meter/index.mdx
@@ -0,0 +1,233 @@
+export const meta = {
+ title: 'Meter',
+ package: '@twilio-paste/meter',
+ description: 'Meter is a visual representation of a numerical value within a known range.',
+ slug: '/components/meter/',
+};
+
+import {Box} from '@twilio-paste/box';
+import {Meter, MeterLabel} from '@twilio-paste/meter';
+import {HelpText} from '@twilio-paste/help-text';
+import {useUID} from '@twilio-paste/uid-library';
+import Changelog from '@twilio-paste/meter/CHANGELOG.md';
+import packageJson from '@twilio-paste/meter/package.json';
+
+import DefaultLayout from '../../../layouts/DefaultLayout';
+import {SidebarCategoryRoutes} from '../../../constants';
+import {getFeature, getNavigationData} from '../../../utils/api';
+import {DoDont, Do, Dont} from '../../../components/DoDont';
+import {defaultMeter, minMaxMeter, hiddenValueLabel} from '../../../component-examples/MeterExamples';
+
+export default DefaultLayout;
+
+export const getStaticProps = async () => {
+ const navigationData = await getNavigationData();
+ const feature = await getFeature('Meter');
+ return {
+ props: {
+ data: {
+ ...packageJson,
+ ...feature,
+ },
+ navigationData,
+ },
+ };
+};
+
+
+
+---
+
+
+
+
+
+
+
+
+ {defaultMeter}
+
+
+## Guidelines
+
+### About Meter
+
+A Meter is a visual representation to indicate how full something is.
+
+### Meter vs. Progress Bar
+
+A Meter represents a bucket that can be empty, full, or somewhere in between. Use a Meter when you need to show capacity. For example, use a Meter to show how much data is being used or how many emails were sent successfully.
+
+A [Progress Bar](/components/progress-bar) represents **only** task completion, like a file upload or filling out a form. If you’re not displaying progress on a particular task, use a Meter.
+
+### Accessibility
+
+A label is required when using Meter. Use one of these options:
+
+- Visible label using `MeterLabel`, with `htmlFor` set equal to the `id` of the Meter (preferred)
+- Visible label that's associated to the Meter with `aria-labelledby`
+- Label directly using `aria-label`
+
+## Examples
+
+### Default
+
+Use a Meter to communicate an amount of something within a range, like number of emails delivered. Use the `valueLabel` prop on the `MeterLabel` component to display the current value being represented by the Meter.
+
+Consider what type of value would be most useful for a user to see (for example, “50%” vs. “5,000 of 10,000”). Avoid using multiple formats to represent the same value (for example, "5,000 of 10,000 (50%)").
+
+
+ {defaultMeter}
+
+
+### Min and max values
+
+Meter has a default value of 0, a default minimum value of 0, and a default maximum value of 100.
+
+Passing `minValue` and `maxValue` to Meter allow you to set a non 0-100 scale. Use `minLabel` and `maxLabel` to display minimum and maximum values below the Meter. If using a non 0-100 scale, displaying min and max labels is required.
+
+
+ {minMaxMeter}
+
+
+## Composition notes
+
+The Meter label should communicate what the Meter is measuring. Where possible, avoid a label that wraps onto two lines.
+
+A Meter almost always will include a numerical value, the value label. When using the `valueLabel` prop, consider what type of value would be most useful for a user to see. For example, choose either “50%” or “5,000 of 10,000”, not both.
+
+Use Help Text to offer additional information to contextualize or help the user understand the Meter.
+
+## When to use a Meter
+
+
+
+
+ Data usage
+
+
+
+
+
+ File upload status
+
+
+
+
+
+
+
+
+
+ Balance
+
+
+ Complete balance due at the end of the billing cycle.
+
+
+
+
+
+ Balance
+
+
+ Complete balance of $1,500 due at the end of the billing cycle.
+
+
+
+
+## Usage Guide
+
+### API
+
+#### Installation
+
+```bash
+yarn add @twilio-paste/core - or - yarn add @twilio-paste/meter
+```
+
+#### Usage
+
+```jsx
+import {Meter, MeterLabel} from '@twilio-paste/core/meter';
+import {HelpText} from '@twilio-paste/core/help-text'
+import {useUID} from '@twilio-paste/core/uid-library'
+
+const Component = () => {
+ const meterId = useUID();
+ const helpTextId = useUID(); // Help text is optional
+
+ return (
+ <>
+ Label
+
+ Help text
+ >
+ );
+};
+```
+
+#### Meter props
+
+| Prop | Type | Description | Default |
+| ----------------- | -------- | -------------------------------------------------------------------------------------------------- | ------- |
+| id | `string` | Must provide an ID to match with a label | |
+| aria-describedby? | `string` | Optional ID to pair the Meter to its help text | |
+| aria-labelledby? | `string` | Optional ID to pair the Meter to its label text (if not using a regular MeterLabel with `htmlFor`) | |
+| aria-label? | `string` | Label text of the Meter (if not using a regular MeterLabel with `htmlFor` or `aria-labelledby`) | |
+| minValue? | `number` | Minimum value of the Meter | 0 |
+| maxValue? | `number` | Maximum valuae of the Meter | 100 |
+| value? | `number` | The current value | 0 |
+| minLabel? | `string` | Label displayed for min value. Only shown when this prop is passed. | |
+| maxLabel? | `string` | Label displayed for max value. Only shown when this prop is passed. | |
+| element? | `string` | Overrides the default element name to apply unique styles with the Customization Provider | 'METER' |
+
+#### MeterLabel props
+
+| Prop | Type | Description | Default |
+| ----------- | -------- | ----------------------------------------------------------------------------------------- | ------------- |
+| valueLabel? | `string` | Custom value label of the Meter | |
+| children | `string` | Label text | |
+| htmlFor | `string` | Pass the id of the associated Meter | |
+| element? | `string` | Overrides the default element name to apply unique styles with the Customization Provider | 'METER_LABEL' |
+
+
+
+
+
+
+
+
diff --git a/packages/paste-website/src/pages/components/slider/index.mdx b/packages/paste-website/src/pages/components/slider/index.mdx
index 3aa4f604f9..0ddd81b7dc 100644
--- a/packages/paste-website/src/pages/components/slider/index.mdx
+++ b/packages/paste-website/src/pages/components/slider/index.mdx
@@ -18,6 +18,7 @@ import {Label} from '@twilio-paste/label';
import {HelpText} from '@twilio-paste/help-text';
import {Form, FormControl} from '@twilio-paste/form';
import {useUID} from '@twilio-paste/uid-library';
+import {Meter, MeterLabel} from '@twilio-paste/meter';
import DefaultLayout from '../../../layouts/DefaultLayout';
import {SidebarCategoryRoutes} from '../../../constants';
@@ -80,7 +81,7 @@ A Slider allows a user to select a numerical value when:
Slider uses [Adobe's Spectrum React-Aria useSlider](https://react-spectrum.adobe.com/react-aria/useSlider.html) under the hood.
-### Slider vs. number Input vs. Meter
+### Slider vs. number Input
Both Sliders and [number Inputs](/components/input#input-with-number-functionality) are form
fields that take numerical values. Because the mouse and touch interaction on a Slider is less
@@ -91,10 +92,6 @@ If the user needs to select an exact value, use a [number Input](/components/inp
instead. If you want to let users select between consecutive values, you can
also use a [Radio Button Group](/components/radio-button-group).
-In cases where visually showing the size of a numerical value is important and
-it’s not enough to show it as text, use a [number Input](/components/input#input-with-number-functionality)
-paired with a Meter (component to come!) instead.
-
### Accessibility
Slider is a form element and follows the same accessibility guidelines as other form fields:
@@ -138,9 +135,6 @@ For additional guidance on how to compose error messages, refer to the
Use a disabled Slider to show users that they can't interact with the Slider.
-If you want to show a value that can't be edited, use a Meter (to come) or
-consider another way of showing static information.
-
{disabledSlider}
@@ -214,10 +208,19 @@ Use a Slider with hidden range labels when the range is obvious or the labels ar
- Coming soon!
+
+ Current balance
+
+
-
+
-
-
- Coming soon!
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
{
| id | `string` | Must provide an id to match with a label | undefined |
| numberFormatter | [`Intl.NumberFormatter`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat) | Used to format the value into i18n formats. Can return localized currencies and percentages | |
| aria-describedby? | `string` | Optional id to pair the input to its help text | undefined |
-| aria-labeledby? | `string` | Optional id to pair the input to its label text (if not using a regular label with `htmlFor`) | undefined |
+| aria-labelledby? | `string` | Optional id to pair the input to its label text (if not using a regular label with `htmlFor`) | undefined |
| disabled? | `boolean` | Disables the slider | false |
| hasError? | `boolean` | Shows error styling on the Slider | false |
| hideRangeLabels? | `boolean` | Hides the min and max values that appear over the slider | false |
diff --git a/yarn.lock b/yarn.lock
index 14b44b0fac..91478d3aa6 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -17010,6 +17010,7 @@ __metadata:
"@twilio-paste/media-object": ^10.0.0
"@twilio-paste/menu": ^14.0.1
"@twilio-paste/menu-primitive": ^2.0.0
+ "@twilio-paste/meter": ^1.0.0
"@twilio-paste/minimizable-dialog": ^4.0.0
"@twilio-paste/modal": ^16.0.0
"@twilio-paste/modal-dialog-primitive": ^2.0.0