From e14c4900df6ef29849deef4f806fd7c7c484637c Mon Sep 17 00:00:00 2001 From: jonniebigodes Date: Fri, 22 Dec 2023 20:50:29 +0000 Subject: [PATCH] Tutorial initialized --- .editorconfig | 16 + .gitignore | 42 + .storybook/main.ts | 17 + .storybook/preview.ts | 18 + .storybook/tsconfig.json | 11 + .storybook/typings.d.ts | 4 + LICENSE | 21 + README.md | 96 + angular.json | 103 + documentation.json | 990 + jest-global-mocks.ts | 33 + jest.config.js | 6 + package-lock.json | 26532 ++++++++++++++++ package.json | 66 + setup-jest.ts | 1 + src/app/app.component.css | 0 src/app/app.component.html | 328 + src/app/app.component.spec.ts | 31 + src/app/app.component.ts | 10 + src/app/app.module.ts | 16 + src/assets/.gitkeep | 0 src/assets/font/OpenSans-Light-webfont.eot | Bin 0 -> 29794 bytes src/assets/font/OpenSans-Light-webfont.svg | 252 + src/assets/font/OpenSans-Light-webfont.ttf | Bin 0 -> 29612 bytes src/assets/font/OpenSans-Light-webfont.woff | Bin 0 -> 19396 bytes src/assets/font/OpenSans-Regular-webfont.eot | Bin 0 -> 29934 bytes src/assets/font/OpenSans-Regular-webfont.svg | 252 + src/assets/font/OpenSans-Regular-webfont.ttf | Bin 0 -> 29744 bytes src/assets/font/OpenSans-Regular-webfont.woff | Bin 0 -> 19624 bytes src/assets/icon/percolate.eot | Bin 0 -> 34208 bytes src/assets/icon/percolate.svg | 139 + src/assets/icon/percolate.ttf | Bin 0 -> 34036 bytes src/assets/icon/percolate.woff | Bin 0 -> 34112 bytes src/environments/environment.prod.ts | 3 + src/environments/environment.ts | 16 + src/favicon.ico | Bin 0 -> 948 bytes src/index.html | 13 + src/main.ts | 7 + src/polyfills.ts | 63 + src/stories/.eslintrc.json | 5 + src/stories/Button.stories.ts | 51 + src/stories/Header.stories.ts | 37 + src/stories/Introduction.mdx | 213 + src/stories/Page.stories.ts | 49 + src/stories/User.ts | 2 + src/stories/assets/code-brackets.svg | 1 + src/stories/assets/colors.svg | 1 + src/stories/assets/comments.svg | 1 + src/stories/assets/direction.svg | 1 + src/stories/assets/flow.svg | 1 + src/stories/assets/plugin.svg | 1 + src/stories/assets/repo.svg | 1 + src/stories/assets/stackalt.svg | 1 + src/stories/button.component.ts | 55 + src/stories/button.css | 30 + src/stories/header.component.ts | 75 + src/stories/header.css | 32 + src/stories/page.component.ts | 77 + src/stories/page.css | 69 + src/styles.css | 460 + tsconfig.app.json | 10 + tsconfig.json | 30 + tsconfig.spec.json | 10 + 63 files changed, 30299 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 .storybook/main.ts create mode 100644 .storybook/preview.ts create mode 100644 .storybook/tsconfig.json create mode 100644 .storybook/typings.d.ts create mode 100644 LICENSE create mode 100644 README.md create mode 100644 angular.json create mode 100644 documentation.json create mode 100644 jest-global-mocks.ts create mode 100644 jest.config.js create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 setup-jest.ts create mode 100644 src/app/app.component.css create mode 100644 src/app/app.component.html create mode 100644 src/app/app.component.spec.ts create mode 100644 src/app/app.component.ts create mode 100644 src/app/app.module.ts create mode 100644 src/assets/.gitkeep create mode 100755 src/assets/font/OpenSans-Light-webfont.eot create mode 100755 src/assets/font/OpenSans-Light-webfont.svg create mode 100755 src/assets/font/OpenSans-Light-webfont.ttf create mode 100755 src/assets/font/OpenSans-Light-webfont.woff create mode 100755 src/assets/font/OpenSans-Regular-webfont.eot create mode 100755 src/assets/font/OpenSans-Regular-webfont.svg create mode 100755 src/assets/font/OpenSans-Regular-webfont.ttf create mode 100755 src/assets/font/OpenSans-Regular-webfont.woff create mode 100644 src/assets/icon/percolate.eot create mode 100644 src/assets/icon/percolate.svg create mode 100644 src/assets/icon/percolate.ttf create mode 100644 src/assets/icon/percolate.woff create mode 100644 src/environments/environment.prod.ts create mode 100644 src/environments/environment.ts create mode 100644 src/favicon.ico create mode 100644 src/index.html create mode 100644 src/main.ts create mode 100644 src/polyfills.ts create mode 100644 src/stories/.eslintrc.json create mode 100644 src/stories/Button.stories.ts create mode 100644 src/stories/Header.stories.ts create mode 100644 src/stories/Introduction.mdx create mode 100644 src/stories/Page.stories.ts create mode 100644 src/stories/User.ts create mode 100644 src/stories/assets/code-brackets.svg create mode 100644 src/stories/assets/colors.svg create mode 100644 src/stories/assets/comments.svg create mode 100644 src/stories/assets/direction.svg create mode 100644 src/stories/assets/flow.svg create mode 100644 src/stories/assets/plugin.svg create mode 100644 src/stories/assets/repo.svg create mode 100644 src/stories/assets/stackalt.svg create mode 100644 src/stories/button.component.ts create mode 100644 src/stories/button.css create mode 100644 src/stories/header.component.ts create mode 100644 src/stories/header.css create mode 100644 src/stories/page.component.ts create mode 100644 src/stories/page.css create mode 100644 src/styles.css create mode 100644 tsconfig.app.json create mode 100644 tsconfig.json create mode 100644 tsconfig.spec.json diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..59d9a3a3 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,16 @@ +# Editor configuration, see https://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.ts] +quote_type = single + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..0711527e --- /dev/null +++ b/.gitignore @@ -0,0 +1,42 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. + +# Compiled output +/dist +/tmp +/out-tsc +/bazel-out + +# Node +/node_modules +npm-debug.log +yarn-error.log + +# IDEs and editors +.idea/ +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# Visual Studio Code +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +.history/* + +# Miscellaneous +/.angular/cache +.sass-cache/ +/connect.lock +/coverage +/libpeerconnection.log +testem.log +/typings + +# System files +.DS_Store +Thumbs.db diff --git a/.storybook/main.ts b/.storybook/main.ts new file mode 100644 index 00000000..c55443c5 --- /dev/null +++ b/.storybook/main.ts @@ -0,0 +1,17 @@ +import type { StorybookConfig } from "@storybook/angular"; +const config: StorybookConfig = { + stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"], + addons: [ + "@storybook/addon-links", + "@storybook/addon-essentials", + "@storybook/addon-interactions", + ], + framework: { + name: "@storybook/angular", + options: {}, + }, + docs: { + autodocs: "tag", + }, +}; +export default config; diff --git a/.storybook/preview.ts b/.storybook/preview.ts new file mode 100644 index 00000000..60167aca --- /dev/null +++ b/.storybook/preview.ts @@ -0,0 +1,18 @@ +import type { Preview } from "@storybook/angular"; +import { setCompodocJson } from "@storybook/addon-docs/angular"; +import docJson from "../documentation.json"; +setCompodocJson(docJson); + +const preview: Preview = { + parameters: { + actions: { argTypesRegex: "^on[A-Z].*" }, + controls: { + matchers: { + color: /(background|color)$/i, + date: /Date$/, + }, + }, + }, +}; + +export default preview; diff --git a/.storybook/tsconfig.json b/.storybook/tsconfig.json new file mode 100644 index 00000000..eb068641 --- /dev/null +++ b/.storybook/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../tsconfig.app.json", + "compilerOptions": { + "types": ["node"], + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true + }, + "exclude": ["../src/test.ts", "../src/**/*.spec.ts"], + "include": ["../src/**/*", "./preview.ts"], + "files": ["./typings.d.ts"] +} diff --git a/.storybook/typings.d.ts b/.storybook/typings.d.ts new file mode 100644 index 00000000..f73d61b3 --- /dev/null +++ b/.storybook/typings.d.ts @@ -0,0 +1,4 @@ +declare module '*.md' { + const content: string; + export default content; +} diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..a45b5c04 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2018 Chroma Software Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 00000000..8809e4fd --- /dev/null +++ b/README.md @@ -0,0 +1,96 @@ +

