
рд╕рднреА рдХреЛ рдирдорд╕реНрдХрд╛рд░, рдЖрдЬ рдореИрдВ рдЖрдкрдХреЛ рдмрддрд╛рдКрдВрдЧрд╛ рдХрд┐ рдореИрдВрдиреЗ рдПрдХреНрд╕рдПрдордЖрд░ рдпреВрдЖрдИ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рд▓рд┐рдП рдмрдЯрди рдХреИрд╕реЗ рд╡рд┐рдХрд╕рд┐рдд рдХрд┐рдпрд╛ред рдЕрд░реЗ рд╣рд╛рдБ, рдпрд╣ рдПрдХ рддрд┐рдкрд╣рд┐рдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдмрддрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рд╣реИред рдореИрдВ рдЦреБрд▓реЗ рд╕реНрд░реЛрдд рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдПрдХ рдирдпрд╛ рдШрдЯрдХ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд╕рд╛рде рдЬреБрдбрд╝реЗ рд╡рд┐рд╡рд░рдгреЛрдВ рдХреЛ рдЫреЛрдбрд╝ рджреВрдВрдЧрд╛ред рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рдореИрдВ рдПрдХ рдЕрд▓рдЧ рд▓реЗрдЦ рдореЗрдВ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░реВрдВрдЧрд╛ред
рдкрд░рд┐рдЪрдп
рдПрдХреНрд╕рдПрдордЖрд░ рдпреВрдЖрдИ рдореЗрд░реА рдирдИ рдУрдкрди рд╕реЛрд░реНрд╕ рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИред HTML / CSS рдФрд░ React рдХреЗ рд▓рд┐рдП UI рдШрдЯрдХреЛрдВ рдХрд╛ рдПрдХ рд╕рд░рд▓ рдкреБрд╕реНрддрдХрд╛рд▓рдпред рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдореИрдВ Vue рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХреА рдпреЛрдЬрдирд╛ рдмрдирд╛ рд░рд╣рд╛ рд╣реВрдВред рдЕрдм рддрдХ, рдЗрд╕рдореЗрдВ рдХреЗрд╡рд▓ рдПрдХ рдмрдЯрди рдФрд░ рдЖрдЗрдХрди рд╣реИ :)
рдЯреЗрд▓реАрдЧреНрд░рд╛рдо рдкреНрд░рддрд┐рдпреЛрдЧрд┐рддрд╛ рдХреЗ рдврд╛рдВрдЪреЗ рдореЗрдВ рдПрдХ рд╡рд┐рдЪрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рдЗрд╕ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХрд╛ рдЬрдиреНрдо рд╣реБрдЖ, рдЬрд┐рд╕рдХрд╛ рд╕рд╛рд░ рдХреНрд▓рд╛рдЗрдВрдЯ рдХрд╛ рдПрдХ рд╡реЗрдм рд╕рдВрд╕реНрдХрд░рдг рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдирд╛ рдерд╛ред рдПрдХ рд╕рд╣рдпреЛрдЧреА рдХреЗ рд╕рд╛рде, рд╣рдордиреЗ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛, рдХреНрдпреЛрдВ рди рдЗрд╕рдореЗрдВ рднрд╛рдЧ рд▓рд┐рдпрд╛ рдЬрд╛рдПред рднреВрдорд┐рдХрд╛рдПрдБ рд╕рд╛рдЭрд╛ рдХреА рдЧрдИрдВ рддрд╛рдХрд┐ рдореЗрд░реЗ рдкрд╛рд╕ рдПрдХ рд▓реЗрдЖрдЙрдЯ рд╣реЛ, рдФрд░ рдЬрдм рдХреЛрдИ рд╕рд╣рдХрд░реНрдореА рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдХреЛ рд╕рдордЭрддрд╛ рд╣реИ, рддреЛ рдореИрдВ рдШрдЯрдХреЛрдВ рдХреЛ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдЬреБрдбрд╝реВрдВрдЧрд╛ред рд╕рдм рдХреБрдЫ рдареАрдХ рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рдЯреЗрд▓реАрдЧреНрд░рд╛рдо рдореЗрдВ рд▓реЙрдЧ рдЗрди рдХрд░рдирд╛ рдЗрддрдирд╛ рд╕рд░рд▓ рдирд╣реАрдВ рд╣реИред рдирддреАрдЬрддрди, рд╣рдордиреЗ рдХреБрдЫ рднреА рдирд╣реАрдВ рднреЗрдЬрд╛, рд▓реЗрдХрд┐рди рдореИрдВрдиреЗ рд╕рдм рдХреБрдЫ рдХрд╛ рдПрдХ рдЧреБрдЪреНрдЫрд╛ рдкрдХрдбрд╝рд╛ рдФрд░ рдпрд╣ рдирд┐рдХрд▓рд╛ - рд╡реНрдпрд░реНрдеред рд▓реЗрдХрд┐рди рдЬреИрд╕рд╛ рдХрд┐ рд╡рд░рд▓рд╛рдореЛрд╡ рдХрд╣рддреЗ рд╣реИрдВ, рдЖрдкрдХреА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдХреБрдЫ рд▓рд╛рдпрдХ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЖрдкрдиреЗ рдЙрд╕ рдкрд░ рдЕрдкрдирд╛ рд╕рдордп рдмрд┐рддрд╛рдпрд╛ рд╣реИред рдЗрд╕рд╕реЗ рдЕрд╕рд╣рдордд рд╣реЛрдирд╛ рдореБрд╢реНрдХрд┐рд▓ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЕрдЧрд░ рдЖрдк рдШрдВрдЯреЛрдВ рдФрд░ рдкреИрд╕реЗ рдореЗрдВ рдЯреНрд░рд╛рдВрд╕рдлрд░ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рд╣реА рд╡реЗрдмрдкреИрдХ рд╕реЗрдЯ рдХрд░рдирд╛ рдЕрдм рдореБрдлреНрдд рдирд╣реАрдВ рд╣реИред рдЗрд╕ рд╕рд╛рд░реЗ рдЕрдкрдорд╛рди рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП, рдореИрдВрдиреЗ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ рдХрд┐ рдореБрдЭреЗ рдХрд┐рд╕реА рддрд░рд╣ рдЗрд╕реЗ рдЦреБрд▓реЗ рд╕реНрд░реЛрдд рдкрд░ рдлреЗрдВрдХрдирд╛ рд╣реИред рдХреНрдпрд╛ рдПрдХ рдмреВрдЯрд╕реНрдЯреНрд░реИрдк рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП? рдореИрдВ рдЕрдкрдиреЗ рдЕрдиреНрдп рдкреНрд░реЛрдЬреЗрдХреНрдЯреНрд╕ рдХреЗ рд▓рд┐рдП рдЕрдкрдирд╛ рдЦреБрдж рдХрд╛ рдпреВрдЖрдИ рдлреНрд░реЗрдорд╡рд░реНрдХ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред
рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдореЗрдВ рдмрдЯрди рд╢рд╛рдпрдж рдореБрдЦреНрдп рддрддреНрд╡ рд╣реИ рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рд╕рд╛рде рдЗрдВрдЯрд░реИрдХреНрдЯ рдХрд░рддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рдпрд╣ рдХрд┐рд╕реА рднреА UI рдлреНрд░реЗрдорд╡рд░реНрдХ / рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЗ рдкрд╣рд▓реЗ рдШрдЯрдХреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИред
рдЯреЗрд▓реАрдЧреНрд░рд╛рдо рдХреЗ рдбрд┐рдЬрд╛рдЗрди рдореЗрдВ, рдмрдЯрди рдХреЗ рдХрдИ рд░реВрдк рдирд╣реАрдВ рд╣реИрдВ:

