Skip to content

Commit

Permalink
finalize range slider
Browse files Browse the repository at this point in the history
  • Loading branch information
ricmars committed Dec 31, 2024
1 parent bcfacb5 commit 6d13ffd
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 39 deletions.
Binary file added .storybook/static/RangeSlider_Configuration_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions src/components/Pega_Extensions_RangeSlider/Docs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,21 @@ The Range slider allows to filter a set of objects by a range value - the fields
## Props

<Controls />

## Configuration

Here is an example of filtering in the end user portal to select a case reference.

![Configuration](RangeSlider_Configuration_1.png)

The new template is used to configure 2 currency types fields for start and end values. The view to refresh is passed to the region of the template.

![Configuration](RangeSlider_Configuration_2.png)

The case reference data page is a parametrized data page that uses the min and max values to filter the list

![Configuration](RangeSlider_Configuration_3.png)

# Contributors

This component was suggested by Sowjanya Thutupalli working with [Areteans | areteanstech.com/](https://areteanstech.com/). See the [Component proposal](https://github.com/pegasystems/constellation-ui-gallery/issues/90).
11 changes: 10 additions & 1 deletion src/components/Pega_Extensions_RangeSlider/demo.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ export default {
table: {
disable: true
}
},
children: {
table: {
disable: true
}
}
},
component: PegaExtensionsRangeSlider
Expand Down Expand Up @@ -50,6 +55,7 @@ export const Default: Story = {
return {
getActionsApi: () => {
return {
updateFieldValue: () => {},
refreshCaseView: () => {
// console.log('updating views');
}
Expand Down Expand Up @@ -89,7 +95,10 @@ export const Default: Story = {
return <PegaExtensionsRangeSlider {...props}>{regionAChildren}</PegaExtensionsRangeSlider>;
},
args: {
heading: 'Range Slider',
label: 'Range Slider',
showLabel: true,
maxValueProperty: 240,
minValueProperty: 120,
min: 0,
max: 500,
step: 1,
Expand Down
94 changes: 56 additions & 38 deletions src/components/Pega_Extensions_RangeSlider/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ import { useCallback, useEffect, useRef, useState, type CSSProperties } from 're
type RangeSliderProps = {
/** Label for the range slider
*/
heading: string;
label: string;
/** show label
* @default true
*/
showLabel: boolean;
/** The minimum value of the range
* @default 0
*/
Expand All @@ -39,28 +43,42 @@ type RangeSliderProps = {
* @default USD
*/
currencyCode: string;
/** Function to get the PConnect object for interacting with the Pega API */
getPConnect: any;
/** The children elements to be rendered inside the range slider component */
children: any;
maxValueProperty: number;
minValueProperty: number;
};

export const PegaExtensionsRangeSlider = (props: RangeSliderProps) => {
const {
heading = '',
label = '',
showLabel = true,
min = 0,
max = 100,
step = 1,
currencyCode = 'USD',
maxValueProperty,
minValueProperty,
getPConnect,
children
} = props;
const [minValue, setMinValue] = useState(40);
const [maxValue, setMaxValue] = useState(200);
const [minValue, setMinValue] = useState(minValueProperty);
const [maxValue, setMaxValue] = useState(maxValueProperty);
const minTrackRef = useRef<HTMLDivElement>(null);
const maxTrackRef = useRef<HTMLDivElement>(null);
const [inMinDrag, setInMinDrag] = useState(false);
const [inMaxDrag, setInMaxDrag] = useState(false);
const { start, end } = useDirection();

// Get the inherited props from the parent to determine label settings
const propsToUse = { label, showLabel, ...getPConnect().getInheritedProps() };
const maxValuePropName =
getPConnect().getRawMetadata().config?.maxValueProperty?.replace('@P ', '') || '';
const minValuePropName =
getPConnect().getRawMetadata().config?.minValueProperty?.replace('@P ', '') || '';

const refreshForm = useCallback(() => {
const caseKey = getPConnect().getCaseInfo().getKey();
const refreshOptions = { autoDetectRefresh: true, propertyName: '' };
Expand Down Expand Up @@ -90,13 +108,14 @@ export const PegaExtensionsRangeSlider = (props: RangeSliderProps) => {
newValue = maxValue;
}
if (newValue !== prevValue) {
getPConnect().getActionsApi().updateFieldValue(minValuePropName, newValue);
refreshForm();
}
}
return newValue;
});
},
[start, end, min, max, step, maxValue, refreshForm]
[start, end, min, max, step, maxValue, getPConnect, minValuePropName, refreshForm]
);

const maxMoveThumb = useCallback(
Expand All @@ -114,13 +133,14 @@ export const PegaExtensionsRangeSlider = (props: RangeSliderProps) => {
newValue = minValue;
}
if (newValue !== prevValue) {
getPConnect().getActionsApi().updateFieldValue(maxValuePropName, newValue);
refreshForm();
}
}
return newValue;
});
},
[start, end, min, max, step, minValue, refreshForm]
[start, end, min, max, step, minValue, getPConnect, maxValuePropName, refreshForm]
);

