Задать вопрос
  • Как сделать кликабельные аннотации в react-pdf?

    sanManjiro
    @sanManjiro Автор вопроса
    Решил проблему сам, оставлю решение, проблема заключается в том, что все ссылки аннотаций размещаются поверх через абсолютную позицию, из-за этого, если нарушаются пропорции экрана, т.е. ширины, все ссылки съезжают, я убрал из компонента TextLayer как scss, так и пропст в , после добавил ref в div, ref={documentWrapperRef}, и в Page добавил вот такую запись width={documentWrapperRef.current?.getBoundingClientRect().width || undefined}. Все работает отлично, вот рабочий код:
    'use client';
    import { useRef } from 'react';
    import { Document, Page, pdfjs } from 'react-pdf';
    
    // COMPONENTS
    import { useModalControl } from '@components/modals/document-modal/hooks/useModalControl';
    import { usePdfViewer } from '@components/modals/document-modal/hooks/usePdfViewer';
    import { PdfControls } from './components/PdfControls';
    
    // STYLES
    import 'react-pdf/dist/Page/AnnotationLayer.css';
    import style from './DocumentModal.module.scss';
    
    // Установите worker
    pdfjs.GlobalWorkerOptions.workerSrc = new URL('pdfjs-dist/build/pdf.worker.min.mjs', import.meta.url).toString();
    
    interface DocumentModalProps {
    	isOpen: boolean;
    	onClose: () => void;
    	documentUrl: string;
    }
    
    export const DocumentModal = ({ isOpen, onClose, documentUrl }: DocumentModalProps) => {
    	const dialogRef = useModalControl(isOpen);
    	const documentWrapperRef = useRef<HTMLDivElement>(null);
    	const {
    		scale,
    		isLoading,
    		error,
    		numPages,
    		handleZoomIn,
    		handleZoomOut,
    		handleLoadSuccess,
    		handleLoadError,
    		handleDownload,
    	} = usePdfViewer();
    
    	if (!isOpen) return null;
    
    	return (
    		<dialog ref={dialogRef} className={style['document-modal']} onClose={onClose}>
    			<div
    				className={style['document-modal__overlay']}
    				onClick={e => {
    					if (e.target === e.currentTarget) {
    						onClose();
    					}
    				}}
    			>
    				<div className={style['document-modal__wrapper']}>
    					<PdfControls
    						scale={scale}
    						onZoomIn={handleZoomIn}
    						onZoomOut={handleZoomOut}
    						onDownload={() => handleDownload(documentUrl)}
    						onClose={onClose}
    					/>
    
    					<div className={style['document-modal__content']} ref={documentWrapperRef}>
    						{isLoading && <div className={style['document-modal__loader']}>Загрузка документа...</div>}
    						{error && <div className={style['document-modal__error']}>{error}</div>}
    
    						<Document
    							file={documentUrl}
    							onLoadSuccess={handleLoadSuccess}
    							onLoadError={handleLoadError}
    							loading={null}
    							noData={null}
    							externalLinkTarget='_blank'
    						>
    							{Array.from(new Array(numPages), (el, index) => (
    								<Page
    									key={`page_${index + 1}`}
    									pageNumber={index + 1}
    									renderAnnotationLayer={true}
    									scale={scale}
    									className={style['document-modal__page']}
    									loading={null}
    									width={documentWrapperRef.current?.getBoundingClientRect().width || undefined}
    								/>
    							))}
    						</Document>
    					</div>
    				</div>
    			</div>
    		</dialog>
    	);
    };
    Ответ написан
    Комментировать
  • Почему данные не подгружаются в форму?

    sanManjiro
    @sanManjiro Автор вопроса
    Хотел использовать Redux для этого, установил и настроил но из-за typescript не было компонента PersistGate, ну или он просто не определял типы, но я нашел для себя заглушку этого, не знаю правда настолько это правильный подход:
    useEffect(() => {
        if (dataForm) {
          setValue("amount", dataForm.amount);
          setValue("term", dataForm.term);
          setValue("lastName", dataForm.lastName);
          setValue("firstName", dataForm.firstName);
          setValue("middleName", dataForm.middleName);
          setValue("numberDate", dataForm.dateOfBirth);
          setValue("numberPhone", dataForm.numberPhone);
          setValue("email", dataForm.email);
          setValue("checkbox", dataForm.checkbox);
        }
      }, [dataForm, setValue]);

    , я добавил просто второй useEffect после первого, где storedData и просто руками записываю значения в форму, это работает как надо и ошибки нету, но я думаю но КОСТЫЛЬ ли это и можно ли считать тему закрытой.
    Ответ написан
  • Как предзагрузить компонент?

    sanManjiro
    @sanManjiro Автор вопроса
    Все оказалось очень просто, я просто сделал функцию асинхронной и все)
    Ответ написан
    Комментировать
  • Как перезаписывать объекты в useState?

    sanManjiro
    @sanManjiro Автор вопроса
    Решил я эту проблему, заключалась она в том, что я о приоре не правильно записывал значения в объект, нужно было писать не setPassport({...passport, placeOfIssue: value}), а что-то вроде такого:
    useEffect (() => {
        PlaceOfIssueScript(
          (value) => setPassport(prevState => {
            return {...prevState, placeOfIssue: value }
          }),
          (value) => setPassport(prevState => {
            return {...prevState, ouCode: value.replace(/[^0-9]/g, '') }
          }),
          setStatusSelec
        )
      }, [passport])

    Я не знаю почему не работал предыдущий способ, потому что по факту, мы делаем то же самое, берем наши объект и применяем на них спрутинг, а потом изменяем то значение в объекте, которое нам нужно изменить.
    Ответ написан
    Комментировать
  • Как запретить ввод цифры 8 и 7 вторым символом через .replace()?

    sanManjiro
    @sanManjiro Автор вопроса
    Я сделал это путем создание функции, которая позволяет первый раз при вводе номера удалять цифры 8 или 7, вот сама функция:
    const setCharAt = (str,index,chr) => {
      if(index > str.length-1) return str;
      str.substring(0,index) + chr + str.substring(index+1);
    }
    
    export const formatNumber = (string) => {
      if (string.charAt(0) === "8" || string.charAt(0) === "7") {
        return string = setCharAt(string, 0, "")
      } else if ((string.charAt(0) === "8" || string.charAt(0) === "7") && (string.charAt(1) === "8" || string.charAt(1) === "7")) { 
        string = setCharAt(string, 0, "")
        return string = setCharAt(string, 1, "")
      }
    }
    Ответ написан
  • Как добавить текст к числу в поле Value?

    sanManjiro
    @sanManjiro Автор вопроса
    Вопрос можно считать закрытым, очень сильно помучившись, методом научного тыка я смог сделать маску, которая добавляет в конец нужный знак или же текст, и при этом делит число на разряды пробелом, и запрещает вводить числа, установленные в mix и max, вот код кому надо:
    <IMaskInput
         value={convertObjectValues(valueSum, true)}
         mask={"a d"}
         blocks={{ d: { mask: "₽" }, a:{mask: Number, thousandsSeparator: ' ', min: 1500, max: 15000} }}
         lazy={false}
         placeholder={valueSum}
         unmask={true}
         onAccept={ (value) => setValueSum(value) }
         onBlur={handlerBlurSum}
         onPointerLeave={handlerBlurSum}
         onClick={handlerBlurSum}
     />
    Ответ написан
    Комментировать