Skip to content

Commit

Permalink
refactor(slider): ♻️ update slider state & track handlers (#278)
Browse files Browse the repository at this point in the history
  • Loading branch information
navin-moorthy authored Nov 26, 2021
1 parent b97630a commit a12c676
Show file tree
Hide file tree
Showing 37 changed files with 1,524 additions and 1,615 deletions.
2 changes: 1 addition & 1 deletion .storybook/preview-body.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
height: 100%;
}
body {
font-family: "Inter", system-ui, -apple-system, BlinkMacSystemFont,
font-family: "Inter var", system-ui, -apple-system, BlinkMacSystemFont,
"Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif,
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol",
"Noto Color Emoji";
Expand Down
2 changes: 1 addition & 1 deletion .storybook/preview-head.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
<link
rel="stylesheet"
crossorigin="anonymous"
href="https://fonts.googleapis.com/css2?family=Inter&display=swap"
href="https://rsms.me/inter/inter.css"
/>
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,17 @@
"@radix-ui/popper": "^0.1.0",
"@radix-ui/react-use-rect": "^0.1.1",
"@radix-ui/react-use-size": "^0.1.0",
"@react-aria/focus": "^3.5.0",
"@react-aria/i18n": "^3.3.2",
"@react-aria/interactions": "^3.6.0",
"@react-aria/slider": "^3.0.3",
"@react-aria/spinbutton": "^3.0.1",
"@react-aria/utils": "^3.9.0",
"@react-stately/slider": "^3.0.3",
"@react-types/slider": "^3.0.2",
"date-fns": "^2.26.0",
"framer-motion": "^5.3.1",
"raf": "^3.4.1",
"react-remove-scroll": "^2.4.3",
"react-spring": "^9.3.1",
"reakit-system": "^0.15.2",
"reakit-utils": "^0.15.2",
"reakit-warning": "^0.6.2"
Expand Down
2 changes: 1 addition & 1 deletion src/number-input/__keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ export const USE_NUMBERINPUT_STATE_KEYS = [
"isDisabled",
"isReadOnly",
"value",
"step",
"min",
"max",
"step",
"keepWithinRange",
"precision",
"isInvalid",
Expand Down
172 changes: 172 additions & 0 deletions src/slider/SliderBaseState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
import { useNumberFormatter } from "@react-aria/i18n";
import { useSliderState } from "@react-stately/slider";

export interface SliderBaseState {
/**
* Values managed by the slider by thumb index.
*/
values: number[];

/**
* Currently-focused thumb index.
*/
focusedThumb: number | undefined;

/**
* The slider's step value.
* @default 1
*/
step: number;

/** Whether the whole Slider is disabled. */
isDisabled: boolean;
}

export interface SliderBaseAction {
/**
* Get Thumb value based on its index
* @param index
*/
getThumbValue(index: number): number;

/**
* Sets the value for the specified thumb.
* The actual value set will be clamped and rounded according to min/max/step.
* @param index
* @param value
*/
setThumbValue(index: number, value: number): void;

/**
* Sets value for the specified thumb by percent offset (between 0 and 1).
* @param index
* @param percent
*/
setThumbPercent(index: number, percent: number): void;

/**
* Whether the specific thumb is being dragged.
* @param index
*/
isThumbDragging(index: number): boolean;

/**
* Set is dragging on the specified thumb.
* @param index
* @param dragging
*/
setThumbDragging(index: number, dragging: boolean): void;

/**
* Set focused true on specified thumb. This will remove focus from
* any thumb that had it before.
* @param index
*/
setFocusedThumb(index: number | undefined): void;

/**
* Returns the specified thumb's value as a percentage from 0 to 1.
* @param index
*/
getThumbPercent(index: number): number;

/**
* Returns the value as a percent between the min and max of the slider.
* @param index
*/
getValuePercent(value: number): number;

/**
* Returns the string label for the specified thumb's value, per props.formatOptions.
* @param index
*/
getThumbValueLabel(index: number): string;

/**
* Returns the string label for the value, per props.formatOptions.
* @param index
*/
getFormattedValue(value: number): string;

/**
* Returns the min allowed value for the specified thumb.
* @param index
*/
getThumbMinValue(index: number): number;

/**
* Returns the max allowed value for the specified thumb.
* @param index
*/
getThumbMaxValue(index: number): number;

/**
* Converts a percent along track (between 0 and 1) to the corresponding value.
* @param percent
*/
getPercentValue(percent: number): number;

/**
* Returns if the specified thumb is editable.
* @param index
*/
isThumbEditable(index: number): boolean;

/**
* Set the specified thumb's editable state.
* @param index
* @param editable
*/
setThumbEditable(index: number, editable: boolean): void;
}

export type SliderBaseInitialState = Partial<
Pick<SliderBaseState, "step" | "isDisabled">
> & {
/** The current value (controlled). */
value?: number[];

/**
* The slider's minimum value.
* @default 0
*/
minValue?: number;

/**
* The slider's maximum value.
* @default 100
*/
maxValue?: number;

/** The default value (uncontrolled). */
defaultValue?: number[];

/** Handler that is called when the value changes. */
onChange?: (value: number[]) => void;

/**
* Get the value when dragging has ended.
*/
onChangeEnd?: (value: number[]) => void;

/**
* The display format of the value label.
*/
formatOptions?: Intl.NumberFormatOptions;
};

export type SliderBaseStateReturn = SliderBaseState & SliderBaseAction;

export function useSliderBaseState(
props: SliderBaseInitialState = {},
): SliderBaseStateReturn {
const { isDisabled = false } = props;

const numberFormatter = useNumberFormatter(props.formatOptions);
const state = useSliderState({ ...props, isDisabled, numberFormatter });

return {
...state,
isDisabled,
};
}
36 changes: 36 additions & 0 deletions src/slider/SliderGroup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { createComponent, createHook } from "reakit-system";
import { GroupHTMLProps, GroupOptions, useGroup } from "reakit";
import { mergeProps } from "@react-aria/utils";

import { SLIDER_GROUP_KEYS } from "./__keys";
import { SliderStateReturn } from "./SliderState";

export type SliderGroupOptions = GroupOptions &
Pick<SliderStateReturn, "groupProps">;

export type SliderGroupHTMLProps = GroupHTMLProps;

export type SliderGroupProps = SliderGroupOptions & SliderGroupHTMLProps;

export const useSliderGroup = createHook<
SliderGroupOptions,
SliderGroupHTMLProps
>({
name: "SliderGroup",
compose: useGroup,
keys: SLIDER_GROUP_KEYS,

useOptions(options, htmlProps) {
return options;
},

useProps(options, htmlProps) {
return mergeProps(options.groupProps, htmlProps);
},
});

export const SliderGroup = createComponent({
as: "div",
memo: true,
useHook: useSliderGroup,
});
Loading

1 comment on commit a12c676

@vercel
Copy link

@vercel vercel bot commented on a12c676 Nov 26, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.