From 93c636e4ce100b6f8ba6e544c26a3a4492199918 Mon Sep 17 00:00:00 2001 From: Mengying Fan Date: Thu, 7 Mar 2024 11:53:18 +0200 Subject: [PATCH 1/3] Tooltip for range slider --- .../control-range/control-range.tsx | 53 ++++++++++++++++--- .../examples/control-range-example-style.tsx | 1 + 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/src/components/control-range/control-range.tsx b/src/components/control-range/control-range.tsx index afe30f6..503e164 100644 --- a/src/components/control-range/control-range.tsx +++ b/src/components/control-range/control-range.tsx @@ -1,10 +1,13 @@ -import React, {ReactElement, ReactNode} from 'react'; +import React, { ReactElement, ReactNode } from 'react'; import * as SliderPrimitive from '@radix-ui/react-slider'; +import * as TooltipPrimitive from '@radix-ui/react-tooltip'; + import PropTypes from 'prop-types'; import omit from '../utils/omit'; import ControlLabel from '../control-label'; import ControlWrapper from '../control-wrapper'; import { InputProps } from '../typings'; +import { getTheme } from '../utils/styles'; const propNames = [ 'id', @@ -24,7 +27,7 @@ const propNames = [ 'validator' ]; -interface Props extends Omit{ +interface Props extends Omit { id: string; onChange: (value: Array, id: string) => void; value?: Array; @@ -39,6 +42,7 @@ interface Props extends Omit{ themeControlThumb?: string; themeControlWrapper?: string; themeLabel?: string; + themeTooltipColoring?: 'light' | 'dark' | 'warning' | 'error'; } export default function ControlRange({ @@ -56,9 +60,9 @@ export default function ControlRange({ themeControlThumb = '', themeControlWrapper, themeLabel, + themeTooltipColoring = 'light', ...props }: Props): ReactElement { - const extraProps = omit(props, propNames); const rootProps = { @@ -76,7 +80,40 @@ export default function ControlRange({ } const renderThumb = (value: number, index: number) => { - return + if (tooltip) { + const { background, borderColor, color, fill, shadowColor } = + getTheme(themeTooltipColoring); + const tooltipClasses = `${background} ${borderColor} ${color} border round txt-s px12 py6 wmax240`; + return ( + + + + + + + {value} + + + + + ); + } + return ( + + ); }; return ( @@ -97,7 +134,9 @@ export default function ControlRange({
- + {value.map(renderThumb)} @@ -134,5 +173,7 @@ ControlRange.propTypes = { /** Assembly classes to apply to the control wrapper */ themeControlWrapper: PropTypes.string, /** Assembly classes to apply to the label element */ - themeLabel: PropTypes.string + themeLabel: PropTypes.string, + /** `'light'`, `'dark'`, `'warning'`, or `'error'`. */ + themeTooltipColoring: PropTypes.oneOf(['light', 'dark', 'warning', 'error']) }; diff --git a/src/components/control-range/examples/control-range-example-style.tsx b/src/components/control-range/examples/control-range-example-style.tsx index c338430..dd051ae 100644 --- a/src/components/control-range/examples/control-range-example-style.tsx +++ b/src/components/control-range/examples/control-range-example-style.tsx @@ -19,6 +19,7 @@ export default function Example() { themeControlRangeActive='bg-blue round' themeControlTrack='bg-gray h3' themeControlThumb='bg-blue border--0 h12 w12 shadow-darken25' + themeTooltipColoring='dark' /> ); } From 49faa3512aef0d910208415b9d378b75b1c43e03 Mon Sep 17 00:00:00 2001 From: Mengying Fan Date: Thu, 7 Mar 2024 11:58:50 +0200 Subject: [PATCH 2/3] Bump version --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 334fc42..2a75181 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@mapbox/mr-ui", - "version": "2.9.0", + "version": "2.9.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@mapbox/mr-ui", - "version": "2.9.0", + "version": "2.9.1", "license": "BSD-2-Clause", "dependencies": { "@mapbox/mbx-assembly": "^1.5.0", diff --git a/package.json b/package.json index 75b3d60..d5b978b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mapbox/mr-ui", - "version": "2.9.0", + "version": "2.9.1", "description": "UI components for Mapbox projects", "main": "index.js", "homepage": "./", From b5cc93cde077e05ba6e82bb9ff1643968c91961a Mon Sep 17 00:00:00 2001 From: Mengying Fan Date: Thu, 7 Mar 2024 12:09:13 +0200 Subject: [PATCH 3/3] test --- .../control-range/control-range.test.tsx | 47 +++++++++++++++---- .../control-range/control-range.tsx | 4 +- 2 files changed, 41 insertions(+), 10 deletions(-) diff --git a/src/components/control-range/control-range.test.tsx b/src/components/control-range/control-range.test.tsx index c5de7c9..ae7bdb8 100644 --- a/src/components/control-range/control-range.test.tsx +++ b/src/components/control-range/control-range.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import ControlRange from './control-range'; -import { render } from '@testing-library/react'; -// import userEvent from '@testing-library/user-event'; +import { render, screen, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; describe('ControlRange', () => { describe('basic', () => { @@ -9,10 +9,10 @@ describe('ControlRange', () => { const props = { id: 'testinput', onChange: mockOnChange - } + }; test('renders', () => { - const { baseElement } = render() + const { baseElement } = render(); expect(baseElement).toMatchSnapshot(); }); }); @@ -23,10 +23,10 @@ describe('ControlRange', () => { id: 'testinput', onChange: mockOnChange, disabled: true - } + }; test('renders', () => { - const { baseElement } = render() + const { baseElement } = render(); expect(baseElement).toMatchSnapshot(); }); }); @@ -49,11 +49,42 @@ describe('ControlRange', () => { themeControlWrapper: 'bg-red-light', themeLabel: 'txt-s txt-bold color-white', onChange: mockOnChange - } + }; test('renders', () => { - const { baseElement } = render() + const { baseElement } = render(); expect(baseElement).toMatchSnapshot(); }); }); + + describe('tooltip', () => { + const mockOnChange = jest.fn(); + window.HTMLElement.prototype.hasPointerCapture = jest.fn(); + const props = { + id: 'testinput', + label: 'All options', + validationError: 'oh no!', + value: [200], + min: 100, + max: 1000, + step: 100, + optional: true, + autoFocus: true, + aside: Aside text, + themeControlRange: 'range--s range--red', + themeControlRangeActive: 'bg-red-dark', + themeControlWrapper: 'bg-red-light', + themeLabel: 'txt-s txt-bold color-white', + tooltip: true, + onChange: mockOnChange + }; + test('renders', async () => { + render(); + await userEvent.hover(screen.getByRole('slider')); + + await waitFor(() => { + expect(screen.getByRole('tooltip')).toBeInTheDocument(); + }); + }); + }); }); diff --git a/src/components/control-range/control-range.tsx b/src/components/control-range/control-range.tsx index 503e164..4670be9 100644 --- a/src/components/control-range/control-range.tsx +++ b/src/components/control-range/control-range.tsx @@ -85,8 +85,8 @@ export default function ControlRange({ getTheme(themeTooltipColoring); const tooltipClasses = `${background} ${borderColor} ${color} border round txt-s px12 py6 wmax240`; return ( - - + +