### Angular Component Setup for Piying View
Source: https://github.com/piying-org/piying-view/blob/main/public/llm/use-angular-piying.md
This TypeScript code demonstrates how to set up an Angular component to use the Piying view. It includes importing necessary modules like `PiyingView` and `PiyingViewGroup`, defining `schema`, `options`, and `model` properties, and implementing a `modelChanged` handler. The `schema` uses Valibot for data validation, and `options` are used for component registration. The `model` is managed using Angular signals.
```typescript
import { Component, signal } from '@angular/core';
import * as v from 'valibot';
import { componentClass, NFCSchema, setComponent } from '@piying/view-angular-core';
import { PiyingView, PiyingViewGroup } from '@piying/view-angular';
@Component({
selector: 'app-root',
imports: [PiyingView],
templateUrl: './app.html',
styleUrl: './app.scss',
})
export class App {
schema = v.object({});
options = {
fieldGlobalConfig: {
types: {},
wrappers: {},
},
};
model = signal({});
modelChanged(event: any) {
console.log(event);
}
}
```
--------------------------------
### Angular Pying Button Component Example
Source: https://github.com/piying-org/piying-view/blob/main/public/llm/to-angular-piying-non-control.md
This example demonstrates converting an HTML input element into an Angular Pying button component. It shows the input HTML and the resulting Angular component, including the template with attribute bindings and the TypeScript class with an input property for content.
```html
```
```html
```
```typescript
import { Component, input, viewChild } from '@angular/core';
import { AttributesDirective } from '@piying/view-angular';
@Component({
selector: 'app-button',
templateUrl: './component.html',
imports: [AttributesDirective],
})
export class ButtonNFCC {
static __version = 2;
templateRef = viewChild.required('templateRef');
content = input('Default');
}
```
--------------------------------
### React Form Component with Piying View and Valibot
Source: https://context7.com/piying-org/piying-view/llms.txt
Demonstrates creating a user registration form in React using the PiyingView component. It utilizes Valibot for schema definition, validation, and integrates with the static-injector library for component configuration like input types and placeholders. Handles form state changes and submission validation.
```typescript
import { PiyingView } from '@piying/view-react';
import * as v from 'valibot';
import { setComponent, setInputs } from '@piying/view-core';
import { useState } from 'react';
function UserRegistrationForm() {
const [model, setModel] = useState({
email: '',
password: '',
role: 'user'
});
// Define schema with validation and component configuration
const schema = v.object({
email: v.pipe(
v.string(),
v.email('Invalid email'),
setComponent('input'),
setInputs({
type: 'email',
placeholder: 'your@email.com',
'aria-label': 'Email address'
})
),
password: v.pipe(
v.string(),
v.minLength(8, 'Password must be at least 8 characters'),
setComponent('input'),
setInputs({
type: 'password',
placeholder: 'Enter password'
})
),
role: v.pipe(
v.picklist(['user', 'admin', 'guest']),
setComponent('select')
)
});
const handleChange = (newValue: any) => {
console.log('Form changed:', newValue);
setModel(newValue);
};
const handleSubmit = () => {
// Validate before submission
const result = v.safeParse(schema, model);
if (result.success) {
console.log('Valid data:', result.output);
// Submit to API
} else {
console.error('Validation errors:', result.issues);
}
};
return (
);
}
export default UserRegistrationForm;
```
--------------------------------
### HTML Template for Piying View Component
Source: https://github.com/piying-org/piying-view/blob/main/public/llm/use-angular-piying.md
This HTML snippet shows how to integrate the Piying view component into an Angular template. It demonstrates binding the component's properties (`schema`, `options`, `model`) using property binding and handling model changes with event binding (`modelChange`). The `piying-view` component is rendered here, utilizing the properties defined in the Angular component class.
```html
```
--------------------------------
### Vue 3 Reactive Form Handling with Valibot
Source: https://context7.com/piying-org/piying-view/llms.txt
Demonstrates creating a reactive form in Vue 3 using the Composition API. It leverages Vue's `ref` and `computed` for state management and Valibot for schema definition and validation. The `PiyingView` component renders the form based on the schema and model, handling user input changes and form submission.
```typescript
import { PiyingView } from '@piying/view-vue';
import * as v from 'valibot';
import { setComponent, setInputs } from '@piying/view-core';
import { ref, computed } from 'vue';
export default {
components: { PiyingView },
setup() {
const formModel = ref({
username: '',
bio: '',
interests: []
});
const formSchema = computed(() => v.object({
username: v.pipe(
v.string(),
v.minLength(3, 'Username must be at least 3 characters'),
setComponent('input'),
setInputs({
placeholder: 'Enter username'
})
),
bio: v.pipe(
v.string(),
v.maxLength(500, 'Bio must be less than 500 characters'),
setComponent('textarea'),
setInputs({
rows: 4,
placeholder: 'Tell us about yourself'
})
),
interests: v.pipe(
v.array(v.string()),
v.minLength(1, 'Select at least one interest')
)
}));
const handleModelChange = (newValue) => {
console.log('Form updated:', newValue);
formModel.value = newValue;
};
const submitForm = () => {
const result = v.safeParse(formSchema.value, formModel.value);
if (result.success) {
console.log('Submitting:', result.output);
// API call here
} else {
console.error('Validation failed:', result.issues);
}
};
return {
formModel,
formSchema,
handleModelChange,
submitForm
};
},
template: `
`
};
```
--------------------------------
### Configure Field Behavior with Valibot Schema Actions
Source: https://context7.com/piying-org/piying-view/llms.txt
These decorator-like functions configure field behavior, component mapping, validation, and UI properties directly on Valibot schemas using the pipe pattern. They allow for detailed customization of form fields, including input types, validation rules, conditional rendering, and event handling. Dependencies include Valibot and specific functions from '@piying/view-core'.
```typescript
import * as v from 'valibot';
import {
setComponent,
setInputs,
setOutputs,
formConfig,
renderConfig,
setWrapper,
hideWhen,
disableWhen,
componentClass
} from '@piying/view-core';
// Complete example with multiple action functions
const productSchema = v.object({
// Text input with custom component and attributes
name: v.pipe(
v.string(),
v.minLength(3, 'Name too short'),
setComponent('input'),
setInputs({
placeholder: 'Product name',
maxlength: 50,
'aria-label': 'Product name'
}),
componentClass('product-name-field'),
formConfig({
updateOn: 'blur', // Update on blur instead of every keystroke
disabled: false
})
),
// Number input with range constraints
price: v.pipe(
v.number(),
v.minValue(0, 'Price must be positive'),
setComponent('input'),
setInputs({
type: 'number',
min: 0,
step: 0.01
}),
formConfig({
transfomer: {
toModel: (value) => parseFloat(value), // Convert string to number
toView: (value) => value.toFixed(2) // Display with 2 decimals
}
})
),
// Conditional field: only show if price > 100
discount: v.pipe(
v.optional(v.number()),
setComponent('input'),
hideWhen((formValue) => formValue.price <= 100),
setInputs({
type: 'number',
placeholder: 'Discount %'
})
),
// Radio button group
category: v.pipe(
v.picklist(['electronics', 'clothing', 'food']),
setComponent('radio'),
setInputs({
options: [
{ label: 'Electronics', value: 'electronics' },
{ label: 'Clothing', value: 'clothing' },
{ label: 'Food', value: 'food' }
]
})
),
// Checkbox with output event handler
inStock: v.pipe(
v.boolean(),
setComponent('checkbox'),
setOutputs({
change: (value) => {
console.log('Stock status changed:', value);
}
})
),
// Field with wrapper component
description: v.pipe(
v.string(),
setComponent('textarea'),
setWrapper('field-wrapper'), // Wraps field in a container component
setInputs({
rows: 5,
placeholder: 'Product description'
})
),
// Conditionally disabled field
specialOffer: v.pipe(
v.optional(v.string()),
setComponent('input'),
disableWhen((formValue) => !formValue.inStock) // Disable if not in stock
),
// Hidden field (not rendered)
internalId: v.pipe(
v.string(),
renderConfig({ hidden: true })
)
});
// Use the schema with a form component
const formModel = {
name: '',
price: 0,
category: 'electronics',
inStock: true,
description: '',
specialOffer: '',
internalId: 'PROD-001'
};
```
--------------------------------
### Angular Custom Component Registration for Piying View
Source: https://context7.com/piying-org/piying-view/llms.txt
Shows how to register custom form field components globally within an Angular application to enhance the `PiyingView` capabilities. It defines a `ColorPickerComponent` and demonstrates how to register it using `PI_VIEW_CONFIG_TOKEN` and then utilize it within a Valibot schema.
```typescript
import { Component, input, output } from '@angular/core';
import { setComponent, PI_VIEW_CONFIG_TOKEN } from '@piying/view-angular';
import * as v from 'valibot';
// Define a custom component
@Component({
selector: 'custom-color-picker',
standalone: true,
template: `
{{ modelValue() }}
`
})
export class ColorPickerComponent {
modelValue = input('#000000');
modelChange = output();
disabled = input(false);
onChange(event: Event) {
const value = (event.target as HTMLInputElement).value;
this.modelChange.emit(value);
}
}
// Register globally
const globalConfig = {
defaultConfig: {
components: {
'color-picker': ColorPickerComponent
}
}
};
// Use in schema
const themeSchema = v.object({
primaryColor: v.pipe(
v.string(),
v.regex(/^#[0-9A-F]{6}$/i, 'Invalid hex color'),
setComponent('color-picker'),
setInputs({
'aria-label': 'Primary theme color'
})
),
secondaryColor: v.pipe(
v.string(),
v.regex(/^#[0-9A-F]{6}$/i, 'Invalid hex color'),
setComponent('color-picker')
)
});
// Provide config in Angular
import { bootstrapApplication } from '@angular/platform-browser';
bootstrapApplication(AppComponent, {
providers: [
{
provide: PI_VIEW_CONFIG_TOKEN,
useValue: globalConfig
}
]
});
```
--------------------------------
### Convert Valibot Schema to Form Configuration (TypeScript)
Source: https://context7.com/piying-org/piying-view/llms.txt
Converts a Valibot schema into a resolved form field configuration. This function handles the creation of the form control hierarchy, including validation, state management, and rendering metadata. It requires a Valibot schema, an injector, a form builder, a core schema handler, global field configuration, and a mechanism to register destroy callbacks.
```typescript
import { convert } from '@piying/view-core';
import { EnvironmentInjector } from '@angular/core';
import { FormBuilder, CoreSchemaHandle } from '@piying/view-core';
import * as v from 'valibot';
// Define a Valibot schema
const userSchema = v.object({
name: v.pipe(v.string(), v.minLength(3, 'Name must be at least 3 characters')),
age: v.pipe(v.number(), v.minValue(18, 'Must be 18 or older')),
email: v.pipe(v.string(), v.email('Invalid email address'))
});
// Convert schema to form configuration
const injector = createEnvironmentInjector([], parentInjector);
const formConfig = convert(userSchema, {
injector: injector,
builder: FormBuilder,
handle: CoreSchemaHandle,
fieldGlobalConfig: {
// Global configuration for all fields
defaultConfig: {
updateOn: 'change' // or 'blur'
}
},
registerOnDestroy: (fn) => {
injector.get(DestroyRef).onDestroy(fn);
}
});
// Access form control and its properties
const control = formConfig.form.control; // FieldGroup instance
console.log(control.value$$()); // Get current form value
console.log(control.status$$()); // Get validation status: 'VALID' | 'INVALID' | 'PENDING'
console.log(control.errors$$()); // Get validation errors
```
--------------------------------
### Piying View Core Form Control Classes (TypeScript)
Source: https://context7.com/piying-org/piying-view/llms.txt
Illustrates the usage of core form control classes from '@piying/view-core': FieldControl for single fields, FieldGroup for object structures, and FieldArray for array structures. Shows how to initialize, update values, check validation status, and manage user interaction states like dirty and touched. Supports Valibot for validation rules.
```typescript
import { FieldControl, FieldGroup, FieldArray } from '@piying/view-core';
import * as v from 'valibot';
// Create a single field control
const nameControl = new FieldControl({
defaultValue: '',
validators: [
(value) => {
const result = v.safeParse(v.pipe(v.string(), v.minLength(3)), value);
return result.success ? null : { minLength: result.issues[0].message };
}
]
});
// Update value and check status
nameControl.updateValue('John');
console.log(nameControl.value$$()); // 'John'
console.log(nameControl.status$$()); // 'VALID' or 'INVALID'
console.log(nameControl.valid); // true/false
console.log(nameControl.dirty); // false (not modified by user)
console.log(nameControl.touched); // false (not focused/blurred)
// Mark as dirty and touched (user interaction)
nameControl.markAsDirty();
nameControl.markAsTouched();
// Create a form group (object-like container)
const addressGroup = new FieldGroup({
children: {
street: new FieldControl({ defaultValue: '' }),
city: new FieldControl({ defaultValue: '' }),
zipCode: new FieldControl({ defaultValue: '' })
}
});
// Update group value
addressGroup.updateValue({
street: '123 Main St',
city: 'New York',
zipCode: '10001'
});
console.log(addressGroup.value$$()); // { street: '123 Main St', city: 'New York', zipCode: '10001' }
// Group is valid only if all children are valid
console.log(addressGroup.valid); // true/false based on children
// Create a form array (array-like container)
const phonesArray = new FieldArray({
children: [
new FieldControl({ defaultValue: '' }),
new FieldControl({ defaultValue: '' })
],
deletionMode: 'shrink' // or 'mark' (sets to undefined)
});
// Add new itemphonesArray.push(new FieldControl({ defaultValue: '' }));
// Remove item at index
phonesArray.removeAt(1);
// Update array value
phonesArray.updateValue(['555-0001', '555-0002']);
console.log(phonesArray.value$$()); // ['555-0001', '555-0002']
console.log(phonesArray.length); // 2
```
--------------------------------
### Angular 皮影控件基础模板
Source: https://github.com/piying-org/piying-view/blob/main/public/llm/to-angular-piying-control.md
定义了 Angular 皮影 (piying) 表单控件的基础 HTML 模板结构,包括 `ng-template` 和 `let-attr`。
```html
```
--------------------------------
### Conditional Rendering of Text Prefix and Suffix
Source: https://github.com/piying-org/piying-view/blob/main/projects/view-angular/test/mat-form-field/form-field/component.html
This logic conditionally renders 'textPrefix' and 'textSuffix' content when provided. It utilizes the '@if' directive with an 'as template' clause to capture and display the content if these properties exist.
```template
@if (props['textPrefix']; as template) {
{{ template }}
}
@if (props['textSuffix']; as template) {
{{ template }}
```
--------------------------------
### Dynamic Form Arrays with Add/Remove (TypeScript)
Source: https://context7.com/piying-org/piying-view/llms.txt
This snippet demonstrates how to manage dynamic form arrays in Angular, allowing users to add or remove items at runtime. It uses Piying View for form rendering and Valibot for schema definition. Dependencies include `@piying/view-angular`, `@piying/view-angular-core`, and `valibot`.
```typescript
import { Component, signal } from '@angular/core';
import { PiyingView } from '@piying/view-angular';
import * as v from 'valibot';
import { setComponent, setInputs, setOutputs } from '@piying/view-angular-core';
@Component({
selector: 'app-contacts-form',
standalone: true,
imports: [PiyingView],
template: `
`
})
export class ContactsFormComponent {
schema = signal(v.object({
contacts: v.pipe(
v.array(v.object({
name: v.pipe(
v.string(),
v.minLength(1, 'Name required'),
setComponent('input'),
setInputs({ placeholder: 'Contact name' })
),
phone: v.pipe(
v.string(),
v.regex(/^\d{3}-\d{3}-\d{4}$/, 'Format: XXX-XXX-XXXX'),
setComponent('input'),
setInputs({ placeholder: '555-555-5555' })
),
email: v.pipe(
v.string(),
v.email('Invalid email'),
setComponent('input'),
setInputs({ type: 'email', placeholder: 'email@example.com' })
)
})),
v.minLength(1, 'At least one contact required')
)
}));
model = signal({
contacts: [
{ name: '', phone: '', email: '' }
]
});
onModelChange(newValue: any) {
this.model.set(newValue);
}
addContact() {
const current = this.model();
this.model.set({
contacts: [
...current.contacts,
{ name: '', phone: '', email: '' }
]
});
}
removeLastContact() {
const current = this.model();
if (current.contacts.length > 1) {
this.model.set({
contacts: current.contacts.slice(0, -1)
});
}
}
}
```
--------------------------------
### Convert JSON Schema to Valibot Schema
Source: https://context7.com/piying-org/piying-view/llms.txt
This utility converts JSON Schema (Draft 2020-12 and Draft 7) to Valibot schemas. This enables integration with existing JSON Schema-based systems and tools, allowing you to leverage Valibot's validation capabilities with schemas defined in the JSON Schema format. The conversion is performed by the `jsonSchemaToValibot` function from '@piying/view-core'.
```typescript
import { jsonSchemaToValibot } from '@piying/view-core';
import * as v from 'valibot';
// Define a JSON Schema
const jsonSchema = {
$schema: 'https://json-schema.org/draft/2020-12/schema',
type: 'object',
properties: {
firstName: {
type: 'string',
minLength: 2,
maxLength: 50
},
lastName: {
type: 'string',
minLength: 2
},
age: {
type: 'integer',
minimum: 0,
maximum: 120
},
email: {
type: 'string',
format: 'email'
},
address: {
type: 'object',
properties: {
street: { type: 'string' },
city: { type: 'string' },
zipCode: { type: 'string', pattern: '^[0-9]{5}$' }
},
required: ['street', 'city']
},
hobbies: {
type: 'array',
items: { type: 'string' },
minItems: 1,
maxItems: 10
}
},
required: ['firstName', 'lastName', 'email']
};
// Convert to Valibot schema
const valibotSchema = jsonSchemaToValibot(jsonSchema);
// Now use with Piying View
const formData = {
firstName: 'John',
lastName: 'Doe',
age: 30,
email: 'john@example.com',
address: {
street: '123 Main St',
city: 'New York',
zipCode: '10001'
},
hobbies: ['reading', 'coding']
};
// Validate using the converted schema
const result = v.safeParse(valibotSchema, formData);
if (result.success) {
console.log('Valid data:', result.output);
} else {
console.error('Validation errors:', result.issues);
}
// Use with form components
//
```
--------------------------------
### Asynchronous Validation with Valibot and Piying View (TypeScript)
Source: https://context7.com/piying-org/piying-view/llms.txt
This snippet illustrates how to implement asynchronous validation for fields like username availability checks against remote APIs. It utilizes Valibot's `customValidator` and `formConfig` with `asyncValidators`. Dependencies include `valibot` and `@piying/view-core`.
```typescript
import * as v from 'valibot';
import { setComponent, formConfig, setInputs } from '@piying/view-core';
import { customValidator } from '@piying/view-core';
// Async validator function
async function checkUsernameAvailable(username: string): Promise {
// Simulate API call
const response = await fetch(`/api/check-username?username=${username}`);
const data = await response.json();
return data.available;
}
// Create schema with async validation
const registrationSchema = v.object({
username: v.pipe(
v.string(),
v.minLength(3, 'Username must be at least 3 characters'),
// Add custom async validator
customValidator(async (value) => {
if (value.length < 3) return null; // Skip if too short
const available = await checkUsernameAvailable(value);
return available ? null : { usernameExists: 'Username already taken' };
}),
setComponent('input'),
setInputs({
placeholder: 'Choose a username'
}),
formConfig({
updateOn: 'blur', // Only validate on blur to reduce API calls
asyncValidators: [
async (value: string) => {
// Additional async validation
if (!value) return null;
const isValid = await checkUsernameAvailable(value);
return isValid ? null : { async: 'Username not available' };
}
]
})
),
email: v.pipe(
v.string(),
v.email('Invalid email'),
setComponent('input'),
setInputs({ type: 'email' })
),
password: v.pipe(
v.string(),
v.minLength(8, 'Password must be at least 8 characters'),
setComponent('input'),
setInputs({ type: 'password' })
)
});
// Use in component
const model = {
username: '',
email: '',
password: ''
};
// Monitor validation status
// control.status$$() will return 'PENDING' during async validation
// control.status$$() will return 'VALID' or 'INVALID' when complete
```
--------------------------------
### Content Rendering Based on Type
Source: https://github.com/piying-org/piying-view/blob/main/projects/view-angular/test/mat-form-field/form-field/component.html
This logic differentiates how content is rendered based on its type. If the 'content' is a string, it's displayed directly. Otherwise, an alternative rendering path (currently empty) is taken.
```template
@if (isString | pure: content) {
{{ content }}
} @else {
// Alternative rendering for non-string content
}
```
--------------------------------
### Conditional Rendering of Prefix and Suffix Templates
Source: https://github.com/piying-org/piying-view/blob/main/projects/view-angular/test/mat-form-field/form-field/component.html
This section handles the conditional rendering of 'prefix' and 'suffix' content if they are provided as templates. It uses the '@if' directive to check for the presence of these properties and then renders their templated content.
```template
@if (props['prefix']; as template) {
{{ template }}
}
@if (props['suffix']; as template) {
{{ template }}
```
--------------------------------
### Angular Component Integration for Schema-Driven Forms (TypeScript)
Source: https://context7.com/piying-org/piying-view/llms.txt
An Angular component that renders schema-driven forms using Piying View. It supports automatic bidirectional data binding and change detection with Angular signals. The component takes a form schema, model, and options as input and emits model changes. It utilizes built-in components and custom input configurations.
```typescript
import { Component, signal } from '@angular/core';
import { PiyingView } from '@piying/view-angular';
import * as v from 'valibot';
import { setComponent, setInputs, formConfig } from '@piying/view-angular-core';
@Component({
selector: 'app-user-form',
standalone: true,
imports: [PiyingView],
template: `
`
})
export class UserFormComponent {
// Define schema with component mappings
formSchema = signal(v.object({
username: v.pipe(
v.string(),
v.minLength(3),
setComponent('input'), // Built-in component type
setInputs({
placeholder: 'Enter username',
class: 'form-control'
}),
formConfig({
updateOn: 'blur'
})
),
age: v.pipe(
v.number(),
v.minValue(18),
setComponent('range'),
setInputs({
min: 18,
max: 100
})
),
newsletter: v.pipe(
v.boolean(),
setComponent('checkbox')
)
}));
// Initial model value
formModel = signal({ username: '', age: 25, newsletter: false });
// Form options
formOptions = signal({
fieldGlobalConfig: {
// Global settings for all fields
}
});
// Handle form changes
onModelChange(newValue: any) {
console.log('Form updated:', newValue);
this.formModel.set(newValue);
// Validation happens automatically
if (this.isValid(newValue)) {
this.submitForm(newValue);
}
}
private isValid(value: any): boolean {
const result = v.safeParse(this.formSchema(), value);
return result.success;
}
private submitForm(data: any) {
console.log('Submitting:', data);
}
}
```
--------------------------------
### Angular 皮影控件基础组件实现
Source: https://github.com/piying-org/piying-view/blob/main/public/llm/to-angular-piying-control.md
提供了 Angular 皮影 (piying) 表单控件的 TypeScript 组件骨架,继承自 `BaseControl` 并实现了 `NG_VALUE_ACCESSOR`。
```typescript
import { Component, forwardRef, viewChild } from '@angular/core';
import { FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
import { AttributesDirective, BaseControl } from '@piying/view-angular';
@Component({
selector: 'app-xxx',
templateUrl: './component.html',
imports: [FormsModule, AttributesDirective],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => XXXFCC),
multi: true,
},
],
})
export class XXXFCC extends BaseControl {
static __version = 2;
templateRef = viewChild.required('templateRef');
}
```
--------------------------------
### Angular 皮影输入控件示例
Source: https://github.com/piying-org/piying-view/blob/main/public/llm/to-angular-piying-control.md
将一个简单的 HTML 输入框转换为 Angular 皮影 (piying) 表单控件,实现了双向数据绑定和属性传递。
```html
```
```typescript
import { Component, forwardRef, viewChild } from '@angular/core';
import { FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
import { AttributesDirective, BaseControl } from '@piying/view-angular';
@Component({
selector: 'app-input',
templateUrl: './component.html',
imports: [FormsModule, AttributesDirective],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => InputFCC),
multi: true,
},
],
})
export class InputFCC extends BaseControl {
static __version = 2;
templateRef = viewChild.required('templateRef');
}
```
--------------------------------
### Angular Pying Non-Form Control Template Structure
Source: https://github.com/piying-org/piying-view/blob/main/public/llm/to-angular-piying-non-control.md
This snippet shows the basic structure for an Angular Pying non-form control template. It uses `ng-template` to define the template content and `let-attr` to receive attributes. The `AttributesDirective` is imported and applied to handle attribute binding.
```html
```
```typescript
import { Component, input, viewChild } from '@angular/core';
import { AttributesDirective } from '@piying/view-angular';
@Component({
selector: 'app-button',
templateUrl: './component.html',
imports: [AttributesDirective],
})
export class ButtonNFCC {
static __version = 2;
templateRef = viewChild.required('templateRef');
}
```
--------------------------------
### Conditional Rendering of Hint and Error Messages
Source: https://github.com/piying-org/piying-view/blob/main/projects/view-angular/test/mat-form-field/form-field/component.html
This snippet shows how to conditionally render hint messages ('description', 'hintStart', 'hintEnd') and error messages. It checks for the presence of hint properties and also calls 'showError$$()' to determine if an error message should be displayed.
```template
@if (props['description'] || props['hintStart']; as hint) {
// Hint rendering logic
}
@if (props['hintEnd']; as hintEnd) {
// HintEnd rendering logic
}
@if (showError$$()) {
{{ errorStr$$() }}
```
--------------------------------
### Add __version and templateRef to Component Class (TypeScript)
Source: https://github.com/piying-org/piying-view/blob/main/public/llm/to-angular-selectorless.md
In the component's TypeScript file, you must add two static properties: `__version` (set to 2) and a `templateRef` property initialized using `viewChild.required('templateRef')`. This prepares the component for selectorless usage.
```typescript
@Component({
/** */
})
export class InputFCC extends BaseControl {
// 固定增加
static __version = 2;
templateRef = viewChild.required('templateRef');
/** 其他代码 */
}
```
--------------------------------
### Wrap Content in ng-template (HTML)
Source: https://github.com/piying-org/piying-view/blob/main/public/llm/to-angular-selectorless.md
This snippet shows how to wrap the content of an Angular component within an ng-template tag. This is the first step in making a component selectorless. The `let-attr` directive allows passing attributes to the template.
```html
```
--------------------------------
### Conditional Rendering of Title and Required Marker
Source: https://github.com/piying-org/piying-view/blob/main/projects/view-angular/test/mat-form-field/form-field/component.html
This snippet demonstrates conditional rendering of a title and a required marker based on properties within a 'props' object. It checks for the existence of a 'title' and ensures 'hideLabel' is not true before displaying the title. A required marker is shown only if 'required' is true and 'hideRequiredMarker' is not true.
```template
@let props = props$$();
@if (props['title'] && props['hideLabel'] !== true) {
{{ props['title'] }}
@if (props['required'] && props['hideRequiredMarker'] !== true) {
*
}
}
```
--------------------------------
### Add Parent Directive for Single Parent Element (HTML)
Source: https://github.com/piying-org/piying-view/blob/main/public/llm/to-angular-selectorless.md
If the content within the ng-template has only a single parent element, you need to add the `[attributes]="attr()"` directive to that parent element. This ensures proper attribute binding when the component is selectorless.
```html
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.