feat(): merge challenge 57

This commit is contained in:
thomas
2025-02-28 11:51:26 +01:00
parent b8d10b940c
commit 3f6f6def3d
24 changed files with 309 additions and 17 deletions

View File

@@ -24,7 +24,7 @@ If you would like to propose a challenge, this project is open source, so feel f
## Challenges ## Challenges
Check [all 56 challenges](https://angular-challenges.vercel.app/) Check [all 57 challenges](https://angular-challenges.vercel.app/)
## Contributors ✨ ## Contributors ✨

View File

@@ -0,0 +1,36 @@
{
"extends": ["../../../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts"],
"extends": [
"plugin:@nx/angular",
"plugin:@angular-eslint/template/process-inline-templates"
],
"rules": {
"@angular-eslint/directive-selector": [
"error",
{
"type": "attribute",
"prefix": "app",
"style": "camelCase"
}
],
"@angular-eslint/component-selector": [
"error",
{
"type": "element",
"prefix": "app",
"style": "kebab-case"
}
]
}
},
{
"files": ["*.html"],
"extends": ["plugin:@nx/angular-template"],
"rules": {}
}
]
}

View File

@@ -0,0 +1,13 @@
# Content Projection Default
> author: thomas-laforge
### Run Application
```bash
npx nx serve angular-content-projection-default
```
### Documentation and Instruction
Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/57-content-projection-default/).

View File

@@ -0,0 +1,81 @@
{
"name": "angular-content-projection-default",
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
"projectType": "application",
"prefix": "app",
"sourceRoot": "apps/angular/57-content-projection-default/src",
"tags": [],
"targets": {
"build": {
"executor": "@angular-devkit/build-angular:application",
"outputs": ["{options.outputPath}"],
"options": {
"outputPath": "dist/apps/angular/57-content-projection-default",
"index": "apps/angular/57-content-projection-default/src/index.html",
"browser": "apps/angular/57-content-projection-default/src/main.ts",
"polyfills": ["zone.js"],
"tsConfig": "apps/angular/57-content-projection-default/tsconfig.app.json",
"inlineStyleLanguage": "scss",
"assets": [
{
"glob": "**/*",
"input": "apps/angular/57-content-projection-default/public"
}
],
"styles": [
"apps/angular/57-content-projection-default/src/styles.scss"
],
"scripts": []
},
"configurations": {
"production": {
"budgets": [
{
"type": "initial",
"maximumWarning": "500kb",
"maximumError": "1mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "4kb",
"maximumError": "8kb"
}
],
"outputHashing": "all"
},
"development": {
"optimization": false,
"extractLicenses": false,
"sourceMap": true
}
},
"defaultConfiguration": "production"
},
"serve": {
"executor": "@angular-devkit/build-angular:dev-server",
"configurations": {
"production": {
"buildTarget": "angular-content-projection-default:build:production"
},
"development": {
"buildTarget": "angular-content-projection-default:build:development"
}
},
"defaultConfiguration": "development"
},
"extract-i18n": {
"executor": "@angular-devkit/build-angular:extract-i18n",
"options": {
"buildTarget": "angular-content-projection-default:build"
}
},
"serve-static": {
"executor": "@nx/web:file-server",
"options": {
"buildTarget": "angular-content-projection-default:build",
"staticFilePath": "dist/apps/angular/57-content-projection-default/browser",
"spa": true
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -0,0 +1,16 @@
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { CardComponent } from './card.component';
@Component({
imports: [CardComponent],
selector: 'app-root',
template: `
<app-card title="Titre 1" message="Message1" />
<app-card title="Titre 2" />
`,
host: {
class: 'p-4 block flex flex-col gap-1',
},
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AppComponent {}

View File

@@ -0,0 +1,5 @@
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
export const appConfig: ApplicationConfig = {
providers: [provideZoneChangeDetection({ eventCoalescing: true })],
};

View File

@@ -0,0 +1,22 @@
import { ChangeDetectionStrategy, Component, input } from '@angular/core';
@Component({
selector: 'app-card',
imports: [],
template: `
<div>{{ title() }}</div>
@if (message()) {
<div>{{ message() }}</div>
} @else {
<div>Aucun message</div>
}
`,
changeDetection: ChangeDetectionStrategy.OnPush,
host: {
class: 'p-4 border border-grey rounded-sm flex flex-col w-[200px]',
},
})
export class CardComponent {
title = input.required<string>();
message = input<string | undefined>(undefined);
}

View File

@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>angular-content-projection-default</title>
<base href="/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/x-icon" href="favicon.ico" />
</head>
<body>
<app-root></app-root>
</body>
</html>

View File

@@ -0,0 +1,7 @@
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app/app.component';
import { appConfig } from './app/app.config';
bootstrapApplication(AppComponent, appConfig).catch((err) =>
console.error(err),
);

View File

@@ -0,0 +1,5 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
/* You can add global styles to this file, and also import other style files */

View File

@@ -0,0 +1,14 @@
const { createGlobPatternsForDependencies } = require('@nx/angular/tailwind');
const { join } = require('path');
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
join(__dirname, 'src/**/!(*.stories|*.spec).{ts,html}'),
...createGlobPatternsForDependencies(__dirname),
],
theme: {
extend: {},
},
plugins: [],
};

View File

@@ -0,0 +1,10 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../../dist/out-tsc",
"types": []
},
"files": ["src/main.ts"],
"include": ["src/**/*.d.ts"],
"exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"]
}

View File

@@ -0,0 +1,6 @@
{
"extends": "./tsconfig.json",
"include": ["src/**/*.ts"],
"compilerOptions": {},
"exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"]
}