+ + Chromatic + +

+ +

+ Chromatic's Intro to Storybook Angular template +

+ +This template ships with the main Angular and Storybook configuration files you'll need to get up and running fast. + +## πŸš… Quick start + +1. **Create the application.** + + Use [degit](https://github.com/Rich-Harris/degit) to get this template. + + ```shell + # Clone the template + npx degit chromaui/intro-storybook-angular-template taskbox + ``` + +1. **Install the dependencies.** + + Navigate into your new site’s directory and install the necessary dependencies. + + ```shell + # Navigate to the directory + cd taskbox/ + + # Install the dependencies + npm install + ``` + +1. **Open the source code and start editing!** + + Open the `taskbox` directory in your code editor of choice and building your first component! + +1. **Browse your stories!** + + Run `npm run storybook` to see your component's stories at `http://localhost:6006`. + +## πŸ”Ž What's inside? + +A quick look at the top-level files and directories included with this template. + + . + β”œβ”€β”€ .storybook + β”œβ”€β”€ node_modules + β”œβ”€β”€ src + β”œβ”€β”€ .editorconfig + β”œβ”€β”€ .gitignore + β”œβ”€β”€ angular.json + β”œβ”€β”€ LICENSE + β”œβ”€β”€ package-lock.json + β”œβ”€β”€ package.json + β”œβ”€β”€ tsconfig.app.json + β”œβ”€β”€ tsconfig.json + β”œβ”€β”€ tsconfig.spec.json + β”œβ”€β”€ tslint.json + └── README.md + +1. **`.storybook`**: This directory contains Storybook's [configuration](https://storybook.js.org/docs/react/configure/overview) files. + +2. **`node_modules`**: This directory contains all of the modules of code that your project depends on (npm packages). + +3. **`src`**: This directory will contain all of the code related to what you will see on your application. + +4. **`.editorconfig`**: This file contains the configurations for [EditorConfig](https://editorconfig.org/). + +5. **`.gitignore`**: This file tells git which files it should not track or maintain during the development process of your project. + +6. **`angular.json`**: This file contains all the configurations required for your Angular project. + +7. **`LICENSE`**: The template is licensed under the MIT licence. + +8. **`package-lock.json`**: This is an automatically generated file based on the exact versions of your npm dependencies that were installed for your project. **(Do not change it manually).** + +9. **`package.json`**: Standard manifest file for Node.js projects, which typically includes project specific metadata (such as the project's name, the author among other information). It's based on this file that npm will know which packages are necessary to the project. + +10. **`tsconfig.app.json`**: This file contains auxiliary configurations for your Angular project. + +11. **`tsconfig.json`**: This file contains configurations the required configurations for TypeScript. + +12. **`tsconfig.spec.json`**: This is a TypeScript configuration file aimed for application testing. + +## Contribute + +If you encounter an issue with the template, we encourage you to open an issue in this template's repository. + +## Learning Storybook + +1. Read our introductory tutorial at [Learn Storybook](https://storybook.js.org/tutorials/intro-to-storybook/angular/en/get-started/). +2. Learn how to transform your component libraries into design systems in our [Design Systems for Developers](https://storybook.js.org/tutorials/design-systems-for-developers/) tutorial. +3. See our official documentation at [Storybook](https://storybook.js.org/). diff --git a/angular.json b/angular.json new file mode 100644 index 00000000..556c7018 --- /dev/null +++ b/angular.json @@ -0,0 +1,103 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "newProjectRoot": "projects", + "projects": { + "taskbox": { + "projectType": "application", + "schematics": {}, + "root": "", + "sourceRoot": "src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:browser", + "options": { + "outputPath": "dist/taskbox", + "index": "src/index.html", + "main": "src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "tsconfig.app.json", + "assets": ["src/favicon.ico", "src/assets"], + "styles": ["src/styles.css"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "taskbox:build:production" + }, + "development": { + "buildTarget": "taskbox:build:development" + } + }, + "defaultConfiguration": "development" + }, + "extract-i18n": { + "builder": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "taskbox:build" + } + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "polyfills": ["zone.js", "zone.js/testing"], + "tsConfig": "tsconfig.spec.json", + "assets": ["src/favicon.ico", "src/assets"], + "styles": ["src/styles.css"], + "scripts": [] + } + }, + "storybook": { + "builder": "@storybook/angular:start-storybook", + "options": { + "configDir": ".storybook", + "browserTarget": "taskbox:build", + "compodoc": true, + "compodocArgs": ["-e", "json", "-d", "."], + "port": 6006 + } + }, + "build-storybook": { + "builder": "@storybook/angular:build-storybook", + "options": { + "configDir": ".storybook", + "browserTarget": "taskbox:build", + "compodoc": true, + "compodocArgs": ["-e", "json", "-d", "."], + "outputDir": "storybook-static" + } + } + } + } + } +} diff --git a/documentation.json b/documentation.json new file mode 100644 index 00000000..b097c1c7 --- /dev/null +++ b/documentation.json @@ -0,0 +1,990 @@ +{ + "pipes": [], + "interfaces": [ + { + "name": "User", + "id": "interface-User-9c7e5f1bbbab702cb032307d130876cb68969b0cd4eedef32a0c8cad8081a54e5f8f577ed6ad4539c1b99a1d246cb34031d198c2ea8eba440e64e91b14f01fdc", + "file": "src/stories/User.ts", + "deprecated": false, + "deprecationMessage": "", + "type": "interface", + "sourceCode": "export interface User {}\n", + "properties": [], + "indexSignatures": [], + "methods": [], + "extends": [] + } + ], + "injectables": [], + "guards": [], + "interceptors": [], + "classes": [], + "directives": [], + "components": [ + { + "name": "AppComponent", + "id": "component-AppComponent-d68608d8b26abf8ee892678b13d3f3fad388b8ed25e6510720354677fdc608c0a617ac19ba8cac9b7f59a76270d9da07ca862a43ca3c875eae5f81564cbc4b12", + "file": "src/app/app.component.ts", + "encapsulation": [], + "entryComponents": [], + "inputs": [], + "outputs": [], + "providers": [], + "selector": "app-root", + "styleUrls": [ + "./app.component.css" + ], + "styles": [], + "templateUrl": [ + "./app.component.html" + ], + "viewProviders": [], + "hostDirectives": [], + "inputsClass": [], + "outputsClass": [], + "propertiesClass": [ + { + "name": "title", + "defaultValue": "'taskbox'", + "deprecated": false, + "deprecationMessage": "", + "type": "string", + "optional": false, + "description": "", + "line": 9 + } + ], + "methodsClass": [], + "deprecated": false, + "deprecationMessage": "", + "hostBindings": [], + "hostListeners": [], + "standalone": false, + "imports": [], + "description": "", + "rawdescription": "\n", + "type": "component", + "sourceCode": "import { Component } from '@angular/core';\n\n@Component({\n selector: 'app-root',\n templateUrl: './app.component.html',\n styleUrls: ['./app.component.css'],\n})\nexport class AppComponent {\n title = 'taskbox';\n}\n", + "assetsDirs": [], + "styleUrlsData": [ + { + "data": "", + "styleUrl": "./app.component.css" + } + ], + "stylesData": "", + "extends": [], + "templateData": "\n\n\n\n\n\n\n\n\n\n\n
\n
\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n

