Why this #import rule is not having any effect on this Web Component? - font-face

const sheet = new CSSStyleSheet()
sheet.replace(`
#import url('https://fonts.googleapis.com/css?family=Roboto&display=swap');
p {
color: red;
font-family: 'Roboto';
}
`)
customElements.define('my-component',
class extends HTMLElement {
constructor() {
super()
const shadowRoot = this.attachShadow({
mode: 'open'
})
shadowRoot.adoptedStyleSheets = [sheet]
shadowRoot.innerHTML = '<p>my component</p>'
}
}
)
Check here: https://jsfiddle.net/jdvivar/h1x2vs3u/
A custom tag my-component is created, a shadow root attached and an adopted stylesheet is copied inside. I think it should render the content with the correct font, but it does not. Only the color style is applied. Do you know why?

Related

How to add and remove classes to navbar on scroll in Vue 3 Composition Api

I have been working to create graana.com clone with Vue 3 and Composition API syntax. I want add remove classes to navbar on scroll. If user scrolls downwards we should automatically add a class ("scrolled") to navbar to apply special styles and when screen is scrolled back to top ("scrolled") class is removed.
See example at https://www.graana.com/.
I want to copy their navbar behaviour using Vue 3 Composition API.
Can you help me out?
<header class="header" ref="headRef">
import { defineComponent, ref } from "vue";
import { onMounted } from "#vue/runtime-core";
setup(){
const headRef = ref(null); // obtain the reference
onMounted(() => {
window.addEventListener("scroll", () => {
var curr = window.pageYOffset;
// You can style header-bg for style purpose
if (curr >= 100) {
headRef.value.classList.add("header-bg");
}else{
headRef.value.classList.remove("header-bg");
}
});
});
return {
headRef
}
}

Customizing colors for PrimeReact datatable

