Break the sidebar out into its own individual component.

This commit is contained in:
Sean Lip
2016-11-15 17:19:01 -08:00
parent c27841f8df
commit 25588fc7bd
7 changed files with 102 additions and 74 deletions

View File

@@ -25,23 +25,23 @@ the main component to be loaded. This will usually be blocklyApp.AppView, but
if you have another component that wraps it, use that one instead.
Customizing the Toolbar and Audio
Customizing the Sidebar and Audio
---------------------------------
The Accessible Blockly workspace comes with a customizable toolbar.
The Accessible Blockly workspace comes with a customizable sidebar.
To customize the toolbar, you will need to declare an ACCESSIBLE_GLOBALS object
To customize the sidebar, you will need to declare an ACCESSIBLE_GLOBALS object
in the global scope that looks like this:
var ACCESSIBLE_GLOBALS = {
mediaPathPrefix: null,
toolbarButtonConfig: []
customSidebarButtons: []
};
The value of mediaPathPrefix should be the location of the accessible/media
folder.
The value of 'toolbarButtonConfig' should be a list of objects, each
representing buttons on the toolbar. Each of these objects should have four
The value of 'customSidebarButtons' should be a list of objects, each
representing buttons on the sidebar. Each of these objects should have five
keys:
- 'text' (the text to display on the button)

View File