View File

@@ -0,0 +1,29 @@
{
"compilerOptions": {
"target": "es2022",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
},
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.editor.json"
},
{
"path": "./tsconfig.app.json"
}
],
"extends": "../../../tsconfig.base.json",
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,
"strictInjectionParameters": true,
"strictInputAccessModifiers": true,
"strictTemplates": true
}
}

View File

@@ -1,6 +1,6 @@
{ {
"total": 56, "total": 57,
"🟢": 21, "🟢": 22,
"🟠": 123, "🟠": 123,
"🔴": 211 "🔴": 211
} }

View File

@@ -0,0 +1,37 @@
---
title: 🟢 Content Projection Default
description: Challenge 57 is about content projection default container
author: thomas-laforge
contributors:
- tomalaforge
challengeNumber: 57
command: angular-content-projection-default
sidebar:
order: 22
badge: New
---
## Information
Content projection in Angular allows developers to create flexible and customizable components by passing content from the parent component to the child component dynamically using `<ng-content>`.
Currently, we have a shared component that relies on `input` properties to receive and display data. However, we want to improve its flexibility by replacing all `inputs` with content projection while maintaining the same appearance and behavior.
## Statement
Your task is to refactor the existing shared component to remove all `input` properties and instead use Angulars `<ng-content>` for content projection. After your modifications, the application should look and function exactly as before, but without any `input`.
### Steps to complete:
- Identify all `input` properties in the shared component.
- Remove them and replace them with appropriate `<ng-content>` containers.
- Adjust the parent component to pass the necessary content using content projection instead of binding to `input`s.
- Ensure that the application still displays the same UI and behavior after the changes.
## Constraints
- You must not use any `input` in the shared component.
- The applications UI and functionality must remain unchanged after the refactoring.
- You must use `<ng-content>` for content projection.
- Do not introduce additional properties or services to pass data.
- Ensure that projected content is correctly styled and positioned as before.

View File

@@ -8,7 +8,6 @@ challengeNumber: 56
command: signal-forms-and-signal command: signal-forms-and-signal
sidebar: sidebar:
order: 211 order: 211
badge: New
--- ---
## Information ## Information

View File

@@ -13,7 +13,7 @@ hero:
icon: right-arrow icon: right-arrow
variant: primary variant: primary
- text: Ir al Desafío más reciente - text: Ir al Desafío más reciente
link: /es/challenges/signal/56-forms-and-signal/ link: /es/challenges/angular/57-content-projection-default/
icon: rocket icon: rocket
- text: Dar una estrella - text: Dar una estrella
link: https://github.com/tomalaforge/angular-challenges link: https://github.com/tomalaforge/angular-challenges
@@ -26,8 +26,8 @@ import MyIcon from '../../../components/MyIcon.astro';
import SubscriptionForm from '../../../components/SubscriptionForm.astro'; import SubscriptionForm from '../../../components/SubscriptionForm.astro';
<CardGrid> <CardGrid>
<Card title="56 Desafíos"> <Card title="57 Desafíos">
Este repositorio contiene 56 Desafíos relacionados con <b>Angular</b>, <b>Nx</b>, <b>RxJS</b>, <b>Ngrx</b> y <b>Typescript</b>. Este repositorio contiene 57 Desafíos relacionados con <b>Angular</b>, <b>Nx</b>, <b>RxJS</b>, <b>Ngrx</b> y <b>Typescript</b>.
Estos desafíos se resuelven en torno a problemas de la vida real o características específicas para mejorar tus habilidades. Estos desafíos se resuelven en torno a problemas de la vida real o características específicas para mejorar tus habilidades.
</Card> </Card>

View File

