From cb799f805710b8ac0ff6e5589a5e4bef664b2cc5 Mon Sep 17 00:00:00 2001 From: RedrockJS Date: Tue, 3 Jun 2025 12:48:49 +0300 Subject: [PATCH] feat: add input --- src/core/styles/variables.scss | 3 +- src/shared/ui/input/input.module.scss | 117 ++++++++++++++++++++++++-- src/shared/ui/input/input.tsx | 77 +++++++++++++---- src/views/home/ui/offer/offer.tsx | 11 ++- 4 files changed, 182 insertions(+), 26 deletions(-) diff --git a/src/core/styles/variables.scss b/src/core/styles/variables.scss index 355a8d8..d01fdb0 100644 --- a/src/core/styles/variables.scss +++ b/src/core/styles/variables.scss @@ -21,4 +21,5 @@ $color-lightgray: #E4E1E1; $color-darkgray: #999999; $color-text: #333333; $color-text-light: #222222; -$color-mark: #E96526; \ No newline at end of file +$color-mark: #E96526; +$color-error: #FF0000; \ No newline at end of file diff --git a/src/shared/ui/input/input.module.scss b/src/shared/ui/input/input.module.scss index 8c70a12..5de0f03 100644 --- a/src/shared/ui/input/input.module.scss +++ b/src/shared/ui/input/input.module.scss @@ -1,14 +1,113 @@ -.Container { +.input { + position: relative; display: flex; + flex-direction: column; justify-content: center; - align-items: center; - padding: 15px 40px; - width: max-content; + align-items: flex-start; + width: 100%; + height: 42px; border: 1px solid $color-darkgray; border-radius: 28px; - background: $color-white; + + //@include iftablet { + // height: rem(53px); + //} + + &__self { + width: 100%; + height: 100%; + padding: 22px 16px 6px 16px; + font-size: 14px; + line-height: 100%; + color: $color-text; + opacity: 0.9; + + //@include iftablet { + // padding: rem(26px) rem(16px) rem(6px) rem(16px); + // font-size: rem(16px); + // line-height: 130%; + //} + } + + &__placeholder { + position: absolute; + top: 12px; + left: 16px; + font-size: 14px; + line-height: 130%; + color: $color-darkgray; + opacity: 0.4; + transition: all 0.15s ease-in; + + //@include iftablet { + // top: rem(16px); + // font-size: rem(16px); + //} + } + + &__placeholder_active { + top: 6px; + left: 16px; + font-size: 11px; + color: $color-darkgray; + + //@include iftablet { + // top: rem(6px); + // left: rem(16px); + // font-size: rem(14px); + //} + } + + &--error { + border-color: $color-error !important; + } + + &__errorMessage { + margin-top: 10px; + + font-size: 12px; + line-height: 130%; + color: $color-error; + + //@include iftablet { + // margin-top: 6px; + //} + } + + &--disabled { + cursor: not-allowed; + color: $color-lightgray; + } + + &__password-rules { + display: flex; + align-items: center; + margin-top: 6px; + gap: 6px; + + //@include iftablet { + // gap: rem(10px); + //} + //@include ifdesktop { + // margin-top: rem(9px); + //} + + &__rule-block { + display: flex; + align-items: center; + justify-content: center; + gap: 4px; + } + + &__rule-text { + font-family: $font-open-sans; + font-size: 11px; + line-height: 100%; + color: rgba(35, 48, 56, 0.7); + + //@include iftablet { + // font-size: rem(14px); + //} + } + } } - -.Input { - -} \ No newline at end of file diff --git a/src/shared/ui/input/input.tsx b/src/shared/ui/input/input.tsx index cd5cfdb..7c52e03 100644 --- a/src/shared/ui/input/input.tsx +++ b/src/shared/ui/input/input.tsx @@ -1,22 +1,69 @@ +'use client'; + import s from './input.module.scss'; -import { clsx } from 'clsx'; -import { DetailedHTMLProps, InputHTMLAttributes } from 'react'; -type InputProps = { - outerClassName?: string; - variant?: 'default' | 'outlined'; -} & DetailedHTMLProps, HTMLInputElement>; +import React, { InputHTMLAttributes, useState } from 'react'; +import clsx from 'clsx'; -export default function input({ - outerClassName, - variant = 'default', +type InputPropsType = { + className?: string; + placeholder: string; + errorMessage?: string | boolean; +} & InputHTMLAttributes; + +const Input = ({ + placeholder, + errorMessage, + disabled, + className, + onChange, ...props -}: InputProps) { +}: InputPropsType) => { + const [onFocus, setOnFocus] = useState(false); + + const hasValue = + typeof props.value === 'string' + ? props.value.length > 0 + : props.value !== undefined && props.value !== null; + return ( -
- +
+
+ + { + if (typeof props.onFocus !== 'undefined') { + props.onFocus(event); + } + setOnFocus(true); + }} + onBlur={(event) => { + if (typeof props.onBlur !== 'undefined') { + props.onBlur(event); + } + setOnFocus(false); + }} + disabled={disabled} + className={clsx(s.input__self, { [s['input--disabled']]: disabled })} + /> +
+ {errorMessage && ( + {errorMessage} + )}
); -} +}; + +export default Input; diff --git a/src/views/home/ui/offer/offer.tsx b/src/views/home/ui/offer/offer.tsx index 40a23f9..38ed608 100644 --- a/src/views/home/ui/offer/offer.tsx +++ b/src/views/home/ui/offer/offer.tsx @@ -1,3 +1,4 @@ +'use client'; import s from './offer.module.scss'; import { Button, Mark, Input } from '@shared/ui'; @@ -11,8 +12,11 @@ import gridFour from '@public/images/grid-4.png'; import gridFive from '@public/images/grid-5.png'; import gridSix from '@public/images/grid-6.png'; import bgForm from '@public/images/bg-form.jpg'; +import { useState } from 'react'; export default function Offer() { + const [name, setName] = useState(''); + return (

@@ -38,7 +42,12 @@ export default function Offer() {
- + setName(e.target.value)} + />