diff --git a/src/meta/play-meta.js b/src/meta/play-meta.js index 7d6afa6e65..94370b664d 100644 --- a/src/meta/play-meta.js +++ b/src/meta/play-meta.js @@ -13,6 +13,7 @@ import { ExpandingCards, AnalogClock, PasswordGenerator, +WhyTypescript, //import play here } from "plays"; @@ -198,5 +199,18 @@ export const plays = [ cover: 'https://securityintelligence.com/wp-content/uploads/2018/10/si-eight-character-password-feature.jpg', blog: '', video: '' + }, { + id: 'pl-why-typescript', + name: 'Why Typescript', + description: 'A simplistic way of understanding the existence of TypeScript', + component: () => {return }, + path: '/plays/why-typescript', + level: 'Intermediate', + tags: 'TSX,TypeScript,Learning,KnowWhat', + github: 'koustov', + cover: 'https://res.cloudinary.com/dgtdljyul/image/upload/v1651923177/ts_why_adazpf.png', + blog: '', + video: '', + language: 'ts' }, //replace new play item here ]; diff --git a/src/plays/index.js b/src/plays/index.js index 95867efe46..754a500644 100644 --- a/src/plays/index.js +++ b/src/plays/index.js @@ -15,4 +15,5 @@ export { default as ExpandingCards } from 'plays/expanding-cards/ExpandingCards' export { default as AnalogClock } from 'plays/analog-clock/AnalogClock'; export { default as PasswordGenerator } from 'plays/password-generator/PasswordGenerator'; +export { default as WhyTypescript } from 'plays/why-typescript/WhyTypescript'; //add export here diff --git a/src/plays/why-typescript/Readme.md b/src/plays/why-typescript/Readme.md new file mode 100644 index 0000000000..b67afcf40e --- /dev/null +++ b/src/plays/why-typescript/Readme.md @@ -0,0 +1,12 @@ +# Why Typescript +The `Why Typescript` project shows how `TypeScript` can be used . + +- It uses simple concept of interface. +- Leverages class and objects. +- Demonstrates the power of casting. +- Shows a process to load json onto your application. +- It shows component creation using TypeScript and consumption + +Well, TypeScript is way more than what has been demonstrated here. The idea is to bring a pointer where "sky is the only limit" + +Happy Coding! diff --git a/src/plays/why-typescript/WhyTypescript.tsx b/src/plays/why-typescript/WhyTypescript.tsx new file mode 100644 index 0000000000..31e8784bc2 --- /dev/null +++ b/src/plays/why-typescript/WhyTypescript.tsx @@ -0,0 +1,35 @@ +import * as React from "react"; +import { getPlayById } from "meta/play-meta-util"; + +import PlayHeader from "common/playlists/PlayHeader"; +import Wizard from "./wizard"; +import data from "./data.json"; + +function WhyTypescript(props: any) { + // Do not remove the below lines. + // The following code is to fetch the current play from the URL + const { id } = props; + const play = getPlayById(id); + + // Your Code Start below. + + return ( + <> +
+ +
+ {/* Your Code Starts Here */} +
+

Play Details - Why Typescript

+
+ +
+
+ {/* Your Code Ends Here */} +
+
+ + ); +} + +export default WhyTypescript; diff --git a/src/plays/why-typescript/data.json b/src/plays/why-typescript/data.json new file mode 100644 index 0000000000..06dd6c513a --- /dev/null +++ b/src/plays/why-typescript/data.json @@ -0,0 +1,31 @@ +[{ + "title": "General", + "details": [ + "A powerful type system that includes generics.", + "TypeScript is nothing but JavaScript with some additional features.", + "It is Structural, rather than nominal way of processing" + ] +},{ + "title": "Power", + "details": [ + "TypeScript provides highly productive development tools for JavaScript IDEs and practices, like static checking.", + "TypeScript makes code easier to read and understand.", + "TypeScript gives us all the benefits of ES6 (ECMAScript 6), plus more productivity." + + ] +},{ + "title": "Friendlyness", + "details": [ + "TypeScript can help us to avoid painful bugs that developers commonly run into when writing JavaScript by type checking the code", + "Typescript is aligned with ECMAScript for compatibility.", + "TypeScript code can be compiled as per ES5 and ES6 standards to support the latest browser." + + ] +},{ + "title": "Features", + "details": [ + "TypeScript simplifies JavaScript code, making it easier to read and debug.", + "With TypeScript, we can make a huge improvement over plain JavaScript.", + "A feature rich language that supports static typing." + ] +}] \ No newline at end of file diff --git a/src/plays/why-typescript/wizard/contract.tsx b/src/plays/why-typescript/wizard/contract.tsx new file mode 100644 index 0000000000..b04fd4fd05 --- /dev/null +++ b/src/plays/why-typescript/wizard/contract.tsx @@ -0,0 +1,37 @@ +export interface IDataContract {} + +export class IPageData { + title: String; + details: Array; +} + +export class PageData implements IDataContract, IPageData { + title: String; + details: Array; + constructor(data: IPageData) { + this.details = data.details; + this.title = data.title; + } +} + +export interface IWizardData { + title: String; + pages: Array; +} + +export class WizardData implements IDataContract, IWizardData { + title: String; + pages: Array = []; + constructor(title: String, pages: Array) { + this.title = title; + pages.forEach((o) => { + const pagedata: IPageData = o as IPageData; + this.pages.push(new PageData(pagedata)); + }); + } +} + +export type AppProps = { + wizdata?: IWizardData; + pagedata?: IPageData; +}; diff --git a/src/plays/why-typescript/wizard/index.css b/src/plays/why-typescript/wizard/index.css new file mode 100644 index 0000000000..12994fe889 --- /dev/null +++ b/src/plays/why-typescript/wizard/index.css @@ -0,0 +1,171 @@ + +.ol-cards, +.ol-cards * { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +.wizard-container { + height: 100%; + display: flex; + flex-direction: column; +} + +.wizard-container--core { + flex: 1 +} + +.wizard-container--buttons { + padding: 1rem; + height: 4em; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} + +.wizard-container--note { + font-size: 10px; + display: flex; + justify-content: center; + align-items: center; +} + +.ol-cards { + --flapWidth: 2rem; + --flapHeigth: 1rem; + --iconSize: 3rem; + --numberSize: 3rem; + --colGapSize: 2rem; + width: min(100%, 40rem); + margin-inline: auto; + display: grid; + gap: 2rem; + padding-inline-start: var(--flapWidth); + font-family: sans-serif; + color: #222; + counter-reset: ol-cards-count; + list-style: none; +} +.ol-cards li { + display: grid; + grid-template-areas: + "icon descr nr"; + gap: 0 var(--colGapSize); + align-items: center; + padding: var(--colGapSize) var(--flapWidth) var(--colGapSize) 0; + border-radius: 1rem 5rem 5rem 1rem; + background-image: linear-gradient(to bottom right, #e9eaec, #ffffff); + counter-increment: ol-cards-count; + filter: drop-shadow(10px 10px 10px rgba(0, 0, 0, 0.25)); + box-shadow: inset 2px 2px 2px white, inset -1px -1px 1px rgba(0, 0, 0, 0.25); +} + +.ol-cards li > .icon { + grid-area: icon; + background:#EE5830; + color: white; + font-size: var(--iconSize); + width: calc(2 * var(--flapWidth) + var(--iconSize)); + padding-block: 1rem; + border-radius: 0 5rem 5rem 0; + margin-inline-start: calc(-1 * var(--flapWidth)); + box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25); + position: relative; + display: grid; + place-items: center; +} +.ol-cards li > .icon::before { + content: ""; + position: absolute; + width: var(--flapWidth); + + height: calc(100% + calc(var(--flapHeigth) * 2)); + left: 0; + top: calc(var(--flapHeigth) * -1); + clip-path: polygon( + 0 var(--flapHeigth), + 100% 0, + 100% 100%, + 0 calc(100% - var(--flapHeigth)) + ); + background-color:#EE5830; + background-image: linear-gradient( + 90deg, + rgba(0, 0, 0, 0.5), + rgba(0, 0, 0, 0.2) + ); + z-index: -1; +} + +.ol-cards li > .descr { + grid-area: descr; + width: 100%; +} +.ol-cards li::after { + grid-area: nr; + content: counter(ol-cards-count, decimal-leading-zero); + color:#EE5830; + font-size: var(--numberSize); + font-weight: 700; +} +@media (max-width: 40rem) { + .ol-cards { + --flapWidth: 1rem; + --flapHeigth: 0.5rem; + --iconSize: 2rem; + --numberSize: 2rem; + --colGapSize: 1rem; + } +} + + +.s-button span { + background: #FFF; + display: block; + padding: 5px 15px; + border-radius: 5px; + border: 2px solid #000; +} +.s-button:hover { + box-shadow: 0 2px 0 #000, 0 2px 0px 2px #000; +} +.s-button:active { + top: 4px; + padding-bottom: 0px; + box-shadow: 0 1px 0 #000; +} +.s-button { + position: relative; + float: left; + font: normal 14px/15px "Patrick Hand", sans-serif; + margin-right: 10px; + text-transform: uppercase; + color: #000; + text-decoration: none; + padding-bottom: 3px; + border-radius: 5px; + box-shadow: 0 2px 0 #000; + transition: padding 0.1s, box-shadow 0.1s, top 0.1s; + background-image: url('data:image/gif;base64,R0lGODlhBAAEAIABAAAAAAAAACH/C1hNUCBEYXRhWE1QPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS4wLWMwNjEgNjQuMTQwOTQ5LCAyMDEwLzEyLzA3LTEwOjU3OjAxICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1LjEgV2luZG93cyIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo5NUY1OENCRDdDMDYxMUUyOTEzMEE1MEM5QzM0NDVBMyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo5NUY1OENCRTdDMDYxMUUyOTEzMEE1MEM5QzM0NDVBMyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjk1RjU4Q0JCN0MwNjExRTI5MTMwQTUwQzlDMzQ0NUEzIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjk1RjU4Q0JDN0MwNjExRTI5MTMwQTUwQzlDMzQ0NUEzIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+Af/+/fz7+vn49/b19PPy8fDv7u3s6+rp6Ofm5eTj4uHg397d3Nva2djX1tXU09LR0M/OzczLysnIx8bFxMPCwcC/vr28u7q5uLe2tbSzsrGwr66trKuqqainpqWko6KhoJ+enZybmpmYl5aVlJOSkZCPjo2Mi4qJiIeGhYSDgoGAf359fHt6eXh3dnV0c3JxcG9ubWxramloZ2ZlZGNiYWBfXl1cW1pZWFdWVVRTUlFQT05NTEtKSUhHRkVEQ0JBQD8+PTw7Ojk4NzY1NDMyMTAvLi0sKyopKCcmJSQjIiEgHx4dHBsaGRgXFhUUExIREA8ODQwLCgkIBwYFBAMCAQAAIfkEAQAAAQAsAAAAAAQABAAAAgYEEpdoeQUAOw=='); +} + +.s-button:disabled { + cursor: not-allowed; +} + +.s-button:disabled span{ + background-color: #ABABAB; +} + +.page-container { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} + +.page-container h1 { + color: #EE5830; +} \ No newline at end of file diff --git a/src/plays/why-typescript/wizard/index.tsx b/src/plays/why-typescript/wizard/index.tsx new file mode 100644 index 0000000000..6c55bc757c --- /dev/null +++ b/src/plays/why-typescript/wizard/index.tsx @@ -0,0 +1,55 @@ +import * as React from "react"; +import Page from "./page"; +import { WizardData } from "./contract"; +import "./index.css"; + +const Wizard = (props: any) => { + const title: String = props.title; + const data: Array = props.data; + const wizData = new WizardData(title, data); + const [index, setIndex] = React.useState(0); + + const nextPage = () => { + setIndex(index + 1); + }; + + const prevPage = () => { + setIndex(index - 1); + }; + + return ( + <> +
+
+ {wizData && wizData.pages.length > 0 ? ( + + ) : null} +
+
+
+ + +
+
+
+ This play has been created using TypeScript. It aims to give a pointer + to typescript, not to elaborate the usage. +
+
+ + ); +}; + +export default Wizard; diff --git a/src/plays/why-typescript/wizard/page.tsx b/src/plays/why-typescript/wizard/page.tsx new file mode 100644 index 0000000000..e320aadfc9 --- /dev/null +++ b/src/plays/why-typescript/wizard/page.tsx @@ -0,0 +1,24 @@ +import * as React from "react"; +import { AppProps, IPageData } from "./contract"; +import "./index.css"; + +const Page = (props: AppProps) => { + const data: IPageData = props.pagedata; + return ( + <> +
+

{data.title}

+
    + {data.details.map((d, dk) => ( +
  1. +
    +
    {d}
    +
  2. + ))} +
+
+ + ); +}; + +export default Page; diff --git a/tsconfig.json b/tsconfig.json index c2e80f9841..c6a772a827 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,6 +8,9 @@ "target": "es5", "allowJs": true, "moduleResolution": "node", + "suppressImplicitAnyIndexErrors": false, + "resolveJsonModule": true, + "allowSyntheticDefaultImports": true }, "include": ["src/**/*"] } \ No newline at end of file