Update shared styles with JavaScript application wide in Polymer 2.0 - css

I have a shared-styles element that keeps most of my applications colors. I can easily change the colors manually in shared-styles.html, and all of my other components can inherit from there if I use the CSS variables.
My problem is I need to update the CSS variables in shared-styles.html and have all the other components that inherit the CSS variables to update their colors accordingly. Below is my shared-styles.html. For brevity, I removed all the variables except --app-primary-color.
<link rel="import" href="../bower_components/polymer/polymer-element.html">
<!-- shared styles for all views -->
<dom-module id="shared-styles">
<template>
<style is="custom-style">
:host {
--app-primary-color:#2196F3;
}
</style>
</template>
<script>
class SharedStyles extends Polymer.Element {
static get is() { return 'shared-styles'; }
ready(){
super.ready();
console.log('update css');
this.updateStyles({'--app-primary-color': 'red'});
}
}
window.customElements.define(SharedStyles.is, SharedStyles);
</script>
</dom-module>
This is how I am including them in the other components. For example:
<dom-module id="test-element">
<template>
<style include="shared-styles">

The shared style is not a Polymer element, so it should not extend Polymer.Element and should not have a <script> tag. It should be defined like this:
shared-styles.html
<link rel="import" href="../bower_components/polymer/polymer-element.html">
<!-- shared styles for all views -->
<dom-module id="shared-styles">
<template>
<style>
:host {
--app-primary-color: #2196F3;
}
</style>
</template>
</dom-module>
Then, call this.updateStyles in the root element (e.g., <my-app>) to apply a global style in Polymer 2.0. Note that all elements under <my-app> would inherit the newly specified styles.
Example
Here are instructions using Polymer CLI's polymer-2-starter-kit template:
Install the bleeding edge Polymer CLI (npm install polymer-cli#next), required for the polymer-2-starter-kit template.
Run:
mkdir polymer-2-shared-styles-demo
cd polymer-2-shared-styles-demo
polymer init polymer-2-starter-kit
In src/my-app.html, add a <button> to the menu, which will change the value of --app-primary-color:
<template>
<app-drawer-layout fullbleed>
<!-- Drawer content -->
<app-drawer id="drawer" slot="drawer">
<app-toolbar>Menu</app-toolbar>
<!-- **** LINE 77: Add button below **** -->
<button on-click="_changeAppColor">Change app color</button>
<script>
class MyApp extends Polymer.Element {
/* *** LINE 130: Define button-click handler below **** */
_changeAppColor() {
this.updateStyles({'--app-primary-color': 'red'});
}
In src/shared-styles.html, change .circle's background to use --app-primary-color:
.circle {
/* *** LINE 33: Use --app-primary-color below **** */
background: var(--app-primary-color, #ddd);
Run polymer serve -o to open the starter kit in the default browser.
Click the button in the menu to change the color of the toolbar and the circles in each page. It should look like this:
GitHub project

Related

Why Tailwind CSS is not working when applying on an active link?

I'm using Tailwind CSS, Vue JS, and Inertia for my practice project. I'm trying to add some other classes when the specific link is visited. But the problem is updated class is not working.
I have tried the below code.
<Link :href="route('profile.index')"
class="link-btn"
:class="{'link-btn-active' :route('profile.index')}">
Profiles
</Link>
This is what I have written in Tailwind CSS
.link-btn{
#apply pl-[5px] bg-red-500 opacity-60;
}
.link-btn-active{
#apply pl-[10px] bg-green-500 opacity-100;
}
Try it like this :
<template>
<Link :href="route('profile.index')"
class="link-btn"
:class="{'link-btn-active' : isActive('profile.index')}">
Profiles
</Link>
</template>
<script>
export default {
computed: {
isActive(routeName) {
return this.$route.name === routeName
}
}
}
</script>

Tailwind classes not getting applied for Astro Layouts

I am using Astro Tailwind integration, and I am trying to add some tailwind classes to MainLayout.astro which resides in layouts directory as follows
<!DOCTYPE html>
<html lang="en">
<head>
...
</head>
<body>
<main class="mx-20 mb-20 md:mb-28 xl:container xl:mx-auto">
<slot />
</main>
</body>
</html>
But styles are not getting applied to the <main> tag (according to browser dev tools inspection), but styles to the rest of the pages are getting applied.
What I have tried?
Restarting the dev server
Edit:
tailwind.config.cjs look like below
/** #type {import('tailwindcss').Config} */
module.exports = {
content: ["./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}"],
...
};
Edit 2:
astro.config.mjs
import { defineConfig } from "astro/config";
import react from "#astrojs/react";
import image from "#astrojs/image";
import tailwind from "#astrojs/tailwind";
// https://astro.build/config
export default defineConfig({
integrations: [
react(),
tailwind(),
image({
serviceEntryPoint: "#astrojs/image/sharp",
}),
],
});

<style> tag not working within a vue.js element

Example:
var vm = new Vue({
el: '#app',
data: {
name: 'Bob'
}
})
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<div id="app">
Hello {{name}}
<style>
body { color: blue; }
</style>
</div>
JS Fiddle: https://jsfiddle.net/7g1vp68b/6/
When tag is outside of the vue element, it renders okay.
Vue can't parse <style> inside template.
If you check console log, there is an warning:
Templates should only be responsible for mapping the state to the UI.
Avoid placing tags with side-effects in your templates, such as
, as they will not be parsed.
You should place <style></style> outside of Vue template, or using Vue single file component

html element appear twice in .net core angular project template

I'm working on a visual studio 2017 template project of .net core 2 + Angular SPA template.
I'm having a problem that some of html elements appear twice, 1 appearance with css applied and the other isn't.
when i deploy the app it looks like in the image below.
As you can see the place holder 'Choose a number' and the dropdown arrow appear twice.
When i press the upper arrow 2 dropdowns are opened with the options.
If i press the downer arrow only the downer dropdown opened.
the whole div should be coloured in blue but only the "not in place" elements are blue.
the component is a prime-NG component but it occurs with other NPM packages (kendo UI for example).
I assume that it might be related to the order of css files and NPM loading during bootstrap but I can't find the place
index.cshtml:
#{
ViewData["Title"] = "Home Page";
}
<app>Loading...</app>
<script src="~/dist/vendor.js" asp-append-version="true"></script>
#section scripts {
<script src="~/dist/main-client.js" asp-append-version="true"></script>
}
_Layout.cshtml:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>#ViewData["Title"] - GSM.WebMonitorTool</title>
<base href="~/" />
<link rel="stylesheet" href="~/dist/vendor.css" asp-append-version="true" />
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.10/css/all.css" integrity="sha384-+d0P83n9kaQMCwj8F4RJB66tzIwOKmrdb46+porD/OvrJ+37WqIM7UoBtwHO6Nlg" crossorigin="anonymous">
</head>
<body>
#RenderBody()
#RenderSection("scripts", required: false)
</body>
</html>
choose-number.component.html:
<div class="query-context-all">
<div class="dropdown">
<p-dropdown [options]="numbers" [(ngModel)]="chosenNumber" placeholder="Choose a number"></p-dropdown>
</div>
</div>
choose-number.component.ts :
import { Component } from '#angular/core';
import { SelectItem } from 'primeng/api';
#Component({
selector: 'context-input',
templateUrl: './context-input.component.html',
styleUrls: ['./context-input.component.css']
})
export class ContextInputComponent {
chosenNumber: string;
numbers: SelectItem[];
constructor() {
this.numbers = [
{ label: "1", value: "1" },
{ label: "2", value: "2" },
{ label: "3", value: "3" }];
}
}
So thanks to John Velasquez, I understood that i had to add primeNG's css file to webpack. Actually each shared components or fonts npm may require this addition. As a beginner with Angular i didn't know they must be added explicitly so I add here my steps that solved it, hoping it will save some time for others :)
steps:
adding the css file to webpack.config.vendor.vs - add the line 'primeng/resources/primeng.css' to nonTreeShakableModules array
update the rules of shared config, a few lines down, to { test: /\.(png|woff|woff2|eot|ttf|svg|jpe?g|gif)(\?|$)/, use: 'url-loader?limit=100000' }
run webpack --config webpack.config.vendor.js
from cmd/powershell, when path is the project folder.

