@brightspace-ui/core 2.98.6 → 2.99.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/collapsible-panel/collapsible-panel.js +1 -1
- package/components/expand-collapse/README.md +3 -29
- package/components/filter/filter-tags.js +4 -4
- package/components/filter/filter.js +5 -9
- package/components/list/list-item-expand-collapse-mixin.js +1 -1
- package/components/list/list-item-mixin.js +5 -2
- package/components/list/list.js +4 -9
- package/components/more-less/README.md +27 -2
- package/controllers/subscriber/README.md +28 -42
- package/controllers/subscriber/subscriberControllers.js +74 -53
- package/package.json +1 -1
|
@@ -135,7 +135,7 @@ class CollapsiblePanel extends FocusMixin(RtlMixin(LitElement)) {
|
|
|
135
135
|
box-shadow: 0 8px 12px -9px rgba(0, 0, 0, 0.3);
|
|
136
136
|
position: sticky;
|
|
137
137
|
top: 0;
|
|
138
|
-
z-index:
|
|
138
|
+
z-index: 12; /* must be greater greater than list-items with open dropdowns or tooltips */
|
|
139
139
|
}
|
|
140
140
|
.d2l-collapsible-panel.focused.scrolled .d2l-collapsible-panel-header {
|
|
141
141
|
top: 2px;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
## Expand Collapse Content [d2l-expand-collapse-content]
|
|
1
|
+
# Expand Collapse Content
|
|
4
2
|
|
|
5
3
|
The `d2l-expand-collapse-content` element can be used to create expandable and collapsible content. This component only provides the logic to expand and collapse the content; controlling when and how it expands or collapses is the responsibility of the user.
|
|
6
4
|
|
|
5
|
+
## Expand Collapse Content [d2l-expand-collapse-content]
|
|
6
|
+
|
|
7
7
|
<!-- docs: demo live name:d2l-expand-collapse-content autoSize:false display:block size:small -->
|
|
8
8
|
```html
|
|
9
9
|
<script type="module">
|
|
@@ -40,29 +40,3 @@ The `d2l-expand-collapse-content` element can be used to create expandable and c
|
|
|
40
40
|
|
|
41
41
|
To make your usage of `d2l-expand-collapse-content` accessible, the [`aria-expanded` attribute](https://www.w3.org/TR/wai-aria/#aria-expanded) should be added to the element that controls expanding and collapsing the content with `"true"` or `"false"` to indicate that the content is expanded or collapsed.
|
|
42
42
|
|
|
43
|
-
## More-Less [d2l-more-less]
|
|
44
|
-
|
|
45
|
-
The `d2l-more-less` element can be used to minimize the display of long content, while providing a way to reveal the full content.
|
|
46
|
-
|
|
47
|
-
<!-- docs: demo live name:d2l-more-less -->
|
|
48
|
-
```html
|
|
49
|
-
<script type="module">
|
|
50
|
-
import '@brightspace-ui/core/components/more-less/more-less.js';
|
|
51
|
-
</script>
|
|
52
|
-
<d2l-more-less>
|
|
53
|
-
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
|
|
54
|
-
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
|
|
55
|
-
</d2l-more-less>
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
<!-- docs: start hidden content -->
|
|
59
|
-
### Properties
|
|
60
|
-
|
|
61
|
-
| Property | Type | Description |
|
|
62
|
-
|---|---|---|
|
|
63
|
-
| `blur-color` | String | Gradient HEX formatted color of the blurring effect (defaults to white). |
|
|
64
|
-
| `expanded` | Boolean | Specifies the expanded/collapsed state of the content |
|
|
65
|
-
| `h-align` | String | A value of `text` aligns the leading edge of text |
|
|
66
|
-
| `height` | String, default: `'4em'` | Maximum height of the content when in "less" mode. The `d2l-more-less` element itself will take up additional vertical space for the fading effect as well as the more/less button itself. |
|
|
67
|
-
| `inactive` | Boolean | Whether the component is active or inactive |
|
|
68
|
-
<!-- docs: end hidden content -->
|
|
@@ -36,10 +36,10 @@ class FilterTags extends LocalizeCoreElement(LitElement) {
|
|
|
36
36
|
super();
|
|
37
37
|
|
|
38
38
|
this._allActiveFilters = new Map();
|
|
39
|
-
this._filters = new IdSubscriberController(this,
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
);
|
|
39
|
+
this._filters = new IdSubscriberController(this, 'active-filters', {
|
|
40
|
+
idPropertyName: 'filterIds',
|
|
41
|
+
onUnsubscribe: this._removeLostFilter.bind(this)
|
|
42
|
+
});
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
render() {
|
|
@@ -136,7 +136,7 @@ class Filter extends FocusMixin(LocalizeCoreElement(RtlMixin(LitElement))) {
|
|
|
136
136
|
line-height: unset;
|
|
137
137
|
overflow: hidden;
|
|
138
138
|
}
|
|
139
|
-
|
|
139
|
+
|
|
140
140
|
.d2l-filter-dimension-set-value-text {
|
|
141
141
|
-webkit-box-orient: vertical;
|
|
142
142
|
display: -webkit-box;
|
|
@@ -191,10 +191,10 @@ class Filter extends FocusMixin(LocalizeCoreElement(RtlMixin(LitElement))) {
|
|
|
191
191
|
this._totalAppliedCount = 0;
|
|
192
192
|
|
|
193
193
|
this._activeFilters = null;
|
|
194
|
-
this._activeFiltersSubscribers = new SubscriberRegistryController(this,
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
);
|
|
194
|
+
this._activeFiltersSubscribers = new SubscriberRegistryController(this, 'active-filters', {
|
|
195
|
+
onSubscribe: this._updateActiveFiltersSubscriber.bind(this),
|
|
196
|
+
updateSubscribers: this._updateActiveFiltersSubscribers.bind(this)
|
|
197
|
+
});
|
|
198
198
|
}
|
|
199
199
|
|
|
200
200
|
static get focusElementSelector() {
|
|
@@ -268,10 +268,6 @@ class Filter extends FocusMixin(LocalizeCoreElement(RtlMixin(LitElement))) {
|
|
|
268
268
|
`;
|
|
269
269
|
}
|
|
270
270
|
|
|
271
|
-
getSubscriberController() {
|
|
272
|
-
return this._activeFiltersSubscribers;
|
|
273
|
-
}
|
|
274
|
-
|
|
275
271
|
requestFilterClearAll() {
|
|
276
272
|
this._handleClearAll();
|
|
277
273
|
}
|
|
@@ -76,7 +76,7 @@ export const ListItemExpandCollapseMixin = superclass => class extends superclas
|
|
|
76
76
|
this._siblingHasNestedItems = false;
|
|
77
77
|
this._renderExpandCollapseSlot = false;
|
|
78
78
|
this._showNestedLoadingSpinner = false;
|
|
79
|
-
this._parentChildUpdateSubscription = new EventSubscriberController(this,
|
|
79
|
+
this._parentChildUpdateSubscription = new EventSubscriberController(this, 'list-child-status');
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
connectedCallback() {
|
|
@@ -108,10 +108,13 @@ export const ListItemMixin = superclass => class extends composeMixins(
|
|
|
108
108
|
display: none;
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
-
:host([
|
|
112
|
-
:host([
|
|
111
|
+
:host([_dropdown-open]),
|
|
112
|
+
:host([_focusing]) {
|
|
113
113
|
z-index: 10; /* must be greater than adjacent selected items (if this is increased, d2l-collapsible-panel must be updated too) */
|
|
114
114
|
}
|
|
115
|
+
:host([_tooltip-showing]) {
|
|
116
|
+
z-index: 11; /* must be greater than adjacent selected items (if this is increased, d2l-collapsible-panel must be updated too) */
|
|
117
|
+
}
|
|
115
118
|
:host([_fullscreen-within]) {
|
|
116
119
|
position: fixed; /* required for Safari */
|
|
117
120
|
z-index: 1000; /* must be greater than floating workflow buttons */
|
package/components/list/list.js
CHANGED
|
@@ -69,11 +69,10 @@ class List extends PageableMixin(SelectionMixin(LitElement)) {
|
|
|
69
69
|
this._listItemChanges = [];
|
|
70
70
|
this._childHasExpandCollapseToggle = false;
|
|
71
71
|
|
|
72
|
-
this._listChildrenUpdatedSubscribers = new SubscriberRegistryController(
|
|
73
|
-
this,
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
);
|
|
72
|
+
this._listChildrenUpdatedSubscribers = new SubscriberRegistryController(this, 'list-child-status', {
|
|
73
|
+
onSubscribe: this._updateActiveSubscriber.bind(this),
|
|
74
|
+
updateSubscribers: this._updateActiveSubscribers.bind(this)
|
|
75
|
+
});
|
|
77
76
|
}
|
|
78
77
|
|
|
79
78
|
connectedCallback() {
|
|
@@ -185,10 +184,6 @@ class List extends PageableMixin(SelectionMixin(LitElement)) {
|
|
|
185
184
|
return new SelectionInfo(keys, selectionInfo.state);
|
|
186
185
|
}
|
|
187
186
|
|
|
188
|
-
getSubscriberController() {
|
|
189
|
-
return this._listChildrenUpdatedSubscribers;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
187
|
_getItemByIndex(index) {
|
|
193
188
|
const items = this.getItems();
|
|
194
189
|
if (index > items.length - 1) return;
|
|
@@ -1,3 +1,28 @@
|
|
|
1
|
-
# More
|
|
1
|
+
# More/Less
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The `d2l-more-less` element can be used to minimize the display of long content, while providing a way to reveal the full content.
|
|
4
|
+
|
|
5
|
+
## More-Less [d2l-more-less]
|
|
6
|
+
|
|
7
|
+
<!-- docs: demo live name:d2l-more-less -->
|
|
8
|
+
```html
|
|
9
|
+
<script type="module">
|
|
10
|
+
import '@brightspace-ui/core/components/more-less/more-less.js';
|
|
11
|
+
</script>
|
|
12
|
+
<d2l-more-less>
|
|
13
|
+
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
|
|
14
|
+
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
|
|
15
|
+
</d2l-more-less>
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
<!-- docs: start hidden content -->
|
|
19
|
+
### Properties
|
|
20
|
+
|
|
21
|
+
| Property | Type | Description |
|
|
22
|
+
|---|---|---|
|
|
23
|
+
| `blur-color` | String | Gradient HEX formatted color of the blurring effect (defaults to white). |
|
|
24
|
+
| `expanded` | Boolean | Specifies the expanded/collapsed state of the content |
|
|
25
|
+
| `h-align` | String | A value of `text` aligns the leading edge of text |
|
|
26
|
+
| `height` | String, default: `'4em'` | Maximum height of the content when in "less" mode. The `d2l-more-less` element itself will take up additional vertical space for the fading effect as well as the more/less button itself. |
|
|
27
|
+
| `inactive` | Boolean | Whether the component is active or inactive |
|
|
28
|
+
<!-- docs: end hidden content -->
|
|
@@ -12,29 +12,19 @@ import { SubscriberRegistryController } from '@brightspace-ui/core/controllers/s
|
|
|
12
12
|
class CableSubscription extends LitElement {
|
|
13
13
|
constructor() {
|
|
14
14
|
super();
|
|
15
|
-
this._sportsSubscribers = new SubscriberRegistryController(this,
|
|
16
|
-
{ onSubscribe: this._unlockSportsChannels.bind(this) },
|
|
17
|
-
{ eventName: 'd2l-channels-subscribe-sports' }
|
|
18
|
-
);
|
|
19
|
-
|
|
20
|
-
this._movieSubscribers = new SubscriberRegistryController(this, {},
|
|
21
|
-
{ onSubscribe: this._unlockMovieChannels.bind(this), updateSubscribers: this._sendMovieGuide.bind(this) },
|
|
22
|
-
{ eventName: 'd2l-channels-subscribe-movies' }
|
|
23
|
-
);
|
|
24
|
-
|
|
25
|
-
// This controller only supports registering by id - no event is needed
|
|
26
|
-
this._kidsChannelSubscribers = new SubscriberRegistryController(this,
|
|
27
|
-
{ onSubscribe: this._unlockKidsChannels.bind(this) }, {});
|
|
28
|
-
}
|
|
29
15
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
16
|
+
this._sportsSubscribers = new SubscriberRegistryController(this, 'channels-sports', {
|
|
17
|
+
onSubscribe: this._unlockSportsChannels.bind(this)
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
this._movieSubscribers = new SubscriberRegistryController(this, 'channels-movies', {
|
|
21
|
+
onSubscribe: this._unlockMovieChannels.bind(this),
|
|
22
|
+
updateSubscribers: this._sendMovieGuide.bind(this)
|
|
37
23
|
}
|
|
24
|
+
|
|
25
|
+
this._kidsChannelSubscribers = new SubscriberRegistryController(this, 'channels-kids', {
|
|
26
|
+
onSubscribe: this._unlockKidsChannels.bind(this)
|
|
27
|
+
});
|
|
38
28
|
}
|
|
39
29
|
|
|
40
30
|
_sendMovieGuide(subscribers) {
|
|
@@ -49,15 +39,13 @@ class CableSubscription extends LitElement {
|
|
|
49
39
|
}
|
|
50
40
|
```
|
|
51
41
|
|
|
52
|
-
When creating the controller, you
|
|
53
|
-
|
|
54
|
-
The `*subscriberController`s will use a `getSubscriberController` method that needs to be exposed on the registry component. If you only have one `SubscriberRegistryController` you can simple return that. If you have multiple, you will return the proper controller depending on the id the subscriber component passed to you.
|
|
42
|
+
When creating the controller, you must provide a unique name for the subscription (e.g. `'channels-sports'`). You may also pass in an optional `updateSubscribers` callback (invoked by calling `.updateSubscribers` on the controller, with built-in debouncing), and lifecycle callbacks to run whenever a subscriber is added (`onSubscribe`) or removed (`onUnsubscribe`).
|
|
55
43
|
|
|
56
44
|
Once this has been set up, components can subscribe to particular registries two different ways:
|
|
57
|
-
1. Using
|
|
58
|
-
2.
|
|
45
|
+
1. Using `EventSubscriberController` with the target subscription name. The component will need to be a child of the registry component for this to work.
|
|
46
|
+
2. Using `IdSubscriberController` with the target subscription name and the `idPropertyName` option, which will point to the registry component's id. The component will need to be in the same DOM scope as the registry component for this to work.
|
|
59
47
|
|
|
60
|
-
Like the `SubscriberRegistryController`, these `*subscriberController`s take optional callbacks
|
|
48
|
+
Like the `SubscriberRegistryController`, these `*subscriberController`s take optional callbacks invoked at different points in the subscription process.
|
|
61
49
|
|
|
62
50
|
```js
|
|
63
51
|
import { EventSubscriberController, IdSubscriberController } from '@brightspace-ui/core/controllers/subscriber/subscriberControllers.js';
|
|
@@ -72,15 +60,12 @@ class GeneralViewer extends LitElement {
|
|
|
72
60
|
constructor() {
|
|
73
61
|
super();
|
|
74
62
|
this._subscribedChannels = new Set();
|
|
75
|
-
|
|
76
|
-
this._sportsSubscription = new EventSubscriberController(this,
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
this._movieSubscription = new EventSubscriberController(this, {},
|
|
82
|
-
{ eventName: 'd2l-channels-subscribe-movies', controllerId: 'movies' }
|
|
83
|
-
);
|
|
63
|
+
|
|
64
|
+
this._sportsSubscription = new EventSubscriberController(this, 'channels-sports', {
|
|
65
|
+
onError: this._onSportsError.bind(this)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
this._movieSubscription = new EventSubscriberController(this, 'channels-movies');
|
|
84
69
|
}
|
|
85
70
|
|
|
86
71
|
addChannels(channels) {
|
|
@@ -106,10 +91,11 @@ class YoungerViewer extends LitElement {
|
|
|
106
91
|
super();
|
|
107
92
|
this._subscribedChannels = new Set();
|
|
108
93
|
|
|
109
|
-
this._kidsSubscription = new IdSubscriberController(this,
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
94
|
+
this._kidsSubscription = new IdSubscriberController(this, 'channels-kids', {
|
|
95
|
+
idPropertyName: 'for',
|
|
96
|
+
onSubscribe: this._onSubscribe.bind(this),
|
|
97
|
+
onUnsubscribe: this._onUnsubscribe.bind(this)
|
|
98
|
+
});
|
|
113
99
|
}
|
|
114
100
|
|
|
115
101
|
addChannels(channels) {
|
|
@@ -129,6 +115,7 @@ class YoungerViewer extends LitElement {
|
|
|
129
115
|
```
|
|
130
116
|
|
|
131
117
|
An example of what this could look like altogether:
|
|
118
|
+
|
|
132
119
|
```html
|
|
133
120
|
<cable-subscription id="rogers">
|
|
134
121
|
<general-viewer></general-viewer>
|
|
@@ -136,13 +123,12 @@ An example of what this could look like altogether:
|
|
|
136
123
|
<younger-viewer for="rogers"></younger-viewer>
|
|
137
124
|
```
|
|
138
125
|
|
|
139
|
-
As of the Lit 2 upgrade, the lifecycle methods `hostConnected`, `hostDisconnected`, and `hostUpdated` will be called automatically.
|
|
140
126
|
## Available Callbacks
|
|
141
127
|
|
|
142
128
|
### SubscriberRegistryController
|
|
143
129
|
| Callback Name | Description | Passed to Callback |
|
|
144
130
|
|---|---|---|
|
|
145
|
-
| `onSubscribe` | Runs whenever a new subscriber is added | Subscriber that was just subscribed |
|
|
131
|
+
| `onSubscribe` | Runs whenever a new subscriber is added | Subscriber that was just subscribed |
|
|
146
132
|
| `onUnsubscribe` | Runs whenever a subscriber is removed | Subscriber that was just unsubscribed |
|
|
147
133
|
| `updateSubscribers` | Runs whenever `updateSubscribers` is called on the controller, handles debouncing requests for you | Map of all current subscribers |
|
|
148
134
|
|
|
@@ -1,14 +1,52 @@
|
|
|
1
1
|
import { cssEscape } from '../../helpers/dom.js';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
class BaseController {
|
|
4
|
+
constructor(host, name, options = {}) {
|
|
5
|
+
if (!host || !name) throw new TypeError('SubscriberController: missing host or subscription name');
|
|
4
6
|
|
|
5
|
-
constructor(host, callbacks, options) {
|
|
6
|
-
this._host = host;
|
|
7
7
|
host.addController(this);
|
|
8
|
-
this.
|
|
9
|
-
this.
|
|
10
|
-
this.
|
|
8
|
+
this._host = host;
|
|
9
|
+
this._name = name;
|
|
10
|
+
this._options = options;
|
|
11
|
+
this._eventName = `d2l-subscribe-${this._name}`;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
class BaseSubscriber extends BaseController {
|
|
16
|
+
_subscribe(target = this._host, targetLabel) {
|
|
17
|
+
const isBroadcast = target === this._host;
|
|
18
|
+
|
|
19
|
+
const options = isBroadcast ? { bubbles: true, composed: true } : {};
|
|
20
|
+
const evt = new CustomEvent(this._eventName, {
|
|
21
|
+
...options,
|
|
22
|
+
detail: { subscriber: this._host }
|
|
23
|
+
});
|
|
24
|
+
target.dispatchEvent(evt);
|
|
25
|
+
|
|
26
|
+
const { registry, registryController } = evt.detail;
|
|
27
|
+
if (!registry) {
|
|
28
|
+
if (this._options.onError) this._options.onError();
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (targetLabel) {
|
|
33
|
+
this._registries.set(targetLabel, registry);
|
|
34
|
+
this._registryControllers.set(targetLabel, registryController);
|
|
35
|
+
} else {
|
|
36
|
+
this._registry = registry;
|
|
37
|
+
this._registryController = registryController;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (this._options.onSubscribe) this._options.onSubscribe(registry);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export class SubscriberRegistryController extends BaseController {
|
|
45
|
+
|
|
46
|
+
constructor(host, name, options) {
|
|
47
|
+
super(host, name, options);
|
|
11
48
|
|
|
49
|
+
this._subscribers = new Map();
|
|
12
50
|
this._handleSubscribe = this._handleSubscribe.bind(this);
|
|
13
51
|
}
|
|
14
52
|
|
|
@@ -27,24 +65,24 @@ export class SubscriberRegistryController {
|
|
|
27
65
|
subscribe(target) {
|
|
28
66
|
if (this._subscribers.has(target)) return;
|
|
29
67
|
this._subscribers.set(target, target);
|
|
30
|
-
if (this.
|
|
68
|
+
if (this._options.onSubscribe) this._options.onSubscribe(target);
|
|
31
69
|
}
|
|
32
70
|
|
|
33
71
|
unsubscribe(target) {
|
|
34
72
|
this._subscribers.delete(target);
|
|
35
|
-
if (this.
|
|
73
|
+
if (this._options.onUnsubscribe) this._options.onUnsubscribe(target);
|
|
36
74
|
}
|
|
37
75
|
|
|
38
76
|
updateSubscribers() {
|
|
39
77
|
if (!this._subscribers || this._subscribers.size === 0) return;
|
|
40
|
-
if (!this.
|
|
78
|
+
if (!this._options.updateSubscribers) return;
|
|
41
79
|
|
|
42
80
|
// debounce the updates
|
|
43
81
|
if (this._updateSubscribersRequested) return;
|
|
44
82
|
|
|
45
83
|
this._updateSubscribersRequested = true;
|
|
46
84
|
setTimeout(() => {
|
|
47
|
-
this.
|
|
85
|
+
this._options.updateSubscribers(this._subscribers);
|
|
48
86
|
this._updateSubscribersRequested = false;
|
|
49
87
|
}, 0);
|
|
50
88
|
}
|
|
@@ -52,20 +90,19 @@ export class SubscriberRegistryController {
|
|
|
52
90
|
_handleSubscribe(e) {
|
|
53
91
|
e.stopPropagation();
|
|
54
92
|
e.detail.registry = this._host;
|
|
55
|
-
|
|
93
|
+
e.detail.registryController = this;
|
|
94
|
+
const target = e.detail.subscriber;
|
|
56
95
|
this.subscribe(target);
|
|
57
96
|
}
|
|
58
97
|
}
|
|
59
98
|
|
|
60
|
-
export class EventSubscriberController {
|
|
99
|
+
export class EventSubscriberController extends BaseSubscriber {
|
|
100
|
+
|
|
101
|
+
constructor(host, name, options) {
|
|
102
|
+
super(host, name, options);
|
|
61
103
|
|
|
62
|
-
constructor(host, callbacks, options) {
|
|
63
|
-
this._host = host;
|
|
64
|
-
host.addController(this);
|
|
65
|
-
this._callbacks = callbacks || {};
|
|
66
|
-
this._eventName = options && options.eventName;
|
|
67
|
-
this._controllerId = options && options.controllerId;
|
|
68
104
|
this._registry = null;
|
|
105
|
+
this._registryController = null;
|
|
69
106
|
}
|
|
70
107
|
|
|
71
108
|
get registry() {
|
|
@@ -74,39 +111,24 @@ export class EventSubscriberController {
|
|
|
74
111
|
|
|
75
112
|
hostConnected() {
|
|
76
113
|
// delay subscription otherwise import/upgrade order can cause selection mixin to miss event
|
|
77
|
-
requestAnimationFrame(() =>
|
|
78
|
-
const evt = new CustomEvent(this._eventName, {
|
|
79
|
-
bubbles: true,
|
|
80
|
-
composed: true,
|
|
81
|
-
detail: {}
|
|
82
|
-
});
|
|
83
|
-
this._host.dispatchEvent(evt);
|
|
84
|
-
this._registry = evt.detail.registry;
|
|
85
|
-
|
|
86
|
-
if (!this._registry) {
|
|
87
|
-
if (this._callbacks.onError) this._callbacks.onError();
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
if (this._callbacks.onSubscribe) this._callbacks.onSubscribe(this._registry);
|
|
91
|
-
});
|
|
114
|
+
requestAnimationFrame(() => this._subscribe());
|
|
92
115
|
}
|
|
93
116
|
|
|
94
117
|
hostDisconnected() {
|
|
95
|
-
if (this.
|
|
118
|
+
if (this._registryController) this._registryController.unsubscribe(this._host);
|
|
96
119
|
}
|
|
97
120
|
|
|
98
121
|
}
|
|
99
122
|
|
|
100
|
-
export class IdSubscriberController {
|
|
123
|
+
export class IdSubscriberController extends BaseSubscriber {
|
|
124
|
+
|
|
125
|
+
constructor(host, name, options) {
|
|
126
|
+
super(host, name, options);
|
|
101
127
|
|
|
102
|
-
constructor(host, callbacks, options) {
|
|
103
|
-
this._host = host;
|
|
104
|
-
host.addController(this);
|
|
105
|
-
this._callbacks = callbacks || {};
|
|
106
128
|
this._idPropertyName = options && options.idPropertyName;
|
|
107
129
|
this._idPropertyValue = this._idPropertyName ? this._host[this._idPropertyName] : undefined;
|
|
108
|
-
this._controllerId = options && options.controllerId;
|
|
109
130
|
this._registries = new Map();
|
|
131
|
+
this._registryControllers = new Map();
|
|
110
132
|
this._timeouts = new Set();
|
|
111
133
|
}
|
|
112
134
|
|
|
@@ -117,8 +139,8 @@ export class IdSubscriberController {
|
|
|
117
139
|
hostDisconnected() {
|
|
118
140
|
if (this._registryObserver) this._registryObserver.disconnect();
|
|
119
141
|
this._timeouts.forEach(timeoutId => clearTimeout(timeoutId));
|
|
120
|
-
this.
|
|
121
|
-
|
|
142
|
+
this._registryControllers.forEach(controller => {
|
|
143
|
+
controller.unsubscribe(this._host);
|
|
122
144
|
});
|
|
123
145
|
}
|
|
124
146
|
|
|
@@ -129,11 +151,12 @@ export class IdSubscriberController {
|
|
|
129
151
|
this._idPropertyValue = propertyValue;
|
|
130
152
|
|
|
131
153
|
if (this._registryObserver) this._registryObserver.disconnect();
|
|
132
|
-
this.
|
|
133
|
-
|
|
134
|
-
if (this.
|
|
154
|
+
this._registryControllers.forEach((controller, key) => {
|
|
155
|
+
controller.unsubscribe(this._host);
|
|
156
|
+
if (this._options.onUnsubscribe) this._options.onUnsubscribe(key);
|
|
135
157
|
});
|
|
136
158
|
this._registries = new Map();
|
|
159
|
+
this._registryControllers = new Map();
|
|
137
160
|
|
|
138
161
|
this._updateRegistries();
|
|
139
162
|
|
|
@@ -159,7 +182,7 @@ export class IdSubscriberController {
|
|
|
159
182
|
|
|
160
183
|
_updateRegistry(registryId, elapsedTime) {
|
|
161
184
|
let registryComponent = this._host.getRootNode().querySelector(`#${cssEscape(registryId)}`);
|
|
162
|
-
if (!registryComponent && this.
|
|
185
|
+
if (!registryComponent && this._options.onError) {
|
|
163
186
|
if (elapsedTime < 3000) {
|
|
164
187
|
const timeoutId = setTimeout(() => {
|
|
165
188
|
this._timeouts.delete(timeoutId);
|
|
@@ -167,20 +190,18 @@ export class IdSubscriberController {
|
|
|
167
190
|
}, 100);
|
|
168
191
|
this._timeouts.add(timeoutId);
|
|
169
192
|
} else {
|
|
170
|
-
this.
|
|
193
|
+
this._options.onError(registryId);
|
|
171
194
|
}
|
|
172
195
|
}
|
|
173
196
|
|
|
174
197
|
registryComponent = registryComponent || undefined;
|
|
175
198
|
if (this._registries.get(registryId) === registryComponent) return;
|
|
176
199
|
|
|
177
|
-
if (registryComponent)
|
|
178
|
-
|
|
179
|
-
this._registries.set(registryId, registryComponent);
|
|
180
|
-
if (this._callbacks.onSubscribe) this._callbacks.onSubscribe(registryComponent);
|
|
181
|
-
} else {
|
|
200
|
+
if (registryComponent) this._subscribe(registryComponent, registryId);
|
|
201
|
+
else {
|
|
182
202
|
this._registries.delete(registryId);
|
|
183
|
-
|
|
203
|
+
this._registryControllers.delete(registryId);
|
|
204
|
+
if (this._options.onUnsubscribe) this._options.onUnsubscribe(registryId);
|
|
184
205
|
}
|
|
185
206
|
}
|
|
186
207
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brightspace-ui/core",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.99.1",
|
|
4
4
|
"description": "A collection of accessible, free, open-source web components for building Brightspace applications",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": "https://github.com/BrightspaceUI/core.git",
|