рдореИрдВрдиреЗ 3 рдореБрдЦреНрдп (рдбрд┐рдлрд╝реЙрд▓реНрдЯ, рдЙрдЪреНрдЪрд╛рд░рдг, рдкреНрд░рд╛рдердорд┐рдХ) рдкрд░ рдкреНрд░рдХрд╛рд╢ рдбрд╛рд▓рд╛, рдПрдХ рдЖрдЗрдХрди рдФрд░ рд╣рд░реЗ рд░рдВрдЧ рдХреЗ рд╕рд╛рде рдЧреЛрд▓ред рдЕрднреА рднреА рдЕрд░реНрдз рдкрд╛рд░рджрд░реНрд╢реА рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕реЗ рдиреАрдЪреЗ рдЬрд╛рдиреЗ рджреЗрдВред рдЕрдзрд┐рдХрд╛рдВрд╢ рднрд╛рдЧ рдХреЗ рд▓рд┐рдП, рдПрдХреНрд╕рдорд░реНрд╕ рдпреВрдЖрдИ рдХреЛ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдореИрдВ рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рд╕реЗ рдЖрдЧреЗ рдмрдврд╝рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддрд╛ рд╣реВрдВ, рдореБрдЭреЗ рдкрддрд╛ рдирд╣реАрдВ рдЪрд▓рд╛ рд╣реИ рдХрд┐ рдкрд╛рд░рджрд░реНрд╢реА рдмрдЯрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХрд╣рд╛рдВ рд╣реЛрдЧреАред
рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рд╕реАрдПрд╕рдПрд╕ рдХрдХреНрд╖рд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЖрд░рд╛рдорджрд╛рдпрдХ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдореИрдВ рдмреАрдИрдПрдо рдЬреИрд╕реЗ рдирд╛рдордХрд░рдг рдкреНрд░рдгрд╛рд▓рд┐рдпреЛрдВ рдХрд╛ рдкреНрд░рд╢рдВрд╕рдХ рдирд╣реАрдВ рд╣реВрдВред рдореБрдЭреЗ рдмреВрдЯрд╕реНрдЯреНрд░реИрдк рдирд╛рдо рдХреА рдХрдХреНрд╖рд╛рдПрдВ рдкрд╕рдВрдж рд╣реИрдВред рд▓реЗрдХрд┐рди рдореИрдВ рдереЛрдбрд╝рд╛ рдФрд░ рд╕рд░рд▓ рдХрд░реВрдВрдЧрд╛ред рдЗрд╕рдХреЗ рдмрдЬрд╛рдп .btn .btn-primary
, .btn .primary
рдФрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдШрдЯрдХ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрд╣ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛:
<Button primary>Hey</Button>
рдПрдХ рд╣реА рдмрдЯрди рд▓реЗрдХрд┐рди рд▓рд╣рд░ рдкреНрд░рднрд╛рд╡:
<Button primary ripple>Hey</Button>
HTML / рд╕реАрдПрд╕рдПрд╕
рдпреВрдЖрдИ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЛ рдХрд┐рд╕реА рднреА рдпреВрдЖрдИ рдврд╛рдВрдЪреЗ рд╕реЗ рдирд╣реАрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдореИрдВ Vue
рдШрдЯрдХреЛрдВ рдкрд░ рд▓реЗрдЖрдЙрдЯ рдХреЛ рдлреИрд▓рд╛рдиреЗ рдХреА рдпреЛрдЬрдирд╛ рдмрдирд╛ рд░рд╣рд╛ рд╣реВрдВред рдЖрдЗрдП рд╕рд░рд▓ HTML / CSS рд╕реЗ рд╢реБрд░реБрдЖрдд рдХрд░реЗрдВред
рдЯреЗрд▓рд╡рд┐рдВрдбрд╕реНрдХреЗрдХреНрд╕ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЗ рд╣реБрдб рдХреЗ рддрд╣рдд, рдпрд╣ рдПрдХ рдЙрдкрдпреЛрдЧрд┐рддрд╛-рдкрд╣рд▓рд╛ рд╕реАрдПрд╕рдПрд╕ рдлреНрд░реЗрдорд╡рд░реНрдХ рд╣реИ, рдЕрд░реНрдерд╛рдд, рдПрдХ рдРрд╕рд╛ рдврд╛рдВрдЪрд╛ рдЬреЛ рдЖрдкрдХреЛ рдкреВрд░реНрдг-рд╡рд┐рдХрд╕рд┐рдд рдШрдЯрдХреЛрдВ рдХреЗ рдмрдЬрд╛рдп рдЙрдкрдпреЛрдЧрд┐рддрд╛рдУрдВ рдХреЗ рд╕рд╛рде рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред

