Skip to content
This repository was archived by the owner on Sep 5, 2024. It is now read-only.

Commit c481d5b

Browse files
committed
feat(panel): initial implementation.
1 parent f5af7a1 commit c481d5b

File tree

2 files changed

+412
-0
lines changed

2 files changed

+412
-0
lines changed

src/components/panel/panel.js

Lines changed: 368 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,368 @@
1+
/**
2+
* @ngdoc module
3+
* @name material.components.panel
4+
*/
5+
angular
6+
.module('material.components.panel', [
7+
'material.core'
8+
])
9+
.service('$mdPanel', MdPanelService);
10+
11+
12+
/***************************************************************************************
13+
* PUBLIC DOCUMENTATION *
14+
***************************************************************************************/
15+
16+
/**
17+
* @ngdoc service
18+
* @name $mdPanel
19+
* @module material.components.panel
20+
*
21+
* @description
22+
* `$mdPanel` is a robust, low-level service for creating floating panels on
23+
* the screen. It can be used to implement tooltips, dialogs, pop-ups, etc.
24+
*
25+
* @usage
26+
* <hljs lang="js">
27+
* (function(angular, undefined) {
28+
* ‘use strict’;
29+
*
30+
* angular
31+
* .module('demoApp', ['ngMaterial'])
32+
* .controller('DemoDialogController', DialogController);
33+
*
34+
* var panelRef;
35+
*
36+
* function showPanel($event) {
37+
* var panelPosition = $mdPanelPosition
38+
* .absolute()
39+
* .top('50%')
40+
* .left('50%');
41+
*
42+
* var panelAnimation = $mdPanelAnimation
43+
* .targetEvent($event)
44+
* .defaultAnimation('md-panel-animate-fly')
45+
* .closeTo('.show-button');
46+
*
47+
* var config = {
48+
* attachTo: angular.element(document.body),
49+
* controller: DialogController,
50+
* controllerAs: 'ctrl',
51+
* position: panelPosition,
52+
* animation: panelAnimation,
53+
* targetEvent: $event,
54+
* template: 'dialog-template.html',
55+
* clickOutsideToClose: true,
56+
* escapeToClose: true,
57+
* focusOnOpen: true
58+
* }
59+
* panelRef = $mdPanel.create(config);
60+
* panelRef.open()
61+
* .finally(function() {
62+
* panelRef = undefined;
63+
* });
64+
* }
65+
*
66+
* function DialogController($mdPanelRef, toppings) {
67+
* var toppings;
68+
*
69+
* function closeDialog() {
70+
* $mdPanelRef.close();
71+
* }
72+
* }
73+
* })(angular);
74+
* </hljs>
75+
*/
76+
77+
/**
78+
* @ngdoc method
79+
* @name $mdPanel#create
80+
* @description
81+
* Creates a panel with the specified options.
82+
*
83+
* @param opt_config {Object=} Specific configuration object that may contain the
84+
* following properties:
85+
*
86+
* N/A
87+
*
88+
* TODO(ErinCoughlan): Add the following config options.
89+
* - `groupName` - `{string=}`: Name of panel groups. This group name is used for
90+
* configuring the number of open panels and identifying specific behaviors for
91+
* groups. For instance, all tooltips will be identified using the same groupName.
92+
* - `template` - `{string=}`: HTML template to show in the dialog. This **must** be
93+
* trusted HTML with respect to Angular’s
94+
* [$sce service](https://docs.angularjs.org/api/ng/service/$sce).
95+
* - `templateUrl` - `{string=}`: The URL that will be used as the content of
96+
* the panel.
97+
* - `controller` - `{(function|string)=}`: The controller to associate with the
98+
* panel. The controller can inject a reference to the returned
99+
* panelRef, which allows the panel to be closed, hidden, and shown.
100+
* Any fields passed in through locals or resolve will be bound to the controller.
101+
* - `controllerAs` - `{string=}`: An alias to assign the controller to on the
102+
* scope.
103+
* - `locals` - `{Object=}`: An object containing key/value pairs. The keys will be
104+
* used as names of values to inject into the controller. For example,
105+
* `locals: {three: 3}` would inject `three` into the controller, with the value
106+
* 3.
107+
* - `resolve` - `{Object=}`: Similar to locals, except it takes promises as
108+
* values. The panel will not open until all of the promises resolve.
109+
* - `attachTo` - `{Element=}`: The element to attach the panel to. Defaults to
110+
* appending to the root element of the application.
111+
* - `position` - `{$mdPanelPosition=}`: An $mdPanelPosition object that specifies
112+
* the alignment of the panel. For more information, see $mdPanelPosition.
113+
* - `animation` - `{$mdPanelAnimation=}`: An $mdPanelAnimation object that specifies
114+
* the animation of the panel. For more information, see $mdPanelAnimation.
115+
* - `hasBackdrop` - `{boolean=}`: Whether there should be an opaque backdrop behind
116+
* the panel. Defaults to false.
117+
* - `escapeToClose` - `{boolean=}`: Whether the user can press escape to close the
118+
* panel. Defaults to false.
119+
* - `clickOutsideToClose` - `{boolean=}`: Whether the user can click outside the
120+
* panel to close it. Defaults to false.
121+
* - `disableParentScroll` - `{boolean=}`: Whether the user can scroll the page
122+
* behind the panel. Defaults to false.
123+
* - `fullScreen` - `{boolean=}`: Whether the panel should be full screen. Applies
124+
* the class `.md-panel-fullscreen` to the panel on open. Defaults to false.
125+
* - `trapFocus` - `{boolean=}`: Whether focus should be trapped within the panel.
126+
* If `trapFocus` is true, the user will not be able to interact with the rest of
127+
* the page until the panel is dismissed. Defaults to false.
128+
* - `focusOnOpen` - `{boolean=}`: An option to override focus behavior on open.
129+
* Only disable if focusing some other way, as focus management is required for
130+
* panels to be accessible. Defaults to true.
131+
*
132+
* @returns {$mdPanelRef} panelRef
133+
*/
134+
135+
/**
136+
* @ngdoc method
137+
* @name $mdPanel#setGroupMaxOpen
138+
* @description
139+
* Sets the maximum number of panels in a group that can be opened at a given time.
140+
*
141+
* @param groupName {string} The name of the group to configure.
142+
* @param maxOpen {number} The max number of panels that can be opened.
143+
*/
144+
145+
146+
/***************************************************************************************
147+
* $mdPanelRef *
148+
***************************************************************************************/
149+
150+
151+
/**
152+
* @ngdoc object
153+
* @name $mdPanelRef
154+
* @description
155+
* A reference to a created panel. This reference contains a unique id for the panel,
156+
* along with the following properties:
157+
* - `id` - `{string}: The unique id for the panel. This id is used to track when
158+
* a panel was interacted with.
159+
* - `config` - `{Object=}`: The entire config object that was used in create.
160+
*
161+
* TODO(ErinCoughlan): Add the following properties.
162+
* - `isOpen` - `{boolean}`: Whether the panel is attached to the DOM. Visibility
163+
* to the user does not factor into isOpen.
164+
* - `isHidden` - `{boolean}`: Whether the panel is attached to the DOM, but not
165+
* visible to the user.
166+
* - `onDomAdded` - `{function=}`: Callback function used to announce when the
167+
* panel is added to the DOM.
168+
* - `onOpenComplete` - `{function=}`: Callback function used to announce when the
169+
* open() action is finished.
170+
* - `onRemoving` - `{function=}`: Callback function used to announce the
171+
* close/hide() action is starting. This allows developers to run custom
172+
* animations in parallel the close animations.
173+
*/
174+
175+
/**
176+
* @ngdoc method
177+
* @name $mdPanelRef#open
178+
* @description
179+
* If the panel is not visible, opens an already created and configured panel.
180+
*
181+
* @returns {angular.$q.Promise} A promise that is resolved when the panel is closed.
182+
*/
183+
184+
/**
185+
* @ngdoc method
186+
* @name $mdPanelRef#close
187+
* @description
188+
* If the panel is visible, closes the panel, resolving the promise that is returned
189+
* from `$mdPanelRef#open`. This method destroys the reference to the panel. In order
190+
* to open the panel again, a new one must be created.
191+
*/
192+
193+
194+
/***************************************************************************************
195+
* $mdPanelPosition *
196+
***************************************************************************************/
197+
198+
199+
/**
200+
* @ngdoc object
201+
* @name $mdPanelPosition
202+
* @description
203+
* Object for configuring the position of the panel. Examples:
204+
*
205+
* Centering the panel:
206+
* `$mdPanelPosition.absolute().top(‘50%’).left(‘50%’);`
207+
*
208+
* Overlapping the panel with an element:
209+
* `$mdPanelPosition.relativeTo(someElement).top(‘0’).left(‘0’);`
210+
*
211+
* Aligning the panel with the bottom of an element:
212+
* `$mdPanelPosition.relativeTo(someElement);`
213+
*/
214+
215+
/**
216+
* @ngdoc method
217+
* @name $mdPanelPosition#absolute
218+
* @description
219+
* Positions the panel absolutely relative to the parent element. If the parent is
220+
* document.body, this is equivalent to positioning the panel absolutely within the
221+
* viewport.
222+
* @returns {$mdPanelPosition}
223+
*/
224+
225+
/**
226+
* @ngdoc method
227+
* @name $mdPanelPosition#relativeTo
228+
* @description
229+
* Positions the panel relative to a specific element.
230+
* @param {!angular.JQLite} element Element to position the panel with respect to.
231+
* @returns {$mdPanelPosition}
232+
*/
233+
234+
/**
235+
* @ngdoc method
236+
* @name $mdPanelPosition#top
237+
* @description
238+
* Sets the value of `top` for the panel.
239+
* @param {string} top Value of `top`.
240+
* @returns {$mdPanelPosition}
241+
*/
242+
243+
/**
244+
* @ngdoc method
245+
* @name $mdPanelPosition#bottom
246+
* @description
247+
* Sets the value of `bottom` for the panel.
248+
* @param {string} top Value of `bottom`.
249+
* @returns {$mdPanelPosition}
250+
*/
251+
252+
/**
253+
* @ngdoc method
254+
* @name $mdPanelPosition#left
255+
* @description
256+
* Sets the value of `left` for the panel.
257+
* @param {string} top Value of `left`.
258+
* @returns {$mdPanelPosition}
259+
*/
260+
261+
/**
262+
* @ngdoc method
263+
* @name $mdPanelPosition#right
264+
* @description
265+
* Sets the value of `right` for the panel.
266+
* @param {string} top Value of `right`.
267+
* @returns {$mdPanelPosition}
268+
*/
269+
270+
/**
271+
* @ngdoc method
272+
* @name $mdPanelPosition#offsetX
273+
* @description
274+
* Sets the value of the offset in the x-direction.
275+
* @param {string} offsetX
276+
* @returns {$mdPanelPosition}
277+
*/
278+
279+
/**
280+
* @ngdoc method
281+
* @name $mdPanelPosition#offsetY
282+
* @description
283+
* Sets the value of the offset in the y-direction.
284+
* @param {string} offsetY
285+
* @returns {$mdPanelPosition}
286+
*/
287+
288+
289+
/***************************************************************************************
290+
* IMPLEMENTATION *
291+
***************************************************************************************/
292+
293+
294+
/**
295+
* A service that is used for controlling/displaying panels on the screen.
296+
* @param {!angular.JQLite} $rootElement
297+
* @param {!angular.$injector} $injector
298+
* @final @constructor @ngInject
299+
*/
300+
function MdPanelService($rootElement, $injector) {
301+
// Default config options for the panel.
302+
this.defaultConfigOptions_ = {
303+
attachTo: $rootElement
304+
};
305+
306+
this.config_ = this.defaultConfigOptions_;
307+
this.$injector_ = $injector;
308+
}
309+
310+
311+
/**
312+
* Creates a panel with the specified options.
313+
* @param {!Object=} opt_config Configuration object for the panel.
314+
* @returns {!$mdPanelRef}
315+
*/
316+
MdPanelService.prototype.create = function(opt_config) {
317+
var configSettings = opt_config || {};
318+
angular.extend(this.config_, configSettings);
319+
320+
return new MdPanelRef(this.$injector_, this.config_);
321+
};
322+
323+
324+
/**
325+
* A reference to a created panel. This reference contains a unique id for the panel,
326+
* along with properties/functions used to control the panel.
327+
*
328+
* @param {!angular.$injector} $injector
329+
* @param {!Object} config
330+
* @final @constructor
331+
*/
332+
function MdPanelRef($injector, config) {
333+
// Injected variables.
334+
this.$mdUtil_ = $injector.get('$mdUtil');
335+
this.$q_ = $injector.get('$q');
336+
337+
// Public variables.
338+
this.config = config;
339+
this.id = 'panel_' + this.$mdUtil_.nextUid();
340+
this.isOpen = false;
341+
342+
// Private variables.
343+
this.openPromise_;
344+
}
345+
346+
347+
/**
348+
* Opens an already created and configured panel. If the panel is already visible,
349+
* does nothing.
350+
*
351+
* @returns {!angular.$q.Promise} A promise that is resolved when the panel is closed.
352+
*/
353+
MdPanelRef.prototype.open = function() {
354+
this.openPromise_ = this.$q_.defer();
355+
this.isOpen = true;
356+
return this.openPromise_.promise;
357+
};
358+
359+
360+
/**
361+
* Closes the panel.
362+
*/
363+
MdPanelRef.prototype.close = function() {
364+
if (this.isOpen) {
365+
this.isOpen = false;
366+
this.openPromise_.resolve(true);
367+
}
368+
};

0 commit comments

Comments
 (0)