const onMinThumbKeyDown = useCallback(
Expand Down Expand Up @@ -168,12 +188,13 @@ export const PegaExtensionsRangeSlider = (props: RangeSliderProps) => {
newValue = maxValue;
}
if (newValue !== prevValue) {
getPConnect().getActionsApi().updateFieldValue(minValuePropName, newValue);
refreshForm();
}
return newValue;
});
},
[minValue, maxValue, start, step, end, min, max, refreshForm]
[maxValue, start, minValue, step, end, min, max, getPConnect, minValuePropName, refreshForm]
);

const onMaxThumbKeyDown = useCallback(
Expand All @@ -197,17 +218,17 @@ export const PegaExtensionsRangeSlider = (props: RangeSliderProps) => {
switch (e.key) {
case 'ArrowDown':
case `Arrow${cap(start)}`:
newValue = maxValue - step;
newValue = prevValue - step;
break;
case 'ArrowUp':
case `Arrow${cap(end)}`:
newValue = maxValue + step;
newValue = prevValue + step;
break;
case 'PageUp':
newValue = maxValue + 10 * step;
newValue = prevValue + 10 * step;
break;
case 'PageDown':
newValue = maxValue - 10 * step;
newValue = prevValue - 10 * step;
break;
case 'Home':
newValue = min;
Expand All @@ -221,17 +242,23 @@ export const PegaExtensionsRangeSlider = (props: RangeSliderProps) => {
newValue = minValue;
}
if (newValue !== prevValue) {
getPConnect().getActionsApi().updateFieldValue(maxValuePropName, newValue);
refreshForm();
}
return newValue;
});
},
[maxValue, minValue, start, step, end, min, max, refreshForm]
[minValue, start, step, end, min, max, getPConnect, maxValuePropName, refreshForm]
);

useEffect(() => {
const onDragEnd = () => {
setInMinDrag(false);
if (inMinDrag) {
setInMinDrag(false);
}
if (inMaxDrag) {
setInMaxDrag(false);
}
};

document.addEventListener('mouseup', onDragEnd);
Expand All @@ -241,24 +268,6 @@ export const PegaExtensionsRangeSlider = (props: RangeSliderProps) => {
document.addEventListener('mousemove', minMoveThumb);
document.addEventListener('touchmove', minMoveThumb);
}

return () => {
document.removeEventListener('mouseup', onDragEnd);
document.removeEventListener('touchend', onDragEnd);
document.removeEventListener('touchcancel', onDragEnd);
document.removeEventListener('mousemove', minMoveThumb);
document.removeEventListener('touchmove', minMoveThumb);
};
}, [inMinDrag, minMoveThumb]);

useEffect(() => {
const onDragEnd = () => {
setInMaxDrag(false);
};

document.addEventListener('mouseup', onDragEnd);
document.addEventListener('touchend', onDragEnd);
document.addEventListener('touchcancel', onDragEnd);
if (inMaxDrag) {
document.addEventListener('mousemove', maxMoveThumb);
document.addEventListener('touchmove', maxMoveThumb);
Expand All @@ -268,16 +277,21 @@ export const PegaExtensionsRangeSlider = (props: RangeSliderProps) => {
document.removeEventListener('mouseup', onDragEnd);
document.removeEventListener('touchend', onDragEnd);
document.removeEventListener('touchcancel', onDragEnd);
document.removeEventListener('mousemove', minMoveThumb);
document.removeEventListener('touchmove', minMoveThumb);
document.removeEventListener('mousemove', maxMoveThumb);
document.removeEventListener('touchmove', maxMoveThumb);
};
}, [inMaxDrag, maxMoveThumb]);
}, [inMinDrag, inMaxDrag, minMoveThumb, maxMoveThumb]);

const minPercentage = ((Number(minValue) - min) / (max - min)) * 100;
const maxPercentage = ((Number(maxValue) - min) / (max - min)) * 100;

return (
<FieldGroup name={heading} as={StyledRangeSliderWrapper}>
<FieldGroup
name={propsToUse.showLabel ? propsToUse?.label : null}
as={StyledRangeSliderWrapper}
>
<Flex
as={StyledSlider}
container={{
Expand Down Expand Up @@ -355,11 +369,15 @@ export const PegaExtensionsRangeSlider = (props: RangeSliderProps) => {
/>
</StyledMaxValue>
</Flex>
{children.map((child: any, i: number) => (
<Flex container={{ direction: 'column' }} key={`r-${i + 1}`}>
{child}
</Flex>
))}
{Array.isArray(children) ? (
children.map((child: any, i: number) => (
<Flex container={{ direction: 'column' }} key={`r-${i + 1}`}>
{child}
</Flex>
))
) : (
<Flex container={{ direction: 'column' }}>{children}</Flex>
)}
</FieldGroup>
);
};
Expand Down

0 comments on commit 6d13ffd

Please sign in to comment.