UNPKG

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
/* =========================== 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; }