There is a way to change a background or text color to a row in PrimeReact Datatable that is using rowClassName={rowClass} where rowClass is a function that allows returning a class configured in the CSS file.
but... what if I want to choose an arbitrary color? for example, one fetched from a database in #RRGGBB format?
Reading de documentation I can't see a way to call a function to return the style string. Another way could be, creating dynamically the class name, for example...
class RRGGBB for a selected color, define this class with background: #RRGGBB and let rowClassName={rowClass} call rowClass function returning this dynamically created class...
I have this approach, but don't work:
const mycolor = "#00ff00";
function createStyle() {
const style = document.createElement("style");
// add CSS styles
style.innerHTML = `
.lulu {
color: white;
background-color: ${mycolor};
}
`;
// append the style to the DOM in <head> section
document.head.appendChild(style);
}
createStyle();
const rowClass = (data) => {
return {
"lulu": data.category === "Accessories"
};
};
.....
<DataTable value={products} rowClassName={rowClass}>
this code is a modified version of the sample code by prime react, here, in sandbox:
https://codesandbox.io/s/o6k1n
thanks!
I have solved it...
What I did is to create a dynamic css, and then use it:
function createStyle(color) {
var style = document.getElementsByTagName("style");
var colortag = color.replace("#", "mycolor");
//Assuming there is a style section in the head
var pos = style[0].innerHTML.indexOf(colortag);
if(pos<0)
style[1].innerHTML += "."+colortag+`
{
color: ${color}!important;
}
`;
return colortag;
const rowClass = (data) => {
var colortag;
if (data.COLOR!=undefined)
colortag=createStyle(data.COLOR);
return { [colortag]: ata.COLOR!=undefined };
}
<DataTable ref={dt} value={Data} rowClassName={rowClass}>
<column>......</column>
</DataTable>
With this code, if in the data there is a field called COLOR:"#RRGGBB" then it will create a style with this color and use it as text color. The same can be applied to background or whatever

How to add navigation links (dots) to slick lightbox?

I have slick carousel and slick lightbox.
The latter has no dots or navigation links. How to add them?
Since lightbox using slick itself:
Add dots : true to dist/slick-lightbox.js (or rebuild coffeescript)
SlickLightbox.prototype.initSlick = function (index) {
/* Runs slick by default, using `options.slick` if provided. If `options.slick` is a function, it gets fired instead of us initializing slick. Merges in initialSlide option. */
var additional;
additional = { initialSlide: index, dots:true };
//...
}
Add styles to make them available
.slick-dots {
bottom: 0;
}
.slick-dots li button::before {
color: #9f9f9f;
}
.slick-dots li.slick-active button::before {
color: white;
}

Ampersand and anchor element

I have a anchor element that sometimes also has a class:
I wish to target this in sass to override css rules on anchor tags, I've tried:
a {
color: red;
}
.btn {
& a {
color: blue;
}
}
But with no luck.
How can this be done?
If you're trying to target anchor tags with the class .btn you can do this...
a {
&.btn {
// styles here
}
}

How to scrollTop a div whose content is managed by AngularDart?

I have a div holding some chat history. I would like for the div content to scroll when it becomes full. I have this working using jQuery in another project, but what would be the proper AngularDart way to achieve this?
Simplifying a bit, in my HTML I have
<div class="chatHistory">{{ctrl.text}}</div>
(using style white-space:pre) and in my controller I have the method
void addToChatHistory(String msg) {
text += msg;
var elt = querySelector(".chatHistory");
elt.scrollTop = elt.scrollHeight;
}
Issues:
This code scrolls the div content but not quite enough because it sets the scrollTop too quickly; i.e., even before the .chatHistory can be updated by Angular.
Besides this (partial) solution doesn't feel very Angular in style given the use of querySelector.
I tried setting up a watch on the text field but that also fires too early. Suggestions?
For the first issue you can use Timer.run to defer the scroll execution :
Timer.run(() => elt.scrollTop = elt.scrollHeight);
For the second issue you can inject the Element managed by your controller and use querySelector on it :
MyController(Element e) : elt = e.querySelector('.chatHistory');
EDIT
I published a package containing this directive: http://pub.dartlang.org/packages/bwu_angular
-------
I would create a Directive/Decorator like NgEventDirective but for the resize event and add it to your div. In the event handler you set your scrollTop property.
I found contradictory info about the resize event.
DART - Resize div element event says it is available everywhere
Onresize for div elements? is a workaround for browsers that don't support this event.
another page covering this topic: http://marcj.github.io/css-element-queries/
I tried to create an Angular implementation for the 'workaround' (2nd link) but run into this issue https://code.google.com/p/dart/issues/detail?id=18062 which contains info about a workaround but I didn't yet find time to implement it.
EDIT
I checked my attempt and it worked in Dartium with the version I downloaded today (Dart VM version: 1.4.0-dev.4.0 (Thu May 1 04:06:09 2014) on "linux_x64").
I haven't tried in other version since I created the issue.
(The code should be improved to make the directive more generic - the event method should be assignable by an attribute not hardcoded)
index.html
<!DOCTYPE html>
<html ng-app>
<head>
<script src="packages/web_components/platform.js"></script>
<style>
.resize-triggers {
visibility: hidden;
}
.resize-triggers, .resize-triggers > div, .contract-trigger:before {
content: " ";
display: block;
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
overflow: hidden;
}
.resize-triggers > div {
background: #eee;
overflow: auto;
}
.contract-trigger:before {
width: 200%;
height: 200%;
}
</style>
<style>
#my_element {
height: 200px;
overflow: scroll;
}
</style>
</head>
<body ng-cloak>
<div>
<div id="my_element" style="border: 1px solid blue;">
<div id='my_sizable' ng-observe-size></div>
</div>
</div>
<script type="application/dart" src="index.dart"></script>
<script type="text/javascript" src="packages/browser/dart.js"></script>
</body>
</html>
index.dart
library angular_observe_resize.main;
import 'dart:async' as async;
import 'dart:html' as dom;
import 'package:angular/angular.dart' as ng;
import 'package:angular/application_factory.dart' as ngaf;
// see https://stackoverflow.com/questions/19329530
// and this bug https://code.google.com/p/dart/issues/detail?id=18062
// source from http://www.backalleycoder.com/2013/03/18/cross-browser-event-based-element-resize-detection/
#ng.Decorator(selector: '[ng-observe-size]')
class NgObserveSizeDirective implements ng.AttachAware, ng.DetachAware {
dom.Element _element;
bool _hasAttacheEvent;
NgObserveSizeDirective(this._element);
void onSizeChange(dom.Event e) {
_element.parent.scrollTop = _element.scrollHeight;
}
dom.HtmlElement _triggers;
void resetTriggers() {
var expand = _triggers.children[0];
var contract = _triggers.children[_triggers.children.length - 1];
var expandChild = expand.children[0];
contract.scrollLeft = contract.scrollWidth;
contract.scrollTop = contract.scrollHeight;
expandChild.style.width = '${expand.offsetWidth + 1}px';
expandChild.style.height = '${expand.offsetHeight + 1}px';
expand.scrollLeft = expand.scrollWidth;
expand.scrollTop = expand.scrollHeight;
}
int _resizeLastWidth;
int _resizeLastHeight;
bool checkTriggers() {
return _element.offsetWidth != _resizeLastWidth ||
_element.offsetHeight != _resizeLastHeight;
}
int _resizeRaf;
void scrollListener(dom.Event e) {
resetTriggers();
if(_resizeRaf != null) {
dom.window.cancelAnimationFrame(_resizeRaf);
}
_resizeRaf = dom.window.requestAnimationFrame((num highResTime){
if(checkTriggers()) {
_resizeLastWidth = _element.offsetWidth;
_resizeLastHeight = _element.offsetHeight;
onSizeChange(e);
}
});
}
#override
void attach() {
if(_element.getComputedStyle().position == 'static') {
_element.style.position = 'relative';
}
_triggers = new dom.DivElement()
..classes.add('resize-triggers')
..append(new dom.DivElement()..classes.add('expand-trigger')..append(new dom.DivElement()))
..append(new dom.DivElement()..classes.add('contract-trigger'));
_element.append(_triggers);
new async.Future.delayed(new Duration(seconds: 1), () {
//_triggers = _element.children[_element.children.length - 1];
resetTriggers();
dom.Element.scrollEvent.forTarget(_element, useCapture: true).listen(scrollListener);
});
}
#override
void detach() {
_triggers.remove();
}
}
class MyAppModule extends ng.Module {
MyAppModule() {
type(NgObserveSizeDirective);
}
}
main() {
print('main');
ngaf.applicationFactory().addModule(new MyAppModule()).run();
new async.Timer.periodic(new Duration(seconds: 1), (t) {
var elt = (dom.querySelector('#my_sizable') as dom.HtmlElement);
elt.append(new dom.Element.html('<div>${new DateTime.now()}</div>'));
});
}
If you're using an AngularDart component you can inject the shadowdom then select an element inside it to focus on. Didnt find a way of getting the container of the shadowdom.
new Future.delayed(new Duration(milliseconds: 300), () {
var rowElement = _shadowRoot.querySelector('.step-container');
if (rowElement != null ) {
rowElement.scrollIntoView(ScrollAlignment.TOP);
}
});
ShadowDom.host might work, though its currently marked as experimental.

Resources