@brightspace-ui/core 2.137.2 → 2.137.4

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.
@@ -189,6 +189,7 @@ The `d2l-filter-dimension-set` component is the main dimension type that will wo
189
189
 
190
190
  | Property | Type | Description |
191
191
  |---|---|---|
192
+ | `has-more` | Boolean | Whether the dimension has more values to load. Must be used with selected-first and manual search-type. |
192
193
  | `header-text` | String | A heading displayed above the list items. This is usually unnecessary, but can be used to emphasize or promote something specific about the list of items to help orient users. |
193
194
  | `introductory-text` | String | The introductory text to display at the top of the filter dropdown |
194
195
  | `key` | String, required | Unique identifier for the dimension |
@@ -232,6 +233,36 @@ This component is built to be used alongside the [d2l-filter-dimension-set](#d2l
232
233
  | `selected` | Boolean, default: `false` | Whether the value in the filter is selected or not |
233
234
  <!-- docs: end hidden content -->
234
235
 
236
+ ## Search and Paging
237
+
238
+ Most filters will not need search or paging features since filter value lists are generally short. For longer lists of filter values when Search is necessary, it can be enabled by setting search-type to `automatic` or `manual`.
239
+
240
+ `automatic` search runs a basic case-insensitive text comparison on the dimension values that are loaded in the browser, having no awareness of server-side values that are not yet loaded.
241
+
242
+ `manual` search dispatches a `d2l-filter-dimension-search` event delegating the search to the component's consumer. The event's detail will contain the key of the dimension from where the event was dispatched (`key`), the text value used for the search (`value`) and a callback (`searchCompleteCallback`). This callback gives the consumer control of which keys to display, either by setting `displayAllKeys` to `true` or passing a list of the keys to display as `keysToDisplay` (all other keys will be hidden). The dimension will be in a loading state until the callback is called.
243
+ ```js
244
+ e.detail.searchCompleteCallback({ keysToDisplay: keysToDisplay });
245
+ e.detail.searchCompleteCallback({ displayAllKeys: true });
246
+ ```
247
+
248
+ As with Search, paging is often unnecessary since filter lists are generally short. For long lists of filter values, load-more paging can be enabled by setting `has-more` on a dimension set, which will display a `d2l-pager-load-more` button at the end of the values. Note however that paging requires the search type to be set to `manual`. Clicking the button replaces its text with a loading spinner and dispatches a `d2l-filter-dimension-load-more` event whose detail, like the search event, contains the dimension key (`key`), active search value (`value`) and a callback (`loadMoreCompleteCallback`) that works just like `searchCompleteCallback` described above. The pager will also be in a loading state until the callback is called.
249
+ ```js
250
+ e.detail.loadMoreCompleteCallback({ keysToDisplay: keysToDisplay });
251
+ e.detail.loadMoreCompleteCallback({ displayAllKeys: true });
252
+ ```
253
+
254
+ ### Selection and manual search/paging
255
+
256
+ The filter component depends entirely on the consumer to include the selected filter values in order for the selected counts and `d2l-filter-tags` to display the correct values. Ideally, all values should be loaded into the dimensions and the event callbacks should be leveraged to set the visibility on those values. However, in the cases where this is not possible and new values are being added/removed manually from the dimension, then selection should be persisted. This means that selected items should always be loaded and included in the dimension and they should not be removed in order to maintain the functionality of counts and filter tags.
257
+ <!-- docs: demo -->
258
+ ```html
259
+ <script type="module">
260
+ import '@brightspace-ui/core/components/filter/demo/filter-load-more-demo.js'
261
+ </script>
262
+ <d2l-filter-load-more-demo>
263
+ </d2l-filter-load-more-demo>
264
+ ```
265
+
235
266
  ## Counts
236
267
 
237
268
  The `count` property displays a count next to each filter value to indicate the number of results a value will yield. This helps users more effectively explore data and make selections, so it’s a good idea to provide these counts if it can be done performantly.
@@ -11,6 +11,11 @@ class FilterDimensionSet extends LitElement {
11
11
 
12
12
  static get properties() {
13
13
  return {
14
+ /**
15
+ * Whether the dimension has more values to load. Manual search and selected first should be set if has more is being used
16
+ * @type {boolean}
17
+ */
18
+ hasMore: { type: Boolean, attribute: 'has-more' },
14
19
  /**
15
20
  * A heading displayed above the list items. This is usually unnecessary, but can be used to emphasize or promote something specific about the list of items to help orient users.
16
21
  * @type {string}
@@ -31,11 +36,6 @@ class FilterDimensionSet extends LitElement {
31
36
  * @type {boolean}
32
37
  */
33
38
  loading: { type: Boolean },
34
- /**
35
- * Whether the dimension has more values to load
36
- * @type {boolean}
37
- */
38
- hasMore: { type: Boolean, attribute: 'has-more' },
39
39
  /**
40
40
  * Whether to hide the search input, perform a simple text search, or fire an event on search
41
41
  * @type {'none'|'automatic'|'manual'}
@@ -47,7 +47,7 @@ class FilterDimensionSet extends LitElement {
47
47
  */
48
48
  selectAll: { type: Boolean, attribute: 'select-all' },
49
49
  /**
50
- * Whether to render the selected items at the top of the filter
50
+ * Whether to render the selected items at the top of the filter. Forced on if load more paging is being used
51
51
  * @type {boolean}
52
52
  */
53
53
  selectedFirst: { type: Boolean, attribute: 'selected-first' },
@@ -69,6 +69,13 @@
69
69
  </template>
70
70
  </d2l-demo-snippet>
71
71
 
72
+ <h2>Instructions</h2>
73
+ <d2l-demo-snippet>
74
+ <template>
75
+ <d2l-input-text label="Name" instructions="Use the keyboard to enter some sweet stuff... :)"></d2l-input-text>
76
+ </template>
77
+ </d2l-demo-snippet>
78
+
72
79
  <h3>Invalid</h3>
73
80
  <d2l-demo-snippet>
74
81
  <template>
@@ -80,6 +80,7 @@ The `<d2l-input-text>` element is a simple wrapper around the native `<input typ
80
80
  | `description` | String | A description to be added to the `input` for accessibility |
81
81
  | `disabled` | Boolean | Disables the input |
82
82
  | `input-width` | String, default: `100%` | Restricts the maximum width of the input box without impacting the width of the label |
83
+ | `instructions` | String | Additional information relating to how to use the component |
83
84
  | `label-hidden` | Boolean | Hides the label visually (moves it to the input's `aria-label` attribute) |
84
85
  | `labelled-by` | String | HTML id of an element in the same shadow root which acts as the input's label |
85
86
  | `max` | String | For number inputs, maximum value |
@@ -242,7 +242,6 @@ class InputDate extends FocusMixin(LabelledMixin(SkeletonMixin(FormElementMixin(
242
242
  ? html`<d2l-icon icon="tier1:alert" slot="left" style="${styleMap({ color: 'var(--d2l-color-cinnabar)' })}"></d2l-icon>`
243
243
  : html`<d2l-icon icon="tier1:calendar" slot="left"></d2l-icon>`;
244
244
  const errorTooltip = (this.validationError && !this.opened && this.childErrors.size === 0) ? html`<d2l-tooltip align="start" announced for="${this._inputId}" state="error">${this.validationError}</d2l-tooltip>` : null;
245
- const infoTooltip = (this._showInfoTooltip && !errorTooltip && !this.invalid && !this.disabled && this.childErrors.size === 0 && !this.skeleton && this._inputTextFocusShowTooltip) ? html`<d2l-tooltip align="start" announced delay="1000" for="${this._inputId}">${this.localize(`${this._namespace}.openInstructions`, { format: shortDateFormat })}</d2l-tooltip>` : null;
246
245
 
247
246
  const dropdownContent = this._dropdownFirstOpened ? html`
248
247
  <d2l-dropdown-content
@@ -276,7 +275,6 @@ class InputDate extends FocusMixin(LabelledMixin(SkeletonMixin(FormElementMixin(
276
275
  <div>${this.emptyText}</div>
277
276
  </div>
278
277
  ${errorTooltip}
279
- ${infoTooltip}
280
278
  <d2l-dropdown ?disabled="${this.disabled || this.skeleton}" no-auto-open>
281
279
  <d2l-input-text
282
280
  ?novalidate="${this.noValidate}"
@@ -284,6 +282,7 @@ class InputDate extends FocusMixin(LabelledMixin(SkeletonMixin(FormElementMixin(
284
282
  @blur="${this._handleInputTextBlur}"
285
283
  @change="${this._handleChange}"
286
284
  class="d2l-dropdown-opener"
285
+ instructions="${ifDefined((this._showInfoTooltip && !errorTooltip && !this.invalid && this.childErrors.size === 0 && this._inputTextFocusShowTooltip) ? this.localize(`${this._namespace}.openInstructions`, { format: shortDateFormat }) : undefined)}"
287
286
  description="${ifDefined(this.emptyText ? this.emptyText : undefined)}"
288
287
  ?disabled="${this.disabled}"
289
288
  @focus="${this._handleInputTextFocus}"
@@ -68,6 +68,11 @@ class InputText extends FocusMixin(LabelledMixin(FormElementMixin(SkeletonMixin(
68
68
  * @type {string}
69
69
  */
70
70
  inputWidth: { attribute: 'input-width', type: String },
71
+ /**
72
+ * ADVANCED: Additional information relating to how to use the component
73
+ * @type {string}
74
+ */
75
+ instructions: { type: String, attribute: 'instructions' },
71
76
  /**
72
77
  * Hides the label visually (moves it to the input's "aria-label" attribute)
73
78
  * @type {boolean}
@@ -461,8 +466,13 @@ class InputText extends FocusMixin(LabelledMixin(FormElementMixin(SkeletonMixin(
461
466
  }
462
467
 
463
468
  let tooltip = nothing;
464
- if (this.validationError && !this.skeleton && !this.noValidate) {
465
- tooltip = html`<d2l-tooltip state="error" announced align="start">${this.validationError} <span class="d2l-offscreen">${this.description}</span></d2l-tooltip>`;
469
+ if (!this.skeleton) {
470
+ if (this.validationError && !this.noValidate) {
471
+ // this tooltip is using "announced" since we don't want aria-describedby wire-up which would bury the message in VoiceOver's More Content Available menu
472
+ tooltip = html`<d2l-tooltip state="error" announced align="start">${this.validationError} <span class="d2l-offscreen">${this.description}</span></d2l-tooltip>`;
473
+ } else if (this.instructions) {
474
+ tooltip = html`<d2l-tooltip align="start" for="${this._inputId}" delay="1000">${this.instructions}</d2l-tooltip>`;
475
+ }
466
476
  }
467
477
 
468
478
  return html`${tooltip}${label}${input}`;
@@ -3827,7 +3827,7 @@
3827
3827
  },
3828
3828
  {
3829
3829
  "name": "has-more",
3830
- "description": "Whether the dimension has more values to load",
3830
+ "description": "Whether the dimension has more values to load. Manual search and selected first should be set if has more is being used",
3831
3831
  "type": "boolean",
3832
3832
  "default": "false"
3833
3833
  },
@@ -3845,7 +3845,7 @@
3845
3845
  },
3846
3846
  {
3847
3847
  "name": "selected-first",
3848
- "description": "Whether to render the selected items at the top of the filter",
3848
+ "description": "Whether to render the selected items at the top of the filter. Forced on if load more paging is being used",
3849
3849
  "type": "boolean",
3850
3850
  "default": "false"
3851
3851
  },
@@ -3899,7 +3899,7 @@
3899
3899
  {
3900
3900
  "name": "hasMore",
3901
3901
  "attribute": "has-more",
3902
- "description": "Whether the dimension has more values to load",
3902
+ "description": "Whether the dimension has more values to load. Manual search and selected first should be set if has more is being used",
3903
3903
  "type": "boolean",
3904
3904
  "default": "false"
3905
3905
  },
@@ -3920,7 +3920,7 @@
3920
3920
  {
3921
3921
  "name": "selectedFirst",
3922
3922
  "attribute": "selected-first",
3923
- "description": "Whether to render the selected items at the top of the filter",
3923
+ "description": "Whether to render the selected items at the top of the filter. Forced on if load more paging is being used",
3924
3924
  "type": "boolean",
3925
3925
  "default": "false"
3926
3926
  },
@@ -6574,6 +6574,11 @@
6574
6574
  "description": "Restricts the maximum width of the input box without impacting the width of the label.",
6575
6575
  "type": "string"
6576
6576
  },
6577
+ {
6578
+ "name": "instructions",
6579
+ "description": "ADVANCED: Additional information relating to how to use the component",
6580
+ "type": "string"
6581
+ },
6577
6582
  {
6578
6583
  "name": "max",
6579
6584
  "description": "For number inputs, maximum value",
@@ -6741,6 +6746,12 @@
6741
6746
  "description": "Restricts the maximum width of the input box without impacting the width of the label.",
6742
6747
  "type": "string"
6743
6748
  },
6749
+ {
6750
+ "name": "instructions",
6751
+ "attribute": "instructions",
6752
+ "description": "ADVANCED: Additional information relating to how to use the component",
6753
+ "type": "string"
6754
+ },
6744
6755
  {
6745
6756
  "name": "max",
6746
6757
  "attribute": "max",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brightspace-ui/core",
3
- "version": "2.137.2",
3
+ "version": "2.137.4",
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",