Skip to content

Commit

Permalink
feat(react-spectrum): add package (#3371)
Browse files Browse the repository at this point in the history
* feat(react-spectrum): add package

* chore: changeset

* fix: folder name typo

* chore: yarn.lock

* fix: codesandbox

* chore: pr review
  • Loading branch information
TheSisb committed Aug 3, 2023
1 parent e1b071c commit c4a70d9
Show file tree
Hide file tree
Showing 15 changed files with 1,930 additions and 181 deletions.
6 changes: 6 additions & 0 deletions .changeset/pretty-needles-accept.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@twilio-paste/core': minor
'@twilio-paste/react-spectrum-library': major
---

[React-Spectrum-Library] Add wrapper around react-spectrum which exposes the `useSlider`, `useSliderThumb`, and `useSliderState` hooks.
1 change: 1 addition & 0 deletions .codesandbox/ci.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
"/packages/paste-core/components/progress-steps",
"/packages/paste-core/components/radio-button-group",
"/packages/paste-core/components/radio-group",
"/packages/paste-libraries/react-spectrum",
"/packages/paste-libraries/react-textarea-autosize",
"/packages/paste-libraries/reakit",
"/packages/paste-core/components/screen-reader-only",
Expand Down
1 change: 1 addition & 0 deletions packages/paste-core/core-bundle/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
/progress-steps
/radio-button-group
/radio-group
/react-spectrum-library
/react-textarea-autosize-library
/reakit-library
/screen-reader-only
Expand Down
1 change: 1 addition & 0 deletions packages/paste-core/core-bundle/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@
"@twilio-paste/progress-steps": "^1.0.0",
"@twilio-paste/radio-button-group": "^3.0.0",
"@twilio-paste/radio-group": "^12.0.0",
"@twilio-paste/react-spectrum-library": "^0.0.0",
"@twilio-paste/react-textarea-autosize-library": "^2.0.0",
"@twilio-paste/reakit-library": "^1.0.0",
"@twilio-paste/screen-reader-only": "^12.0.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from '@twilio-paste/react-spectrum-library';
Empty file.
3 changes: 3 additions & 0 deletions packages/paste-libraries/react-spectrum/build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const {build} = require('../../../tools/build/esbuild');

build(require('./package.json'));
42 changes: 42 additions & 0 deletions packages/paste-libraries/react-spectrum/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"name": "@twilio-paste/react-spectrum-library",
"version": "0.0.0",
"category": "library",
"status": "production",
"description": "React Spectrum Library is a collection of tools that help you build adaptive, accessible, and robust user experiences.",
"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"
},
"dependencies": {
"react-aria": "3.26.0",
"react-stately": "3.24.0"
},
"peerDependencies": {
"@types/react": "^16.8.6 || ^17.0.2 || ^18.0.27",
"@types/react-dom": "^16.8.6 || ^17.0.2 || ^18.0.10",
"react": "^16.8.6 || ^17.0.2 || ^18.0.0",
"react-dom": "^16.8.6 || ^17.0.2 || ^18.0.0"
},
"devDependencies": {
"@types/react": "^18.0.27",
"@types/react-dom": "^18.0.10",
"react": "^18.0.0",
"react-dom": "^18.0.0"
}
}
2 changes: 2 additions & 0 deletions packages/paste-libraries/react-spectrum/src/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './react-aria';
export * from './react-stately';
1 change: 1 addition & 0 deletions packages/paste-libraries/react-spectrum/src/react-aria.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {useSlider, useSliderThumb} from 'react-aria';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {useSliderState, type SliderStateOptions, type SliderState} from 'react-stately';
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import * as React from 'react';
import type {StoryFn, Meta} from '@storybook/react';
import {Box} from '@twilio-paste/box';
import {ScreenReaderOnly} from '@twilio-paste/screen-reader-only';

import {useSliderState, useSlider, useSliderThumb, type SliderStateOptions, type SliderState} from '../src';

// eslint-disable-next-line import/no-default-export
export default {
title: 'Libraries/React-Spectrum/useSlider',
parameters: {},
} as Meta;

interface ThumbProps {
index: number;
state: SliderState;
trackRef: React.RefObject<HTMLDivElement>;
isDisabled?: boolean;
}

const Thumb: React.FC<ThumbProps> = ({state, trackRef, index, isDisabled}) => {
const inputRef = React.useRef(null);
const [focused, setFocused] = React.useState(false);
const {thumbProps, inputProps, isDragging} = useSliderThumb(
{
index,
trackRef,
inputRef,
},
state
);

return (
<Box
{...thumbProps}
backgroundColor={isDisabled ? 'colorBackgroundPrimaryWeak' : 'colorBackgroundPrimaryStrong'}
borderRadius="borderRadiusCircle"
boxShadow={isDragging || focused ? 'shadowFocus' : 'none'}
width="18px"
height="18px"
marginTop="space10"
>
<ScreenReaderOnly>
<input ref={inputRef} {...inputProps} onFocus={() => setFocused(true)} onBlur={() => setFocused(false)} />
</ScreenReaderOnly>
</Box>
);
};

const Slider: React.FC<SliderStateOptions<number | number[]>> = (props) => {
const trackRef = React.useRef(null);
const state = useSliderState(props);
const {groupProps, trackProps, labelProps, outputProps} = useSlider(props, state, trackRef);

return (
<Box {...groupProps} className={`slider ${state.orientation}`}>
{/* Create a container for the label and output element. */}
{props.label && (
<div className="label-container">
<label {...labelProps}>{props.label}</label>
<output {...outputProps}>{state.getThumbValueLabel(0)}</output>
</div>
)}
{/* The track element holds the visible track line and the thumb. */}
<Box {...trackProps} ref={trackRef} height="13px" width="100%" display="flex" alignItems="center">
<Box
backgroundColor={props.isDisabled ? 'colorBackgroundPrimaryWeak' : 'colorBackgroundPrimary'}
height="4px"
width="100%"
borderRadius="borderRadius20"
>
<Thumb index={0} state={state} trackRef={trackRef} isDisabled={props.isDisabled} />
</Box>
</Box>
</Box>
);
};

export const Default: StoryFn = () => {
return <Slider label="Opacity" numberFormatter={new Intl.NumberFormat()} />;
};

export const Disabled: StoryFn = () => {
return <Slider isDisabled value={42} label="Opacity" numberFormatter={new Intl.NumberFormat()} />;
};
8 changes: 8 additions & 0 deletions packages/paste-libraries/react-spectrum/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "../../../tsconfig.json",
"compilerOptions": {
"outDir": "dist/"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "__tests__"]
}
2 changes: 1 addition & 1 deletion tools/build/esbuild.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ async function build(packageJson) {
* Sets the target environment so the code is changed into a format that
* works with node12 and the listed browsers
*/
target: ['chrome66', 'firefox58', 'safari11', 'edge79', 'node12.19.0'],
target: ['chrome100', 'firefox100', 'safari14', 'edge100', 'node18.16.0'],
define: {
'process.env.NODE_ENV': `"${process.env.NODE_ENV}"`,
},
Expand Down
Loading

0 comments on commit c4a70d9

Please sign in to comment.