mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-15 05:36:17 -08:00
* perf(web): provide form-field defaults per component, not at the root app.config.ts provided MAT_FORM_FIELD_DEFAULT_OPTIONS in the root injector. Importing the token kept @angular/material/form-field in main.js, and Material 22.2's form field imports @angular/forms/signals, which would add @angular/forms to startup as well (the reason the Angular 22.2 dependency update exceeds the initial-bytes ratchet). Every form field renders in a lazy chunk, so the outline + dynamic defaults now come from provideFormFieldDefaults() (@iptvnator/ui/components/form-field-defaults) on each component that renders <mat-form-field>. tools/nx/check-form-field-defaults.mjs (ui:form-field-defaults:validate, run in CI) reports a component that renders a form field without the provider, and any use of the token outside the shared provider. The Xtream import form test asserts outlined, dynamically sized fields with no root provider; without the component provider they render as fill. renderer.initialBytes: 1,596,201 -> 1,534,604 bytes (-61,597) on a local production build; the baseline is lowered to the measured value. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * perf(web): cite #1928 as the initial-bytes baseline evidence Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(ui): check form-field providers per component on the TypeScript AST The guard matched templates and providers with regular expressions over the whole file: a quoted inline template went unread, one component's provider covered another in the same file, an earlier array-valued provider hid the call, and provideFormFieldDefaults() in app.config or a route passed although it loads Material's form field on startup again. It now reads each @Component decorator's own template and providers array, and reports any provideFormFieldDefaults() call outside one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: 4gray <fourgray@proton.me> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
53 lines
1.9 KiB
TypeScript
53 lines
1.9 KiB
TypeScript
import {
|
|
Component,
|
|
input,
|
|
output,
|
|
ViewEncapsulation,
|
|
ChangeDetectionStrategy,
|
|
} from '@angular/core';
|
|
import { FormGroup, ReactiveFormsModule } from '@angular/forms';
|
|
import { MatButtonModule } from '@angular/material/button';
|
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
import { MatIconModule } from '@angular/material/icon';
|
|
import { MatInputModule } from '@angular/material/input';
|
|
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
import { TranslateModule } from '@ngx-translate/core';
|
|
import { QRCodeComponent } from 'angularx-qrcode';
|
|
import { markSectionForCheckOnFormEvents } from './settings-section-form-render';
|
|
import { provideFormFieldDefaults } from '@iptvnator/ui/components/form-field-defaults';
|
|
|
|
@Component({
|
|
selector: 'app-settings-remote-control-section',
|
|
providers: [provideFormFieldDefaults()],
|
|
imports: [
|
|
MatButtonModule,
|
|
MatFormFieldModule,
|
|
MatIconModule,
|
|
MatInputModule,
|
|
MatSlideToggleModule,
|
|
MatTooltipModule,
|
|
QRCodeComponent,
|
|
ReactiveFormsModule,
|
|
TranslateModule,
|
|
],
|
|
templateUrl: './settings-remote-control-section.component.html',
|
|
encapsulation: ViewEncapsulation.None,
|
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
styleUrls: ['./settings-remote-control-section.component.scss'],
|
|
})
|
|
export class SettingsRemoteControlSectionComponent {
|
|
readonly form = input.required<FormGroup>();
|
|
|
|
constructor() {
|
|
// Parent patches (Discard, backup import) change the form outside
|
|
// this OnPush section's events.
|
|
markSectionForCheckOnFormEvents(this.form);
|
|
}
|
|
|
|
readonly localIpAddresses = input.required<string[]>();
|
|
readonly visibleQrCodeIp = input<string | null>(null);
|
|
|
|
readonly toggleQrCode = output<string>();
|
|
}
|