Hone logo
Hone
Problems

Angular Component Code Generator

This challenge focuses on building a simple code generator within an Angular application. You will create a component that allows users to define basic properties of a new Angular component, and then generates the corresponding TypeScript, HTML, and CSS files for that component. This is a valuable exercise for understanding how to programmatically create and manipulate code, a concept useful in scaffolding tools and automated development workflows.

Problem Description

Your task is to create an Angular component that acts as a code generator for new Angular components. The user will provide a component name and optionally some input properties. Based on this information, the generator will output the basic boilerplate code for a new Angular component.

Key Requirements:

  1. Component Name Input: A text input field for the user to enter the desired name of the new Angular component (e.g., UserProfile, ProductCard).
  2. Input Property Definition (Optional): A way for the user to define input properties for the component. This could be a simple text area where each line represents an input property in the format @Input() propertyName: type; (e.g., userName: string, userId: number).
  3. Code Generation: A button to trigger the code generation.
  4. Output Display: Display the generated TypeScript (.ts), HTML (.html), and CSS (.css or .scss) code for the new component. The output should be clearly separated and labeled.
  5. File Naming Convention: The generated files should follow Angular's standard naming conventions (e.g., user-profile.component.ts, user-profile.component.html, user-profile.component.css).

Expected Behavior:

When the user enters a component name like MyCustomComponent and clicks "Generate," the output should display the following:

  • my-custom.component.ts: Containing a basic class structure with the provided @Input() properties.
  • my-custom.component.html: Containing a simple template structure.
  • my-custom.component.css: Containing an empty stylesheet.

Edge Cases:

  • Invalid Component Names: Handle cases where the user enters invalid characters or an empty string for the component name.
  • No Input Properties: The generator should still produce valid component code even if no input properties are defined.
  • Malformed Input Properties: Gracefully handle lines in the input properties text area that do not conform to the expected @Input() propertyName: type; format.

Examples

Example 1:

Input:
Component Name: UserProfile

Output:

// user-profile.component.ts
import { Component, Input } from '@angular/core';

@Component({
  selector: 'app-user-profile',
  templateUrl: './user-profile.component.html',
  styleUrls: ['./user-profile.component.css']
})
export class UserProfileComponent {
  // Generated Input Properties will go here
}

// user-profile.component.html
<p>
  user-profile works!
</p>

// user-profile.component.css
/* Styles for user-profile component */

Explanation: A basic UserProfileComponent is generated with standard Angular annotations and a placeholder for input properties.

Example 2:

Input:
Component Name: ProductCard
Input Properties:
  productName: string
  price: number
  isAvailable: boolean

Output:

// product-card.component.ts
import { Component, Input } from '@angular/core';

@Component({
  selector: 'app-product-card',
  templateUrl: './product-card.component.html',
  styleUrls: ['./product-card.component.css']
})
export class ProductCardComponent {
  @Input() productName: string;
  @Input() price: number;
  @Input() isAvailable: boolean;
}

// product-card.component.html
<div class="product-card">
  <h2>{{ productName }}</h2>
  <p>Price: ${{ price }}</p>
  <p>{{ isAvailable ? 'In Stock' : 'Out of Stock' }}</p>
</div>

// product-card.component.css
.product-card {
  border: 1px solid #ccc;
  padding: 10px;
  margin: 10px;
}

Explanation: The ProductCardComponent is generated with specific @Input() properties and a slightly more elaborated HTML template that uses these inputs. The CSS provides basic styling for the card.

Example 3: (Edge Case - Malformed Input)

Input:
Component Name: DataDisplay
Input Properties:
  data: any
  id: number
  invalid_line

Output:

// data-display.component.ts
import { Component, Input } from '@angular/core';

@Component({
  selector: 'app-data-display',
  templateUrl: './data-display.component.html',
  styleUrls: ['./data-display.component.css']
})
export class DataDisplayComponent {
  @Input() data: any;
  @Input() id: number;
  // Note: 'invalid_line' was not parsed as a valid @Input property.
}

// data-display.component.html
<p>
  data-display works!
</p>

// data-display.component.css
/* Styles for data-display component */

Explanation: The invalid_line in the input properties is ignored because it doesn't conform to the expected format, and a note is implicitly handled by the generator not including it.

Constraints

  • The component name must be a valid Angular selector name (alphanumeric characters, hyphens, and start with a letter).
  • Input properties should be defined using the format @Input() propertyName: type; or propertyName: type; (where @Input() is implicitly added by the generator). The generator should attempt to parse basic types like string, number, boolean, any, Array<T>, object, etc.
  • The generated code should be syntactically correct TypeScript, HTML, and CSS.
  • The application should remain responsive during the generation process; no significant performance bottlenecks are expected for this scale of operation.

Notes

  • Consider using regular expressions to parse the input properties effectively.
  • You'll need to convert the component name into the kebab-case format for file names and the selector.
  • Think about how to dynamically construct the string content for each generated file.
  • You might want to implement a basic validation for the component name input to ensure it adheres to common Angular naming conventions.
  • For the HTML and CSS, providing sensible default templates and styles can enhance the utility of the generator.
  • This challenge focuses on generating the code strings. You are not required to actually create files on the file system or integrate with Angular CLI commands. Displaying the generated code in the UI is sufficient.
Loading editor...
typescript