Binding polymer paper-dropdown-menu to localstorage

Admittedly silly-seeming question... And...
before anyone hastily replies, "RTFM," I have yet I still don't quite grok it -- data-binding.
So, I've got a sort of form, which is really a component consisting of inputs and whatnot and also a core-localstorage element. I've successfully persisted the values of other inputs between sessions, yet I've gotten fuzzy on the paper-dropdown-menu. gridlocked...
What I want to do is use the label for the display value, and when the machine in machines bit is going, I want the selected paper-item to reflect the value from local storage (the label)
Oh, and this is in jade, btw. Here's how it's looking:
//- JADE
/** Stuff that works: **/
core-localstorage(id='storage', name='vbms-user-settings', value='{{settings}}')
.subhead General
paper-input(floatingLabel, label='Username', inputValue='{{settings.username}}', on-change='{{updateStorage}}')
paper-input(floatingLabel, label='Password', inputValue='{{settings.password}}', on-change='{{updateStorage}}', type='password')
paper-checkbox#vpn_gui_toggle.accent(label='Run Headless', checked, style='margin-right: 16px;')
/** The confusing input **/
paper-dropdown-menu#vm_dropdown(valueattr='label', on-core-select='{{updateDefaultVM}}')
template(repeat="{{machine in machines}}")
paper-item(label="{{machine.name}}")
Here's some js... this works fine; i'm trying to do things the "dogmatic" Polymer way.
/*\ JS
|*| ...blah blah polymer jank...
\*/
objectToStorage: function(obj) {
this.$.storage.value=obj;
this.$.storage.save();
},
updateStorage: function() {
this.objectToStorage(this.settings);
},
updateDefaultVM: function() {}
Can anyone lead me to the most-probably simple solution to this hangup?!
Thanks in advance!
I believe that the recommended way of using <paper-dropdown-menu> is to have a two layers of containers between it and the <paper-item>s, based on the example from the current docs.
If you're using that setup, you've now got a <core-menu>, which inherits from <core-selector>. Things that inherit from <core-selector> can make use of the selected attribute to control which item is selected. But <core-selected> defaults to checking to see if any of the items it contains has a name attribute whose value matches the selected value, so we also need to add in name attributes to all of the <paper-item>s.
The end result of something simple, that doesn't rely on loading in values from <core-localstorage>, looks like the following. You should be able to do something similar if you're loading in the initial value from <core-localstorage> instead of hardcoding it.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Polymer Demo</title>
</head>
<body>
<script src="//www.polymer-project.org/webcomponents.js"></script>
<link rel="import" href="//www.polymer-project.org/components/paper-dropdown-menu/paper-dropdown-menu.html">
<link rel="import" href="//www.polymer-project.org/components/paper-dropdown/paper-dropdown.html">
<link rel="import" href="//www.polymer-project.org/components/core-menu/core-menu.html">
<link rel="import" href="//www.polymer-project.org/components/paper-item/paper-item.html">
<template id="page-template" is="auto-binding">
<h1>Pastry Menu</h1>
<paper-dropdown-menu label="Your favorite pastry">
<paper-dropdown class="dropdown">
<core-menu class="menu" selected="{{initiallySelected}}">
<template repeat="{{pastry in pastries}}">
<paper-item name="{{pastry}}">{{pastry}}</paper-item>
</template>
</core-menu>
</paper-dropdown>
</paper-dropdown-menu>
</template>
<script>
var pageTemplate = document.querySelector('#page-template');
pageTemplate.pastries = [
'Croissant',
'Donut',
'Financier',
'Madeleine'
];
// Set this to whatever you want the initially selected item to be. It's value can be loaded from localStorage.
pageTemplate.initiallySelected = 'Financier';
</script>
</body>
</html>

Resources