Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support slider editable #1006

Merged
merged 14 commits into from
Jul 17, 2024
10 changes: 7 additions & 3 deletions assets/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@
&-dragging&-dragging&-dragging {
border-color: tint(@primary-color, 20%);
box-shadow: 0 0 0 5px tint(@primary-color, 50%);

&-delete {
opacity: 0;
}
}

&:focus {
Expand Down Expand Up @@ -186,11 +190,11 @@
left: 5px;
width: 4px;
}

&-track-draggable {
border-top:0;
border-bottom: 0;
border-top: 0;
border-right: 5px solid rgba(0, 0, 0, 0);
border-bottom: 0;
border-left: 5px solid rgba(0, 0, 0, 0);
transform: translateX(-5px);
}
Expand Down
8 changes: 8 additions & 0 deletions docs/demo/editable.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
title: Multiple
nav:
title: Demo
path: /demo
---

<code src="../examples/editable.tsx"></code>
43 changes: 43 additions & 0 deletions docs/examples/editable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/* eslint react/no-multi-comp: 0, no-console: 0 */
import Slider from 'rc-slider';
import React from 'react';
import '../../assets/index.less';

const style: React.CSSProperties = {
width: 400,
margin: 50,
};

export default () => {
const [value, setValue] = React.useState([0, 50, 80]);

Check notice

Code scanning / CodeQL

Unused variable, import, function or class Note documentation

Unused variable value.

return (
<div>
<div style={style}>
<Slider
// range
range={{
editable: true,
}}
track={false}
min={0}
max={100}
value={value}
// defaultValue={null}
onChange={(nextValue) => {
console.error('Change:', nextValue);
setValue(nextValue as any);
}}
onChangeComplete={(nextValue) => {
console.log('Complete', nextValue);
}}
styles={{
rail: {
background: `linear-gradient(to right, blue, red)`,
},
}}
/>
</div>
</div>
);
};
4 changes: 2 additions & 2 deletions docs/examples/multiple.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const NodeWrapper = ({ children }: { children: React.ReactElement }) => {
};

export default () => {
const [value, setValue] = React.useState([0, 5, 8]);
const [value, setValue] = React.useState([0, 50, 80]);

return (
<div>
Expand All @@ -27,7 +27,7 @@ export default () => {
// defaultValue={[0, 10, 30]}
// onChange={log}
min={0}
max={10}
max={100}
value={value}
onChange={(nextValue) => {
// console.log('>>>', nextValue);
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
"@testing-library/react": "^12.1.3",
"@types/classnames": "^2.2.9",
"@types/jest": "^29.5.1",
"@types/node": "^20.14.10",
"@types/react": "^18.2.42",
"@types/react-dom": "^18.0.11",
"@umijs/fabric": "^4.0.1",
Expand Down
12 changes: 12 additions & 0 deletions src/Handles/Handle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ interface RenderProps {
prefixCls: string;
value: number;
dragging: boolean;
draggingDelete: boolean;
}

export interface HandleProps
Expand All @@ -19,7 +20,9 @@ export interface HandleProps
value: number;
valueIndex: number;
dragging: boolean;
draggingDelete: boolean;
onStartMove: OnStartMove;
onDelete: (index: number) => void;
onOffsetChange: (value: number | 'min' | 'max', valueIndex: number) => void;
onFocus: (e: React.FocusEvent<HTMLDivElement>, index: number) => void;
onMouseEnter: (e: React.MouseEvent<HTMLDivElement>, index: number) => void;
Expand All @@ -37,9 +40,11 @@ const Handle = React.forwardRef<HTMLDivElement, HandleProps>((props, ref) => {
value,
valueIndex,
onStartMove,
onDelete,
style,
render,
dragging,
draggingDelete,
onOffsetChange,
onChangeComplete,
onFocus,
Expand Down Expand Up @@ -118,6 +123,11 @@ const Handle = React.forwardRef<HTMLDivElement, HandleProps>((props, ref) => {
case KeyCode.PAGE_DOWN:
offset = -2;
break;

case KeyCode.BACKSPACE:
case KeyCode.DELETE:
onDelete(valueIndex);
break;
}

if (offset !== null) {
Expand Down Expand Up @@ -177,6 +187,7 @@ const Handle = React.forwardRef<HTMLDivElement, HandleProps>((props, ref) => {
{
[`${handlePrefixCls}-${valueIndex + 1}`]: valueIndex !== null && range,
[`${handlePrefixCls}-dragging`]: dragging,
[`${handlePrefixCls}-dragging-delete`]: draggingDelete,
},
classNames.handle,
)}
Expand All @@ -197,6 +208,7 @@ const Handle = React.forwardRef<HTMLDivElement, HandleProps>((props, ref) => {
prefixCls,
value,
dragging,
draggingDelete,
});
}

Expand Down
44 changes: 27 additions & 17 deletions src/Handles/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export interface HandlesProps {
onOffsetChange: (value: number | 'min' | 'max', valueIndex: number) => void;
onFocus?: (e: React.FocusEvent<HTMLDivElement>) => void;
onBlur?: (e: React.FocusEvent<HTMLDivElement>) => void;
onDelete: (index: number) => void;
handleRender?: HandleProps['render'];
/**
* When config `activeHandleRender`,
Expand All @@ -20,6 +21,7 @@ export interface HandlesProps {
*/
activeHandleRender?: HandleProps['render'];
draggingIndex: number;
draggingDelete: boolean;
onChangeComplete?: () => void;
}

Expand All @@ -37,6 +39,7 @@ const Handles = React.forwardRef<HandlesRef, HandlesProps>((props, ref) => {
handleRender,
activeHandleRender,
draggingIndex,
draggingDelete,
onFocus,
...restProps
} = props;
Expand Down Expand Up @@ -74,31 +77,38 @@ const Handles = React.forwardRef<HandlesRef, HandlesProps>((props, ref) => {

return (
<>
{values.map<React.ReactNode>((value, index) => (
<Handle
ref={(node) => {
if (!node) {
delete handlesRef.current[index];
} else {
handlesRef.current[index] = node;
}
}}
dragging={draggingIndex === index}
style={getIndex(style, index)}
key={index}
value={value}
valueIndex={index}
{...handleProps}
/>
))}
{values.map<React.ReactNode>((value, index) => {
const dragging = draggingIndex === index;

return (
<Handle
ref={(node) => {
if (!node) {
delete handlesRef.current[index];
} else {
handlesRef.current[index] = node;
}
}}
dragging={dragging}
draggingDelete={dragging && draggingDelete}
style={getIndex(style, index)}
key={index}
value={value}
valueIndex={index}
{...handleProps}
/>
);
})}

{/* Used for render tooltip, this is not a real handle */}
{activeHandleRender && (
<Handle
key="a11y"
{...handleProps}
value={values[activeIndex]}
valueIndex={null}
dragging={draggingIndex !== -1}
draggingDelete={draggingDelete}
render={activeHandleRender}
style={{ pointerEvents: 'none' }}
tabIndex={null}
Expand Down
Loading
Loading