@@ -37,6 +37,7 @@ blocklyApp.AppView = ng.core.Component({
<div>
<blockly-toolbox></blockly-toolbox>
<blockly-workspace></blockly-workspace>
<blockly-sidebar></blockly-sidebar>
</div>
<label aria-hidden="true" hidden id="blockly-button">{{'BUTTON'|translate}}</label>
@@ -46,7 +47,7 @@ blocklyApp.AppView = ng.core.Component({
`,
directives: [
blocklyApp.ToolboxComponent, blocklyApp.WorkspaceComponent,
blocklyApp.BlockOptionsModalComponent],
blocklyApp.BlockOptionsModalComponent, blocklyApp.SidebarComponent],
pipes: [blocklyApp.TranslatePipe],
// All services are declared here, so that all components in the
// application use the same instance of the service.

View File

@@ -6,7 +6,7 @@
float: left;
width: 350px;
}
.blocklyToolbarColumn {
.blocklySidebarColumn {
float: left;
margin-left: 10px;
margin-top: 20px;

View File

@@ -0,0 +1,81 @@
/**
* AccessibleBlockly
*
* Copyright 2016 Google Inc.
* https://developers.google.com/blockly/
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Angular2 Component representing the sidebar that is shown next
* to the workspace.
*
* @author sll@google.com (Sean Lip)
*/
blocklyApp.SidebarComponent = ng.core.Component({
selector: 'blockly-sidebar',
template: `
<div class="blocklySidebarColumn">
<div id="blockly-workspace-sidebar" (keydown)="onSidebarKeypress($event)">
<span *ngFor="#buttonConfig of customSidebarButtons">
<button *ngIf="!buttonConfig.isHidden()"
(click)="handleButtonClick(buttonConfig)"
[attr.aria-describedby]="buttonConfig.ariaDescribedBy"
class="blocklyTree blocklySidebarButton">
{{buttonConfig.text}}
</button>
</span>
<button id="clear-workspace" (click)="workspace.clear()"
[attr.aria-disabled]="isWorkspaceEmpty()"
class="blocklyTree blocklySidebarButton">
{{'CLEAR_WORKSPACE'|translate}}
</button>
</div>
</div>
`,
pipes: [blocklyApp.TranslatePipe]
})
.Class({
constructor: [
blocklyApp.NotificationsService, blocklyApp.TreeService,
blocklyApp.UtilsService,
function(_notificationsService, _treeService, _utilsService) {
// ACCESSIBLE_GLOBALS is a global variable defined by the containing
// page. It should contain a key, customSidebarButtons, describing
// additional buttons that should be displayed after the default ones.
// See README.md for details.
this.customSidebarButtons =
ACCESSIBLE_GLOBALS && ACCESSIBLE_GLOBALS.customSidebarButtons ?
ACCESSIBLE_GLOBALS.customSidebarButtons : [];
this.workspace = blocklyApp.workspace;
this.notificationsService = _notificationsService;
this.treeService = _treeService;
this.utilsService = _utilsService;
}
],
handleButtonClick: function(buttonConfig) {
buttonConfig.action();
if (buttonConfig.onClickNotification) {
this.notificationsService.setStatusMessage(
buttonConfig.onClickNotification);
}
},
onSidebarKeypress: function(e) {
this.treeService.onSidebarKeypress(e, document.activeElement.id);
},
isWorkspaceEmpty: function() {
return this.utilsService.isWorkspaceEmpty();
}
});

View File

@@ -49,9 +49,8 @@ blocklyApp.TreeService = ng.core.Class({
getWorkspaceTreeNodes_: function() {
return Array.from(document.querySelectorAll('ol.blocklyWorkspaceTree'));
},
getWorkspaceToolbarButtonNodes_: function() {
return Array.from(document.querySelectorAll(
'button.blocklyWorkspaceToolbarButton'));
getSidebarButtonNodes_: function() {
return Array.from(document.querySelectorAll('button.blocklySidebarButton'));
},
getToolboxWorkspace: function(categoryNode) {
if (categoryNode.attributes && categoryNode.attributes.name) {
@@ -90,7 +89,7 @@ blocklyApp.TreeService = ng.core.Class({
getAllTreeNodes_: function() {
var treeNodes = [this.getToolboxTreeNode_()];
treeNodes = treeNodes.concat(this.getWorkspaceTreeNodes_());
treeNodes = treeNodes.concat(this.getWorkspaceToolbarButtonNodes_());
treeNodes = treeNodes.concat(this.getSidebarButtonNodes_());
return treeNodes;
},
isTopLevelWorkspaceTree: function(treeId) {
@@ -227,7 +226,7 @@ blocklyApp.TreeService = ng.core.Class({
that.setActiveDesc(blockId + 'blockRoot', domNode.id);
}, 100);
},
onWorkspaceToolbarKeypress: function(e, treeId) {
onSidebarKeypress: function(e, treeId) {
if (e.keyCode == 9) {
// Tab key.
var destinationTreeId =

View File

@@ -20,6 +20,7 @@
/**
* @fileoverview Angular2 Component that details how a Blockly.Workspace is
* rendered in AccessibleBlockly.
*
* @author madeeha@google.com (Madeeha Ghori)
*/
@@ -44,73 +45,19 @@ blocklyApp.WorkspaceComponent = ng.core.Component({
</span>
</div>
</div>
<div class="blocklyToolbarColumn">
<div id="blockly-workspace-toolbar" (keydown)="onWorkspaceToolbarKeypress($event)">
<span *ngFor="#buttonConfig of toolbarButtonConfig">
<button *ngIf="!buttonConfig.isHidden()"
(click)="handleButtonClick(buttonConfig)"
[attr.aria-describedby]="buttonConfig.ariaDescribedBy"
class="blocklyTree blocklyWorkspaceToolbarButton">
{{buttonConfig.text}}
</button>
</span>
<button id="clear-workspace" (click)="clearWorkspace()"
[attr.aria-disabled]="isWorkspaceEmpty()"
class="blocklyTree blocklyWorkspaceToolbarButton">
{{'CLEAR_WORKSPACE'|translate}}
</button>
</div>
</div>
`,
directives: [blocklyApp.WorkspaceTreeComponent],
pipes: [blocklyApp.TranslatePipe]
})
.Class({
constructor: [
blocklyApp.NotificationsService, blocklyApp.TreeService,
blocklyApp.UtilsService, blocklyApp.ModalService,
function(
_notificationsService, _treeService, _utilsService, _modalService) {
// ACCESSIBLE_GLOBALS is a global variable defined by the containing
// page. It should contain a key, toolbarButtonConfig, whose
// corresponding value is an Array with two keys: 'text' and 'action'.
// The first is the text to display on the button, and the second is
// the function that gets run when the button is clicked.
this.toolbarButtonConfig =
ACCESSIBLE_GLOBALS && ACCESSIBLE_GLOBALS.toolbarButtonConfig ?
ACCESSIBLE_GLOBALS.toolbarButtonConfig : [];
this.workspace = blocklyApp.workspace;
this.notificationsService = _notificationsService;
this.treeService = _treeService;
this.utilsService = _utilsService;
this.modalService = _modalService;
}
],
isModalShown: function() {
return this.modalService.isModalShown();
},
clearWorkspace: function() {
this.workspace.clear();
},
constructor: [blocklyApp.TreeService, function(_treeService) {
this.treeService = _treeService;
this.workspace = blocklyApp.workspace;
}],
getActiveDescId: function(treeId) {
return this.treeService.getActiveDescId(treeId);
},
handleButtonClick: function(buttonConfig) {
buttonConfig.action();
if (buttonConfig.onClickNotification) {
this.notificationsService.setStatusMessage(
buttonConfig.onClickNotification);
}
},
onWorkspaceToolbarKeypress: function(e) {
this.treeService.onWorkspaceToolbarKeypress(
e, document.activeElement.id);
},
onKeypress: function(e, tree) {
this.treeService.onKeypress(e, tree);
},
isWorkspaceEmpty: function() {
return this.utilsService.isWorkspaceEmpty();
}
});

View File

@@ -31,6 +31,7 @@
<script src="../../accessible/block-options-modal.component.js"></script>
<script src="../../accessible/toolbox-tree.component.js"></script>
<script src="../../accessible/toolbox.component.js"></script>
<script src="../../accessible/sidebar.component.js"></script>
<script src="../../accessible/workspace-tree.component.js"></script>
<script src="../../accessible/workspace.component.js"></script>
<script src="../../accessible/app.component.js"></script>
@@ -76,9 +77,8 @@
var ACCESSIBLE_GLOBALS = {
// Prefix of path to sound files.
mediaPathPrefix: '../../accessible/media/',
// Additional buttons for the workspace toolbar that
// go before the "Clear Workspace" button.
toolbarButtonConfig: []
// Additional buttons for the sidebar.
customSidebarButtons: []
};
document.addEventListener('DOMContentLoaded', function() {
ng.platform.browser.bootstrap(blocklyApp.AppView);