Applying class scoped CSS custom properties to web component - web

Is there a specific rule around how class scoped CSS custom properties cascade/are inherited with the shadow root? Let's say I have a default theme with custom properties scoped to :root and a dark theme scoped to a .dark-mode class, I can apply that class to the app-container component and my simple-button text color is set to blue. However, if I apply the dark-mode class directly to the simple-button as demonstrated, it inherits black from :root. It doesn't even pick up .dark-mode. I'm looking for some official docs that might explain this as well.
<!DOCTYPE html>
<head>
<script type="module" src="./app-container.js"></script>
<style>
:root {
--text-color: black;
}
</style>
<style>
.dark-mode {
--text-color: blue;
}
</style>
</head>
<body>
<app-container name="World"></app-container>
</body>
// app-container.js
import {html, css, LitElement} from 'lit';
import './simple-button.js';
export class AppContainer extends LitElement {
static styles = css`p { color: var(--text-color)}`;
static properties = {
};
constructor() {
super();
}
render() {
return html`
<p>App Container</p>
<simple-button class="dark-mode"></simple-button>
`;
}
}
customElements.define('app-container', AppContainer);
// simple-button.js
import {html, css, LitElement} from 'lit';
export class SimpleButton extends LitElement {
static styles = css`button { color: var(--text-color)}`;
static properties = {
};
constructor() {
super();
}
render() {
return html`<button>Button</button>`;
}
}
customElements.define('simple-button', SimpleButton);

Related

lit-element - How to call an event from a slot button?

element
import { LitElement, html } from 'lit-element';
class Component extends LitElement {
render () {
return html`
<slot name="activator">
<button #click="${this.openDialog}">Default Button</button>
</slot>
<custom-dialog></custom-dialog>
`;
}
openDialog () {
// code to open dialog
}
}
customElements.define('custom-dialog', Component);
index.html
<head>
<script type="module" src="src/custom-dialog.js"></script>
</head>
<body>
<custom-dialog>
<button slot="activator">Outside Button</button>
</custom-dialog>
</body>
Given the custom component above and my implementation on a simple html page. You'll notice that I'm using a slot button.
How do I call the openDialog() method using the slot button?
I checked docs for events but I found nothing relevant to this.
Thanks in advance.
You need a click event listener on the slot or some ancestor of the slot:
Try moving the #click binding to the slot element itself. click events bubble, so this will handle both the default slot content button and the slotted button from the light DOM. This might not work in ShadyDOM, so you may want to put the event listened on a wrapper element around the slot.
import { LitElement, html } from 'lit-element';
class Component extends LitElement {
render () {
return html`
<slot name="activator" #click="${this.openDialog}">
<button>Default Button</button>
</slot>
<custom-dialog></custom-dialog>
`;
}
openDialog () {
// code to open dialog
}
}
customElements.define('custom-dialog', Component);

Change substring color in JavaFX Text Area

