blob: 747c1c6f7a3487e6e1528a4482142de65679d719 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'package:html_shim/html.dart';
import 'package:meta/meta.dart';
import 'html_elements.dart';
import 'html_icon_renderer.dart';
import 'icons.dart';
class PSelect extends CoreElement {
PSelect() : super('select', classes: 'form-select');
void small() => clazz('select-sm');
void option(String name, {String value}) {
final CoreElement e = CoreElement('option', text: name);
if (value != null) {
final OptionElement optionElement = e.element;
optionElement.value = value;
}
add(e);
}
String get value {
final SelectElement selectElement = element;
return selectElement.value;
}
set selectedIndex(int index) {
final SelectElement selectedElement = element;
selectedElement.selectedIndex = index;
}
Stream<Event> get onChange => element.onChange.where((_) => !disabled);
/// Subscribe to the [onChange] event stream with a no-arg handler.
StreamSubscription<Event> change(void handle()) {
return onChange.listen((Event e) {
e.stopImmediatePropagation();
handle();
});
}
}
class PTooltip {
static void add(CoreElement element, String text) {
element.toggleClass('tooltipped', true);
element.toggleClass('tooltipped-nw', true);
element.setAttribute('aria-label', text);
}
static void remove(CoreElement element) {
element.toggleClass('tooltipped', false);
element.toggleClass('tooltipped-nw', false);
element.toggleAttribute('aria-label', false);
}
}
class PButton extends CoreElement {
PButton([String text]) : super('button', text: text, classes: 'btn') {
setAttribute('type', 'button');
}
PButton.octicon(String text, {@required String icon})
: super('button', classes: 'btn optional-text') {
tooltip = text;
add(<CoreElement>[
span(c: 'octicon octicon-$icon'),
span(c: 'optional-text', text: text),
]);
small();
}
PButton.icon(String text, DevToolsIcon icon,
{String title, List<String> classes})
: super('button', classes: 'btn optional-text') {
setAttribute('type', 'button');
setAttribute('title', title ?? text);
classes?.forEach(clazz);
if (icon != null) {
_icon = icon;
add(createIconElement(icon));
if (text != null) {
add(span(text: text));
}
} else {
element.text = text;
}
}
DevToolsIcon _icon;
void changeIcon(String url) {
if (_icon != null) {
element.children.first.style.backgroundImage = 'url("$url")';
}
}
void primary() => clazz('btn-primary');
void small() => clazz('btn-sm');
}
class PFlash extends CoreElement {
PFlash({String text}) : super('div', classes: 'flash', text: text);
void warning() {
clazz('flash-warn');
}
void error() {
clazz('flash-error');
}
CoreElement addClose() {
return add(span(c: 'octicon octicon-x flash-close js-flash-close'));
}
}
/// A tabbed container (ala Chrome tabs).
class PTabNav extends CoreElement {
PTabNav(List<PTabNavTab> tabs) : super('div', classes: 'tabnav') {
final CoreElement nav = add(CoreElement('nav', classes: 'tabnav-tabs'));
nav.add(tabs);
if (tabs.isNotEmpty) {
selectTab(tabs.first);
}
for (PTabNavTab tab in tabs) {
tab.click(() {
selectTab(tab);
});
}
}
final StreamController<PTabNavTab> _selectedTabController =
StreamController<PTabNavTab>.broadcast();
Stream<PTabNavTab> get onTabSelected => _selectedTabController.stream;
PTabNavTab selectedTab;
void selectTab(PTabNavTab tab) {
selectedTab?.toggleClass('selected', false);
selectedTab = tab;
selectedTab?.toggleClass('selected', true);
_selectedTabController.add(selectedTab);
}
}
class PTabNavTab extends CoreElement {
PTabNavTab(String name) : super('div', classes: 'tabnav-tab', text: name);
}
/// A menu navigation element - a vertically oriented list of items.
class PNavMenu extends CoreElement {
PNavMenu(
List<CoreElement> items, {
bool supportsSelection = true,
}) : super('nav', classes: 'menu') {
add(items);
if (supportsSelection) {
if (items.isNotEmpty && items.first is PNavMenuItem) {
selectItem(items.first);
}
for (CoreElement item in items) {
if (item is PNavMenuItem) {
item.click(() => selectItem(item));
}
}
}
}
PNavMenuItem selectedItem;
void selectItem(PNavMenuItem item) {
selectedItem?.toggleClass('selected', false);
selectedItem = item;
selectedItem?.toggleClass('selected', true);
}
}
class PNavMenuItem extends CoreElement {
PNavMenuItem(String name) : super('a', classes: 'menu-item', text: name);
}