Tailwindcss рдХреЗ рдЕрд▓рд╛рд╡рд╛, PostCSS рдХрд╛ рдЙрдкрдпреЛрдЧ рдорд┐рд╢реНрд░рдг, рдЪрд░, рдФрд░ рдиреЗрд╕реНрдЯреЗрдб рд╢реИрд▓рд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдЗрд╕ рддрд░рд╣ рдХреЗ рдврд╛рдВрдЪреЗ рдХреЗ рдЙрдкрдпреЛрдЧ рдФрд░ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЛ рдХреИрд╕реЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ, рдореИрдВ рдПрдХ рдЕрд▓рдЧ рд▓реЗрдЦ рдореЗрдВ рдмрддрд╛рдКрдВрдЧрд╛ред рдЗрд╕ рд╕реНрддрд░ рдкрд░, рдпрд╣ рдкрд░реНрдпрд╛рдкреНрдд рд╣реИ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЗрд╕ рддрд░рд╣ рдХреЗ рдПрдХ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рдЯреВрд▓рдХрд┐рдЯ рд╣реИ рдФрд░ рдШрдЯрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕реЗ рдкреВрд░реНрдг рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
<button>
рдореЗрдВ рдХрдИ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд╢реИрд▓рд┐рдпрд╛рдБ рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рд╣рдореЗрдВ рд╣рдЯрд╛рдиреЗ рдпрд╛ рдлрд┐рд░ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

Tailwindcss рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдмрдЯрди рдЯреИрдЧ рдореЗрдВ рдпрд╣ рд╢реИрд▓реА рд╣реИ:

рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рд╣рдЯрд╛рдП рдЧрдП рд╕рднреА рдЕрдирд╛рд╡рд╢реНрдпрдХред рдЖрдк рдмрд┐рдирд╛ рдХрд┐рд╕реА рдбрд░ рдХреЗ рдЬреЛ рдЪрд╛рд╣реЗ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдпрд╣рд╛рдБ рдПрдХ рдЪреЗрддрд╛рд╡рдиреА рд╣реИ, рдбрд┐рдлрд╝реЙрд▓реНрдЯ outline
рдЕрднреА рднреА рдирд╛рдорд╛рдВрдХрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:

XMars UI рдХреЗ рдПрдХ рдмрдЯрди рдореЗрдВ рдПрдХ .btn
рд╡рд░реНрдЧ рд╣реИ:
<button class="btn">Button</button>
рд╣рдорд╛рд░реА рд╢реИрд▓реА рдореЗрдВ рдЗрд╕ рд╡рд░реНрдЧ рдХреЛ рдЬреЛрдбрд╝реЗрдВ:
.btn { @apply text-black text-base leading-snug; @apply py-3 px-4 border-none rounded-lg; @apply inline-block cursor-pointer no-underline; &:focus { @apply outline-none; } }
рдЗрд╕ рддрдереНрдп рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдХрд┐ рдЯреЗрд▓рд╡рд┐рдВрдбрд╕реНрдХреЗрдХреНрд╕ рдЙрди рдХрдХреНрд╖рд╛рдУрдВ рдХреЛ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ рдЬрд┐рдиреНрд╣реЗрдВ рдЖрдк рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╣ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдорд┐рд╢реНрд░рдг рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред @apply
рдпрд╛ PostCSS рдХреЗ рд▓рд┐рдП рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХрд╛ рдкреНрд▓рдЧрдЗрди рдирд╣реАрдВ рд╣реИред рдпрд╣ рд╕реНрд╡рдпрдВ рдЯреЗрд▓рд╡рд┐рдВрдбрд╕реНрдХреЗрдХреНрд╕ рдХрд╛ рд╡рд╛рдХреНрдп рд╡рд┐рдиреНрдпрд╛рд╕ рд╣реИред рд▓рд╛рдЧреВ рд╣реЛрдиреЗ рд╡рд╛рд▓реА рд╢реИрд▓рд┐рдпрд╛рдБ рдЖрдорддреМрд░ рдкрд░ рдирд╛рдо рд╕реЗ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╕реНрдкрд╖реНрдЯ рд╣реЛрддреА рд╣реИрдВред py-3
рдФрд░ px-4
рдЕрдХреЗрд▓реЗ рд╕рд╡рд╛рд▓ рдкреИрджрд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдкрд╣рд▓реЗ y рдХреЗ рд╕рд╛рде рдкреИрдбрд┐рдВрдЧ рд╣реИ, рдЕрд░реНрдерд╛рдд, рд▓рдВрдмрд╡рдд, рдпрд╛рдиреА padding-top: 0.75rem;
padding-bottom: 0.75rem;
ред рдирддреАрдЬрддрди, px-4
рдХреНрд╖реИрддрд┐рдЬ рд░реВрдк рд╕реЗ padding-right: 1rem;
, padding-left: 1rem;
ред
рдЯреЗрд▓реАрдЧреНрд░рд╛рдо рдХреЛ рдЗрд╕реЗ рд╣рд▓реНрдХрд╛ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЬреЛ рдбрд┐рдЬрд╝рд╛рдЗрди рдкреНрд░рджрд╛рди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд╡рд╣ рдмрд╣реБрдд рдЦрд░рд╛рдм рд╣реИ рдФрд░ border-radius
рдмрдЯрди рдЬреИрд╕реА рдЪреАрдЬрд╝реЛрдВ рдХреЛ рдЫрд╡рд┐ рд╕реЗ рд╕реАрдзреЗ рд╢рд╛рд╕рдХ рдХреЗ рд╕рд╛рде рд▓реЗрдирд╛ рдкрдбрд╝рддрд╛ рд╣реИред рдХрднреА рд╕реЛрдЪрд╛ рд╣реИ рдХрд┐ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ border-radius
рдореЗрдВ рдореВрд▓реНрдпреЛрдВ рдХрд╛ рдХреНрдпрд╛ рдорддрд▓рдм рд╣реИ?

