fix(icons): standardize dropdown/select/pagination/expander chevrons
app-select (the shared select used across every admin form) rendered the browser's native dropdown indicator - inconsistent across Chrome/Firefox/Safari and outside the icon system entirely. Hid it (appearance: none) and added a consistent chevronDown via app-icon. app-pagination used literal HTML entities (« / ») for prev/next instead of icons. Replaced with chevronLeft/chevronRight. Every native <details>/<summary> expander (7 call sites across admin product form, page editor, and the builder's widget advanced-settings panel) relied on the browser's default disclosure triangle, which again varies per browser and shares no visual relationship with the rest of the icon system. Added one global CSS rule (details > summary) that hides the native marker and draws the same Lucide chevron path used everywhere else, animated on open/close - covers all 7 without touching each template. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
[attr.aria-label]="previousLabel()"
|
||||
(click)="goTo(currentPage() - 1)"
|
||||
>
|
||||
«
|
||||
<app-icon name="chevronLeft" [size]="16" />
|
||||
</app-button>
|
||||
|
||||
@for (page of pages(); track $index) {
|
||||
@@ -32,6 +32,6 @@
|
||||
[attr.aria-label]="nextLabel()"
|
||||
(click)="goTo(currentPage() + 1)"
|
||||
>
|
||||
»
|
||||
<app-icon name="chevronRight" [size]="16" />
|
||||
</app-button>
|
||||
</nav>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { ChangeDetectionStrategy, Component, computed, input, output } from '@angular/core';
|
||||
import { ButtonComponent } from '../button/button.component';
|
||||
import { IconComponent } from '../icon/icon.component';
|
||||
|
||||
const SIBLING_COUNT = 1;
|
||||
const ELLIPSIS = '…' as const;
|
||||
@@ -7,7 +8,7 @@ const ELLIPSIS = '…' as const;
|
||||
@Component({
|
||||
selector: 'app-pagination',
|
||||
standalone: true,
|
||||
imports: [ButtonComponent],
|
||||
imports: [ButtonComponent, IconComponent],
|
||||
templateUrl: './pagination.component.html',
|
||||
styleUrl: './pagination.component.scss',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
|
||||
@@ -1,20 +1,23 @@
|
||||
<select
|
||||
class="app-select"
|
||||
[class.app-select--sm]="size() === 'sm'"
|
||||
[class.app-select--md]="size() === 'md'"
|
||||
[class.app-select--lg]="size() === 'lg'"
|
||||
[disabled]="isDisabled || disabled()"
|
||||
[attr.id]="formField?.fieldId ?? null"
|
||||
[attr.aria-label]="ariaLabel()"
|
||||
[attr.aria-describedby]="formField?.describedBy() ?? null"
|
||||
[value]="value"
|
||||
(change)="handleChange($event)"
|
||||
(blur)="handleBlur()"
|
||||
>
|
||||
@for (option of options(); track option.value) {
|
||||
<option [value]="option.value" [title]="option.description ?? ''">{{ option.label }}</option>
|
||||
}
|
||||
</select>
|
||||
<div class="app-select-wrap">
|
||||
<select
|
||||
class="app-select"
|
||||
[class.app-select--sm]="size() === 'sm'"
|
||||
[class.app-select--md]="size() === 'md'"
|
||||
[class.app-select--lg]="size() === 'lg'"
|
||||
[disabled]="isDisabled || disabled()"
|
||||
[attr.id]="formField?.fieldId ?? null"
|
||||
[attr.aria-label]="ariaLabel()"
|
||||
[attr.aria-describedby]="formField?.describedBy() ?? null"
|
||||
[value]="value"
|
||||
(change)="handleChange($event)"
|
||||
(blur)="handleBlur()"
|
||||
>
|
||||
@for (option of options(); track option.value) {
|
||||
<option [value]="option.value" [title]="option.description ?? ''">{{ option.label }}</option>
|
||||
}
|
||||
</select>
|
||||
<app-icon name="chevronDown" [size]="16" class="app-select-arrow" />
|
||||
</div>
|
||||
@if (activeDescription(); as description) {
|
||||
<small class="app-select-description">{{ description }}</small>
|
||||
}
|
||||
|
||||
@@ -7,8 +7,24 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.app-select-wrap {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.app-select-arrow {
|
||||
position: absolute;
|
||||
right: 12px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
color: var(--text-secondary, #6b7280);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.app-select {
|
||||
width: 100%;
|
||||
appearance: none;
|
||||
padding-right: 36px;
|
||||
border: 1px solid var(--border-color, #e4e4e7);
|
||||
border-radius: var(--radius-md, 6px);
|
||||
background: var(--bg-primary, #fff);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { ChangeDetectionStrategy, Component, forwardRef, inject, input } from '@angular/core';
|
||||
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
import { FormFieldContext } from '../form-field/form-field.component';
|
||||
import { IconComponent } from '../icon/icon.component';
|
||||
|
||||
export type SelectSize = 'sm' | 'md' | 'lg';
|
||||
|
||||
@@ -13,6 +14,7 @@ export interface SelectOption {
|
||||
@Component({
|
||||
selector: 'app-select',
|
||||
standalone: true,
|
||||
imports: [IconComponent],
|
||||
templateUrl: './select.component.html',
|
||||
styleUrl: './select.component.scss',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
|
||||
Reference in New Issue
Block a user