Refactor preview popover and fix dropdown header styling

- Refactor preview popover into reusable component with filter input and load more
- Fix sort controls: connect sort-field-select to btn-sort-dir (shared border)
- Fix refine controls: connect btn-refine-negate to refine-input
- Add flex-shrink: 0 and min-width to prevent button shrinking
- Fix grid view items: border on all 4 sides, no padding
- Add EXCEPT separator styling for selection groups
- Various button width and height fixes for consistency

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-29 12:13:13 +00:00
parent eb15170e1c
commit 6f248605a7
11 changed files with 1675 additions and 1136 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1579,14 +1579,6 @@
var groupType = $badge.data('type'); var groupType = $badge.data('type');
var groupName = $badge.data('groupName'); var groupName = $badge.data('groupName');
console.log('[EntitySelector] Filter toggle count clicked', {
groupId: groupId,
groupType: groupType,
groupName: groupName,
hasMethod: typeof self.showFilterGroupPreviewPopover === 'function',
self: self
});
if ($badge.hasClass('popover-open')) { if ($badge.hasClass('popover-open')) {
self.hidePreviewPopover(); self.hidePreviewPopover();
} else { } else {
@@ -1594,6 +1586,25 @@
} }
}); });
// View mode select change
this.$dropdown.on('change', '.view-mode-select', function() {
var mode = $(this).val();
self.viewMode = mode;
// Remove all view mode classes and add the new one
self.$dropdown
.removeClass('view-list view-tree view-cols-2 view-cols-3 view-cols-4 view-cols-5 view-cols-6 view-cols-7 view-cols-8')
.addClass('view-' + mode.replace('cols-', 'cols-'));
// For tree view, load the category tree
if (mode === 'tree') {
self.loadCategoryTree();
} else {
// Re-render current results with new view mode
self.renderSearchResults(false);
}
});
// Close values row // Close values row
this.$dropdown.on('click', '.btn-close-values', function(e) { this.$dropdown.on('click', '.btn-close-values', function(e) {
e.preventDefault(); e.preventDefault();

File diff suppressed because it is too large Load Diff

View File

@@ -392,7 +392,9 @@
html += '</div>'; html += '</div>';
// Add product-specific columns (price, sale price, stock, sold) // Add product-specific columns (price, sale price, stock, sold)
if (item.type === 'product' && isListView) { if (item.type === 'product') {
if (isListView) {
// List view: full columns
// Regular price // Regular price
html += '<div class="result-col result-col-price">'; html += '<div class="result-col result-col-price">';
html += '<span class="col-value">' + (item.regular_price_formatted || item.price_formatted || '') + '</span>'; html += '<span class="col-value">' + (item.regular_price_formatted || item.price_formatted || '') + '</span>';
@@ -418,6 +420,20 @@
html += '<div class="result-col result-col-sales">'; html += '<div class="result-col result-col-sales">';
html += '<span class="col-value">' + (item.sales_qty !== undefined ? item.sales_qty : '0') + '</span>'; html += '<span class="col-value">' + (item.sales_qty !== undefined ? item.sales_qty : '0') + '</span>';
html += '</div>'; html += '</div>';
} else {
// Grid view: compact info line
var gridStockClass = item.stock_status === 'out_of_stock' ? 'stock-out' :
(item.stock_status === 'low_stock' ? 'stock-low' : '');
html += '<div class="result-grid-info">';
html += '<span class="grid-price">' + (item.price_formatted || '') + '</span>';
if (item.stock_qty !== undefined) {
html += '<span class="grid-stock ' + gridStockClass + '">' + item.stock_qty + ' qty</span>';
}
if (item.has_discount) {
html += '<span class="grid-discount">-' + (item.discount_percent || '') + '%</span>';
}
html += '</div>';
}
} }
html += '</div>'; html += '</div>';

View File

@@ -21,6 +21,12 @@
justify-content: space-between; justify-content: space-between;
} }
@mixin grid-columns($cols) {
display: grid;
grid-template-columns: repeat($cols, 1fr);
gap: $es-spacing-sm;
}
// ============================================================================= // =============================================================================
// Text // Text
// ============================================================================= // =============================================================================

View File

@@ -159,26 +159,29 @@
} }
// Result item (both class names for compatibility) // Result item (both class names for compatibility)
.dropdown-result-item, // Note: Main dropdown-item styling is in the global .target-search-dropdown section below
.dropdown-item { .dropdown-result-item {
display: flex; display: flex;
align-items: center; align-items: center;
gap: $es-spacing-sm; gap: $es-spacing-sm;
padding: $es-spacing-sm; padding: $es-spacing-sm 0;
background: $es-white; background: $es-white;
border: 1px solid $es-border-color; border: none;
border-radius: $es-radius-md; border-bottom: 1px solid $es-border-color;
border-radius: 0;
cursor: pointer; cursor: pointer;
transition: all $es-transition-fast; transition: background $es-transition-fast;
&:last-child {
border-bottom: none;
}
&:hover { &:hover {
background: $es-bg-hover; background: $es-bg-hover;
border-color: $es-slate-300;
} }
&.selected { &.selected {
background: $es-primary-light; background: $es-primary-light;
border-color: $es-primary;
} }
&.disabled { &.disabled {
@@ -187,7 +190,6 @@
&:hover { &:hover {
background: $es-white; background: $es-white;
border-color: $es-border-color;
} }
} }
} }
@@ -963,26 +965,71 @@ body > .target-search-dropdown,
.sort-controls { .sort-controls {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 0.25rem; // No gap - elements are connected
}
.sort-field-select {
@include input-base;
padding: 0.25rem 0.5rem;
font-size: $es-font-size-xs;
min-width: 80px;
height: 28px; // Match btn-sort-dir height
border-radius: $es-radius-sm 0 0 $es-radius-sm;
border-right: none;
}
.btn-sort-dir {
display: flex;
align-items: center;
justify-content: center;
width: 38px;
min-width: 38px;
flex-shrink: 0;
height: 28px;
padding: 0;
margin: 0;
color: $es-text-muted;
background: $es-white;
border: 1px solid $es-border-color;
border-radius: 0 $es-radius-sm $es-radius-sm 0;
cursor: pointer;
transition: all $es-transition-fast;
i {
font-size: 14px;
}
&:hover {
background: $es-bg-hover;
color: $es-text-primary;
}
&.active {
background: $es-primary-light;
border-color: $es-primary;
color: $es-primary;
}
} }
.sort-field-select,
.view-mode-select { .view-mode-select {
@include input-base; @include input-base;
padding: 0.25rem 0.5rem; padding: 0.25rem 0.5rem;
font-size: $es-font-size-xs; font-size: $es-font-size-xs;
min-width: 80px; min-width: 80px;
margin-left: 0.25rem;
} }
.btn-sort-dir,
.btn-toggle-filters, .btn-toggle-filters,
.btn-show-history { .btn-show-history {
@include button-reset;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
width: 28px; width: 32px;
min-width: 32px;
flex-shrink: 0;
height: 28px; height: 28px;
padding: 0;
margin: 0;
color: $es-text-muted; color: $es-text-muted;
background: $es-white; background: $es-white;
border: 1px solid $es-border-color; border: 1px solid $es-border-color;
@@ -990,6 +1037,10 @@ body > .target-search-dropdown,
cursor: pointer; cursor: pointer;
transition: all $es-transition-fast; transition: all $es-transition-fast;
i {
font-size: 14px;
}
&:hover { &:hover {
background: $es-bg-hover; background: $es-bg-hover;
color: $es-text-primary; color: $es-text-primary;
@@ -1005,33 +1056,66 @@ body > .target-search-dropdown,
.refine-compact { .refine-compact {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 0.25rem; // No gap - elements are connected
// Connected to refine-input
.btn-refine-negate {
display: flex;
align-items: center;
justify-content: center;
width: 32px;
min-width: 32px;
flex-shrink: 0;
height: 28px;
padding: 0;
margin: 0;
color: $es-text-muted;
background: $es-white;
border: 1px solid $es-border-color;
border-right: none;
border-radius: $es-radius-sm 0 0 $es-radius-sm;
cursor: pointer;
transition: all $es-transition-fast;
&:hover {
background: $es-bg-hover;
color: $es-text-primary;
}
&.active {
background: $es-danger-light;
color: $es-danger;
border-color: $es-danger;
}
}
.refine-input { .refine-input {
@include input-base; @include input-base;
width: 100px; width: 100px;
padding: 0.25rem 0.5rem; padding: 0.25rem 0.5rem;
font-size: $es-font-size-xs; font-size: $es-font-size-xs;
border-radius: 0 $es-radius-sm $es-radius-sm 0;
} }
.btn-refine-negate,
.btn-clear-refine { .btn-clear-refine {
@include button-reset;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
width: 24px; width: 28px;
height: 24px; height: 28px;
padding: 0;
margin: 0;
margin-left: -1px; // Overlap input border when visible
color: $es-text-muted; color: $es-text-muted;
border-radius: $es-radius-sm; background: $es-white;
border: 1px solid $es-border-color;
border-radius: 0 $es-radius-sm $es-radius-sm 0;
cursor: pointer; cursor: pointer;
transition: all $es-transition-fast;
&:hover { &:hover {
background: $es-bg-hover; background: $es-bg-hover;
} color: $es-text-primary;
&.active {
color: $es-danger;
} }
} }
} }
@@ -1380,34 +1464,6 @@ body > .target-search-dropdown,
padding: $es-spacing-sm; padding: $es-spacing-sm;
} }
// Dropdown item
.dropdown-item {
display: flex;
align-items: center;
gap: $es-spacing-sm;
padding: $es-spacing-sm;
background: $es-white;
border: 1px solid $es-border-color;
border-radius: $es-radius-md;
cursor: pointer;
transition: all $es-transition-fast;
&:hover {
background: $es-bg-hover;
border-color: $es-slate-300;
}
&.selected {
background: $es-primary-light;
border-color: $es-primary;
}
&.disabled {
opacity: 0.5;
cursor: not-allowed;
}
}
.item-checkbox { .item-checkbox {
flex-shrink: 0; flex-shrink: 0;
width: 16px; width: 16px;
@@ -1589,7 +1645,8 @@ body > .target-search-dropdown,
color: $es-text-primary; color: $es-text-primary;
} }
.btn-remove-history { .btn-remove-history,
.btn-delete-history {
@include button-reset; @include button-reset;
display: flex; display: flex;
align-items: center; align-items: center;
@@ -1598,18 +1655,20 @@ body > .target-search-dropdown,
height: 20px; height: 20px;
color: $es-text-muted; color: $es-text-muted;
border-radius: $es-radius-sm; border-radius: $es-radius-sm;
opacity: 0;
transition: all $es-transition-fast; transition: all $es-transition-fast;
&:hover { &:hover {
background: $es-slate-200; background: $es-slate-200;
color: $es-text-primary; color: $es-danger;
}
} }
} }
&:hover .btn-remove-history { // Search history list container
opacity: 1; .search-history-list {
} display: flex;
flex-direction: column;
gap: $es-spacing-xs;
} }
// Results header (for list view columns) // Results header (for list view columns)
@@ -1644,46 +1703,44 @@ body > .target-search-dropdown,
// Results container // Results container
.dropdown-results { .dropdown-results {
padding: $es-spacing-sm; padding: $es-spacing-sm;
background: $es-white;
min-height: 200px;
} }
// Grid view modes // Dropdown item (search result)
.dropdown-results-grid { .dropdown-item {
display: grid; position: relative;
gap: $es-spacing-sm;
&.view-list {
grid-template-columns: 1fr;
}
&.view-grid-2 {
grid-template-columns: repeat(2, 1fr);
}
&.view-grid-3 {
grid-template-columns: repeat(3, 1fr);
}
}
// Result item styles
.dropdown-result-item {
display: flex; display: flex;
align-items: center; align-items: center;
gap: $es-spacing-sm; gap: $es-spacing-sm;
padding: $es-spacing-sm; padding: $es-spacing-sm 0;
background: $es-white; background: $es-white;
border: 1px solid $es-border-color; border: none;
border-radius: $es-radius-md; border-bottom: 1px solid $es-border-color;
border-radius: 0;
cursor: pointer; cursor: pointer;
transition: all $es-transition-fast; transition: background $es-transition-fast;
&:last-child {
border-bottom: none;
}
&:hover { &:hover {
background: $es-bg-hover; background: $es-bg-hover;
border-color: $es-slate-300;
} }
&.selected { &.selected {
background: $es-primary-light; background: $es-primary-light;
.result-checkbox {
background: $es-primary;
border-color: $es-primary; border-color: $es-primary;
color: $es-white;
i {
display: block;
}
}
} }
&.disabled { &.disabled {
@@ -1692,6 +1749,136 @@ body > .target-search-dropdown,
} }
} }
// Checkbox indicator
.result-checkbox {
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
width: 18px;
height: 18px;
background: $es-white;
border: 2px solid $es-border-dark;
border-radius: 3px;
transition: all $es-transition-fast;
i {
display: none;
font-size: 10px;
}
}
// View mode classes (applied to dropdown container)
&.view-cols-2 .dropdown-results { @include grid-columns(2); }
&.view-cols-3 .dropdown-results { @include grid-columns(3); }
&.view-cols-4 .dropdown-results { @include grid-columns(4); }
&.view-cols-5 .dropdown-results { @include grid-columns(5); }
&.view-cols-6 .dropdown-results { @include grid-columns(6); }
&.view-cols-7 .dropdown-results { @include grid-columns(7); }
&.view-cols-8 .dropdown-results { @include grid-columns(8); }
// Grid view item styling (compact cards)
&.view-cols-2,
&.view-cols-3,
&.view-cols-4,
&.view-cols-5,
&.view-cols-6,
&.view-cols-7,
&.view-cols-8 {
.dropdown-item {
flex-direction: column;
align-items: center;
text-align: center;
padding: 0;
border: 1px solid $es-border-color;
border-radius: $es-radius-sm;
.result-checkbox {
position: absolute;
top: $es-spacing-xs;
left: $es-spacing-xs;
}
.result-image,
.result-icon {
width: 48px;
height: 48px;
margin-bottom: $es-spacing-xs;
}
.result-info {
width: 100%;
}
.result-name {
font-size: $es-font-size-xs;
line-height: 1.3;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.result-subtitle {
display: none;
}
// Show compact product info in grid
.result-col {
display: none;
}
.result-grid-info {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 0.25rem;
margin-top: $es-spacing-xs;
font-size: 0.65rem;
.grid-price {
color: $es-text-primary;
font-weight: $es-font-weight-semibold;
}
.grid-stock {
color: $es-text-muted;
&.stock-out { color: $es-danger; }
&.stock-low { color: $es-warning; }
}
.grid-discount {
color: $es-success;
font-weight: $es-font-weight-medium;
}
}
}
// Hide results header in grid views
.results-header {
display: none;
}
}
// Smaller items for higher column counts
&.view-cols-5,
&.view-cols-6,
&.view-cols-7,
&.view-cols-8 {
.dropdown-item {
.result-image,
.result-icon {
width: 40px;
height: 40px;
}
.result-name {
font-size: 0.65rem;
}
}
}
// Product-specific result item // Product-specific result item
.result-item-product { .result-item-product {
display: flex; display: flex;
@@ -1881,20 +2068,25 @@ body > .target-search-dropdown,
} }
.btn-load-more { .btn-load-more {
@include button-reset;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
width: 24px; padding: $es-spacing-xs;
height: 24px; margin: 0;
border: none;
color: $es-primary; color: $es-primary;
background: $es-primary-light; background: $es-primary-light !important;
border-radius: $es-radius-sm; border-radius: $es-radius-sm;
cursor: pointer; cursor: pointer;
transition: all $es-transition-fast; transition: all $es-transition-fast;
font: inherit;
i {
font-size: 14px;
}
&:hover { &:hover {
background: rgba($es-primary, 0.2); background: rgba($es-primary, 0.2) !important;
} }
} }
} }