рдпрд╣ рд╡рд╕реНрддреБрддрдГ рдХреЛрдиреЗ рдореЗрдВ рдкрд░рд┐рдгрд╛рдореА рдЪрдХреНрд░ рдХреА рддреНрд░рд┐рдЬреНрдпрд╛ рд╣реИред рдпрджрд┐ рд╕рд╛рдореВрд╣рд┐рдХ рдЦреЗрдд рд╣реИ, рддреЛ рдЖрдк рд╢рд╛рд╕рдХ рдХреЛ рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВ рдЬреИрд╕рд╛ рдХрд┐ рдКрдкрд░ рдЪрд┐рддреНрд░ рдореЗрдВ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ рдЬрд┐рдореНрдк рдореЗрдВ рдЖрдпрддрд╛рдХрд╛рд░ рдЪрдпрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ред

рдбрд┐рдЬрд╝рд╛рдЗрди рдореЗрдВ рдмрдЯрдиреЛрдВ border-radius
10px рд╣реИ, рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ рдЯреЗрд▓рд╡рд┐рдВрдбрд╕реНрдХреЙрд▓реНрд╕ рдореЗрдВ рдмреЙрдХреНрд╕ рд╕реЗ рдРрд╕реА рдХреЛрдИ рдХрдХреНрд╖рд╛ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВрдиреЗ рдиреЗрддреНрд░рд╣реАрди рдЧреЛрд▓- rounded-lg
рдХрд┐рдпрд╛ рдерд╛ рдЬреЛ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдлрд╝реЙрдиреНрдЯ рдЖрдХрд╛рд░ (рд░реЗрдо) рдХреЗ рд▓рд┐рдП 8px
ред
рдпрд╣рд╛рдБ рдЗрд╕ рд╕рдордп рдХреНрдпрд╛ рд╣реБрдЖ рд╣реИ, рдореИрдВрдиреЗ рдмрдЯрди рдХреЛ рдЧреНрд░реЗ рд░рдВрдЧ рдореЗрдВ рдЪрд┐рддреНрд░рд┐рдд рдХрд┐рдпрд╛ рддрд╛рдХрд┐ рдХрд┐рдирд╛рд░реЛрдВ рдХреЛ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХреЗ:

рдЕрдЧрд▓рд╛, рд╣рдо рдкрд░ рдПрдХ рдкреНрд░рднрд╛рд╡ рдмрдирд╛рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ :hover
ред рддрдм рдЯреЗрд▓реАрдЧреНрд░рд╛рдо рдХреЗ рдбрд┐рдЬрд╛рдЗрдирд░реЛрдВ рдиреЗ рдХреБрдЫ рдкреНрд░рдХрд╛рд╢ рдбрд╛рд▓рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ рдФрд░ #707579
рд╕реЗ 0.08% рдХреЗ рд░реВрдк рдореЗрдВ рд░рдВрдЧ рдХрд╛ рд╕рдВрдХреЗрдд рджрд┐рдпрд╛ред рдореБрдЭреЗ рджреЛ рд╡рд┐рдХрд▓реНрдк рджрд┐рдЦрд╛рдИ рджреЗрддреЗ рд╣реИрдВ, рдмрд╕ рдЖрдИрдбреНрд░реЙрдкрд░ рдХреЗ рд╕рд╛рде рд░рдВрдЧ рд▓реЗрдВ рдпрд╛ рдЗрд╕реЗ рджрд╕реНрддрд╛рд╡реЗрдЬ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд░реЗрдВред рдкрд╣рд▓рд╛ рд╡рд┐рдХрд▓реНрдк рд╕рд░рд▓ рд╣реИ, рд▓реЗрдХрд┐рди рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдпрд╣ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рдирд╣реАрдВ рд╣реИред рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ рдЕрдЧрд░ рдкреГрд╖реНрдарднреВрдорд┐ рд╕рдлреЗрдж рд╕реЗ рдЕрд▓рдЧ рд╣реИ, рддреЛ рдкрд░ :hover
рд╣рдореЗрдВ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд░рдВрдЧ рдорд┐рд▓реЗрдЧрд╛, рдмрдЯрди рдХреА "рд▓рдкрдЯ" рдФрд░ рдкрд╛рд░рджрд░реНрд╢рд┐рддрд╛ рдЦреЛ рджреЗрдВрдЧреЗред рдЗрд╕рдХреЗ рд▓рд┐рдП рдкреНрд░рд▓реЗрдЦрди рдХрд╛ рдкрд╛рд▓рди рдХрд░рдирд╛ рдФрд░ рдЕрд▓реНрдлрд╛ рд░рдЦрдирд╛ рдмреЗрд╣рддрд░ рд╣реИ рдирд░ рдЪреИрдирд▓ред рдпрд╣ рдЕрдирдЧрд┐рдирдд рддрд░реАрдХреЛрдВ рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП SCSS рд░рдВрдЧ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ред рд▓реЗрдХрд┐рди рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдХреЛрдИ SCSS рдирд╣реАрдВ рд╣реИ, рдФрд░ рдЙрд╕реА рд░рдВрдЧ рдХреЗ рдХрд╛рд░рдг, рдореИрдВ рдХрд┐рд╕реА рдкреНрд▓рдЧ-рдЗрди рдХреЛ PostCSS рд╕реЗ рдЬреЛрдбрд╝рдирд╛ рдирд╣реАрдВ рдЪрд╛рд╣рддрд╛, рд╣рдо рд╕рдм рдХреБрдЫ рдмрд╣реБрдд рд╕рд░рд▓ рдХрд░ рджреЗрдВрдЧреЗред рдХреНрд░реЛрдо рдореЗрдВ, рдПрдХ рдХреЛрд▓реЛрдкреЗрдХрд░ рд╣реИ рдЬреЛ рдЖрдкрдХреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдкреНрд░рдгрд╛рд▓рд┐рдпреЛрдВ рдореЗрдВ рд░рдВрдЧ рдмрджрд▓рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, #707579
рд░рдВрдЧ #707579
, rgba
рдореЗрдВ рдЕрдиреБрд╡рд╛рдж рдХрд░реЗрдВ рдФрд░ рдЕрд▓реНрдлрд╛ рдЪреИрдирд▓ - 0.08% рд╕реЗрдЯ рдХрд░реЗрдВред

