| <!-- |
| // Copyright 2015 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 src="sky-element.sky" /> |
| <import src="sky-icon.sky" /> |
| |
| <sky-element attributes="selected:boolean, group:string"> |
| <template> |
| <style> |
| :host { |
| display: inline-block; |
| -webkit-user-select: none; |
| margin: 8px 16px; |
| } |
| </style> |
| <sky-icon size="18" /> |
| </template> |
| <script> |
| import "dart:sky"; |
| |
| final Map<Node, _RadioGroupController> _controllerMap = new Map(); |
| |
| class _RadioGroupController { |
| static _RadioGroupController forRadio(radio) { |
| Node owner = radio.owner; |
| return _controllerMap.putIfAbsent(owner, () => |
| new _RadioGroupController(owner)); |
| } |
| |
| final Node _scope; |
| final Set<SkyRadio> _radios = new Set<SkyRadio>(); |
| |
| _RadioGroupController(this._scope); |
| |
| void addRadio(SkyRadio radio) { |
| _radios.add(radio); |
| // If this new radio is default-selected, take selection from the group. |
| if (radio.selected) |
| takeSelectionFromGroup(radio); |
| } |
| |
| void removeRadio(SkyRadio radio) { |
| _radios.remove(radio); |
| if (_radios.isEmpty) |
| _controllerMap.remove(_scope); |
| } |
| |
| void takeSelectionFromGroup(SkyRadio selectedRadio) { |
| String group = selectedRadio.group; |
| if (group == null) |
| return; |
| _radios.forEach((SkyRadio radio) { |
| if (selectedRadio == radio) |
| return; |
| if (radio.group != group) |
| return; |
| radio.selected = false; |
| }); |
| } |
| } |
| |
| const String _kOnIcon = 'toggle/radio_button_on_black'; |
| const String _kOffIcon = 'toggle/radio_button_off_black'; |
| |
| @Tagname('sky-radio') |
| class SkyRadio extends SkyElement { |
| _RadioGroupController _controller; |
| SkyIcon _icon; |
| |
| SkyRadio() { |
| addEventListener('click', _handleClick); |
| } |
| |
| void shadowRootReady() { |
| _icon = shadowRoot.querySelector('sky-icon'); |
| _icon.type = selected ? _kOnIcon : _kOffIcon; |
| } |
| |
| void attached() { |
| super.attached(); |
| _controller = _RadioGroupController.forRadio(this); |
| _controller.addRadio(this); |
| } |
| |
| void detached() { |
| super.detached(); |
| _controller.removeRadio(this); |
| _controller = null; |
| } |
| |
| void selectedChanged(bool oldValue, bool newValue) { |
| if (_icon != null) |
| _icon.type = newValue ? _kOnIcon : _kOffIcon; |
| if (newValue && _controller != null) |
| _controller.takeSelectionFromGroup(this); |
| } |
| |
| void groupChanged(String oldValue, String newValue) { |
| if (selected && _controller != null) |
| _controller.takeSelectionFromGroup(this); |
| } |
| |
| _handleClick(_) { |
| this.selected = true; |
| } |
| } |
| |
| _init(script) => register(script, SkyRadio); |
| </script> |
| </sky-element> |