UNPKG

contacts-pane

Version:

Contacts Pane: Contacts manager for Address Book, Groups, and Individuals.

620 lines (524 loc) 17.1 kB
/* Focus indicator for keyboard navigation */ .contactPane table tr[tabindex="0"]:focus { outline: var(--focus-ring-width) solid var(--color-primary); outline-offset: 2px; background: var(--color-info-bg); } /* contactsPane styles — extracted from inline styles in contactsPane.js */ /* Uses CSS custom properties from the global stylesheet (dev-global.css / mashlib) */ /* ── Layout: Three-column browser ────────────────────────────── */ .contactPane .peopleSection .selected { background-color: var(--color-info-bg) !important; } .contactPane .detailSection, .contactPane .addressBookSection { display: flex; flex-direction: column; align-items: stretch; flex: 1 1 0; /* allow it to grow but not force wrap */ min-width: 0; /* allow sections to collapse when stacked */ box-sizing: border-box; background: var(--color-section-bg); } .contactPane .detailsSectionContent { flex: 1 1 auto; min-height: 12.5rem; /* 200px */ padding: var(--spacing-lg); max-width: 56.25rem; /* 900px */ width: 100%; box-sizing: border-box; } .contactPane .detailsSectionContent--wide { max-width: 56.25rem; /* 900px */ } .contactPane .cardFooter { display: flex; flex-wrap: nowrap; /* keep buttons inline */ align-items: center; /* vertical centering if varied heights */ gap: var(--spacing-xs); padding-top: var(--spacing-md); margin-top: var(--spacing-md); } .contactPane .detailsSectionContent { margin: 0; } /* ── Contact type chooser ───────────────────────────────────── */ .contactPane .contactTypeChooser { display: flex; flex-direction: column; gap: var(--spacing-sm); max-width: 22.5rem; /* 360px */ } .contactPane .contactTypeChooser h3 { margin: 0 0 var(--spacing-xs) 0; font-size: var(--font-size-lg); } .contactPane .contactTypeSelect { height: var(--min-touch-target); border: var(--border-width-sm, 1px) solid var(--color-border-pale); border-radius: var(--border-radius-base); padding: 0 var(--spacing-sm); font-size: var(--font-size-sm); background: var(--color-section-bg); } /* ── Search ──────────────────────────────────────────────────── */ .contactPane .allGroupsButton { border-radius: var(--border-radius-full) !important; /* existing styles */ } /* wrapper to position clear icon/button */ .contactPane .searchDiv { position: relative; } .contactPane .searchInput { height: var(--min-touch-target); border: var(--border-width-sm, 1px) solid var(--color-border-pale); background-color: var(--color-section-bg); background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23999' viewBox='0 0 24 24' width='20' height='20'%3E%3Cpath d='M15.5 14h-.79l-.28-.27A6.471 6.471 0 0 0 16 9.5 6.5 6.5 0 1 0 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99c.41.41 1.09.41 1.5 0s.41-1.09 0-1.5l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: 0.5rem center; /* 8px */ background-size: 1.25rem 1.25rem; /* 20px 20px */ border-radius: var(--border-radius-base); padding: 0 var(--spacing-sm) 0 2.125rem; /* 34px */ font-size: var(--font-size-base); width: 100%; box-sizing: border-box; } /* clear button inside search input */ .contactPane .searchClearButton { position: absolute; right: var(--spacing-sm); top: 50%; transform: translateY(-50%); border: none; background: transparent; font-size: var(--font-size-base); line-height: 1; padding: 0; cursor: pointer; color: var(--color-text-muted); /* visibility is controlled via the generic `.hidden` utility class */ display: block; } .contactPane .searchClearButton.hidden { display: none; } .contactPane .searchClearButton:hover { color: var(--color-text); } /* ── Contact toolbar (top-right link + delete) ──────────────── */ .contactPane .contact-toolbar { display: flex; align-items: center; gap: var(--spacing-sm); padding: var(--spacing-xs) 0; } .contactPane .contact-toolbar a { margin: 0.3rem; } .contactPane .contact-toolbar a img { width: 1.3rem; height: 1rem; margin: 0; } .contact-toolbar .deleteButton { margin-left: auto; /* keeps delete icon on the right */ margin-right: var(--spacing-xxxs, 0.2rem); width: var(--icon-xxs, 1rem); height: var(--icon-xxs, 1rem); float: none; /* important: prevents overlap behavior */ } /* ── "All" groups button ─────────────────────────────────────── */ .contactPane .allGroupsButton { margin-left: var(--spacing-md); font-size: var(--font-size-base); } .contactPane .allGroupsButton--loading { background-color: var(--color-primary); } .contactPane .allGroupsButton--active { background-color: var(--color-primary); color: var(--color-background); } .contactPane .allGroupsButton--loaded { background-color: var(--color-primary); } /* ── Mint new address book ───────────────────────────────────── */ .contactPane .claimSuccess { font-size: var(--font-size-xl); } .contactPane { display: flex; flex-direction: column; min-height: 0; } .contactPane .addressBook-grid { display: flex; flex-wrap: nowrap; /* keep sections side-by-side */ flex: 1; min-width: 0; /* allow it to shrink */ align-items: stretch; width: 100%; box-sizing: border-box; overflow-x: hidden; } @media ((min-width: 500px) and (max-width: 900px)) { .contactPane .addressBookSection { max-width: 900px; } .contactPane .addressBookSection section { max-width: 485px; } } .contactPane.contactPane--narrow .addressBook-grid { flex-direction: column !important; flex-wrap: nowrap !important; min-width: 0 !important; overflow-x: hidden !important; } .contactPane.contactPane--narrow .addressBookSection, .contactPane.contactPane--narrow .detailSection { flex: 1 1 100% !important; max-width: 100% !important; min-width: 0 !important; width: 100% !important; } @media (max-width: 1000px) { /* Stack sidebar + details vertically on narrow screens */ .contactPane { min-height: auto !important; } .contactPane .addressBook-grid { flex-direction: column !important; flex-wrap: nowrap !important; min-height: auto !important; height: auto !important; } .contactPane .addressBookSection, .contactPane .detailSection { order: initial !important; flex: none !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; } .contactPane .addressBookSection { max-height: none !important; min-height: auto !important; overflow-y: visible !important; padding-bottom: var(--spacing-lg) !important; display: flex !important; flex-direction: column !important; height: auto !important; } .contactPane .peopleSection ul { max-height: 50vh; overflow-y: auto; } .contactPane .detailSection { max-height: none !important; min-height: auto !important; overflow-y: visible !important; } .contactPane .detailsSectionContent { display: flex !important; flex-direction: column !important; justify-content: flex-start !important; align-items: stretch !important; min-height: auto !important; height: auto !important; overflow-y: visible !important; } .contactPane .detailSection > .detailsSectionContent { padding-top: var(--spacing-sm) !important; box-sizing: border-box !important; } /* Keep a normal mobile text scale while preserving comfortable touch targets */ /* The following rule made all text much larger on mobile; comment out to restore normal font size for non-buttons. .contactPane, .contactPane * { font-size: 1.5rem !important; } */ .contactPane .actionButton, .contactPane .searchInput, .contactPane .flatButton, .contactPane .buttonSection button, .contactPane .groupButtonsList button { min-height: calc(var(--min-touch-target) + 0.5em) !important; font-size: 1.5rem !important; padding: 0.875em 1em !important; } .contactPane .group-membership-item .group-membership-toolbar > img.hoverControlHide, .contactPane .group-membership-item .group-membership-toolbar > [data-testid="deleteButtonWithCheck"], .individualPane .hoverControl img.hoverControlHide, .individualPane .hoverControl [data-testid="deleteButtonWithCheck"] { display: inline-flex !important; visibility: visible !important; opacity: 1 !important; } } /* Card Section Background */ .contactPane .addressBookSection.section-bg { background: var(--color-section-bg); padding: var(--spacing-md); box-sizing: border-box; border: none !important; border-radius: 0 !important; } /* Keep detail section content anchored at top */ .contactPane .detailSection { display: flex; flex-direction: column; justify-content: flex-start; align-items: stretch; } .contactPane .detailsSectionContent { display: flex; flex-direction: column; justify-content: flex-start; align-items: stretch; } /* ── Button section: horizontal scrollable row ──────────────── */ .contactPane .buttonSection { display: flex; flex-wrap: nowrap; align-items: center; padding: var(--spacing-sm); padding-bottom: 0; overflow-x: auto; overflow-y: hidden; -webkit-overflow-scrolling: touch; scrollbar-width: thin; margin-bottom: 0; } @media (max-width: 1000px) { .contactPane .buttonSection { position: sticky; top: 0; z-index: 2; background: var(--color-section-bg); box-shadow: 0 2px 4px -2px rgba(0,0,0,0.04); } } .contactPane .buttonSection::-webkit-scrollbar { height: 6px; } .contactPane .buttonSection::-webkit-scrollbar-thumb { background: var(--color-border-pale); border-radius: var(--border-radius-base); } .contactPane .buttonSection::-webkit-scrollbar-track { background: transparent; } .contactPane .buttonSection .selected { background: none !important; } .contactPane .groupButtonsList { display: flex; flex-wrap: nowrap; align-items: center; gap: var(--spacing-xs); list-style: none; } .contactPane .buttonSection .groupButtonsList { margin-left: var(--spacing-xs); margin-right: var(--spacing-xs); padding-left: 0; } .contactPane .groupButtonsList li { flex-shrink: 0; } .contactPane .groupButtonsList button { white-space: nowrap; flex-shrink: 0; min-width: max-content; margin-left: 0; } /* Groups list in details section — flexible 2-column grid */ .contactPane .detailsSectionContent .groupButtonsList { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--spacing-sm); list-style: none; padding: 0; width: 100%; box-sizing: border-box; } .contactPane .detailsSectionContent .groupButtonsList li { width: 100%; aspect-ratio: auto; display: flex; flex-direction: column; align-items: stretch; gap: var(--spacing-xs); } .contactPane .detailsSectionContent .groupButtonsList button { width: 100%; height: auto; text-align: center; border-radius: var(--border-radius-base); word-wrap: break-word; overflow-wrap: break-word; } .contactPane .detailsSectionContent .groupButtonsList li > img.hoverControlHide, .contactPane .detailsSectionContent .groupButtonsList li > img[data-testid="deleteButtonWithCheck"] { display: block; align-self: flex-end; float: none !important; margin: 0 !important; } @media (max-width: 599px) { .contactPane .detailsSectionContent .groupButtonsList { grid-template-columns: repeat(2, 1fr); gap: var(--spacing-xs); } .contactPane .detailsSectionContent .groupButtonsList button { font-size: var(--font-size-sm); border-radius: var(--border-radius-base); } } @media (min-width: 900px) { .contactPane .detailsSectionContent .groupButtonsList { grid-template-columns: repeat(3, 1fr); } } .contactPane .detailsSectionContent .newGroupBtn { width: 100%; box-sizing: border-box; margin-top: var(--spacing-sm); } .contactPane .detailsSectionContent h3 { font-size: var(--font-size-xl); margin-bottom: var(--spacing-sm); padding-left: 0; } /* Delete confirmation POPUP — centered overlay in details section */ .contactPane .detailSection { position: relative; } .contactPane .webidControl div[style*="position: relative"]:has(> div[style*="display: grid"]) { position: static !important; } .contactPane .webidControl .personaRow--webid td > div[style*="position: relative"] > div, .contactPane .detailsSectionContent .groupButtonsList li > div[style*="position: relative"] > div, .contactPane .detailsSectionContent .contact-toolbar > div[style*="position: relative"] > div { position: absolute !important; left: auto !important; z-index: 9999 !important; display: grid !important; pointer-events: auto !important; opacity: 1 !important; visibility: visible !important; padding: var(--spacing-btn) !important; min-width: 12em !important; background: var(--color-background) !important; border: var(--border-width-sm) solid var(--color-primary) !important; border-radius: var(--border-radius-base) !important; box-shadow: var(--box-shadow-popup) !important; grid-template-columns: auto auto !important; gap: var(--spacing-xxs) !important; } .contactPane .detailsSectionContent .contact-toolbar > div[style*="position: relative"] > div > button:has(> img[src$=".svg"]), .contactPane .detailsSectionContent .group-membership-item .group-membership-toolbar > div[style*="position: relative"] > div > button:has(> img[src$=".svg"]), .contactPane .webidControl .personaRow--webid td > div[style*="position: relative"] > div > button:has(> img[src$=".svg"]) { background-color: transparent !important; } /* Selected state for All contacts button */ .contactPane .allGroupsButton--selected { background-color: var(--color-primary); color: var(--color-background); } /* ── Header section ──────────────────────────────────────────── */ .contactPane .headerSection { background: var(--color-background); padding: var(--spacing-sm); border-top-left-radius: var(--border-radius-full); border-top-right-radius: var(--border-radius-full); margin-bottom: 0; } .contactPane .headerSection header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 0; } .contactPane .headerSection h2 { margin-bottom: 0; } /* ── Dotted horizontal rule ─────────────────────────────────── */ .contactPane .dottedHr { border: none; border-top: var(--border-width-sm, 0.1rem) dotted var(--color-text-muted); margin: 0; } /* ── Search section ─────────────────────────────────────────── */ .contactPane .searchSection { padding: var(--spacing-sm); padding-bottom: 0; margin-bottom: 0; } /* ── People list section ────────────────────────────────────── */ .contactPane .peopleSection { display: flex; background: var(--color-background); border-top: 1px dotted var(--color-text-muted); margin-bottom: 0; } .contactPane .peopleSection ul { list-style: none; padding: 0; margin: 0; width: 100%; max-height: 70vh; overflow-y: auto; } .contactPane .peopleSection li { border-top: var(--border-width-sm, 0.1rem) solid var(--color-border-pale); padding: var(--spacing-xs); } /* ── Person list item (addressBookPresenter) ─────────────────── */ .contactPane .personLi-row { display: flex; align-items: center; justify-content: space-between; } .contactPane .personLi-avatar { width: 2.813rem /* 45px */; height: 2.813rem /* 45px */; flex-shrink: 0; display: flex; align-items: center; justify-content: center; } .contactPane .personLi-avatar .avatar-placeholder { width: 2.25rem /* 36px */; height: 2.25rem /* 36px */; display: flex; align-items: center; justify-content: center; } .contactPane .personLi-avatar img { width: 2.5rem /* 40px */; height: 2.5rem /* 40px */; border-radius: 50%; object-fit: cover; } .contactPane .personLi-info { flex: 1; margin-left: var(--spacing-sm); overflow: hidden; } .contactPane .personLi-name { font-weight: bold; font-size: var(--font-size-base); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .contactPane .personLi-arrow { margin-left: auto; display: flex; align-items: center; } .contactPane .personLi--error { opacity: 0.5; }