рджреЗрдЦрд╛! рдХреБрдЫ рддреЗрдЬреА рд╕реЗ рдореЗрд░реА рддрд╕реНрд╡реАрд░ рднрдбрд╝рдХреА:

рд╣рдореЗрдВ rgba(112, 117, 121, 0.08)
- rgba(112, 117, 121, 0.08)
ред

(: рд╣реЙрд╡рд░)
рдФрд░ рдЕрдзрд┐рдХ рдЙрдмрд╛рдК рдФрд░ рдмрд╣реБрдд рдкреНрд░рдпрд╛рд╕ рдХреЗ рдмрд┐рдирд╛, рдореИрдВрдиреЗ рдмрд╛рдХреА рд░рд╛рдЬреНрдп рдЬреЛрдбрд╝рд╛:
&:hover { background-color: var(--grey04); } &.accent { color: var(--blue01); } &.primary { @apply text-white; background-color: var(--blue01); &:hover { background-color: var(--blue02); } }
рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдШрдЯрдХ
рдкреНрд░рд╛рд░рдВрдн рдореЗрдВ, рдЯреЗрд▓реАрдЧреНрд░рд╛рдо рдкреНрд░рддрд┐рдпреЛрдЧрд┐рддрд╛ рдХреЗ рд▓рд┐рдП рдмрдЯрди рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рдерд╛ рдФрд░ рдХрд┐рд╕реА рднреА рдврд╛рдВрдЪреЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЕрд╕рдВрднрд╡ рдерд╛ред рдореБрдЭреЗ рд╢реБрджреНрдз рдЬреЗрдПрд╕ рдкрд░ рддрд░рдВрдЧ рдкреНрд░рднрд╛рд╡ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдерд╛ред рдореИрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдРрд╕рд╛ рд╣реА рд░рд╣рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛, рд▓реЗрдХрд┐рди рдЬрдм рдЖрдк рдЕрдХреЗрд▓реЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХрд░ рд░рд╣реЗ рд╣реЛрдВ, рддреЛ рдЖрдкрдХреЛ рдХреБрдЫ рддреНрдпрд╛рдЧ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред
рдРрд╕реЗ рдШрдЯрдХ рдЬрд┐рдиреНрд╣реЗрдВ рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХреЗ рддрд░реНрдХ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЬреИрд╕реЗ рдХрд┐ рддрд░рдВрдЧ рдкреНрд░рднрд╛рд╡, рдХреЛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рдХреЗрд╡рд▓ рд░рд┐рдПрдХреНрдЯ рдШрдЯрдХреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрд▓рдмреНрдз рд╣реЛрдЧрд╛ред
рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдШрдЯрдХ рдореЗрдВ рдмрдЯрди рдХреЛ рд▓рдкреЗрдЯрдирд╛ рдореБрд╢реНрдХрд┐рд▓ рдирд╣реАрдВ рд╣реИ:
import React, { FunctionComponent } from 'react'; export interface ButtonProps { } const Button: FunctionComponent<ButtonProps> = (props) => { return ( <button className="btn">props.children</button> ); } export default Button;
рдпрд╣ рдмрдЯрди рдирд┐рд░реНрджрд┐рд╖реНрдЯ рд╢реИрд▓реА рдореЗрдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рд▓реЗрдХрд┐рди рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдпрд╣ рдХрдо рдЙрдкрдпреЛрдЧ рдХрд╛ рд╣реИред рд╣рдореЗрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдмрдЯрди рдХреЛ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░рдиреЗ, рдХрд╕реНрдЯрдо рд╢реИрд▓рд┐рдпреЛрдВ рдХреЛ рдЬреЛрдбрд╝рдиреЗ, рдЗрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд░ рдХреЛ рд▓рдЯрдХрд╛рдиреЗ рдФрд░ рдЗрддрдиреЗ рдкрд░ рд╕рдХреНрд╖рдо рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдЖрд╡рд╢реНрдпрдХ рд╣рд░ рдЪреАрдЬ рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП, рдкрд╣рд▓реЗ рдЖрдкрдХреЛ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рджреВрд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЕрдиреНрдпрдерд╛ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдСрдирдХреНрд▓рд┐рдХ рднреА рдЖрдкрдХреЛ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрдЧрд╛ред ButtonProps
рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рдереЛрдбрд╝рд╛ рд╕рдВрдкрд╛рджрд┐рдд ButtonProps
, рд╣рдо рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рддреЗ рд╣реИрдВ:
export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement>
рдЬрд┐рд╕рдХреЗ рдмрд╛рдж рд╣рдо рд╕реБрд░рдХреНрд╖рд┐рдд рд░реВрдк рд╕реЗ рд╡рд┐рдирд╛рд╢ рдХреЛ props
рд╕рдХрддреЗ рд╣реИрдВ:
<button className="btn" {...props}>props.children</button>
рдмрдЯрди рдХрд╛ рд╕рдорд╛рди рдЙрдкрдпреЛрдЧ рдЕрдкреЗрдХреНрд╖рд┐рдд рд░реВрдк рд╕реЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░реЗрдЧрд╛:
<Button onClick={() => alert()}>Hey</Button>

