/** * Entity Item - Shared Base Component * Unified styling for entity items in chips, lists, and previews * * Variants: * - .entity-item (base) - default list-row style * - .entity-item.chip-style - pill/chip style (compact) * - .entity-item.card-style - card/grid style */ @use '../variables' as *; @use '../mixins' as *; // ============================================================================= // Entity Item Sizing // ============================================================================= $entity-item-image-sm: 20px; $entity-item-image-md: 32px; $entity-item-image-lg: 48px; // ============================================================================= // Base Entity Item (list-row layout) // ============================================================================= .entity-item { display: flex; align-items: center; gap: $es-spacing-sm; padding: $es-spacing-sm; background: $es-white; border-radius: $es-radius-sm; transition: background $es-transition-fast; &:hover { background: $es-bg-hover; } // Clickable variant &.clickable { cursor: pointer; } // Selected state &.selected { background: $es-primary-light; } } // ----------------------------------------------------------------------------- // Entity Item Image // ----------------------------------------------------------------------------- .entity-item-image { flex-shrink: 0; width: $entity-item-image-md; height: $entity-item-image-md; object-fit: cover; border-radius: $es-radius-sm; background: $es-slate-100; } // Size variants .entity-item-image--sm { width: $entity-item-image-sm; height: $entity-item-image-sm; border-radius: 50%; } .entity-item-image--lg { width: $entity-item-image-lg; height: $entity-item-image-lg; } // No-image placeholder .entity-item-no-image { display: flex; align-items: center; justify-content: center; flex-shrink: 0; width: $entity-item-image-md; height: $entity-item-image-md; background: $es-slate-100; color: $es-text-muted; border-radius: $es-radius-sm; font-size: $es-font-size-sm; &--sm { width: $entity-item-image-sm; height: $entity-item-image-sm; font-size: 10px; border-radius: 50%; } } // ----------------------------------------------------------------------------- // Entity Item Info (name + meta) // ----------------------------------------------------------------------------- .entity-item-info { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 0.125rem; } .entity-item-name { font-size: $es-font-size-sm; font-weight: $es-font-weight-medium; color: $es-text-primary; @include text-truncate; } .entity-item-meta { font-size: $es-font-size-xs; color: $es-text-muted; @include text-truncate; } // ----------------------------------------------------------------------------- // Entity Item Badge/Price (right side) // ----------------------------------------------------------------------------- .entity-item-badge { flex-shrink: 0; padding: 0.125rem 0.5rem; font-size: $es-font-size-xs; font-weight: $es-font-weight-medium; background: $es-slate-100; color: $es-text-muted; border-radius: $es-radius-sm; } .entity-item-price { flex-shrink: 0; font-size: $es-font-size-sm; font-weight: $es-font-weight-semibold; color: $es-primary; } // ----------------------------------------------------------------------------- // Entity Item Actions (remove button, etc.) // ----------------------------------------------------------------------------- .entity-item-action { @include button-reset; display: flex; align-items: center; justify-content: center; flex-shrink: 0; width: 20px; height: 20px; color: $es-text-muted; border-radius: 50%; transition: all $es-transition-fast; &:hover { background: rgba(0, 0, 0, 0.1); color: $es-danger; } i { font-size: 10px; } } // ============================================================================= // Chip Style Variant (compact pill) // ============================================================================= .entity-item.chip-style { display: inline-flex; gap: 0.375rem; padding: 0.25rem 0.5rem; background: $es-slate-100; border-radius: $es-radius-full; &:hover { background: $es-slate-200; } .entity-item-image { width: $entity-item-image-sm; height: $entity-item-image-sm; border-radius: 50%; } .entity-item-no-image { width: $entity-item-image-sm; height: $entity-item-image-sm; font-size: 10px; border-radius: 50%; } .entity-item-info { flex-direction: row; align-items: center; gap: 0.25rem; } .entity-item-name { font-size: $es-font-size-xs; } .entity-item-meta { display: none; } .entity-item-action { width: 16px; height: 16px; margin-left: 0.125rem; } } // ============================================================================= // List Style Variant (bordered rows) // ============================================================================= .entity-item.list-style { padding: $es-spacing-sm 0; background: transparent; border-bottom: 1px solid $es-border-color; border-radius: 0; &:last-child { border-bottom: none; } &:hover { background: $es-bg-hover; } } // ============================================================================= // Entity Item Container (wrapper for multiple items) // ============================================================================= .entity-items-container { display: flex; flex-direction: column; background: $es-slate-50; border: 1px solid $es-border-color; border-radius: $es-radius-md; overflow: hidden; } // Toolbar (filter, sort, count, clear) .entity-items-toolbar { display: none; align-items: center; flex-wrap: nowrap; gap: $es-spacing-sm; padding: $es-spacing-sm $es-spacing-md; padding-bottom: 0; background: transparent; &.has-items { display: flex; } } // Filter input .entity-items-filter { all: unset; display: block; flex: 1 1 auto; min-width: 80px; width: auto; height: auto; padding: 0.2rem 0.5rem 0.2rem 1.5rem; background: $es-white url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cpath d='m21 21-4.35-4.35'/%3E%3C/svg%3E") no-repeat 0.375rem center; background-size: 10px; border: 1px solid $es-slate-300; border-radius: $es-radius-sm; font-size: 11px; line-height: 1.4; color: $es-text-primary; box-sizing: border-box; transition: all $es-transition-fast; &::placeholder { color: $es-text-muted; font-size: 11px; } &:focus { outline: none; border-color: $es-primary; box-shadow: 0 0 0 2px rgba($es-primary, 0.1); } } // Sort dropdown .entity-items-sort { all: unset; flex: 0 0 auto; padding: 0.2rem 1.25rem 0.2rem 0.5rem; border: 1px solid $es-border-color; border-radius: $es-radius-sm; background: $es-white url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3E%3Cpath fill='%23666' d='M0 2l4 4 4-4z'/%3E%3C/svg%3E") no-repeat right 0.375rem center; background-size: 8px; font-size: 10px; line-height: 1.4; color: $es-text-secondary; cursor: pointer; box-sizing: border-box; white-space: nowrap; &:hover { border-color: $es-primary; } &:focus { outline: none; border-color: $es-primary; box-shadow: 0 0 0 2px rgba($es-primary, 0.1); } } // Count badge .entity-items-count { display: inline-flex; align-items: center; flex-shrink: 0; gap: 0.125rem; padding: 0.2rem 0.5rem; background: $es-slate-200; color: $es-text-secondary; font-size: 10px; font-weight: $es-font-weight-semibold; border-radius: $es-radius-sm; white-space: nowrap; line-height: 1.4; &.has-filter { background: $es-cyan-100; color: $es-cyan-700; } } // Clear button .entity-items-clear { @include button-reset; display: inline-flex; align-items: center; flex-shrink: 0; gap: 0.25rem; padding: 0.2rem 0.5rem; color: $es-danger; font-size: 10px; font-weight: $es-font-weight-medium; background: rgba($es-danger, 0.1); border-radius: $es-radius-sm; transition: all $es-transition-fast; white-space: nowrap; line-height: 1.4; &:hover { background: $es-danger; color: $es-white; } i { font-size: 9px; flex-shrink: 0; } } // Items list area .entity-items-list { display: flex; flex-wrap: wrap; gap: $es-spacing-xs; padding: $es-spacing-sm $es-spacing-md $es-spacing-md; min-height: 40px; max-height: 300px; overflow-y: auto; @include custom-scrollbar; &:empty { display: none; } // List layout (vertical) &.list-layout { flex-direction: column; flex-wrap: nowrap; gap: 0; padding: $es-spacing-sm; } } // Load more section .entity-items-load-more { display: flex; align-items: center; justify-content: center; gap: $es-spacing-sm; padding: $es-spacing-sm $es-spacing-md; background: transparent; border-top: 1px dashed $es-border-color; .load-more-label { font-size: $es-font-size-xs; color: $es-text-muted; } .load-more-select { appearance: none; padding: 0.25rem 1.75rem 0.25rem 0.5rem; border: 1px solid $es-border-color; border-radius: $es-radius-sm; background: $es-white url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3E%3Cpath fill='%23666' d='M0 2l4 4 4-4z'/%3E%3C/svg%3E") no-repeat right 0.5rem center; background-size: 8px; font-size: $es-font-size-xs; font-weight: $es-font-weight-medium; color: $es-primary; cursor: pointer; transition: all $es-transition-fast; height: auto; min-height: 0; line-height: 1.3; &:hover { border-color: $es-primary; background-color: $es-primary-light; } &:focus { outline: none; border-color: $es-primary; box-shadow: 0 0 0 2px rgba($es-primary, 0.1); } } .load-more-remaining { font-size: $es-font-size-xs; color: $es-text-muted; .remaining-count { font-weight: $es-font-weight-semibold; color: $es-text-secondary; } } .btn-load-more { display: flex; align-items: center; justify-content: center; padding: $es-spacing-xs; margin: 0; border: none; color: $es-primary; background: $es-primary-light; border-radius: $es-radius-sm; cursor: pointer; transition: all $es-transition-fast; font: inherit; i { font-size: 14px; } &:hover { background: rgba($es-primary, 0.2); } &.loading { cursor: wait; i { animation: spin 0.6s linear infinite; } } } } // ============================================================================= // Empty & Loading States // ============================================================================= .entity-items-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: $es-spacing-sm; padding: $es-spacing-xl; text-align: center; color: $es-text-muted; i { font-size: 2rem; opacity: 0.5; } p { margin: 0; font-size: $es-font-size-sm; } } .entity-items-loading { display: flex; align-items: center; justify-content: center; padding: $es-spacing-xl; color: $es-text-muted; i { font-size: 20px; animation: spin 0.6s linear infinite; } }