mirror of
https://github.com/Raghu-Ch/angular-challenges.git
synced 2026-02-10 12:53:03 -05:00
refactor: move libs
This commit is contained in:
18
apps/angular/44-view-transition/.eslintrc.json
Normal file
18
apps/angular/44-view-transition/.eslintrc.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"extends": ["../../../.eslintrc.json"],
|
||||
"ignorePatterns": ["!**/*"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.ts"],
|
||||
"extends": [
|
||||
"plugin:@nx/angular",
|
||||
"plugin:@angular-eslint/template/process-inline-templates"
|
||||
]
|
||||
},
|
||||
{
|
||||
"files": ["*.html"],
|
||||
"extends": ["plugin:@nx/angular-template"],
|
||||
"rules": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
13
apps/angular/44-view-transition/README.md
Normal file
13
apps/angular/44-view-transition/README.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# View Transition
|
||||
|
||||
> author: thomas-laforge
|
||||
|
||||
### Run Application
|
||||
|
||||
```bash
|
||||
npx nx serve angular-view-transition
|
||||
```
|
||||
|
||||
### Documentation and Instruction
|
||||
|
||||
Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/44-view-transition/).
|
||||
73
apps/angular/44-view-transition/project.json
Normal file
73
apps/angular/44-view-transition/project.json
Normal file
@@ -0,0 +1,73 @@
|
||||
{
|
||||
"name": "angular-view-transition",
|
||||
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
|
||||
"projectType": "application",
|
||||
"prefix": "app",
|
||||
"sourceRoot": "apps/angular/44-view-transition/src",
|
||||
"tags": [],
|
||||
"targets": {
|
||||
"build": {
|
||||
"executor": "@angular-devkit/build-angular:application",
|
||||
"outputs": ["{options.outputPath}"],
|
||||
"options": {
|
||||
"outputPath": "dist/apps/angular/44-view-transition",
|
||||
"index": "apps/angular/44-view-transition/src/index.html",
|
||||
"browser": "apps/angular/44-view-transition/src/main.ts",
|
||||
"polyfills": ["zone.js"],
|
||||
"tsConfig": "apps/angular/44-view-transition/tsconfig.app.json",
|
||||
"inlineStyleLanguage": "scss",
|
||||
"assets": [
|
||||
"apps/angular/44-view-transition/src/favicon.ico",
|
||||
"apps/angular/44-view-transition/src/assets"
|
||||
],
|
||||
"styles": ["apps/angular/44-view-transition/src/styles.scss"],
|
||||
"scripts": []
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"budgets": [
|
||||
{
|
||||
"type": "initial",
|
||||
"maximumWarning": "500kb",
|
||||
"maximumError": "1mb"
|
||||
},
|
||||
{
|
||||
"type": "anyComponentStyle",
|
||||
"maximumWarning": "2kb",
|
||||
"maximumError": "4kb"
|
||||
}
|
||||
],
|
||||
"outputHashing": "all"
|
||||
},
|
||||
"development": {
|
||||
"optimization": false,
|
||||
"extractLicenses": false,
|
||||
"sourceMap": true
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "production"
|
||||
},
|
||||
"serve": {
|
||||
"executor": "@angular-devkit/build-angular:dev-server",
|
||||
"configurations": {
|
||||
"production": {
|
||||
"buildTarget": "angular-view-transition:build:production"
|
||||
},
|
||||
"development": {
|
||||
"buildTarget": "angular-view-transition:build:development"
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "development"
|
||||
},
|
||||
"extract-i18n": {
|
||||
"executor": "@angular-devkit/build-angular:extract-i18n",
|
||||
"options": {
|
||||
"buildTarget": "angular-view-transition:build"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint",
|
||||
"outputs": ["{options.outputFile}"]
|
||||
}
|
||||
}
|
||||
}
|
||||
13
apps/angular/44-view-transition/src/app/app.component.ts
Normal file
13
apps/angular/44-view-transition/src/app/app.component.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { RouterOutlet } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
imports: [RouterOutlet],
|
||||
selector: 'app-root',
|
||||
template: `
|
||||
<router-outlet />
|
||||
`,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class AppComponent {}
|
||||
17
apps/angular/44-view-transition/src/app/app.config.ts
Normal file
17
apps/angular/44-view-transition/src/app/app.config.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { ApplicationConfig } from '@angular/core';
|
||||
import { provideRouter, withComponentInputBinding } from '@angular/router';
|
||||
|
||||
export const appConfig: ApplicationConfig = {
|
||||
providers: [
|
||||
provideRouter(
|
||||
[
|
||||
{ path: '', loadComponent: () => import('./blog/blog.component') },
|
||||
{
|
||||
path: 'post/:id',
|
||||
loadComponent: () => import('./post/post.component'),
|
||||
},
|
||||
],
|
||||
withComponentInputBinding(),
|
||||
),
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { posts } from '../data';
|
||||
import { ThumbnailComponent } from './thumbnail.component';
|
||||
|
||||
@Component({
|
||||
selector: 'blog',
|
||||
standalone: true,
|
||||
imports: [ThumbnailComponent],
|
||||
template: `
|
||||
<div
|
||||
class="fixed left-0 right-0 top-0 z-50 flex h-20 items-center justify-center border-b-2 bg-white text-4xl shadow-md">
|
||||
Blog List
|
||||
</div>
|
||||
<div class="my-20 flex h-screen flex-col items-center gap-10 border p-10">
|
||||
@for (post of posts; track post.id) {
|
||||
<blog-thumbnail [post]="post" />
|
||||
}
|
||||
</div>
|
||||
`,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export default class BlogComponent {
|
||||
posts = posts;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import { NgOptimizedImage } from '@angular/common';
|
||||
import { Component, input } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'thumbnail-header',
|
||||
standalone: true,
|
||||
imports: [NgOptimizedImage],
|
||||
template: `
|
||||
<div class="flex gap-3">
|
||||
<img
|
||||
ngSrc="assets/profil.webp"
|
||||
alt=""
|
||||
class="rounded-full border border-black p-0.5"
|
||||
width="50"
|
||||
height="50" />
|
||||
<div class="flex flex-col justify-center gap-0.5">
|
||||
<span class="text-md font-bold uppercase">Thomas Laforge</span>
|
||||
<span class="text-sm">{{ date() }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<img ngSrc="assets/angular.webp" alt="" width="50" height="50" />
|
||||
`,
|
||||
host: {
|
||||
class: 'flex w-full px-4 py-5 gap-4 justify-between',
|
||||
},
|
||||
})
|
||||
export class ThumbnailHeaderComponent {
|
||||
date = input.required<string>();
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import { NgOptimizedImage } from '@angular/common';
|
||||
import { ChangeDetectionStrategy, Component, input } from '@angular/core';
|
||||
import { RouterLinkWithHref } from '@angular/router';
|
||||
import { Post } from '../post.model';
|
||||
import { ThumbnailHeaderComponent } from './thumbnail-header.component';
|
||||
|
||||
@Component({
|
||||
selector: 'blog-thumbnail',
|
||||
standalone: true,
|
||||
imports: [NgOptimizedImage, ThumbnailHeaderComponent, RouterLinkWithHref],
|
||||
template: `
|
||||
<a [routerLink]="['post', post().id]">
|
||||
<img
|
||||
[ngSrc]="post().image"
|
||||
alt=""
|
||||
width="960"
|
||||
height="540"
|
||||
class="rounded-t-3xl"
|
||||
[priority]="post().id === '1'" />
|
||||
<h2 class="p-3 text-3xl">{{ post().title }}</h2>
|
||||
<p class="p-3">{{ post().description }}</p>
|
||||
<thumbnail-header [date]="post().date" />
|
||||
</a>
|
||||
`,
|
||||
host: {
|
||||
class: 'w-full max-w-[600px] rounded-3xl border-none shadow-lg',
|
||||
},
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class ThumbnailComponent {
|
||||
post = input.required<Post>();
|
||||
}
|
||||
38
apps/angular/44-view-transition/src/app/data.ts
Normal file
38
apps/angular/44-view-transition/src/app/data.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { Post } from './post.model';
|
||||
|
||||
export const posts: Post[] = [
|
||||
{
|
||||
id: '1',
|
||||
title: 'Future of Change Detection in Angular with Signals',
|
||||
description:
|
||||
'Learn how change detection is evolving and how signal will improve performance in the future.',
|
||||
image: '/assets/signal-cd.full.webp',
|
||||
date: 'May 23, 2023',
|
||||
readingTime: 5,
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
title: 'Everything you need to know about route Guard in Angular',
|
||||
description:
|
||||
'Routing is a significant aspect of any SPA application, and protecting these routes is often necessary. We’ll learn all build-in guards',
|
||||
image: '/assets/guard.full.webp',
|
||||
date: 'Jan 18, 2023',
|
||||
readingTime: 5,
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
title: 'Create a highly customizable component',
|
||||
description: 'Learn how to create highly customizable component',
|
||||
image: '/assets/highly-custom.full.webp',
|
||||
date: 'Nov 9, 2022',
|
||||
readingTime: 5,
|
||||
},
|
||||
];
|
||||
|
||||
export const fakeTextChapters = [
|
||||
'Cyprum itidem insulam procul a continenti discretam et portuosam inter municipia crebra urbes duae faciunt claram Salamis et Paphus, altera Iovis delubris altera Veneris templo insignis. tanta autem tamque multiplici fertilitate abundat rerum omnium eadem Cyprus ut nullius externi indigens adminiculi indigenis viribus a fundamento ipso carinae ad supremos usque carbasos aedificet onerariam navem omnibusque armamentis instructam mari committat',
|
||||
'Et quoniam mirari posse quosdam peregrinos existimo haec lecturos forsitan, si contigerit, quamobrem cum oratio ad ea monstranda deflexerit quae Romae gererentur, nihil praeter seditiones narratur et tabernas et vilitates harum similis alias, summatim causas perstringam nusquam a veritate sponte propria digressurus',
|
||||
'Utque aegrum corpus quassari etiam levibus solet offensis, ita animus eius angustus et tener, quicquid increpuisset, ad salutis suae dispendium existimans factum aut cogitatum, insontium caedibus fecit victoriam luctuosam',
|
||||
'Novo denique perniciosoque exemplo idem Gallus ausus est inire flagitium grave, quod Romae cum ultimo dedecore temptasse aliquando dicitur Gallienus, et adhibitis paucis clam ferro succinctis vesperi per tabernas palabatur et conpita quaeritando Graeco sermone, cuius erat inpendio gnarus, quid de Caesare quisque sentiret. et haec confidenter agebat in urbe ubi pernoctantium luminum claritudo dierum solet imitari fulgorem. postremo agnitus saepe iamque, si prodisset, conspicuum se fore contemplans, non nisi luce palam egrediens ad agenda quae putabat seria cernebatur. et haec quidem medullitus multis gementibus agebantur.',
|
||||
'Et quoniam mirari posse quosdam peregrinos existimo haec lecturos forsitan, si contigerit, quamobrem cum oratio ad ea monstranda deflexerit quae Romae gererentur, nihil praeter seditiones narratur et tabernas et vilitates harum similis alias, summatim causas perstringam nusquam a veritate sponte propria digressurus.',
|
||||
];
|
||||
8
apps/angular/44-view-transition/src/app/post.model.ts
Normal file
8
apps/angular/44-view-transition/src/app/post.model.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
export interface Post {
|
||||
id: string;
|
||||
title: string;
|
||||
description: string;
|
||||
image: string;
|
||||
date: string;
|
||||
readingTime: number;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import { NgOptimizedImage } from '@angular/common';
|
||||
import { Component, input } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'post-header',
|
||||
standalone: true,
|
||||
imports: [NgOptimizedImage],
|
||||
template: `
|
||||
<div class="relative">
|
||||
<img
|
||||
ngSrc="assets/profil.webp"
|
||||
alt=""
|
||||
class="rounded-full border border-black p-0.5"
|
||||
width="50"
|
||||
height="50" />
|
||||
<img
|
||||
ngSrc="assets/angular.webp"
|
||||
alt=""
|
||||
width="30"
|
||||
height="30"
|
||||
class="absolute -bottom-2 -right-2" />
|
||||
</div>
|
||||
<span class="text-md mt-2 font-bold uppercase">Thomas Laforge</span>
|
||||
<span class="text-sm">{{ date() }}</span>
|
||||
`,
|
||||
host: {
|
||||
class: 'flex flex-col justify-center items-center',
|
||||
},
|
||||
})
|
||||
export class PostHeaderComponent {
|
||||
date = input.required<string>();
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import { NgOptimizedImage } from '@angular/common';
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
computed,
|
||||
input,
|
||||
} from '@angular/core';
|
||||
import { RouterLink } from '@angular/router';
|
||||
import { ThumbnailHeaderComponent } from '../blog/thumbnail-header.component';
|
||||
import { fakeTextChapters, posts } from '../data';
|
||||
import { PostHeaderComponent } from './post-header.component';
|
||||
|
||||
@Component({
|
||||
selector: 'post',
|
||||
standalone: true,
|
||||
imports: [
|
||||
ThumbnailHeaderComponent,
|
||||
NgOptimizedImage,
|
||||
PostHeaderComponent,
|
||||
RouterLink,
|
||||
],
|
||||
template: `
|
||||
<div class="relative w-full max-w-[800px]">
|
||||
<button
|
||||
routerLink="/"
|
||||
class="absolute left-2 top-2 z-20 rounded-md border bg-white p-2">
|
||||
Back
|
||||
</button>
|
||||
<img [ngSrc]="post().image" alt="" width="960" height="540" />
|
||||
<h2 class="p-7 text-center text-5xl">{{ post().title }}</h2>
|
||||
<post-header [date]="post().date" class="mb-20" />
|
||||
@for (chapter of fakeTextChapter; track $index) {
|
||||
<p class="mt-6 px-3">{{ chapter }}</p>
|
||||
}
|
||||
</div>
|
||||
`,
|
||||
host: {
|
||||
class: 'flex h-full justify-center',
|
||||
},
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export default class PostComponent {
|
||||
id = input.required<string>();
|
||||
post = computed(() => posts.filter((p) => p.id === this.id())[0]);
|
||||
|
||||
fakeTextChapter = fakeTextChapters;
|
||||
}
|
||||
0
apps/angular/44-view-transition/src/assets/.gitkeep
Normal file
0
apps/angular/44-view-transition/src/assets/.gitkeep
Normal file
BIN
apps/angular/44-view-transition/src/assets/angular.webp
Normal file
BIN
apps/angular/44-view-transition/src/assets/angular.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
BIN
apps/angular/44-view-transition/src/assets/guard.full.webp
Normal file
BIN
apps/angular/44-view-transition/src/assets/guard.full.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
BIN
apps/angular/44-view-transition/src/assets/profil.webp
Normal file
BIN
apps/angular/44-view-transition/src/assets/profil.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
BIN
apps/angular/44-view-transition/src/assets/signal-cd.full.webp
Normal file
BIN
apps/angular/44-view-transition/src/assets/signal-cd.full.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
BIN
apps/angular/44-view-transition/src/favicon.ico
Normal file
BIN
apps/angular/44-view-transition/src/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
13
apps/angular/44-view-transition/src/index.html
Normal file
13
apps/angular/44-view-transition/src/index.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>angular-view-transition</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>
|
||||
7
apps/angular/44-view-transition/src/main.ts
Normal file
7
apps/angular/44-view-transition/src/main.ts
Normal 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),
|
||||
);
|
||||
3
apps/angular/44-view-transition/src/styles.scss
Normal file
3
apps/angular/44-view-transition/src/styles.scss
Normal file
@@ -0,0 +1,3 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
14
apps/angular/44-view-transition/tailwind.config.js
Normal file
14
apps/angular/44-view-transition/tailwind.config.js
Normal 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: [],
|
||||
};
|
||||
10
apps/angular/44-view-transition/tsconfig.app.json
Normal file
10
apps/angular/44-view-transition/tsconfig.app.json
Normal 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"]
|
||||
}
|
||||
7
apps/angular/44-view-transition/tsconfig.editor.json
Normal file
7
apps/angular/44-view-transition/tsconfig.editor.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"include": ["src/**/*.ts"],
|
||||
"compilerOptions": {
|
||||
"types": []
|
||||
}
|
||||
}
|
||||
30
apps/angular/44-view-transition/tsconfig.json
Normal file
30
apps/angular/44-view-transition/tsconfig.json
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es2022",
|
||||
"useDefineForClassFields": false,
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.app.json"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.editor.json"
|
||||
}
|
||||
],
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"angularCompilerOptions": {
|
||||
"enableI18nLegacyMessageIdFormat": false,
|
||||
"strictInjectionParameters": true,
|
||||
"strictInputAccessModifiers": true,
|
||||
"strictTemplates": true
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user