рдЕрдЧрд▓рд╛, рд╣рдо рдмрдЯрди рд╢реИрд▓рд┐рдпреЛрдВ рдФрд░ рдПрдХ рдХрд╕реНрдЯрдо (рдЕрдЪрд╛рдирдХ рдХрд┐рд╕реА рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА) рдХреЛ рдкрдВрдЬреАрдХреГрдд рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдХреЛ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред рдЗрди рдЙрджреНрджреЗрд╢реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП npm classnames рдкреИрдХреЗрдЬ рдПрдХрджрдо рд╕рд╣реА рд╣реИред
export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> { primary?: boolean, accent?: boolean, additionalClass?: string, } ... const classNames = classnames( 'btn', { primary }, { accent }, additionalClass ); ... <button className={classNames} {...props}>props.children</button>
btn
рд╡рд░реНрдЧ рд╣рдореЗрд╢рд╛ рд╕реЗрдЯ рд╣реЛрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди primary
рдФрд░ accent
рдХреЗрд╡рд▓ рдЕрдЧрд░ true
ред рдХреНрд▓рд╛рд╕рдирд╛рдо рдПрдХ рд╡рд░реНрдЧ рдХреЛ рдЬреЛрдбрд╝рддрд╛ рд╣реИ рдпрджрд┐ рдЗрд╕рдХрд╛ рдПрдХ рддрд╛рд░реНрдХрд┐рдХ true
рдореВрд▓реНрдп рд╣реИ, рддреЛ ES6 рд╕реЗ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рдирд╛рдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╣рдо { primary: true }
рдмрдЬрд╛рдп рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ { primary }
рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВред
additionalClass
рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╣реИ, рдФрд░ рдпрджрд┐ рдпрд╣ рдЦрд╛рд▓реА рдпрд╛ рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд рд╣реИ, рддреЛ рдпрд╣ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рд╢реЗрд╖ рднреВрдорд┐рдХрд╛ рдирд╣реАрдВ рдирд┐рднрд╛рддрд╛ рд╣реИ, рдмрд╕ рддрддреНрд╡ рдореЗрдВ рдХреБрдЫ рднреА рдирд╣реАрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рдПрдЧрд╛ред
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдореИрдВрдиреЗ props
рдХреЛ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╕реМрдВрдкрд╛:
{...omit(props, ['additionalClass', 'primary'])}
рд╕рдм рдХреБрдЫ рд╣реИ рдХрд┐ рдмрдЯрди рддрддреНрд╡ рдХреЗ props
рдХреА props
рдкрд░ рд▓рд╛рдЧреВ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдкреНрд░рд╕реНрддреБрдд рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ред
рддрд░рдВрдЧ рдкреНрд░рднрд╛рд╡

рджрд░рдЕрд╕рд▓, рдпрд╣ рд╡рд╣реА рд╣реИ рдЬреЛ рджрд┐рдЦрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рд╡рд╛рдВрдЫрдиреАрдп рд╣реИ рдХрд┐ "рд▓рд╣рд░" рдХреНрд▓рд┐рдХ рдХреЗ рд╕реНрдерд╛рди рд╕реЗ рд╡рд┐рдЪрд▓рди рдХрд░рддреА рд╣реИред
рдРрд╕реЗ рдПрдиреАрдореЗрд╢рди рдмрдирд╛рдиреЗ рдХреЗ рдЕрдирдЧрд┐рдирдд рддрд░реАрдХреЗ рд╣реИрдВ, рдпрд╣ рдиреАрд▓реЗ рд╡рд░реНрдЧ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рдордЬрд╛рдХ рдХреА рддрд░рд╣ рд╣реИред
рд▓реЗрдХрд┐рди google, рдХреЛрдбрдкреЗрди рдХреЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП, рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реЛ рдЧрдпрд╛ рдХрд┐ рдЬреНрдпрд╛рджрд╛рддрд░ рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рдПрдХ "рд▓рд╣рд░" рдХрд╛ рдПрд╣рд╕рд╛рд╕ рдПрдХ рдмрд╛рд▓ рддрддреНрд╡ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╣реЛрддрд╛ рд╣реИ, рдЬреЛ рдлреИрд▓рддрд╛ рд╣реИ рдФрд░ рдЧрд╛рдпрдм рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред
рдпрд╣ рдХреНрд▓рд┐рдХ рдХреЗ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдмрдЯрди рдХреЗ рдЕрдВрджрд░ рд╕реНрдерд┐рдд рд╣реИред рдПрдХреНрд╕рдПрдордЖрд░ рдпреВрдЖрдИ рдореЗрдВ , рдЗрд╕ рд╕рдордп рдореИрдВрдиреЗ рдСрдирдПрдк рдкрд░ рдЗрд╕ рдкреНрд░рднрд╛рд╡ рдХреЛ рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ рдЬреИрд╕рд╛ рдХрд┐ рдордЯреЗрд░рд┐рдпрд▓ рдпреВрдЖрдИ рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдЗрд╕реЗ onPress
рдпреЛрдЬрдирд╛ рдмрдирд╛ рд░рд╣рд╛ рд╣реВрдВред рдЕрднреА рддрдХ, рдХреЗрд╡рд▓ onClick
ред