@@ -13,7 +13,7 @@ hero:
icon: right-arrow icon: right-arrow
variant: primary variant: primary
- text: Aller au dernier Challenge - text: Aller au dernier Challenge
link: /fr/challenges/signal/56-forms-and-signal/ link: /fr/challenges/angular/57-content-projection-default/
icon: rocket icon: rocket
- text: Donne une étoile - text: Donne une étoile
link: https://github.com/tomalaforge/angular-challenges link: https://github.com/tomalaforge/angular-challenges
@@ -26,8 +26,8 @@ import MyIcon from '../../../components/MyIcon.astro';
import SubscriptionForm from '../../../components/SubscriptionForm.astro'; import SubscriptionForm from '../../../components/SubscriptionForm.astro';
<CardGrid> <CardGrid>
<Card title="56 Défis"> <Card title="57 Défis">
Ce répertoire rassemble 56 Défis liés à <b>Angular</b>, <b>Nx</b>, <b>RxJS</b>, <b>Ngrx</b> et <b>Typescript</b>. Ces défis portent sur des problèmes réels ou des fonctionnalités spécifiques pour améliorer vos compétences. Ce répertoire rassemble 57 Défis liés à <b>Angular</b>, <b>Nx</b>, <b>RxJS</b>, <b>Ngrx</b> et <b>Typescript</b>. Ces défis portent sur des problèmes réels ou des fonctionnalités spécifiques pour améliorer vos compétences.
</Card> </Card>
<Card title="Subscribe to get notify of latest challenges"> <Card title="Subscribe to get notify of latest challenges">

View File

@@ -27,8 +27,8 @@ import MyIcon from '../../components/MyIcon.astro';
import SubscriptionForm from '../../components/SubscriptionForm.astro'; import SubscriptionForm from '../../components/SubscriptionForm.astro';
<CardGrid> <CardGrid>
<Card title="56 Challenges"> <Card title="57 Challenges">
This repository gathers 56 Challenges related to <b>Angular</b>, <b>Nx</b>, <b>RxJS</b>, <b>Ngrx</b> and <b>Typescript</b>. This repository gathers 57 Challenges related to <b>Angular</b>, <b>Nx</b>, <b>RxJS</b>, <b>Ngrx</b> and <b>Typescript</b>.
These challenges resolve around real-life issues or specific features to elevate your skills. These challenges resolve around real-life issues or specific features to elevate your skills.
</Card> </Card>

View File

@@ -13,7 +13,7 @@ hero:
icon: right-arrow icon: right-arrow
variant: primary variant: primary
- text: Ir para o desafio mais recente - text: Ir para o desafio mais recente
link: /pt/challenges/signal/56-forms-and-signal/ link: /pt/challenges/angular/57-content-projection-default/
icon: rocket icon: rocket
- text: Dar uma estrela - text: Dar uma estrela
link: https://github.com/tomalaforge/angular-challenges link: https://github.com/tomalaforge/angular-challenges
@@ -26,8 +26,8 @@ import MyIcon from '../../../components/MyIcon.astro';
import SubscriptionForm from '../../../components/SubscriptionForm.astro'; import SubscriptionForm from '../../../components/SubscriptionForm.astro';
<CardGrid> <CardGrid>
<Card title="56 Desafios"> <Card title="57 Desafios">
Este repositório possui 56 Desafios relacionados a <b>Angular</b>, <b>Nx</b>, <b>RxJS</b>, Este repositório possui 57 Desafios relacionados a <b>Angular</b>, <b>Nx</b>, <b>RxJS</b>,
<b>Ngrx</b> e <b>Typescript</b>. <b>Ngrx</b> e <b>Typescript</b>.
Esses desafios são voltados para problemas reais ou funcionalidades específicas afim de Esses desafios são voltados para problemas reais ou funcionalidades específicas afim de
melhorar suas habilidades. melhorar suas habilidades.

View File

@@ -13,7 +13,7 @@ hero:
icon: right-arrow icon: right-arrow
variant: primary variant: primary
- text: Перейти к последней задаче - text: Перейти к последней задаче
link: /ru/challenges/signal/56-forms-and-signal/ link: /ru/challenges/angular/57-content-projection-default/
icon: rocket icon: rocket
- text: Добавить звезду - text: Добавить звезду
link: https://github.com/tomalaforge/angular-challenges link: https://github.com/tomalaforge/angular-challenges

View File

@@ -1,7 +1,6 @@
import { Component } from '@angular/core'; import { Component } from '@angular/core';
@Component({ @Component({
standalone: true,
imports: [], imports: [],
selector: 'app-root', selector: 'app-root',
template: ``, template: ``,