Hello, {{ title }}

\n

Congratulations! Your app is running. πŸŽ‰

\n
\n
\n
\n
\n @for (item of [ { title: 'Explore the Docs', link: 'https://angular.dev'\n }, { title: 'Learn with Tutorials', link:\n 'https://angular.dev/tutorials' }, { title: 'CLI Docs', link:\n 'https://angular.dev/tools/cli' }, { title: 'Angular Language Service',\n link: 'https://angular.dev/tools/language-service' }, { title: 'Angular\n DevTools', link: 'https://angular.dev/tools/devtools' }, ]; track\n item.title) {\n \n {{ item.title }}\n \n \n \n \n }\n
\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n
\n
\n
\n\n\n\n\n\n\n\n\n" + }, + { + "name": "ButtonComponent", + "id": "component-ButtonComponent-a53fd738b978780d39fb5fcc9ae4cfe0088e57a1f6ce674862d57dab9192140bd1c05548a9910db0469a431142886e658ff2e761f15781b2ad430e58d64724d0", + "file": "src/stories/button.component.ts", + "encapsulation": [], + "entryComponents": [], + "inputs": [], + "outputs": [], + "providers": [], + "selector": "storybook-button", + "styleUrls": [ + "./button.css" + ], + "styles": [], + "template": "", + "templateUrl": [], + "viewProviders": [], + "hostDirectives": [], + "inputsClass": [ + { + "name": "backgroundColor", + "deprecated": false, + "deprecationMessage": "", + "rawdescription": "\n\nWhat background color to use\n", + "description": "

What background color to use

\n", + "line": 28, + "type": "string", + "decorators": [] + }, + { + "name": "label", + "defaultValue": "'Button'", + "deprecated": false, + "deprecationMessage": "", + "jsdoctags": [ + { + "pos": 786, + "end": 799, + "flags": 16842752, + "modifierFlagsCache": 0, + "transformFlags": 0, + "kind": 334, + "tagName": { + "pos": 787, + "end": 795, + "flags": 16842752, + "modifierFlagsCache": 0, + "transformFlags": 0, + "kind": 80, + "escapedText": "required" + }, + "comment": "" + } + ], + "rawdescription": "\n\nButton contents\n\n", + "description": "

Button contents

\n", + "line": 42, + "type": "string", + "decorators": [] + }, + { + "name": "primary", + "defaultValue": "false", + "deprecated": false, + "deprecationMessage": "", + "rawdescription": "\n\nIs this the principal call to action on the page?\n", + "description": "

Is this the principal call to action on the page?

\n", + "line": 22, + "type": "boolean", + "decorators": [] + }, + { + "name": "size", + "defaultValue": "'medium'", + "deprecated": false, + "deprecationMessage": "", + "rawdescription": "\n\nHow large should the button be?\n", + "description": "

How large should the button be?

