Let's suppose I need an Angular component which is so small that the best option for it would be a single-file component.
An error alert like the one below would be such an example:
#Component({
selector: 'app-errors',
template: `<div class="alert-error">{{ errorMessage }}</div>`,
styles: [
`
.alert-error {
color: #721c24;
background-color: #f8d7da;
border-color: #f5c6cb;
padding: 0.75rem 1.25rem;
margin-bottom: 1rem;
text-align: center;
border: 1px solid transparent;
border-radius: 0.25rem;
}
`,
],
})
export class ErrorsComponent {}
In order to make this component I have run ng g c error-alert in the CLI. Then I deleted all the files generated by the CLI except error-alert.ts. Then I moved it outside of the error-alert directory (which I deleted).
The problem
I wished (and still do) there was a simpler and faster way to make a single-file component.
Questions
Is there a CLI command that would generate a single-file component?
If there isn't such a command, can we configure the CLI so that there is? How?
You could try adding some flags like so.
> ng generate component <component-name> --inlineTemplate=true --inlineStyle=true --skip-tests=true
This should stop the generation of css/html/spec file.
There is now also an option on more modern versions to do the same with standalone components.
--standalone
More options surrounding generating with specific goals can be found in the angular CLI docs.
You can also edit schematics object in your angular.json to set these flags to default when generating a component if you wanted to take this further.
"schematics": {
"#schematics/angular": {
"component": {
"inlineTemplate": true
}
}
}
Related
I have the next postcss config
module.exports = {
plugins: [
[
'postcss-preset-env',
{
browsers: 'last 2 versions, IE 11, not dead',
preserve: false,
features: {
'custom-media-queries': true,
'custom-properties': true,
'nesting-rules': true
},
importFrom: ['src/styles/variables.css']
}
]
]
}
And this file with css variables
#custom-media --desktop screen and (min-width: 768px);
#custom-media --mobile screen and (max-width: 767px);
:root {
--montserrat: montserrat, sans-serif;
--sfProDisplay: sf pro display, sans-serif;
--helvetica: helvetica, sans-serif;
--blue: #315efb;
--middleBlue: #2c54e2;
--darkBlue: #274bc8;
--lightBlue: #e0ebff;
--green: #21a038;
--grey: #62687f;
--darkGray: #343b4c;
--blueGray: #8d96b2;
--cloudGray: #f3f4f7;
--cloudGray7: #afb6c9;
--darkCarbone: #1f2431;
--paleYellow: #fffde5;
--red: #ff564e;
}
After i built my project via next build && next export, colors are not displayed correctly. For example, color: var(--blueGray), instead color: #8d96b2. Has anybody idea what's wrong?
I believe you should import your CSS variables directly in your styles section and not in config. but I might have got you wrong
Global CSS needs to be included in the /pages/_app file.
From the Adding a Global Stylesheet
documentation:
To add a (global) stylesheet to your application, import the CSS file within
pages/_app.js.
(...) In development, expressing stylesheets this way allows your
styles to be hot reloaded as you edit them—-meaning you can keep
application state.
In production, all CSS files will be automatically concatenated into a
single minified .css file.
Make sure you import the file where the CSS variables are defined in your custom _app.
import '../styles/globals.css'
import '../styles/variables.css'
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />;
}
export default MyApp;
This may not be worth the bounty but from NextJS docs.
CSS variables are not compiled because it is not possible to safely do
so. If you must use variables, consider using something like Sass
variables which are compiled away by Sass.
I'm trying to import interactive.js 1.7.2 in Angular 8. I installed as follows:
npm install interactjs#next
then imported in different ways and none worked:
import * as interact from 'interactjs';
import interact from 'interactjs'
import from 'interactjs';
import * as interact from '#interactjs/interactjs';
declare var interact:any; (with no imports)
The solution here seems to work for others but not for me.
I get many errors when starting up Angular so it has to be a problem with the import, for example I get:
src/app/web/visuals/svg.rectangle.ts(65,25): error TS2349: Cannot
invoke an expression whose type lacks a call signature. Type 'typeof
import("C:/projects/myproject/node_modules/#interactjs/interactjs/index")'
has no compatible call signatures.
../../node_modules/#interactjs/core/Interactable.d.ts(7,19): error TS1086: An accessor cannot be declared in an ambient context.
../../node_modules/#interactjs/core/Interaction.d.ts(74,45): error TS2304: Cannot find name 'Omit'.
How to fix this issue?
UPDATE
This problem is documented here but with no solution.
You can do like this using es5 syntax
const interact = require('interactjs')
import interact from 'interactjs'
interact('.item').draggable({
onmove(event) {
console.log(event.pageX,
event.pageY)
}
})
https://interactjs.io/
As shown on the official page
For angular 8 below code work for me.
import * as InteractJS from 'interactjs/dist/interact.js';
ngOnInit() {
InteractJS('.item').draggable({
onmove(event) {
console.log(event.pageX, event.pageY);
}
});
}
.item {
touch-action: none;
user-select: none;
height: 80px;
width: 80px;
background-color: red;
}
I am developing an angular component and I would like to import into my scss file variables (such as colors) from my ts file and I am going throught some issues.
I have seen some examples with node-sass and webpack but are not very clear to me.
Thanks
One option is CSS Variables.
This is not a SASS variable that is available in preprocessing, but rather something available in the browser during runtime. Therefore, you can get/set it with javascript, and the CSS style will update based on the variable value.
For instance, let's say your component allows you to set the text color through a javascript variable textColor:
CSS:
p { color: var(--text-color); }
JS:
element.style.setProperty("--text-color", textColor);
And if you want the flexibility/maintainability of variables in your SCSS -- you can have the variables point to the JS/CSS variables.
SCSS:
// _vars.scss
$text-color: var(--text-color);
// _styles.scss
p { color: $text-color }
Make sure to verify that this feature has the level of browser support your app needs.
have you tried ngStyle
<some-element [ngStyle]="{'color': styleExp}">...</some-element>
and then in your .ts
styleExp = 'red'
you can read more on it on the official docs
https://angular.io/api/common/NgStyle
It is not possible to import variables to scss files from the ts files. Instead, you can use angular angular properties ngStyle and ngClass
constructor(private elem: ElementRef){
this.colorValue = "yellow";
this.elem.nativeElement.style.setProperty('--text-color', colorValue);
}
then in the css or scss you can use --text-color variable
p { color: var(--text-color); }
I know this is old, but I would like to give an answer that people might be interest:
in example.component.ts
#Component({
selector: 'example',
templateUrl: './example.component.html',
styleUrls: ['./example.component.scss'],
})
export class ExampleComponent implements OnInit {
...
#HostBinding('style.--nameOfVar') nameOfVar = 'red';
...
}
in example.component.scss (or css)
.example {
color: var(--nameOfVar);
}
I have a project that is built in Vue and I want to reuse the components from the Vue application in an Angular application so I don't have to go and rebuild every single component from scratch.
I saw this tutorial on medium: How to use Vue 2.0 components in an angular application, but that tutorial is for AngularJS.
I'm wondering if anyone has done this before, if it's worth it and if anyone knows of any tutorials or reference material.
Wrap your Vue components as native Web Components.
Since Angular supports using custom Web Components, you'll be able to use the Vue components (wrapped as Web Components).
To Angular it doesn't make a difference if the custom Web Components were generated by Vue or not (for all Angular knows, they could be native HTML elements).
Demo
Runnable DEMO here.
The demo is an Angular 5 app. The Vue custom component is defined in index.html. Notice how in app/app.component.html it is used directly in the template, as if it were a native element.
Step by step below.
In Vue
Use vue-custom-element to wrap your Vue components as Web Components:
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/vue-custom-element#3.0.0/dist/vue-custom-element.js"></script>
<script>
const MyVueWebComp = {
props: ['msg'],
template:`
<div style="border: 3px dashed green; padding: 5px">
I am my-vue-web-comp.<br>
Value of "msg" prop: {{ msg }}<br>
<input v-model="text"><button #click="addText">Click me</button>
<div v-for="t in texts">
Text: {{ t }}
</div>
</div>
`,
data() {
return {
text: '',
texts: []
};
},
methods: {
addText() {
this.texts.push(this.text);
this.text = '';
}
}
};
Vue.customElement('my-vue-web-comp', MyVueWebComp);
</script>
That will create a <my-vue-web-comp> web component that can be used directly in the DOM, without the need to have a working Vue instance.
The above is just a demo runnable directly in the browser. If you have .vue files and a vue-cli app, you'll need to do npm install vue-custom-element --save and then create a .js file like:
import Vue from 'vue';
import vueCustomElement from 'vue-custom-element';
import MyElement from './MyElement.vue';
Vue.use(vueCustomElement);
Vue.customElement('my-element', MyElement);
And then this, when bundled, will generate a .js file that can be imported directly as a single <script> tag, instead of the whole code and script tags above.
For more details, check vue-custom-element's docs.
In Angular
Now, in the Angular app, after importing the Web Components (being them Vue-generated or not), configure them to be used by Angular by adding schemas: [CUSTOM_ELEMENTS_SCHEMA] in your #NgModule:
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '#angular/core';
//...
#NgModule({
// ...
schemas: [
CUSTOM_ELEMENTS_SCHEMA // added this
]
})
export class AppModule {
Now use the Web Components (generated from Vue or not) directly in Angular templates. E.g. the component defined in the code above could be used like:
<my-vue-web-comp [msg]="name"></my-vue-web-comp>
In fact, the runnable demo shows an example of that usage.
Limitations
You may need polyfills for older browser support. Please check vue-custom-element's docs for more details.
I'm trying to learn Svelte and TypeScript. I was wondering if there is any pattern to include or program svelte component using ES6 classes. Currently file contains all the script, html and data, css. I want to make them separate files. Please help me!
You can use a task runner to automate this. If you are using es6 classes I would recommend using rollup with rollup-plugin-svelte and rollup-plugin-buble.
I use Gulp to take the separate js, html and css files and concat them into a single file with the appropriate tags enclosing the script and styles. The combined file can be compiled then deleted.
Structure
To help keep the file files clean and easy to work with the HTML, CSS and JavaScript can be seperate.
src/hello/hello.css
.message {
font-size: 10pt;
}
src/hello/hello.html
<div class="message">{{message}}</div>
src/hello/hello.js
export default {
data: function () {
return {
message: 'Hello, world!'
}
}
}
Combine
Svelte requires that components be just a single html file, so the three separate files need to be combined into a single file. Since this file is HTML, the JavaScript must be wrapped in tags and the CSS must be wrapped in tags.
src/hello/hello.temp.html
<style>
.message {
font-size: 10pt;
}
</style>
<div class="message">{{message}}</div>
<script>
export default {
data: function () {
return {
message: 'Hello, world!'
}
}
}
</script>
Compile
The temp file can be compiled using svelte or rollup with the svelte plugin then deleted.
[Edit]
Here is a gist with a gulp file showing how this works.
Link here
[Edit 2]
There is a Yeoman generator to set this all up for you, here is a link to the npm package.
generator-svelte-workbench