feat(): challenge 58

This commit is contained in:
thomas
2025-03-08 13:01:08 +01:00
parent 49eca53c7f
commit ec0f415735
23 changed files with 324 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 57 challenges](https://angular-challenges.vercel.app/) Check [all 58 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 Condition
> author: thomas-laforge
### Run Application
```bash
npx nx serve angular-content-projection-condition
```
### Documentation and Instruction
Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/58-content-projection-condition/).

View File

@@ -0,0 +1,84 @@
{
"name": "angular-content-projection-condition",
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
"projectType": "application",
"prefix": "app",
"sourceRoot": "apps/angular/58-content-projection-condition/src",
"tags": [],
"targets": {
"build": {
"executor": "@angular-devkit/build-angular:application",
"outputs": ["{options.outputPath}"],
"options": {
"outputPath": "dist/apps/angular/58-content-projection-condition",
"index": "apps/angular/58-content-projection-condition/src/index.html",
"browser": "apps/angular/58-content-projection-condition/src/main.ts",
"polyfills": ["zone.js"],
"tsConfig": "apps/angular/58-content-projection-condition/tsconfig.app.json",
"inlineStyleLanguage": "scss",
"assets": [
{
"glob": "**/*",
"input": "apps/angular/58-content-projection-condition/public"
}
],
"styles": [
"apps/angular/58-content-projection-condition/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-condition:build:production"
},
"development": {
"buildTarget": "angular-content-projection-condition:build:development"
}
},
"defaultConfiguration": "development"
},
"extract-i18n": {
"executor": "@angular-devkit/build-angular:extract-i18n",
"options": {
"buildTarget": "angular-content-projection-condition:build"
}
},
"lint": {
"executor": "@nx/eslint:lint"
},
"serve-static": {
"executor": "@nx/web:file-server",
"options": {
"buildTarget": "angular-content-projection-condition:build",
"staticFilePath": "dist/apps/angular/58-content-projection-condition/browser",
"spa": true
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -0,0 +1,22 @@
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { CardComponent } from './card.component';
@Component({
imports: [CardComponent],
selector: 'app-root',
template: `
<app-card>
<div title>Card 1</div>
<div message>Message 1</div>
</app-card>
<app-card [small]="true">
<div title>Card 2</div>
<div message>Message 2</div>
</app-card>
`,
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,25 @@
import { ChangeDetectionStrategy, Component, input } from '@angular/core';
@Component({
selector: 'app-card',
template: `
@if (small()) {
<ng-content select="[title]" />
<ng-content select="[message]" />
} @else {
<div class="p-4">
<div class="text-2xl">
<ng-content select="[title]" />
</div>
<ng-content select="[message]" />
</div>
}
`,
changeDetection: ChangeDetectionStrategy.OnPush,
host: {
class: 'p-4 border border-grey rounded-sm flex flex-col w-[200px]',
},
})
export class CardComponent {
small = input<boolean>(false);
}

View File

@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>angular-content-projection-condition</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": 57, "total": 58,
"🟢": 22, "🟢": 22,
"🟠": 123, "🟠": 124,
"🔴": 211 "🔴": 211
} }

View File

@@ -8,7 +8,6 @@ challengeNumber: 57
command: angular-content-projection-default command: angular-content-projection-default
sidebar: sidebar:
order: 22 order: 22
badge: New
--- ---
## Information ## Information

View File

@@ -0,0 +1,39 @@
---
title: 🟠 Content Projection Condition
description: Challenge 58 is about conditional content projection in Angular
author: thomas-laforge
contributors:
- tomalaforge
challengeNumber: 58
command: angular-content-projection-condition
sidebar:
order: 124
badge: New
---
## Information
Content projection in Angular allows you to create flexible and reusable components by dynamically inserting content from a parent component using `<ng-content>`. However, debugging content projection issues can sometimes be tricky.
In this challenge, we have a `CardComponent` that supports a small mode, which conditionally changes how the projected content is displayed. However, there is a bug: when `small` is `false`, the card does not render properly.
Your task is to identify and fix this issue without adding `inputs` while ensuring that the intended behavior remains unchanged.
## Statement
Your goal is to fix the issue where the `CardComponent` does not render when `small` is `false`.
## Steps to complete:
- Analyze how the `small` property is used inside the template.
- Identify why the content is not displayed when `small` is `false`.
- Modify the component to ensure that both cases (`small` = `true` and `small` = `false`) work as expected, while keeping the same structure and behavior.
- Ensure that no new `input` properties are introduced in the component.
## Constraints
- You must not add any new `input` properties.
- The expected UI and behavior must remain unchanged.
- The `@if` directive must be correctly handled to ensure content projection works.
- Do not introduce additional services or state management solutions.
- The fix should be minimal and focused on resolving the rendering issue.

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/angular/57-content-projection-default/ link: /es/challenges/angular/58-content-projection-condition/
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="57 Desafíos"> <Card title="58 Desafíos">
Este repositorio contiene 57 Desafíos relacionados con <b>Angular</b>, <b>Nx</b>, <b>RxJS</b>, <b>Ngrx</b> y <b>Typescript</b>. Este repositorio contiene 58 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/angular/57-content-projection-default/ link: /fr/challenges/angular/58-content-projection-condition/
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="57 Défis"> <Card title="58 Défis">
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. Ce répertoire rassemble 58 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

@@ -13,7 +13,7 @@ hero:
icon: right-arrow icon: right-arrow
variant: primary variant: primary
- text: Go to the latest Challenge - text: Go to the latest Challenge
link: /challenges/angular/57-content-projection-default/ link: /challenges/angular/58-content-projection-condition/
icon: rocket icon: rocket
- text: Give a star - text: Give a star
link: https://github.com/tomalaforge/angular-challenges link: https://github.com/tomalaforge/angular-challenges
@@ -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="57 Challenges"> <Card title="58 Challenges">
This repository gathers 57 Challenges related to <b>Angular</b>, <b>Nx</b>, <b>RxJS</b>, <b>Ngrx</b> and <b>Typescript</b>. This repository gathers 58 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/angular/57-content-projection-default/ link: /pt/challenges/angular/58-content-projection-condition/
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="57 Desafios"> <Card title="58 Desafios">
Este repositório possui 57 Desafios relacionados a <b>Angular</b>, <b>Nx</b>, <b>RxJS</b>, Este repositório possui 58 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/angular/57-content-projection-default/ link: /ru/challenges/angular/58-content-projection-condition/
icon: rocket icon: rocket
- text: Добавить звезду - text: Добавить звезду
link: https://github.com/tomalaforge/angular-challenges link: https://github.com/tomalaforge/angular-challenges