рдКрдкрд░ рдХреА рддрд╕реНрд╡реАрд░ рд╕рднреА рдЬрд╛рджреВ рд╣реИред рдПрдХ рдХреНрд▓рд┐рдХ рд╕реЗ рдЪрд╛рдЗрд▓реНрдб рдмрдЯрди рдПрд▓рд┐рдореЗрдВрдЯ рдмрдирддрд╛ рд╣реИ, рдпрд╣ рдХреНрд▓рд┐рдХ рдХреЗ рдХреЗрдВрджреНрд░ рдореЗрдВ рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдлреИрд▓рддрд╛ рд╣реИред overflow: hidden
рд╕рдВрдкрддреНрддрд┐ рд▓рд╣рд░ рдХреЛ рдмрдЯрди рд╕реЗ рдкрд░реЗ рдЬрд╛рдиреЗ рд╕реЗ overflow: hidden
ред рдПрдиреАрдореЗрд╢рди рдХреЗ рдЕрдВрдд рдореЗрдВ рдЖрдЗрдЯрдо рдХреЛ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рдЙрди рд╢реИрд▓рд┐рдпреЛрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВрдЧреЗ рдЬрд╣рд╛рдВ рд╣рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрд┐рддрдирд╛ рд╕рдВрднрд╡ рд╣реЛ рд╕рдХреЗ рдЯреЗрд▓рд╡рд┐рдВрдбрд╕реНрдХрд▓реНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛:
.with-ripple { @apply relative overflow-hidden; @keyframes ripple { to { @apply opacity-0; transform: scale(2.5); } } .ripple { @apply absolute; z-index: 1; border-radius: 50%; background-color: var(--grey04); transform: scale(0); animation: ripple 0.6s linear; } &.primary { .ripple { background-color: var(--black02); } } }
рдкреНрд░рднрд╛рд╡ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рддрддреНрд╡ рдХреЛ рд╡рд░реНрдЧ .ripple
рд╕реМрдВрдкрд╛ рдЬрд╛рдПрдЧрд╛ред border-radius: 50%;
рдПрдХ рд╡реГрддреНрдд (рдХреЛрдг * 2 рдкрд░ 50% рдкрдЯреНрдЯрд┐рдХрд╛) рдХреЗ рдмрд░рд╛рдмрд░ рд╣реЛрддрд╛ рд╣реИ, рдмрдЯрди рдореЗрдВ рд╕рд╛рдкреЗрдХреНрд╖ рд╕реНрдерд┐рддрд┐ рд╣реЛрддреА рд╣реИ .ripple
рдмрдЯрди рдореЗрдВ рдкреВрд░реНрдг рд╕реНрдерд┐рддрд┐ рд╣реЛрддреА рд╣реИред рдПрдиреАрдореЗрд╢рди рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИ, рдмрдврд╝рддреА рд▓рд╣рд░ 0.6 рд╕реЗрдХрдВрдб рдореЗрдВ рдкрд╛рд░рджрд░реНрд╢реА рд╣реЛ рдЬрд╛рддреА рд╣реИред рдкреГрд╖реНрдарднреВрдорд┐ рдХрд╛ рд░рдВрдЧ рд╕рдорд╛рди рд╣реИ :hover
рдФрд░ рдлреЛрд▓реНрдбрд┐рдВрдЧ, рджреЛ рдкрд╛рд░рджрд░реНрд╢реА "рддрд░рдВрдЧ" рд░рдВрдЧ рдФрд░ рдмрдЯрди рд╣рдореЗрдВ рд╡рд╛рдВрдЫрд┐рдд рдкрд░рд┐рдгрд╛рдо рджреЗрддреЗ рд╣реИрдВред рдиреАрд▓реЗ .primary
рдмрдЯрди рдкрд░, рдпрд╣ рдЗрддрдирд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдирд╣реАрдВ рд╣реИ рдФрд░ рд╡рд╣рд╛рдВ рдЖрдк рдПрдХ рдЧреИрд░-рдкрд╛рд░рджрд░реНрд╢реА рд░рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдХреНрд▓рд┐рдХ рдХрд░рдиреЗ рдкрд░, рдЖрдкрдХреЛ "рддрд░рдВрдЧ" рддрддреНрд╡ рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рд╣рдо рдЗрд╕ рд╡реНрдпрд╡рд╕рд╛рдп рдХреЗ рд▓рд┐рдП рдПрдХ рд░рд╛рдЬреНрдп рдмрдирд╛рддреЗ рд╣реИрдВ рдФрд░ рдмрдЯрди рдкрд░ рдЙрдкрдпреБрдХреНрдд рдХреНрд▓рд┐рдХ рд╣реИрдВрдбрд▓рд░ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЗрд╕ рддрд░рд╣ рд╕реЗ рдХрд┐ рдпрд╣ рдХрд╕реНрдЯрдо рдСрдирдХреНрд▓рд┐рдХ рдХреЗ рд╕рд╛рде рд╣рд╕реНрддрдХреНрд╖реЗрдк рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред
... const [rippleElements, setRippleElements] = useState<JSX.Element[]>([]); ... function renderRippleElements() { return rippleElements; } return ( <button className={classNames} {...props} onClick={(event) => { if (props.onClick) { props.onClick(event); } if (ripple) { onRippleClick(event); } }} > {children} {renderRippleElements()} </button> );
rippleElements
- rippleElements
рддрддреНрд╡реЛрдВ рдХреА рдПрдХ рд╕рд░рдгреА, рдпрд╣рд╛рдБ рд░реЗрдВрдбрд░ рдлрд╝рдВрдХреНрд╢рди рдирд┐рд░рд░реНрдердХ рд▓рдЧ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рднрд╡рд┐рд╖реНрдп рдХреЗ рд▓рд┐рдП рд╕реНрдЯрд╛рдЗрд▓ рдФрд░ рдирд┐рдЧрдорди рдХрд╛ рд╡рд┐рд╖рдп рд╣реИред
function onRippleClick(event: React.MouseEvent<HTMLButtonElement, MouseEvent>) { var rect = event.currentTarget.getBoundingClientRect(); const d = Math.max(event.currentTarget.clientWidth, event.currentTarget.clientHeight); const left = event.clientX - rect.left - d/2 + 'px'; const top = event.clientY - rect.top - d/2 + 'px'; const rippleElement = newRippleElement(d, left, top); setRippleElements([...rippleElements, rippleElement]); } function newRippleElement(d: number, left: string, top: string) { const key = uuid(); return ( <div key={key} className="ripple" style={{width: d, height: d, left, top}} onAnimationEnd={() => onAnimationEnd(key)} > </div> ); }
onRippleClick
рд╣реИрдВрдбрд▓рд░ рдЬреЛ "рддрд░рдВрдЧреЗрдВ" рдмрдирд╛рддрд╛ рд╣реИред рдмрдЯрди рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░рдХреЗ, рд╣рдо рдЙрд╕ рдмрдЯрди рдХреЗ рдЖрдХрд╛рд░ рдХрд╛ рдкрддрд╛ newRippleElement
рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рд╕рд░реНрдХрд▓ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рдмрд╛рдж рдЖрд╡рд╢реНрдпрдХ рд╕рднреА newRippleElement
рдХреЛ newRippleElement
рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдкрд╛рд╕ рдХрд┐рдпрд╛ newRippleElement
рд╣реИ newRippleElement
рдЬреЛ рдмрджрд▓реЗ рдореЗрдВ рдХреЗрд╡рд▓ newRippleElement
рдХреНрд▓рд╛рд╕ рдХреЗ рд╕рд╛рде рдПрдХ newRippleElement
рддрддреНрд╡ рдмрдирд╛рддрд╛ рд╣реИ, рд╕реНрдерд┐рддрд┐ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╢реИрд▓рд┐рдпреЛрдВ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рддрд╛ рд╣реИред
onAnimationEnd
рд╣рд╛рдЗрд▓рд╛рдЗрдЯ рдХрд░рдиреЗ рд▓рд╛рдпрдХ рдореБрдЦреНрдп рдЪреАрдЬреЛрдВ рдореЗрдВ рд╕реЗред рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП рддрддреНрд╡реЛрдВ рд╕реЗ рдбреЛрдо рдХреЛ рдЦрд╛рд▓реА рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдореЗрдВ рдЗрд╕ рдШрдЯрдирд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
function onAnimationEnd(key: string) { setRippleElements(rippleElements => rippleElements.filter(element => element.key !== key)); }
рдпрд╣ рдмрд╣реБрдд рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ рдХрд┐ рднреВрд▓ рди рдХрд░реЗрдВ, рд╡рд░реНрддрдорд╛рди rippleElements
рдХреЛ рддрд░реНрдХреЛрдВ рдореЗрдВ рдкрд╛рд░рд┐рдд рдХрд░реЗрдВ, рдЕрдиреНрдпрдерд╛ рдЖрдк рдкреБрд░рд╛рдиреЗ рдореВрд▓реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рд╕рд░рдгреА рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рд╕рдмрдХреБрдЫ рдЗрд░рд╛рджрд╛ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ред
рдкреВрд░реНрдг рдмрдЯрди рдХреЛрдб:
import React, { FunctionComponent, ButtonHTMLAttributes, useState } from 'react'; import uuid from 'uuid/v4'; import classnames from 'classnames'; export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> { primary?: boolean, accent?: boolean, circle?: boolean, ripple?: boolean, additionalClass?: string, } const Button: FunctionComponent<ButtonProps> = (props) => { const [rippleElements, setRippleElements] = useState<JSX.Element[]>([]); const {primary, accent, circle, ripple, additionalClass, children} = props; const classNames = classnames( 'btn', { primary }, { 'with-ripple': ripple }, { circle }, { accent }, additionalClass ); function onAnimationEnd(key: string) { setRippleElements(rippleElements => rippleElements.filter(element => element.key !== key)); } function onRippleClick(event: React.MouseEvent<HTMLButtonElement, MouseEvent>) { var rect = event.currentTarget.getBoundingClientRect(); const d = Math.max(event.currentTarget.clientWidth, event.currentTarget.clientHeight); const left = event.clientX - rect.left - d/2 + 'px'; const top = event.clientY - rect.top - d/2 + 'px'; const rippleElement = newRippleElement(d, left, top); setRippleElements([...rippleElements, rippleElement]); } function newRippleElement(d: number, left: string, top: string) { const key = uuid(); return ( <div key={key} className="ripple" style={{width: d, height: d, left, top}} onAnimationEnd={() => onAnimationEnd(key)} > </div> ); } function renderRippleElements() { return rippleElements; } return ( <button className={classNames} {...props} onClick={(event) => { if (props.onClick) { props.onClick(event); } if (ripple) { onRippleClick(event); } }} > {children} {renderRippleElements()} </button> ); } export default Button;
рдЕрдВрддрд┐рдо рдкрд░рд┐рдгрд╛рдо рдпрд╣рд╛рдВ рдмрддрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдирд┐рд╖реНрдХрд░реНрд╖
рдХрд╛рдлреА рдХреБрдЫ рдЫреЛрдбрд╝ рджрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреИрд╕реЗ рд╕реНрдерд╛рдкрд┐рдд рдХреА рдЧрдИ рдереА, рджрд╕реНрддрд╛рд╡реЗрдЬ рдХреИрд╕реЗ рд▓рд┐рдЦреЗ рдЧрдП рд╣реИрдВ, рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдПрдХ рдирдП рдШрдЯрдХ рдХреЗ рд▓рд┐рдП рдкрд░реАрдХреНрд╖рдгред рдореИрдВ рдЗрди рд╡рд┐рд╖рдпреЛрдВ рдХреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдкреНрд░рдХрд╛рд╢рдиреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╡рд░ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реВрдВрдЧрд╛ред
рдПрдХреНрд╕рдПрдордЖрд░ рдпреВрдЖрдИ рдЬреАрдердм рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА