hs-library
Version:
Optimistic UI library for React and Next.js. Modern, reusable components: Inputs, Buttons, Cards, Dropdowns, Modals, Toasts — and more magical UI tools for frontend developers. author: Hitesh Saini
625 lines (544 loc) • 11.6 kB
CSS
/* ===========================
Base Container & Label
=========================== */
.hs_container {
position: relative;
width: 100%;
margin-bottom: 1rem;
font-family: "Inter", sans-serif;
}
.hs_label {
display: block;
font-size: 0.9rem;
font-weight: 600;
color: #374151;
margin-bottom: 0.35rem;
}
.hs_required {
color: #ef4444;
margin-left: 0.25rem;
font-weight: bold;
}
/* ===========================
Input Styles
=========================== */
.hs_input {
width: 350px;
padding: 0.6rem 0.75rem;
border-radius: 0.5rem;
border: 1px solid #d1d5db;
background-color: #fff;
font-size: 0.95rem;
color: #111827;
transition: all 0.2s ease;
}
.hs_input:hover {
border-color: #9ca3af;
}
.hs_input:focus {
outline: none;
border-color: #2563eb;
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.3);
}
/* Disabled State */
.hs_disabled {
cursor: not-allowed;
background-color: #f3f4f6;
color: #9ca3af;
opacity: 0.7;
}
/* ===========================
Input State Variants
=========================== */
.hs_input--success {
border-color: #10b981;
background-color: #ecfdf5;
}
.hs_input--error {
border-color: #ef4444;
background-color: #fef2f2;
}
.hs_input--warning {
border-color: #f59e0b;
background-color: #fffbeb;
}
.hs_input--small {
padding: 0.4rem 0.5rem;
font-size: 0.85rem;
}
.hs_input--large {
padding: 0.85rem 1rem;
font-size: 1rem;
}
/* ===========================
Dropdown Menu
=========================== */
.hs_dropdown {
position: absolute;
z-index: 20;
margin-top: 0.35rem;
width: 100%;
background-color: #fff;
border: 1px solid #d1d5db;
border-radius: 0.5rem;
box-shadow: 0px 4px 12px rgba(0, 0, 0, 0.08);
max-height: 15rem;
overflow-y: auto;
animation: dropdownFade 0.15s ease-in-out;
}
/* Dropdown Animation */
@keyframes dropdownFade {
from {
opacity: 0;
transform: translateY(-0.25rem);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* ===========================
Search Bar
=========================== */
.hs_searchWrapper {
padding: 0.5rem;
border-bottom: 1px solid #e5e7eb;
background-color: #fafafa;
}
.hs_searchInput {
width: 100%;
padding: 0.4rem 0.5rem;
border-radius: 0.375rem;
border: 1px solid #d1d5db;
font-size: 0.9rem;
}
.hs_searchInput:focus {
outline: none;
border-color: #2563eb;
box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.25);
}
/* ===========================
Options
=========================== */
.hs_option {
padding: 0.6rem 1rem;
font-size: 0.95rem;
cursor: pointer;
transition: background 0.2s ease;
}
.hs_option:hover,
.hs_option[aria-selected="true"] {
background-color: #ebf4ff;
color: #1d4ed8;
font-weight: 500;
}
/* Option Disabled */
.hs_option--disabled {
color: #9ca3af;
cursor: not-allowed;
background-color: #f9fafb;
}
/* ===========================
Messages
=========================== */
.hs_message {
padding: 0.75rem 1rem;
font-size: 0.9rem;
text-align: center;
color: #6b7280;
font-style: italic;
}
/* States */
.hs_message--success {
color: #059669;
}
.hs_message--error {
color: #dc2626;
}
.hs_message--warning {
color: #d97706;
}
/* ===========================
Utility
=========================== */
.hs_pointer {
cursor: pointer;
}
.hs_hidden {
display: none;
}
.hs_center {
text-align: center;
}
.hs_flex {
display: flex;
align-items: center;
justify-content: space-between;
}
.hs_input_message_required {
color: red;
padding: 1px 6px;
}
/* ===========================
Profile Upload Component
=========================== */
/* =========================
Profile Component Styles
Prefix: hs_
========================= */
.hs_profileContainer {
display: flex;
align-items: center;
gap: 20px;
font-family: "Inter", sans-serif;
}
/* Wrapper ensures correct positioning */
.hs_profileWrapper {
position: relative;
width: 130px;
height: 130px;
flex-shrink: 0;
}
/* Profile image avatar */
.hs_profileAvatar {
width: 100%;
height: 100%;
border-radius: 50%;
border: 3px solid #444a57;
object-fit: cover;
background-color: #f8f8f8;
box-shadow: 0 6px 14px rgba(0, 0, 0, 0.25);
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.hs_profileAvatar:hover {
transform: scale(1.03);
box-shadow: 0 8px 18px rgba(0, 0, 0, 0.3);
}
/* Placeholder if no image */
.hs_profilePlaceholder {
width: 100%;
height: 100%;
border-radius: 50%;
background: linear-gradient(135deg, #e0e2e4, #c7c9cc);
color: #777;
display: flex;
justify-content: center;
align-items: center;
font-weight: 600;
font-size: 20px;
border: 3px solid #999ca3;
box-shadow: 0 6px 14px rgba(0, 0, 0, 0.25);
user-select: none;
}
/* Upload button (camera icon wrapper) */
.hs_uploadLabel {
position: absolute;
bottom: 4px;
right: 4px;
width: 20px;
height: 20px;
background: #ffffff;
border-radius: 50%;
border: 2px solid #ddd;
display: flex;
justify-content: center;
align-items: center;
box-shadow: 0 3px 8px rgba(0, 0, 0, 0.25);
cursor: pointer;
transition: all 0.25s ease;
}
.hs_uploadLabel:hover {
background: #f7f7f7;
transform: scale(1.05);
}
/* Hidden input */
.hs_uploadInput {
display: none;
}
/* Uploading state */
.hs_uploadingText {
font-size: 13px;
color: #666;
margin-top: 8px;
font-style: italic;
}
/* Overlay */
.hs_modal-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.6);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
}
/* Modal */
.hs_modal-content {
background: #fff;
padding: 20px;
border-radius: 12px;
width: 400px;
max-width: 90%;
position: relative;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
}
/* Modal Body */
.hs_modal-body {
font-size: 16px;
color: #333;
}
/* Close Button Base */
.hs_close-btn {
position: absolute;
cursor: pointer;
padding: 3px;
background: white;
transition: background 0.2s ease-in-out;
}
.hs_close-btn:hover {
background: #ebe9e9;
border-radius: 5px;
padding: 3px;
}
/* Position Options */
.hs_top-right {
top: 10px;
right: 10px;
}
.hs_top-left {
top: 10px;
left: 10px;
}
.hs_bottom-right {
bottom: 3px;
right: 3px;
}
.hs_bottom-left {
bottom: 3px;
left: 4px;
}
/* =============================
Profile Upload Container
============================= */
.hs_profileContainer {
display: flex;
flex-direction: column;
align-items: center;
font-family: "Inter", sans-serif;
gap: 12px;
}
/* =============================
Avatar Wrapper & Image
============================= */
.hs_profileWrapper {
position: relative;
width: 130px;
height: 130px;
}
.hs_profileAvatar {
width: 130px;
height: 130px;
border-radius: 50%;
border: 3px solid #d1d5db;
object-fit: cover;
box-shadow: 0 6px 14px rgba(0, 0, 0, 0.2);
transition: transform 0.25s ease, box-shadow 0.25s ease;
}
.hs_profileAvatar:hover {
transform: scale(1.03);
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.25);
}
.hs_profilePlaceholder {
width: 130px;
height: 130px;
border-radius: 50%;
background: linear-gradient(135deg, #f3f4f6, #e5e7eb);
display: flex;
justify-content: center;
align-items: center;
border: 3px solid #d1d5db;
color: #6b7280;
font-size: 2rem;
box-shadow: 0 6px 14px rgba(0, 0, 0, 0.2);
}
/* =============================
Upload Button
============================= */
.hs_uploadLabel {
position: absolute;
bottom: 8px;
right: 8px;
background: #ffffff;
padding: 8px;
border-radius: 50%;
display: flex;
cursor: pointer;
box-shadow: 0 3px 8px rgba(0, 0, 0, 0.2);
transition: background 0.2s ease, transform 0.2s ease;
}
.hs_uploadLabel:hover {
background: #f3f4f6;
transform: scale(1.1);
}
.hs_uploadInput {
display: none;
}
/* =============================
Eye Button
============================= */
.hs_eyeBtn {
position: absolute;
top: 50%;
right: 40%;
background: #a7a6a680;
padding: 2px;
display: flex;
justify-content: center;
align-items: center;
border-radius: 50%;
transform: translateY(-50%);
border: none;
cursor: pointer;
transition: background 0.2s ease, transform 0.2s ease;
}
.hs_eyeBtn:hover {
transform: scale(1.05) translateY(-50%);
}
/* =============================
Uploading Text
============================= */
.hs_uploadingText {
font-size: 14px;
color: #6b7280;
}
/* Modal Overlay */
.hs_modalOverlay {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.65);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
animation: fadeIn 0.25s ease-in-out;
}
/* Modal Content */
.hs_modalContent {
position: relative;
background: transparent;
border-radius: 12px;
max-width: 90%;
max-height: 90%;
animation: scaleUp 0.25s ease-in-out;
}
/* Modal Image */
.hs_modalImage {
max-width: 100%;
max-height: 90vh;
border-radius: 12px;
object-fit: contain;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
}
/* Close Button (Floating Outside) */
.hs_modalCloseBtn {
position: fixed;
top: 20px;
right: 20px;
background: #ffffff;
border: none;
border-radius: 50%;
padding: 8px;
cursor: pointer;
z-index: 1100;
box-shadow: 0 3px 8px rgba(0, 0, 0, 0.25);
transition: background 0.2s ease, transform 0.2s ease;
}
.hs_modalCloseBtn:hover {
background: #f3f4f6;
transform: scale(1.1);
}
/* Animations */
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes scaleUp {
from {
transform: scale(0.95);
}
to {
transform: scale(1);
}
}
/* ===========================
Multi-Select Styles
=========================== */
/* Wrapper for selected chips */
.hs_multiWrapper {
min-height: 42px;
width: 350px;
border: 1px solid #d1d5db;
border-radius: 0.5rem;
padding: 0.35rem 0.5rem;
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0.4rem;
cursor: pointer;
background-color: #fff;
transition: border 0.2s ease, box-shadow 0.2s ease;
}
.hs_multiWrapper:hover {
border-color: #9ca3af;
}
.hs_multiWrapper:focus-within {
border-color: #2563eb;
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.25);
}
/* Chips */
.hs_chip {
display: inline-flex;
align-items: center;
gap: 0.35rem;
background: #f3f4f6;
border-radius: 9999px;
padding: 0.25rem 0.6rem;
font-size: 0.85rem;
font-weight: 500;
color: #374151;
border: 1px solid #e5e7eb;
white-space: nowrap;
}
.hs_chip:hover {
background: #e5e7eb;
}
.hs_chipRemove {
border: none;
background: transparent;
color: #6b7280;
cursor: pointer;
font-size: 14px;
line-height: 1;
transition: color 0.2s ease;
}
.hs_chipRemove:hover {
color: #ef4444;
}
/* Placeholder text inside multi select */
.hs_multiPlaceholder {
color: #9ca3af;
font-size: 0.9rem;
}
/* Checkbox inside options */
.hs_optionCheckbox {
margin-right: 0.5rem;
pointer-events: none;
accent-color: #2563eb;
}