mirror of
https://github.com/hanzoai/cd-ui.git
synced 2026-10-30 20:42:45 +00:00
* chore: fix Rules-of-React violations for React Compiler readiness Add eslint-plugin-react-hooks v7 (recommended-latest) and fix all error-level Rules-of-React findings so the React Compiler can optimize the component library. The healthcheck reports 100% of components compilable; these fixes clear the 34 ESLint errors across the src and v2 component trees: - refs: stop accessing ref.current during render (incl. the react-form compat shim, whose public ref-forwarding API is preserved) - set-state-in-effect: convert to derived state or restructure effects - immutability: clone-before-mutate; stop mutating props/state - rules-of-hooks: hoist conditional hook calls to top level All 47 unit tests pass; behavior is preserved. Signed-off-by: Jonathan Winters <[email protected]> * chore: resolve react-hooks deps from public npm registry The eslint-plugin-react-hooks@7 dependency subtree was locked to an internal mirror, which the public CI runner can't reach (ETIMEDOUT). Rewrite the 21 affected resolved URLs to registry.yarnpkg.com. Signed-off-by: Jonathan Winters <[email protected]> * useKeybinding -> registerKeybinding Signed-off-by: Jonathan Winters <[email protected]> * chore: fix Rules-of-React refs violations from registerKeybinding rename The useKeybinding->registerKeybinding rename turned hook calls into plain function calls in the render body; since registerKeybinding takes ref targets, the new react-hooks/refs lint flagged them. Move the calls into useEffect (registration is a side effect) in sliding-panel and the v2 autocomplete. In the v1 autocomplete, the flagged value is a forwarded callback ref, not a render-time read, so suppress that one with a comment. Also dedupe pnpm-lock.yaml. Signed-off-by: Jonathan Winters <[email protected]> --------- Signed-off-by: Jonathan Winters <[email protected]>
62 lines
2.0 KiB
TypeScript
62 lines
2.0 KiB
TypeScript
import * as React from 'react';
|
|
import {ThemeDiv} from '../theme-div/theme-div';
|
|
|
|
import './input.scss';
|
|
|
|
export interface InputProps {
|
|
value: string;
|
|
ref: React.MutableRefObject<HTMLInputElement>;
|
|
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
|
}
|
|
|
|
export type SetInputFxn = (val: string) => void;
|
|
export const FormResetFactory = (setFxns: SetInputFxn[]) => {
|
|
return () => {
|
|
setFxns.forEach((reset) => reset(''));
|
|
};
|
|
};
|
|
|
|
export const useInput = (init: string, callback?: (val: string) => void): [string, SetInputFxn, InputProps] => {
|
|
const [state, setState] = React.useState(init);
|
|
const inputRef = React.useRef(null);
|
|
|
|
const InputP: InputProps = {
|
|
value: state,
|
|
ref: inputRef,
|
|
onChange: (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
setState(e.target.value);
|
|
if (callback) {
|
|
callback(e.target.value);
|
|
}
|
|
},
|
|
};
|
|
|
|
return [state, setState, InputP];
|
|
};
|
|
|
|
export const useDebounce = (value: string, debouncems: number): string => {
|
|
const [val, setVal] = React.useState(value);
|
|
|
|
React.useEffect(() => {
|
|
const to = setTimeout(() => {
|
|
setVal(value);
|
|
}, debouncems);
|
|
return () => clearInterval(to);
|
|
}, [value, debouncems]);
|
|
|
|
return val;
|
|
};
|
|
|
|
/**
|
|
* A formatted field, accompanied by the `useInput` hook. `useInput` returns a `[data, setData, props]` thruple, where `data` and `setData` are analagous to `React.useState`,
|
|
* and `props` are designed to be included in the Input component with a spread operator: `<Input YOUR_PROPS_HERE {...props} />`
|
|
*/
|
|
export const Input = (props: React.InputHTMLAttributes<HTMLInputElement> & {innerref?: React.MutableRefObject<any>, className?: string}) => {
|
|
const {innerref, className, ...rest} = props;
|
|
return (
|
|
<ThemeDiv className='input-container'>
|
|
<input {...(rest as any)} className={className ? `${className} input` : 'input'} ref={innerref} />
|
|
</ThemeDiv>
|
|
);
|
|
};
|