Skip to content

Commit

Permalink
Merge branch 'master' into context-tests
Browse files Browse the repository at this point in the history
  • Loading branch information
anuraghazra committed Oct 23, 2020
2 parents 5ae1990 + f67c05e commit 293cf54
Show file tree
Hide file tree
Showing 15 changed files with 91 additions and 71 deletions.
18 changes: 8 additions & 10 deletions src/accordion/AccordionState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ export type AccordionState = CompositeState & {
/**
* The current selected accordion's `id`.
*/
selectedId?: AccordionState["currentId"];
selectedId: AccordionState["currentId"];
/**
* Initial selected accordion's `id`.
* @default []
*/
selectedIds?: AccordionState["currentId"][];
selectedIds: AccordionState["currentId"][];
/**
* Lists all the panels.
*/
Expand All @@ -28,17 +28,17 @@ export type AccordionState = CompositeState & {
* Whether the accodion selection should be manual.
* @default true
*/
manual?: boolean;
manual: boolean;
/**
* Allow to open multiple accordion items
* @default false
*/
allowMultiple?: boolean;
allowMultiple: boolean;
/**
* Allow to toggle accordion items
* @default false
*/
allowToggle?: boolean;
allowToggle: boolean;
};

export type AccordionActions = CompositeActions & {
Expand Down Expand Up @@ -71,11 +71,9 @@ export type AccordionActions = CompositeActions & {
};

export type AccordionInitialState = CompositeInitialState &
Partial<
Pick<
AccordionState,
"selectedId" | "selectedIds" | "manual" | "allowMultiple" | "allowToggle"
>
Pick<
Partial<AccordionState>,
"selectedId" | "selectedIds" | "manual" | "allowMultiple" | "allowToggle"
>;

export type AccordionStateReturn = AccordionState & AccordionActions;
Expand Down
30 changes: 16 additions & 14 deletions src/meter/MeterState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import {
useSealedState,
} from "reakit-utils/useSealedState";

import { isFunction, valueToPercent } from "../utils";
import { getDefaultOptimumValue, calculateStatus, clamp } from "./helpers";
import { calculateStatus, clamp } from "./helpers";
import { isFunction, valueToPercent, getOptimumValue } from "../utils";

type Status = "safe" | "caution" | "danger" | undefined;

Expand All @@ -13,38 +13,42 @@ type AriaValueText = string | ((value: number, percent: number) => string);
export type MeterState = {
/**
* The `value` of the meter indicator.
*
* If `undefined`/`not valid` the meter bar will be equal to `min`
* @default 0
*/
value?: number;
value: number;
/**
* The minimum value of the meter
* @default 0
*/
min?: number;
min: number;
/**
* The maximum value of the meter
* @default 1
*/
max?: number;
max: number;
/**
* The higher limit of min range.
*
* Defaults to `min`.
* @default 0
*/
low?: number;
low: number;
/**
* The lower limit of max range.
*
* Defaults to `max`.
* @default 1
*/
high?: number;
high: number;
/**
* The lower limit of max range.
*
* Defaults to `median of low & high`.
* @default 0.5
*/
optimum?: number;
optimum: number;
/**
* Defines the human readable text alternative of aria-valuenow for a range widget.
*/
Expand All @@ -59,11 +63,9 @@ export type MeterState = {
status: Status;
};

export type MeterInitialState = Partial<
Pick<
MeterState,
"value" | "min" | "max" | "low" | "optimum" | "high" | "ariaValueText"
>
export type MeterInitialState = Pick<
Partial<MeterState>,
"value" | "min" | "max" | "low" | "optimum" | "high" | "ariaValueText"
>;

export type MeterStateReturn = MeterState;
Expand All @@ -81,7 +83,7 @@ export const useMeterState = (
const initialLow = sealed.low ?? min;
const initialHigh = sealed.high ?? max;
const initialOptimum =
sealed.optimum ?? getDefaultOptimumValue(initialLow, initialHigh);
sealed.optimum ?? getOptimumValue(initialLow, initialHigh);

const value = clamp(initialValue, min, max);
const optimum = clamp(initialOptimum, min, max);
Expand Down
3 changes: 2 additions & 1 deletion src/meter/__tests__/Meter.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const MeterComp: React.FC<MeterInitialState> = props => {
max,
});

return <Meter {...meter} {...rest} />;
return <Meter aria-label="meter" {...meter} {...rest} />;
};

describe("Meter", () => {
Expand All @@ -35,6 +35,7 @@ describe("Meter", () => {
expect(container).toMatchInlineSnapshot(`
<div>
<div
aria-label="meter"
aria-valuemax="1"
aria-valuemin="0"
aria-valuenow="0"
Expand Down
8 changes: 1 addition & 7 deletions src/meter/__tests__/helpers.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
import { clamp, isInRange, getDefaultOptimumValue } from "../helpers";
import { clamp, isInRange } from "../helpers";

describe("Meter Helpers", () => {
test("getDefaultOptimumValue", () => {
expect(getDefaultOptimumValue(0, 100)).toBe(50);
expect(getDefaultOptimumValue(100, 0)).toBe(100);
expect(getDefaultOptimumValue(100, 500)).toBe(300);
});

test("isInRange", () => {
expect(isInRange(100, 0, 50)).toBe(false);
expect(isInRange(50, 0, 50)).toBe(true);
Expand Down
12 changes: 2 additions & 10 deletions src/meter/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,4 @@
/**
* The candidate optimum point is the midpoint between the minimum value and
* the maximum value.
*
* @see https://html.spec.whatwg.org/multipage/form-elements.html#the-meter-element:attr-meter-high-8:~:text=boundary.-,The%20optimum%20point
*/
export function getDefaultOptimumValue(min: number, max: number) {
return max < min ? min : min + (max - min) / 2;
}
import { isNull } from "../utils";

/**
* Handle Inequalities with received values
Expand All @@ -19,7 +11,7 @@ export function getDefaultOptimumValue(min: number, max: number) {
* @see https://html.spec.whatwg.org/multipage/form-elements.html#the-meter-element:attr-meter-max-3:~:text=following%20inequalities%20must%20hold
*/
export function clamp(value: number, min: number, max: number) {
if (value == null) return 0;
if (isNull(value)) return 0;

return Math.min(Math.max(value, min), max);
}
Expand Down
1 change: 1 addition & 0 deletions src/meter/stories/MeterComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export const StyledMeter: React.FC<StyledMeterInitialState> = props => {
<div className={meterStyle}>
<Meter
className={meterBarStyle(meter, props)}
aria-label="meter"
{...meter}
{...rest}
></Meter>
Expand Down
4 changes: 2 additions & 2 deletions src/progress/Progress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import { useWarning } from "reakit-warning";
import { BoxHTMLProps, BoxOptions, useBox } from "reakit";
import { createHook, createComponent, useCreateElement } from "reakit-system";

import { dataAttr } from "../utils";
import { PROGRESS_KEYS } from "./__keys";
import { dataAttr, isNull } from "../utils";
import { ProgressStateReturn } from "./ProgressState";

export type ProgressOptions = BoxOptions &
Expand All @@ -35,7 +35,7 @@ export const useProgress = createHook<ProgressOptions, ProgressHTMLProps>({
"data-indeterminate": dataAttr(isIndeterminate),
"aria-valuemax": max,
"aria-valuemin": min,
"aria-valuenow": isIndeterminate ? undefined : value,
"aria-valuenow": isNull(value) ? undefined : value,
"aria-valuetext": `${ariaValueText}`,
...htmlProps,
};
Expand Down
43 changes: 24 additions & 19 deletions src/progress/ProgressState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,20 @@
import * as React from "react";
import { SealedInitialState, useSealedState } from "reakit-utils";

import { valueToPercent, isFunction } from "../utils";
import { valueToPercent, isFunction, isNull } from "../utils";

type AriaValueText = string | ((value: number, percent: number) => string);
type AriaValueText =
| string
| ((value: number | null, percent: number | null) => string);

export interface ProgressState {
/**
* The `value` of the progress indicator.
* If `undefined` the progress bar will be in `indeterminate` state
*
* If `null` the progress bar will be in `indeterminate` state
* @default 0
*/
value: number;
value: number | null;
/**
* The minimum value of the progress
* @default 0
Expand All @@ -30,31 +33,28 @@ export interface ProgressState {
max: number;
/**
* Set isInterminate state
* @default false
*/
isIndeterminate?: boolean;
isIndeterminate: boolean;
/**
* Defines the human readable text alternative of aria-valuenow for a range widget.
*/
ariaValueText: AriaValueText;
/**
* Percentage of the value progressed with respect to min & max
*/
percent: number;
percent: number | null;
}

export interface ProgressAction {
/**
* Update the value of the progress indicator
*/
setValue?: React.Dispatch<React.SetStateAction<number>>;
setValue: React.Dispatch<React.SetStateAction<number | null>>;
}

export type ProgressInitialState = Partial<
Pick<
ProgressState,
"value" | "min" | "max" | "isIndeterminate" | "ariaValueText"
>
export type ProgressInitialState = Pick<
Partial<ProgressState>,
"value" | "min" | "max" | "ariaValueText"
>;

export type ProgressStateReturn = ProgressState & ProgressAction;
Expand All @@ -66,23 +66,28 @@ export function useProgressState(
value: initialValue = 0,
min = 0,
max = 100,
isIndeterminate = false,
ariaValueText,
} = useSealedState(initialState);
const [value, setValue] = React.useState(
initialValue == null ? 0 : initialValue,
);
const percent = valueToPercent(value, min, max);
const [value, setValue] = React.useState(clampValue(initialValue, min, max));
const percent = isNull(value) ? null : valueToPercent(value, min, max);

return {
value,
setValue,
min,
max,
isIndeterminate,
isIndeterminate: isNull(value),
percent,
ariaValueText: isFunction(ariaValueText)
? ariaValueText?.(value, percent)
: isNull(value)
? "indeterminate"
: `${percent}`,
};
}

function clampValue(value: number | null, min: number, max: number) {
if (isNull(value)) return null;

return Math.min(Math.max(value, min), max);
}
5 changes: 3 additions & 2 deletions src/progress/__tests__/Progress.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const ProgressComp = (props: Partial<ProgressProps>) => {

return (
<div>
<Progress data-testid="progress" {...progress} />
<Progress data-testid="progress" aria-label="progress" {...progress} />
</div>
);
};
Expand All @@ -22,6 +22,7 @@ describe("Progress", () => {
<div>
<div>
<div
aria-label="progress"
aria-valuemax="100"
aria-valuemin="0"
aria-valuenow="10"
Expand All @@ -36,7 +37,7 @@ describe("Progress", () => {
});

it("should render isIndeterminate", () => {
const { getByTestId: testid } = render(<ProgressComp isIndeterminate />);
const { getByTestId: testid } = render(<ProgressComp value={null} />);

expect(testid("progress")).toHaveAttribute("data-indeterminate", "");
});
Expand Down
2 changes: 1 addition & 1 deletion src/progress/stories/CircularProgress.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ export const WithLabel = Base.bind({});
WithLabel.args = { withLabel: true };

export const IsIndeterminate = Base.bind({});
IsIndeterminate.args = { isIndeterminate: true };
IsIndeterminate.args = { value: null };
2 changes: 1 addition & 1 deletion src/progress/stories/CircularProgress.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export const CircularProgress: React.FC<CircularProgressInitialState> = props =>
return (
<div>
<div>
<Progress {...state} className={rootStyles}>
<Progress {...state} className={rootStyles} aria-label="progress">
<svg viewBox="0 0 100 100" className={svgStyles(isIndeterminate)}>
<circle
cx={50}
Expand Down
2 changes: 1 addition & 1 deletion src/progress/stories/LinearProgress.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ WithStripeAnimation.args = {
};

export const IsIndeterminate = Base.bind({});
IsIndeterminate.args = { isIndeterminate: true };
IsIndeterminate.args = { value: null };
2 changes: 2 additions & 0 deletions src/progress/stories/LinearProgress.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export const LinearProgress: React.FC<LinearProgressInitialState> = props => {
...rest
} = props;
const state = useProgressState(rest);
console.log("%c state", "color: #33cc99", state);
const { value, setValue, percent, isIndeterminate } = state;

React.useEffect(() => {
Expand All @@ -60,6 +61,7 @@ export const LinearProgress: React.FC<LinearProgressInitialState> = props => {
<Progress
{...state}
value={value}
aria-label="progress"
className={cx(
progressBarStyle(percent),
withStripe && stripStyles,
Expand Down
Loading

0 comments on commit 293cf54

Please sign in to comment.