\n", + "line": 34, + "type": "\"small\" | \"medium\" | \"large\"", + "decorators": [] + } + ], + "outputsClass": [ + { + "name": "onClick", + "defaultValue": "new EventEmitter()", + "deprecated": false, + "deprecationMessage": "", + "rawdescription": "\n\nOptional click handler\n", + "description": "

Optional click handler

\n", + "line": 48, + "type": "EventEmitter" + } + ], + "propertiesClass": [], + "methodsClass": [], + "deprecated": false, + "deprecationMessage": "", + "hostBindings": [], + "hostListeners": [], + "standalone": false, + "imports": [ + { + "name": "CommonModule", + "type": "module" + } + ], + "description": "", + "rawdescription": "\n", + "type": "component", + "sourceCode": "import { CommonModule } from '@angular/common';\nimport { Component, Input, Output, EventEmitter } from '@angular/core';\n\n@Component({\n selector: 'storybook-button',\n imports: [CommonModule],\n template: ` \n {{ label }}\n `,\n styleUrls: ['./button.css'],\n})\nexport default class ButtonComponent {\n /**\n * Is this the principal call to action on the page?\n */\n @Input()\n primary = false;\n\n /**\n * What background color to use\n */\n @Input()\n backgroundColor?: string;\n\n /**\n * How large should the button be?\n */\n @Input()\n size: 'small' | 'medium' | 'large' = 'medium';\n\n /**\n * Button contents\n *\n * @required\n */\n @Input()\n label = 'Button';\n\n /**\n * Optional click handler\n */\n @Output()\n onClick = new EventEmitter();\n\n public get classes(): string[] {\n const mode = this.primary ? 'storybook-button--primary' : 'storybook-button--secondary';\n\n return ['storybook-button', `storybook-button--${this.size}`, mode];\n }\n}\n", + "assetsDirs": [], + "styleUrlsData": [ + { + "data": ".storybook-button {\n font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;\n font-weight: 700;\n border: 0;\n border-radius: 3em;\n cursor: pointer;\n display: inline-block;\n line-height: 1;\n}\n.storybook-button--primary {\n color: white;\n background-color: #1ea7fd;\n}\n.storybook-button--secondary {\n color: #333;\n background-color: transparent;\n box-shadow: rgba(0, 0, 0, 0.15) 0px 0px 0px 1px inset;\n}\n.storybook-button--small {\n font-size: 12px;\n padding: 10px 16px;\n}\n.storybook-button--medium {\n font-size: 14px;\n padding: 11px 20px;\n}\n.storybook-button--large {\n font-size: 16px;\n padding: 12px 24px;\n}\n", + "styleUrl": "./button.css" + } + ], + "stylesData": "", + "extends": [], + "accessors": { + "classes": { + "name": "classes", + "getSignature": { + "name": "classes", + "type": "[]", + "returnType": "string[]", + "line": 50 + } + } + } + }, + { + "name": "HeaderComponent", + "id": "component-HeaderComponent-a71f246366d5d3dd2485d220bc2c384ceb3f056eb50faded8ff9e4a6404ca4a28c23117da4b98825de8da482bc2ba3b9abeab416745b32d1a89f68595d2dc939", + "file": "src/stories/header.component.ts", + "encapsulation": [], + "entryComponents": [], + "inputs": [], + "outputs": [], + "providers": [], + "selector": "storybook-header", + "styleUrls": [ + "./header.css" + ], + "styles": [], + "template": "
\n
\n \n \n \n \n \n \n \n

Acme

\n
\n
\n
\n \n Welcome, {{ user.name }}!\n \n \n
\n
\n \n \n
\n
\n
\n
", + "templateUrl": [], + "viewProviders": [], + "hostDirectives": [], + "inputsClass": [ + { + "name": "user", + "defaultValue": "null", + "deprecated": false, + "deprecationMessage": "", + "line": 65, + "type": "User | null", + "decorators": [] + } + ], + "outputsClass": [ + { + "name": "onCreateAccount", + "defaultValue": "new EventEmitter()", + "deprecated": false, + "deprecationMessage": "", + "line": 74, + "type": "EventEmitter" + }, + { + "name": "onLogin", + "defaultValue": "new EventEmitter()", + "deprecated": false, + "deprecationMessage": "", + "line": 68, + "type": "EventEmitter" + }, + { + "name": "onLogout", + "defaultValue": "new EventEmitter()", + "deprecated": false, + "deprecationMessage": "", + "line": 71, + "type": "EventEmitter" + } + ], + "propertiesClass": [], + "methodsClass": [], + "deprecated": false, + "deprecationMessage": "", + "hostBindings": [], + "hostListeners": [], + "standalone": false, + "imports": [], + "description": "", + "rawdescription": "\n", + "type": "component", + "sourceCode": "import { Component, Input, Output, EventEmitter } from '@angular/core';\nimport type { User } from './User';\n\n@Component({\n selector: 'storybook-header',\n template: `
\n
\n
\n \n \n \n \n \n \n \n

Acme

\n
\n
\n
\n \n Welcome, {{ user.name }}!\n \n \n
\n
\n \n \n
\n
\n
\n
`,\n styleUrls: ['./header.css'],\n})\nexport default class HeaderComponent {\n @Input()\n user: User | null = null;\n\n @Output()\n onLogin = new EventEmitter();\n\n @Output()\n onLogout = new EventEmitter();\n\n @Output()\n onCreateAccount = new EventEmitter();\n}\n", + "assetsDirs": [], + "styleUrlsData": [ + { + "data": ".wrapper {\n font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;\n border-bottom: 1px solid rgba(0, 0, 0, 0.1);\n padding: 15px 20px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n}\n\nsvg {\n display: inline-block;\n vertical-align: top;\n}\n\nh1 {\n font-weight: 700;\n font-size: 20px;\n line-height: 1;\n margin: 6px 0 6px 10px;\n display: inline-block;\n vertical-align: top;\n}\n\nbutton + button {\n margin-left: 10px;\n}\n\n.welcome {\n color: #333;\n font-size: 14px;\n margin-right: 10px;\n}\n", + "styleUrl": "./header.css" + } + ], + "stylesData": "", + "extends": [] + }, + { + "name": "PageComponent", + "id": "component-PageComponent-f5d2fd9ba0ee70c24f514ef21ebdae50beb2e2f42594802a96cdbeb02a59371897162b6be17fcb45cdc0d237d3e4bee611d1ad1d446a54e0699ba35b48991b87", + "file": "src/stories/page.component.ts", + "encapsulation": [], + "entryComponents": [], + "inputs": [], + "outputs": [], + "providers": [], + "selector": "storybook-page", + "styleUrls": [ + "./page.css" + ], + "styles": [], + "template": "
\n
\n

Pages in Storybook

\n

\n We recommend building UIs with a\n \n component-driven\n \n process starting with atomic components and ending with pages.\n

\n

\n Render pages with mock data. This makes it easy to build and review page states without\n needing to navigate to them in your app. Here are some handy patterns for managing page data\n in Storybook:\n

\n
    \n
  • \n Use a higher-level connected component. Storybook helps you compose such data from the\n \"args\" of child component stories\n
  • \n
  • \n Assemble data in the page component from your services. You can mock these services out\n using Storybook.\n
  • \n
\n

\n Get a guided tutorial on component-driven development at\n \n Storybook tutorials\n \n . Read more in the\n docs \n .\n

\n
\n Tip Adjust the width of the canvas with the\n \n \n \n \n \n Viewports addon in the toolbar\n
\n
\n
", + "templateUrl": [], + "viewProviders": [], + "hostDirectives": [], + "inputsClass": [], + "outputsClass": [], + "propertiesClass": [ + { + "name": "user", + "defaultValue": "null", + "deprecated": false, + "deprecationMessage": "", + "type": "User | null", + "optional": false, + "description": "", + "line": 64 + } + ], + "methodsClass": [ + { + "name": "doCreateAccount", + "args": [], + "optional": false, + "returnType": "void", + "typeParameters": [], + "line": 74, + "deprecated": false, + "deprecationMessage": "" + }, + { + "name": "doLogin", + "args": [], + "optional": false, + "returnType": "void", + "typeParameters": [], + "line": 70, + "deprecated": false, + "deprecationMessage": "" + }, + { + "name": "doLogout", + "args": [], + "optional": false, + "returnType": "void", + "typeParameters": [], + "line": 66, + "deprecated": false, + "deprecationMessage": "" + } + ], + "deprecated": false, + "deprecationMessage": "", + "hostBindings": [], + "hostListeners": [], + "standalone": false, + "imports": [], + "description": "", + "rawdescription": "\n", + "type": "component", + "sourceCode": "import { Component } from '@angular/core';\nimport type { User } from './User';\n\n@Component({\n selector: 'storybook-page',\n template: `
\n \n
\n

Pages in Storybook

\n

\n We recommend building UIs with a\n \n component-driven\n \n process starting with atomic components and ending with pages.\n

\n

\n Render pages with mock data. This makes it easy to build and review page states without\n needing to navigate to them in your app. Here are some handy patterns for managing page data\n in Storybook:\n

\n
    \n
  • \n Use a higher-level connected component. Storybook helps you compose such data from the\n \"args\" of child component stories\n
  • \n
  • \n Assemble data in the page component from your services. You can mock these services out\n using Storybook.\n
  • \n
\n

\n Get a guided tutorial on component-driven development at\n \n Storybook tutorials\n \n . Read more in the\n docs \n .\n

\n
\n Tip Adjust the width of the canvas with the\n \n \n \n \n \n Viewports addon in the toolbar\n
\n
\n
`,\n styleUrls: ['./page.css'],\n})\nexport default class PageComponent {\n user: User | null = null;\n\n doLogout() {\n this.user = null;\n }\n\n doLogin() {\n this.user = { name: 'Jane Doe' };\n }\n\n doCreateAccount() {\n this.user = { name: 'Jane Doe' };\n }\n}\n", + "assetsDirs": [], + "styleUrlsData": [ + { + "data": "section {\n font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;\n font-size: 14px;\n line-height: 24px;\n padding: 48px 20px;\n margin: 0 auto;\n max-width: 600px;\n color: #333;\n}\n\nsection h2 {\n font-weight: 700;\n font-size: 32px;\n line-height: 1;\n margin: 0 0 4px;\n display: inline-block;\n vertical-align: top;\n}\n\nsection p {\n margin: 1em 0;\n}\n\nsection a {\n text-decoration: none;\n color: #1ea7fd;\n}\n\nsection ul {\n padding-left: 30px;\n margin: 1em 0;\n}\n\nsection li {\n margin-bottom: 8px;\n}\n\nsection .tip {\n display: inline-block;\n border-radius: 1em;\n font-size: 11px;\n line-height: 12px;\n font-weight: 700;\n background: #e7fdd8;\n color: #66bf3c;\n padding: 4px 12px;\n margin-right: 10px;\n vertical-align: top;\n}\n\nsection .tip-wrapper {\n font-size: 13px;\n line-height: 20px;\n margin-top: 40px;\n margin-bottom: 40px;\n}\n\nsection .tip-wrapper svg {\n display: inline-block;\n height: 12px;\n width: 12px;\n margin-right: 4px;\n vertical-align: top;\n margin-top: 3px;\n}\n\nsection .tip-wrapper svg path {\n fill: #1ea7fd;\n}\n", + "styleUrl": "./page.css" + } + ], + "stylesData": "", + "extends": [] + } + ], + "modules": [ + { + "name": "AppModule", + "id": "module-AppModule-2ec58e7a32463b9b6cd970cb31e08e29029a47873b1b978b2bb334fc7975f6f5b3557f06f1d8edb8d9117c1bc37b26d4301c2a5e8ccced6f4a56dde5c6a98af4", + "description": "", + "deprecationMessage": "", + "deprecated": false, + "file": "src/app/app.module.ts", + "methods": [], + "sourceCode": "import { NgModule } from '@angular/core';\nimport { BrowserModule } from '@angular/platform-browser';\n\nimport { AppComponent } from './app.component';\n\n@NgModule({\n declarations: [\n AppComponent\n ],\n imports: [\n BrowserModule\n ],\n providers: [],\n bootstrap: [AppComponent]\n})\nexport class AppModule { }\n", + "children": [ + { + "type": "providers", + "elements": [] + }, + { + "type": "declarations", + "elements": [ + { + "name": "AppComponent" + } + ] + }, + { + "type": "imports", + "elements": [] + }, + { + "type": "exports", + "elements": [] + }, + { + "type": "bootstrap", + "elements": [ + { + "name": "AppComponent" + } + ] + }, + { + "type": "classes", + "elements": [] + } + ] + } + ], + "miscellaneous": { + "variables": [ + { + "name": "environment", + "ctype": "miscellaneous", + "subtype": "variable", + "file": "src/environments/environment.prod.ts", + "deprecated": false, + "deprecationMessage": "", + "type": "object", + "defaultValue": "{\n production: true,\n}" + }, + { + "name": "environment", + "ctype": "miscellaneous", + "subtype": "variable", + "file": "src/environments/environment.ts", + "deprecated": false, + "deprecationMessage": "", + "type": "object", + "defaultValue": "{\n production: false,\n}" + }, + { + "name": "Large", + "ctype": "miscellaneous", + "subtype": "variable", + "file": "src/stories/Button.stories.ts", + "deprecated": false, + "deprecationMessage": "", + "type": "Story", + "defaultValue": "{\n args: {\n size: 'large',\n label: 'Button',\n },\n}" + }, + { + "name": "LoggedIn", + "ctype": "miscellaneous", + "subtype": "variable", + "file": "src/stories/Header.stories.ts", + "deprecated": false, + "deprecationMessage": "", + "type": "Story", + "defaultValue": "{\n args: {\n user: {\n name: 'Jane Doe',\n },\n },\n}" + }, + { + "name": "LoggedIn", + "ctype": "miscellaneous", + "subtype": "variable", + "file": "src/stories/Page.stories.ts", + "deprecated": false, + "deprecationMessage": "", + "type": "Story", + "defaultValue": "{\n render: (args: Page) => ({\n props: args,\n }),\n play: async ({ canvasElement }) => {\n const canvas = within(canvasElement);\n const loginButton = canvas.getByRole('button', { name: /Log in/i });\n await expect(loginButton).toBeInTheDocument();\n await userEvent.click(loginButton);\n await expect(loginButton).not.toBeInTheDocument();\n\n const logoutButton = canvas.getByRole('button', { name: /Log out/i });\n await expect(logoutButton).toBeInTheDocument();\n },\n}" + }, + { + "name": "LoggedOut", + "ctype": "miscellaneous", + "subtype": "variable", + "file": "src/stories/Header.stories.ts", + "deprecated": false, + "deprecationMessage": "", + "type": "Story", + "defaultValue": "{}" + }, + { + "name": "LoggedOut", + "ctype": "miscellaneous", + "subtype": "variable", + "file": "src/stories/Page.stories.ts", + "deprecated": false, + "deprecationMessage": "", + "type": "Story", + "defaultValue": "{\n render: (args: Page) => ({\n props: args,\n }),\n}" + }, + { + "name": "meta", + "ctype": "miscellaneous", + "subtype": "variable", + "file": "src/stories/Button.stories.ts", + "deprecated": false, + "deprecationMessage": "", + "type": "Meta`, + styleUrls: ['./button.css'], +}) +export default class ButtonComponent { + /** + * Is this the principal call to action on the page? + */ + @Input() + primary = false; + + /** + * What background color to use + */ + @Input() + backgroundColor?: string; + + /** + * How large should the button be? + */ + @Input() + size: 'small' | 'medium' | 'large' = 'medium'; + + /** + * Button contents + * + * @required + */ + @Input() + label = 'Button'; + + /** + * Optional click handler + */ + @Output() + onClick = new EventEmitter(); + + public get classes(): string[] { + const mode = this.primary ? 'storybook-button--primary' : 'storybook-button--secondary'; + + return ['storybook-button', `storybook-button--${this.size}`, mode]; + } +} diff --git a/src/stories/button.css b/src/stories/button.css new file mode 100644 index 00000000..dc91dc76 --- /dev/null +++ b/src/stories/button.css @@ -0,0 +1,30 @@ +.storybook-button { + font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; + font-weight: 700; + border: 0; + border-radius: 3em; + cursor: pointer; + display: inline-block; + line-height: 1; +} +.storybook-button--primary { + color: white; + background-color: #1ea7fd; +} +.storybook-button--secondary { + color: #333; + background-color: transparent; + box-shadow: rgba(0, 0, 0, 0.15) 0px 0px 0px 1px inset; +} +.storybook-button--small { + font-size: 12px; + padding: 10px 16px; +} +.storybook-button--medium { + font-size: 14px; + padding: 11px 20px; +} +.storybook-button--large { + font-size: 16px; + padding: 12px 24px; +} diff --git a/src/stories/header.component.ts b/src/stories/header.component.ts new file mode 100644 index 00000000..603ac7cf --- /dev/null +++ b/src/stories/header.component.ts @@ -0,0 +1,75 @@ +import { Component, Input, Output, EventEmitter } from '@angular/core'; +import type { User } from './User'; + +@Component({ + selector: 'storybook-header', + template: `
+
+
+ + + + + + + +

Acme

+
+
+
+ + Welcome, {{ user.name }}! + + +
+
+ + +
+
+
+
`, + styleUrls: ['./header.css'], +}) +export default class HeaderComponent { + @Input() + user: User | null = null; + + @Output() + onLogin = new EventEmitter(); + + @Output() + onLogout = new EventEmitter(); + + @Output() + onCreateAccount = new EventEmitter(); +} diff --git a/src/stories/header.css b/src/stories/header.css new file mode 100644 index 00000000..44c549da --- /dev/null +++ b/src/stories/header.css @@ -0,0 +1,32 @@ +.wrapper { + font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; + border-bottom: 1px solid rgba(0, 0, 0, 0.1); + padding: 15px 20px; + display: flex; + align-items: center; + justify-content: space-between; +} + +svg { + display: inline-block; + vertical-align: top; +} + +h1 { + font-weight: 700; + font-size: 20px; + line-height: 1; + margin: 6px 0 6px 10px; + display: inline-block; + vertical-align: top; +} + +button + button { + margin-left: 10px; +} + +.welcome { + color: #333; + font-size: 14px; + margin-right: 10px; +} diff --git a/src/stories/page.component.ts b/src/stories/page.component.ts new file mode 100644 index 00000000..02cc3f06 --- /dev/null +++ b/src/stories/page.component.ts @@ -0,0 +1,77 @@ +import { Component } from '@angular/core'; +import type { User } from './User'; + +@Component({ + selector: 'storybook-page', + template: `
+ +
+

Pages in Storybook

+

+ We recommend building UIs with a + + component-driven + + process starting with atomic components and ending with pages. +

+

+ Render pages with mock data. This makes it easy to build and review page states without + needing to navigate to them in your app. Here are some handy patterns for managing page data + in Storybook: +

+
    +
  • + Use a higher-level connected component. Storybook helps you compose such data from the + "args" of child component stories +
  • +
  • + Assemble data in the page component from your services. You can mock these services out + using Storybook. +
  • +
+

+ Get a guided tutorial on component-driven development at + + Storybook tutorials + + . Read more in the + docs + . +

+
+ Tip Adjust the width of the canvas with the + + + + + + Viewports addon in the toolbar +
+
+
`, + styleUrls: ['./page.css'], +}) +export default class PageComponent { + user: User | null = null; + + doLogout() { + this.user = null; + } + + doLogin() { + this.user = { name: 'Jane Doe' }; + } + + doCreateAccount() { + this.user = { name: 'Jane Doe' }; + } +} diff --git a/src/stories/page.css b/src/stories/page.css new file mode 100644 index 00000000..fb64fe46 --- /dev/null +++ b/src/stories/page.css @@ -0,0 +1,69 @@ +section { + font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; + font-size: 14px; + line-height: 24px; + padding: 48px 20px; + margin: 0 auto; + max-width: 600px; + color: #333; +} + +section h2 { + font-weight: 700; + font-size: 32px; + line-height: 1; + margin: 0 0 4px; + display: inline-block; + vertical-align: top; +} + +section p { + margin: 1em 0; +} + +section a { + text-decoration: none; + color: #1ea7fd; +} + +section ul { + padding-left: 30px; + margin: 1em 0; +} + +section li { + margin-bottom: 8px; +} + +section .tip { + display: inline-block; + border-radius: 1em; + font-size: 11px; + line-height: 12px; + font-weight: 700; + background: #e7fdd8; + color: #66bf3c; + padding: 4px 12px; + margin-right: 10px; + vertical-align: top; +} + +section .tip-wrapper { + font-size: 13px; + line-height: 20px; + margin-top: 40px; + margin-bottom: 40px; +} + +section .tip-wrapper svg { + display: inline-block; + height: 12px; + width: 12px; + margin-right: 4px; + vertical-align: top; + margin-top: 3px; +} + +section .tip-wrapper svg path { + fill: #1ea7fd; +} diff --git a/src/styles.css b/src/styles.css new file mode 100644 index 00000000..bc016bce --- /dev/null +++ b/src/styles.css @@ -0,0 +1,460 @@ +* { + box-sizing: border-box; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); + -webkit-tap-highlight-color: transparent; +} + +html, +body { + margin: 0; + padding: 0; + font-size: 100%; + outline: none; + font-family: "Nunito Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-style: 400; + color: #333; + font-size: 16px; + background-color: #26c6da; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +h1, +p, +label { + margin: 0; + padding: 0; + border: 0; + font-weight: normal; + font-style: normal; + font-size: 100%; + line-height: 1; + font-family: inherit; + vertical-align: baseline; + vertical-align: middle; + line-height: normal; + overflow: visible; + font-family: "Nunito Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; +} + +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} + +button, +input[type="button"], +input[type="reset"], +input[type="submit"] { + cursor: pointer; + -webkit-appearance: button; +} + +@keyframes spin { + 0% { + transform: rotate(0deg); + } + + 100% { + transform: rotate(359deg); + } +} + +@keyframes glow { + 0%, + 100% { + opacity: 1; + } + + 50% { + opacity: 0.5; + } +} + +@font-face { + font-family: "Nunito Sans"; + font-style: italic; + font-weight: 400; + src: url(https://fonts.gstatic.com/s/nunitosans/v6/pe0oMImSLYBIv1o4X1M8cce4E9lKcw.ttf) + format("truetype"); +} + +@font-face { + font-family: "Nunito Sans"; + font-style: normal; + font-weight: 400; + src: url(https://fonts.gstatic.com/s/nunitosans/v6/pe0qMImSLYBIv1o4X1M8cce9I94.ttf) + format("truetype"); +} + +@font-face { + font-family: "Nunito Sans"; + font-style: normal; + font-weight: 800; + src: url(https://fonts.gstatic.com/s/nunitosans/v6/pe03MImSLYBIv1o4X1M8cc8aBc5tU1Q.ttf) + format("truetype"); +} + +.type-light { + font-family: "Nunito Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 300; +} + +.type-bold { + font-family: "Nunito Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 800; +} + +.type-italic { + font-family: "Nunito Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 400; + font-style: italic; +} + +input[type="text"], +input[type="email"], +input[type="password"], +textarea { + font-size: 14px; + line-height: 20px; + font-family: "Nunito Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-style: 400; + padding: 0.75rem 0; + line-height: 1.5rem !important; + border: none; + border-radius: 0; + box-sizing: border-box; + color: #333; + outline: none; +} + +.checkbox { + display: inline-block; + height: 3rem; + position: relative; + vertical-align: middle; + width: 44px; +} + +.checkbox input[type="checkbox"] { + font-size: 1em; + visibility: hidden; +} + +.checkbox input[type="checkbox"] + span:before { + position: absolute; + top: 50%; + right: auto; + bottom: auto; + left: 50%; + width: 0.85em; + height: 0.85em; + transform: translate3d(-50%, -50%, 0); + background: transparent; + box-shadow: #2cc5d2 0 0 0 1px inset; + content: ""; + display: block; +} + +.checkbox input[type="checkbox"]:checked + span:before { + font-size: 16px; + line-height: 24px; + box-shadow: none; + color: #2cc5d2; + margin-top: -1px; + font-family: "percolate"; + font-style: normal; + font-weight: normal; + font-variant: normal; + text-transform: none; + line-height: 1; + + content: "\e65e"; +} + +.input-symbol { + display: inline-block; + position: relative; +} + +.input-symbol.error [class^="icon-"], +.input-symbol.error [class*=" icon-"] { + color: #ff4400; +} + +.input-symbol [class^="icon-"], +.input-symbol [class*=" icon-"] { + left: 1em; +} + +.input-symbol input { + padding-left: 3em; +} + +.input-symbol input { + width: 100%; +} + +.input-symbol input:focus + [class^="icon-"], +.input-symbol input:focus + [class*=" icon-"] { + color: #2cc5d2; +} + +.input-symbol [class^="icon-"], +.input-symbol [class*=" icon-"] { + transition: all 300ms ease-in; + transform: translate3d(0, -50%, 0); + background: transparent; + color: #aaa; + font-size: 1em; + height: 1em; + position: absolute; + top: 50%; + width: 1em; +} + +@font-face { + font-family: "percolate"; + src: url("./assets/icon/percolate.eot?-5w3um4"); + src: url("./assets/icon/percolate.eot?#iefix5w3um4") + format("embedded-opentype"), + url("./assets/icon/percolate.woff?5w3um4") format("woff"), + url("./assets/icon/percolate.ttf?5w3um4") format("truetype"), + url("./assets/icon/percolate.svg?5w3um4") format("svg"); + font-weight: normal; + font-style: normal; +} + +[class^="icon-"], +[class*=" icon-"] { + font-family: "percolate"; + + font-style: normal; + font-weight: normal; + font-variant: normal; + text-transform: none; + line-height: 1; +} + +.icon-star:before { + content: "\e608"; +} + +.icon-face-sad:before { + content: "\e60f"; +} + +.icon-check:before { + content: "\e65e"; +} + +.list-heading { + letter-spacing: 0.3em; + text-indent: 0.3em; + text-transform: uppercase; + font-family: "Nunito Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 800; + font-size: 11px; + padding-left: 15px; + line-height: 40px; + background: #f8f8f8; + color: #aaa; +} + +.list-heading .icon-sync { + opacity: 1; + animation: spin 2s infinite linear; + display: inline-block; + margin-right: 4px; +} + +.list-item { + font-size: 14px; + line-height: 20px; + display: flex; + flex-wrap: wrap; + height: 3rem; + width: 100%; + background: white; + transition: all ease-out 150ms; +} + +.list-item .title { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + flex: 1; +} + +.list-item input[type="text"] { + background: transparent; + width: 100%; +} + +.list-item input[type="text"]:focus { + cursor: text; +} + +.pin-button { + width: 3rem; + height: 3rem; + background: transparent; + border: none; + text-align: center; + transition: all 200ms ease-in; + color: #eee; + font-size: 16px; + line-height: 3rem; + outline: none; +} + +.pin-button:hover { + color: #2cc5d2; +} +.pin-button:focus { + outline-color: transparent; +} + +.pin-button:active { + color: #555; +} + +.list-item.TASK_PINNED .icon-star { + color: #2cc5d2; +} + +.list-item.TASK_ARCHIVED input[type="text"] { + color: #a0aec0; + text-decoration: line-through; +} + +.list-item:hover { + background-image: linear-gradient(to bottom, #e5f9f7 0%, #f0fffd 100%); +} + +.list-item:hover .checkbox { + cursor: pointer; +} + +.list-item + .list-item { + border-top: 1px solid #f0f9fb; +} + +.list-item.checked input[type="text"] { + color: #ccc; + text-decoration: line-through; +} + +.list-item.checked .delete-item { + display: inline-block; +} + +.loading-item { + height: 3rem; + width: 100%; + background: white; + display: flex; + align-items: center; + line-height: 1rem; + padding-left: 16px; +} + +.loading-item .glow-checkbox, +.loading-item .glow-text span { + animation: glow 1.5s ease-in-out infinite; + background: #eee; + color: transparent; + cursor: progress; + display: inline-block; +} + +.loading-item .glow-checkbox { + margin-right: 16px; + width: 12px; + height: 12px; +} + +.loading-item + .loading-item { + border-top: 1px solid #f0f9fb; +} + +.list-items { + position: relative; + background: white; + min-height: 288px; +} + +.list-items .select-placeholder { + border: none; + width: 48px; +} + +.wrapper-message { + position: absolute; + top: 45%; + right: 0; + bottom: auto; + left: 0; + width: auto; + height: auto; + transform: translate3d(0, -50%, 0); + text-align: center; +} + +.wrapper-message [class^="icon-"], +.wrapper-message [class*=" icon-"] { + font-size: 48px; + line-height: 56px; + color: #2cc5d2; + display: block; +} + +.wrapper-message .title-message { + font-size: 16px; + line-height: 24px; + font-family: "Nunito Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 800; + color: #4a5568; +} + +.wrapper-message .subtitle-message { + font-size: 14px; + line-height: 20px; + color: #4a5568; +} + +.page.lists-show { + min-height: 100vh; + background: white; +} + +.page.lists-show nav { + background: #d3edf4; + padding: 1.5rem 1.25rem; + text-align: center; +} + +@media screen and (min-width: 40em) { + .page.lists-show nav { + text-align: left; + } +} + +.page.lists-show nav .title-page { + font-size: 20px; + line-height: 24px; + line-height: 2rem; + cursor: pointer; + white-space: nowrap; + font-family: "Nunito Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + overflow: hidden; + text-overflow: ellipsis; + font-weight: 800; + color: #1c3f53; + display: inline-block; + vertical-align: top; + max-width: 100%; +} diff --git a/tsconfig.app.json b/tsconfig.app.json new file mode 100644 index 00000000..84f1f992 --- /dev/null +++ b/tsconfig.app.json @@ -0,0 +1,10 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/app", + "types": [] + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"] +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..1b8bd003 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,30 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "compileOnSave": false, + "compilerOptions": { + "baseUrl": "./", + "outDir": "./dist/out-tsc", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "sourceMap": true, + "declaration": false, + "downlevelIteration": true, + "experimentalDecorators": true, + "moduleResolution": "node", + "importHelpers": true, + "target": "ES2022", + "module": "ES2022", + "useDefineForClassFields": false, + "lib": ["ES2022", "dom"] + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": false + } +} diff --git a/tsconfig.spec.json b/tsconfig.spec.json new file mode 100644 index 00000000..c7cfc0e2 --- /dev/null +++ b/tsconfig.spec.json @@ -0,0 +1,10 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/spec", + "module": "CommonJs", + "types": ["jest"] + }, + "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] +}