CodeMirror6 in Vaadin 14 & Lit - vaadin

I created a simple LitElement with CodeMirror6 I can see the Editor, but when I call the same LitElement in Vaadin , the styling is completely gone.
I have tried both 14 and 23. Same issue.
CodeMirror6 Lit
import { LitElement, html } from 'lit';
import { EditorState, EditorView, basicSetup } from "#codemirror/basic-setup"
import { sql } from '#codemirror/lang-sql';
import { oneDark } from '#codemirror/theme-one-dark';
export class App extends LitElement {
static get properties() {
return {
value: String,
};
}
render() {
return html`
<div id="codeeditor"></div>`;
}
firstUpdated() {
let editorState = EditorState.create({
doc: this.value, extensions: [
basicSetup,
oneDark,
sql(),
]
});
var element = document.getElementById('codeeditor');
const editor = new EditorView(
{
state: editorState,
parent: element
}
);
}
createRenderRoot() {
return this;
}
}
customElements.define('code-mirror', App);
LitElement Code Editor Image - https://i.stack.imgur.com/0MsjU.png
No issue here works perfectly, but When I call the above litelement into Vaadin . The formatting and styling is completely gone.
LitElement in Vaadin Image : https://i.stack.imgur.com/RP35C.png
Any suggestion or pointer for me to fix this issue.

The problem is way on which vaadin renders child components in a Vertical|Horizontal layout (shadowRoot with slots).
If you add your implementation to the ROOT content (first layout), the codemirror will work fine as the styles will be applied correctly.
I tried extending new module about #CssImport with codemirror styles. The module was displaying correctly but the codemirror events stopped working because of the vaadin structure ;/
The problem can be worked around as follows. I know it's not elegant, but it works.
Create a new element in document.body
Init codemirror in the new element
Move codemirror from created element to element rendered by module
import {EditorState, EditorView, basicSetup} from "#codemirror/basic-setup"
import {sql} from "#codemirror/lang-sql"
import {html, LitElement} from "lit";
import { oneDark } from '#codemirror/theme-one-dark';
export class App extends LitElement {
static get properties() {
return {
value: String,
};
}
createRenderRoot() {
return this;
}
render() {
return html`<span id="codeeditor"></span>`;
}
firstUpdated() {
var element = document.getElementById('codeeditor');
var parent = document.createElement("div");
document.body.append(parent);
new EditorView({
state: EditorState.create({
extensions: [basicSetup, oneDark ,sql()]
}),
parent: parent
})
document.body.removeChild(parent);
element.appendChild(parent);
}
}
customElements.define('code-mirror', App);

Related

Call obj for a component

I'm calling an obj for my index.js screen like that ...
index.js
import React from 'react';
import { View, Text } from 'react-native';
import ScreenUsers from './ScreenUsers';
const Users = (props) => {
const username = props?.route?.params?.user.map(name => (
name.userDetails.nameUser
));
return (
<Text>{username}</Text>
{ScreenUsers()}
);
}
Until then my index.js works, pull the username, however my index has a component from another screen called ScreenUsers.js where I make a list of users. In this other component that is breaking because it does not return what I want.
ScreenUsers.js
import React from 'react';
import { View, Text } from 'react-native';
function ScreenUsers(props) {
const fullnanme = props?.route?params?.user.users;
return <Text>{fullname}</Text>
}
ScreenUsers have route error
you use ScreenUsers as component not as screen, you can't handle route in this case, if you want to use it as navigation screen you must use navigation read here
and if you want to use it only as component
edit this line {ScreenUsers()} to
//pass prop fullname down
<ScreenUsers fullname={"user name1"} />
//recieve props fullname
function ScreenUsers(props) {
return <Text>{props?.fullname}</Text>
}
if you already use ScreenUsers as screen in navigation and you want also to use it as component you can do something like this
//pass prop route
<ScreenUsers route={{params : {fullname : "user name1"}} />
//recieve props fullname
function ScreenUsers(props) {
return <Text>{props?.route?.params?.fullname}</Text>
}

Vaadin 12: Setting innerHTML 2x to the same value does not work

is this expected behavior?
Clicking 2x on the "set to 'foo'"-Button will cause the innerHTML to become empty.
import java.util.Random;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.router.Route;
#Route("test2")
public class V_Test2 extends Div
{
public V_Test2()
{
Div div = new Div();
add(div);
{
Button button = new Button("set to 'foo'");
button.addClickListener(e -> div.getElement().setProperty("innerHTML", "foo"));
add(button);
}
{
Button button = new Button("set random");
button.addClickListener(e -> div.getElement().setProperty("innerHTML", "bar-" + new Random().nextInt()));
add(button);
}
{
Button button = new Button("set to null");
button.addClickListener(e -> div.getElement().setProperty("innerHTML", null));
add(button);
}
}
}
This is a known bug: https://github.com/vaadin/flow/issues/4644. You can bypass the broken logic by instead using JavaScript to set the innerHMTL value. This would be something along the lines of div.getElement().executeJavaScript("this.innerHTML = $0", "foo");.

document:click not working

I'm trying to make a global click event directive. But document:click does not work for me.
import 'package:angular/angular.dart';
#Directive(
selector: '[clickOutside]'
)
class ClickOutsideDirective {
#HostListener('click', [r'$event.target'])
void onClick(targetElement){
print('Target:' + targetElement.toString());
}
}
When changing document:click to click I get expected behavior. But of course not globally. What am I doing wrong?
The document: and similar event scopes were removed in Dart.
Use instead
import 'dart:html';
class ClickOutsideDirective implements OnInit, OnDestroy {
StreamSubscription _docClickSub;
ngOnInit() {
_docClickSub = document.onClick.listen((event) {
print('Target:' + event.target.toString());
});
}
ngOnDestroy() {
_docClickSub?.cancel();
_docClickSub = null;
}
}