I need to change substring text from Text Area in JavaFX for example in text below static and void be red.
public static void main(String[] args) {
}
I don't know about CSS is there any simple code or tutorial?
The TextArea does not support anything like rich text different formatting within one component. I would propose you look into directions of
TextFlow - see http://docs.oracle.com/javase/8/javafx/api/javafx/scene/text/TextFlow.html.
It is meant for static display of rich text, but it does not provide editing. The Oracle tutorial may be a viable starting point: http://docs.oracle.com/javase/8/javafx/user-interface-tutorial/text-settings.htm
WebView - see http://docs.oracle.com/javase/8/javafx/api/javafx/scene/web/WebView.html.
WebView can be used to display HTML content. There are several ways to utilize this. You may construct your formatted and colored text as HTML code and set it as WebView content - or you even load one of the popular JavaScript source code formatters/highlighters into the WebView component.
If you are about to create something like a java source code view in JavaFX, you might want to have a look on the 2nd approach. A short sketch (using the ACE Editor libraries, done for JavaScript syntax coloring) might look like this:
First, initialize the WebView with your HTML, here done in an FXML controller:
#Override
public void initialize(URL url, ResourceBundle rb) {
WebEngine engine = this.webView.getEngine();
engine.setJavaScriptEnabled(true);
engine.setOnAlert(new EventHandler<WebEvent<String>>() {
#Override
public void handle(WebEvent<String> t) {
String data = t.getData();
System.out.println("alert: " + data);
textArea.appendText(data);
}
});
engine.load(this.getClass().getResource("content/basics-javascript.html").toExternalForm());
}
Second part: content/basics-javascript.html contains an HTML page that loads the JavaScript libraries necessary for the formatting and highlighting:
<html>
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<style type="text/css" media="screen">
#editor {
position: absolute;
top: 30px;
right: 5px;
bottom: 5px;
left: 5px;
border: 1px solid #ccc;
background-color: #eee;
}
</style>
</head>
<body>
<div>ACE-Editor</div>
<div id="editor">
function foo(items) {
var x = "All this is syntax highlighted";
return x;
</div>
<script type="text/javascript" src="js/libs/ace/ace.js" ></script>
<script type="text/javascript">
var editor = ace.edit('editor');
editor.getSession().setMode("ace/mode/javascript");
</script>
</body>
</html>
Hope that helps!

Create a Cancel button for Joomla 3.2 custom component

I am trying to build a Joomla 3.2 custom component and am having a difficult time getting the cancel button (admin section) to work. I've added the button, but when I click it I get the error:
0 Invalid controller: name='helloworld', format=''
This is for the component 'helloworld' and the view 'goodbye'. Could someone look at my files and tell me how to get the 'cancel' button to work? I just want it to close the current page and return to the default component page.
Thanks for any help.
/administrator/views/goodbye/view.html.php
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
// import Joomla view library
jimport('joomla.application.component.view');
/**
* HTML View class for the HelloWorld Component
*/
class HelloWorldViewGoodbye extends JViewLegacy
{
// Overwriting JView display method
function display($tpl = null)
{
$this->addToolbar();
// Display the view
parent::display($tpl);
}
protected function addToolbar()
{
JToolbarHelper::title('Race Results','tbar');
JToolbarHelper::cancel('helloworld.cancel', 'JTOOLBAR_CLOSE');
}
}
/administrator/views/goodbye/tmpl/default.php
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
?>
<h1>Cancel Race Results</h1>
<script type="text/javascript">
Joomla.submitbutton = function(task)
{
if (task == 'helloworld.cancel')
{
Joomla.submitform(task, document.getElementById('helloworld-form'));
}
}
</script>
<form id="helloworld-form" name="adminForm" method="post" action="<?php echo JRoute::_('index.php?option=com_helloworld&view=goodbye'); ?>">
<input type="hidden" name="option" value="com_helloworld" />
<input type="hidden" name="task" value="" />
<input type="hidden" name="view" value="goodbye" />
<?php echo JHtml::_('form.token'); ?>
</form>
/administrator/controllers/goodbye.php
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
// import Joomla modelitem library
jimport('joomla.application.component.controller');
/**
* HelloWorld Model
*/
class HelloWorldControllerGoodbye extends JControllerLegacy
{
public function edit() {
}
public function add() {
}
public function remove() {
}
public function save() {
}
public function apply() {
}
}
/administrator/models/goodbye.php
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
// import Joomla modelitem library
jimport('joomla.application.component.model');
/**
* HelloWorld Model
*/
class HelloWorldModelGoodbye extends JModelLegacy
{
}
depending on action you would like to achieve
Add to controller
public function cancel($key = null) {
JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN'));
$this->setRedirect(JRoute::_('index.php?option='.$this->option.'&view=name_of the_view' , false));
return true;
}
In view.html add condition to your button
if (condition when to use button)
{
JToolbarHelper::cancel('your_controller_name.cancel');
}
else
{
JToolbarHelper::cancel('your_controller_name', 'JTOOLBAR_CLOSE');
}
Change HelloWorldViewGoodbye to GoodbyeViewGoodbye and same other.

Wicket autocomplete with comboboxes and IE6

I have form in which there is AutoCompleteTextField and two combo boxes (DropDowns in wicket).
When drop down for autocomplete is shown, combo boxes are hidden in IE6.
My test page code is:
package net.betlista;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import org.apache.wicket.Session;
import org.apache.wicket.extensions.ajax.markup.html.autocomplete.AutoCompleteTextField;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.model.Model;
public class AutoCompleteAndDropDownTestPage extends WebPage {
public AutoCompleteAndDropDownTestPage() {
final DropDownChoice<Integer> drop1 = new DropDownChoice<Integer>("drop1", getNewList(15));
drop1.setOutputMarkupId(true);
final DropDownChoice<Integer> drop2 = new DropDownChoice<Integer>("drop2", getNewList(10));
drop2.setOutputMarkupId(true);
Session.get().setLocale(Locale.ENGLISH);
final AutoCompleteTextField<Integer> auto = new AutoCompleteTextField<Integer>("auto", new Model<Integer>(null)) {
#Override
protected Iterator<Integer> getChoices(final String input) {
return getNewList(20).iterator();
}
};
add(auto);
add(drop1);
add(drop2);
add(new TextField<String>("text"));
}
private static List<Integer> getNewList(final int upTo) {
final LinkedList<Integer> list = new LinkedList<Integer>();
for (int i = 0; i < upTo; i++) {
list.add(i);
}
return list;
}
}
test page markup is
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form>
<input type="text" wicket:id="auto"/><br>
<select wicket:id="drop1"></select><br>
<select wicket:id="drop2"></select><br>
<input type="text" wicket:id="text"/><br>
</form>
</body>
</html>
Wicket does NOT support IE6, so I'm looking for a workaround.
You should try to upgrade to 6.7.0, this issue sees fixed : https://issues.apache.org/jira/browse/WICKET-4893

GroupBox / TitledBorder in JavaFX 2?

Is there something like a GroupBox or TitledBorder available on JavaFX 2?
Thanks for any hint :-)
Unless you need the custom styling in this answer, I prefer the TitledPane with setCollapsible(false) solution by Andriy Kryvtsun. For use, see a TitledPane tutorial.
No such exact standard control, but it it is easy to create your own. Here is a sample implementation:
/** Places content in a bordered pane with a title. */
class BorderedTitledPane extends StackPane {
BorderedTitledPane(String titleString, Node content) {
Label title = new Label(" " + titleString + " ");
title.getStyleClass().add("bordered-titled-title");
StackPane.setAlignment(title, Pos.TOP_CENTER);
StackPane contentPane = new StackPane();
content.getStyleClass().add("bordered-titled-content");
contentPane.getChildren().add(content);
getStyleClass().add("bordered-titled-border");
getChildren().addAll(title, contentPane);
}
}
And the accompanying css for it:
.label {
-fx-font: 28px Vivaldi;
}
.bordered-titled-title {
-fx-background-color: white;
-fx-translate-y: -16;
}
.bordered-titled-border {
-fx-content-display: top;
-fx-border-insets: 20 15 15 15;
-fx-background-color: white;
-fx-border-color: black;
-fx-border-width: 2;
}
.bordered-titled-content {
-fx-padding: 26 10 10 10;
}
The code is from a example I created in response to an Oracle JavaFX forum thread post "Equivalent to BorderFactory.createTitledBorder".
The output of the example program is as shown below.
I used TitledPane with setCollapsible(false). It looks more consistent than using CSS styles. Here is result
FXML version of jewelsea's answer:
TitledBorder (I renamed the BorderedTitledPane to TitledBorder)
package com.example.controls;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
public class TitledBorder extends StackPane
{
private Label titleLabel = new Label();
private StackPane contentPane = new StackPane();
private Node content;
public void setContent(Node content)
{
content.getStyleClass().add("bordered-titled-content");
contentPane.getChildren().add(content);
}
public Node getContent()
{
return content;
}
public void setTitle(String title)
{
titleLabel.setText(" " + title + " ");
}
public String getTitle()
{
return titleLabel.getText();
}
public TitledBorder()
{
titleLabel.setText("default title");
titleLabel.getStyleClass().add("bordered-titled-title");
StackPane.setAlignment(titleLabel, Pos.TOP_CENTER);
getStyleClass().add("bordered-titled-border");
getChildren().addAll(titleLabel, contentPane);
}
}
FXML usage:
<?import com.example.controls.*?>
<TitledBorder title="title" >
<Label text="label with text" />
</TitledBorder>
Do no forget the Stylesheet!
Use this CSS for a normal font:
.bordered-titled-title {
-fx-background-color: white;
-fx-translate-y: -10; /* play around with this value when changing the title font to get a vertically centered title */
}
.bordered-titled-border {
-fx-content-display: top;
-fx-border-insets: 20 15 15 15;
-fx-background-color: white;
-fx-border-color: black;
-fx-border-width: 2;
}
.bordered-titled-content {
-fx-padding: 26 10 10 10;
}
Using this CSS it now looks like this:
Update:
Problems when title is longer then content:
Any hint to fix this problem?
Here is an FXML document that can be loaded into SceneBuilder which has similar functionality:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane style="-fx-border-insets: 8 0 0 0; -fx-background-color: #FFFFFF; -fx-border-color: black;">
<children>
<Label alignment="TOP_LEFT" layoutX="14.0" style="-fx-padding: 0 5; -fx-background-color: inherit;" text="Title" />
<AnchorPane prefHeight="200.0" prefWidth="200.0" AnchorPane.bottomAnchor="1.0" AnchorPane.leftAnchor="1.0" AnchorPane.rightAnchor="1.0" AnchorPane.topAnchor="10.0" />
</children>
</AnchorPane>
If you need to make the label text / border size larger you should only have to edit the CSS and the topAnchor of the child AnchorPane and the first argument of -fx-border-insets of the parent AnchorPane.
GroupBox - that is usual Group layout, as far as I see.
TitledBorder - looks like a TitledPane (which is usually a component of Accordion, but could be a separately existing control).
JavaFX-2 analogs looks different from yours (but not significantly), and as usual, you can use different ways of control appearance changing: css, control's skin replacing, etc
Here is a GroupBox implementation based on TitledPane. It provides three methods to set the title, content, and content padding of the GroupBox.
public final class GroupBox extends Parent {
private StackPane _stackPane;
private TitledPane _titledPane;
public GroupBox() {
_stackPane = new StackPane();
_titledPane = new TitledPane();
setContentPadding(new Insets(10));
_titledPane.setCollapsible(false);
_titledPane.setContent(_stackPane);
super.getChildren().add(_titledPane);
}
public GroupBox(String title, Node content) {
this();
setText(title);
setContent(content);
}
public GroupBox(String title, Node content, Insets contentPadding) {
this(title, content);
setContentPadding(contentPadding);
}
public void setText(String value) {
_titledPane.setText(value);
}
public void setContent(Node node) {
_stackPane.getChildren().add(node);
}
public void setContentPadding(Insets value) {
_stackPane.setPadding(value);
}
}

Resources