View File

@@ -86,16 +86,95 @@
gap: $es-spacing-xs; gap: $es-spacing-xs;
} }
// Filter input section
.preview-filter {
padding: $es-spacing-sm $es-spacing-md;
border-bottom: 1px solid $es-border-color;
.preview-filter-input {
@include input-base;
width: 100%;
padding: $es-spacing-sm;
font-size: $es-font-size-sm;
box-sizing: border-box;
&::placeholder {
color: $es-text-muted;
}
}
}
.preview-footer { .preview-footer {
padding: $es-spacing-sm $es-spacing-md; padding: $es-spacing-sm $es-spacing-md;
background: $es-slate-50; background: $es-slate-50;
border-top: 1px solid $es-border-color; border-top: 1px solid $es-border-color;
text-align: center;
.preview-more-info { .preview-more-info {
font-size: $es-font-size-xs; font-size: $es-font-size-xs;
color: $es-text-muted; color: $es-text-muted;
font-weight: $es-font-weight-medium; font-weight: $es-font-weight-medium;
text-align: center;
}
}
// Load more controls (select dropdown style)
.load-more-controls {
display: flex;
align-items: center;
justify-content: center;
gap: $es-spacing-sm;
font-size: $es-font-size-xs;
color: $es-text-muted;
.load-more-label {
white-space: nowrap;
}
.load-more-select {
@include input-base;
padding: 0.25rem 0.5rem;
font-size: $es-font-size-xs;
min-width: 70px;
}
.load-more-of {
white-space: nowrap;
}
.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 !important;
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) !important;
}
&.loading {
cursor: wait;
i {
animation: spin 0.6s linear infinite;
}
}
} }
} }
} }
@@ -111,20 +190,24 @@
gap: $es-spacing-xs; gap: $es-spacing-xs;
} }
// Preview item // Preview item (list-style with bottom border divider)
.preview-item { .preview-item {
display: flex; display: flex;
align-items: center; align-items: center;
gap: $es-spacing-sm; gap: $es-spacing-sm;
padding: $es-spacing-sm; padding: $es-spacing-sm 0;
background: $es-white; background: $es-white;
border: 1px solid $es-border-color; border: none;
border-radius: $es-radius-md; border-bottom: 1px solid $es-border-color;
transition: all $es-transition-fast; border-radius: 0;
transition: background $es-transition-fast;
&:last-child {
border-bottom: none;
}
&:hover { &:hover {
background: $es-bg-hover; background: $es-bg-hover;
border-color: $es-slate-300;
} }
} }