react native status bar not displaying dark-content

I am using the following code, though the status bar appears to be displaying white text instead of black. Any help would be great
// #flow
import React, { Component } from 'react'
import { View, StatusBar } from 'react-native'
import NavigationRouter from '../Navigation/NavigationRouter'
import { connect } from 'react-redux'
import StartupActions from '../Redux/StartupRedux'
import ReduxPersist from '../Config/ReduxPersist'
// Styles
import styles from './Styles/RootContainerStyle'
class RootContainer extends Component {
componentDidMount () {
// if redux persist is not active fire startup action
if (!ReduxPersist.active) {
this.props.startup()
}
}
render () {
return (
<View style={styles.applicationView}>
<StatusBar barStyle='dark-content' />
<NavigationRouter />
</View>
)
}
}
// wraps dispatch to create nicer functions to call within our component
const mapDispatchToProps = (dispatch) => ({
startup: () => dispatch(StartupActions.startup())
})
export default connect(null, mapDispatchToProps)(RootContainer)
Issue ended up being 2 root containers and the incorrect one was being updated

How to request fullscreen in compiled dart

I'm playing around with a Dart app trying to get fullscreen mode to work. My HTML (excluding boilerplate):
<div id="fullscreen_div">
Clicking this should cause it to go fullscreen!
</div>
My Dart code:
import 'dart:html';
void main() {
var div = querySelector('#fullscreen_div');
div.onClick.listen((MouseEvent e) {
div.requestFullscreen();
print('requested fullscreen');
});
}
Here it is on DartPad.
If I've done this correctly, clicking the div once should cause the div to go into fullscreen mode. On Chromium, this works. When compiled to JavaScript (both debug and minified), this does not happen, and the console outputs:
Uncaught TypeError: undefined is not a function
This happens on both Chrome, Firefox and IE (tested on Windows 7). From what I've understood this is a common JavaScript error, and searching does not bring up anything obvious.
Any ideas why requestFullScreen won't work when dart is compiled to JS?
As pointed out in the comments (thanks Günter!), this is a known issue. #12 in that thread posted a good workaround, edited by me to be a bit more generic:
import 'dart:js';
void fullscreenWorkaround(Element element) {
var elem = new JsObject.fromBrowserObject(element);
if (elem.hasProperty("requestFullscreen")) {
elem.callMethod("requestFullscreen");
}
else {
List<String> vendors = ['moz', 'webkit', 'ms', 'o'];
for (String vendor in vendors) {
String vendorFullscreen = "${vendor}RequestFullscreen";
if (vendor == 'moz') {
vendorFullscreen = "${vendor}RequestFullScreen";
}
if (elem.hasProperty(vendorFullscreen)) {
elem.callMethod(vendorFullscreen);
return;
}
}
}
}
I used this in my code, and replaced this call
div.requestFullscreen();
with
fullscreenWorkaround(div);
which worked great. Tested and working compiled on Chrome and IE.
Here is an extended version of Tobbe hack to use the whole fullscreen API.
import 'dart:html';
import 'dart:js';
// Workaround for https://code.google.com/p/dart/issues/detail?id=4136
class FullscreenWorkaround {
static void requestFullscreen(Element element) {
_callMethods(element, [
'requestFullscreen',
'webkitRequestFullscreen',
'mozRequestFullScreen',
'msRequestFullscreen',
'oRequestFullscreen'
]);
}
static void exitFullscreen() {
_callMethods(document, [
'exitFullscreen',
'webkitExitFullscreen',
'mozCancelFullScreen',
'msExitFullscreen',
'oExitFullscreen'
]);
}
static bool get fullscreenEnabled {
var result = _getProperty(document, [
'fullscreenEnabled',
'webkitFullscreenEnabled',
'mozFullScreenEnabled',
'msFullscreenEnabled',
'oFullscreenEnabled'
]);
return result != null ? result : false;
}
static get fullscreenElement {
return _getProperty(document, [
'fullscreenElement',
'webkitFullscreenElement',
'mozFullScreenElement',
'msFullscreenElement',
'oFullscreenElement'
]);
}
static _callMethods(browserObject, List methods) {
var jsElem = new JsObject.fromBrowserObject(browserObject);
for (String methodName in methods) {
if (jsElem.hasProperty(methodName)) {
return jsElem.callMethod(methodName);
}
}
}
static _getProperty(browserObject, List properties) {
var jsElem = new JsObject.fromBrowserObject(browserObject);
for (String propertyName in properties) {
if (jsElem.hasProperty(propertyName)) {
return jsElem[propertyName];
}
}
}
}

Resources