feat: manually mirror opencoze's code from bytedance

Change-Id: I09a73aadda978ad9511264a756b2ce51f5761adf
This commit is contained in:
fanlv
2025-07-20 17:36:12 +08:00
commit 890153324f
14811 changed files with 1923430 additions and 0 deletions

View File

@@ -0,0 +1,86 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from 'react';
import { type SliderProps } from 'rc-slider';
import { Tooltip } from '@coze-arch/bot-semi';
interface HandleTooltipProps {
value: number;
children: React.ReactElement;
visible: boolean;
tipFormatter?: (value: number) => React.ReactNode;
}
export const HandleTooltip: React.FC<HandleTooltipProps> = props => {
const {
value,
children,
visible,
tipFormatter = val => `${val}`,
...restProps
} = props;
const rafRef = React.useRef<number | null>(null);
// 用来更新 Tooltip 的位置
const [refreshKey, setRefreshKey] = React.useState('1');
function cancelKeepAlign() {
if (rafRef.current) {
window.cancelAnimationFrame(rafRef.current);
}
}
function keepAlign() {
rafRef.current = window.requestAnimationFrame(() => {
setRefreshKey(Math.random().toString());
});
}
React.useEffect(() => {
if (visible) {
keepAlign();
} else {
cancelKeepAlign();
}
return cancelKeepAlign;
}, [value, visible]);
return (
<Tooltip
placement="top"
content={tipFormatter(value)}
overlayInnerStyle={{ minHeight: 'auto' }}
rePosKey={refreshKey}
visible={visible}
{...restProps}
>
{children}
</Tooltip>
);
};
export const handleRender: SliderProps['handleRender'] = (node, props) => (
<HandleTooltip
value={props.value as number}
visible={props.dragging as boolean}
>
{node}
</HandleTooltip>
);

View File

@@ -0,0 +1,30 @@
.rc-slider-wrapper {
:global {
.rc-slider {
padding: 13px 0;
&-track,
&-tracks {
height: 4px;
background-color: rgba(77, 83, 232, 1);
}
&-handle {
height: 24px;
width: 24px;
border: none;
opacity: 1;
margin-top: -11px;
}
&-handle,
&-handle:focus,
&-handle:focus-visible,
&-handle:active,
.rc-slider-handle-dragging.rc-slider-handle-dragging.rc-slider-handle-dragging {
box-shadow: 0px 0px 1px 0px rgba(0, 0, 0, 0.3);
box-shadow: 0px 4px 6px 0px rgba(0, 0, 0, 0.1);
}
}
}
}

View File

@@ -0,0 +1,75 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from 'react';
import RcSlider, { type SliderProps } from 'rc-slider';
import 'rc-slider/assets/index.css';
import { handleRender } from './handle-render';
import styles from './index.module.less';
interface InputSliderProps {
value?: number;
onChange?: (v: number) => void;
max?: number;
min?: number;
step?: number;
disabled?: boolean;
className?: string;
useRcSlider?: boolean;
marks?: SliderProps['marks'];
tipFormatter?: (
value: string | number | boolean | (string | number | boolean)[],
) => string;
handleRender?: SliderProps['handleRender'];
}
export type RCSliderProps = SliderProps;
export const RCSliderWrapper: React.FC<InputSliderProps> = props => {
const {
value,
onChange,
max = 1,
min = 0,
step = 1,
disabled,
marks,
className,
} = props;
return (
<div className={styles['rc-slider-wrapper']}>
<RcSlider
className={className}
disabled={disabled}
value={value}
max={max}
min={min}
step={step}
marks={marks}
handleRender={handleRender}
onChange={v => {
if (typeof v === 'number') {
onChange?.(v);
}
}}
/>
</div>
);
};