@brightspace-ui/core 2.175.0 → 2.176.0
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/button/README.md +21 -0
- package/components/button/button-add.js +11 -11
- package/components/list/list-item-generic-layout.js +18 -4
- package/components/list/list-item-mixin.js +18 -4
- package/components/list/list.js +13 -2
- package/custom-elements.json +22 -7
- package/package.json +1 -1
@@ -175,6 +175,27 @@ To make your `d2l-button-icon` accessible, use the following properties when app
|
|
175
175
|
</d2l-button-icon>
|
176
176
|
```
|
177
177
|
|
178
|
+
## Add Button [d2l-button-add]
|
179
|
+
|
180
|
+
The `d2l-button-add` element is for quickly adding new items inline (for example in a list).
|
181
|
+
|
182
|
+
<!-- docs: demo code properties name:d2l-button-add display:block autoSize:false size:xsmall -->
|
183
|
+
```html
|
184
|
+
<script type="module">
|
185
|
+
import '@brightspace-ui/core/components/button/button-add.js';
|
186
|
+
</script>
|
187
|
+
<d2l-button-add text="Add New Item"></d2l-button-add>
|
188
|
+
```
|
189
|
+
|
190
|
+
<!-- docs: start hidden content -->
|
191
|
+
### Properties
|
192
|
+
|
193
|
+
| Property | Type | Description |
|
194
|
+
|--|--|--|
|
195
|
+
| `text` | String, required | The text associated with the button. When mode is "icon-and-text", this text is displayed next to the icon. Otherwise this text is in a tooltip. |
|
196
|
+
| `mode` | String | Display mode of the component. Defaults to "icon" (plus icon is always visible). Other options are "icon-and-text" (plus icon and text are always visible), and "icon-when-interacted" (plus icon is only visible when hover or focus). |
|
197
|
+
<!-- docs: end hidden content -->
|
198
|
+
|
178
199
|
## Floating Buttons [d2l-floating-buttons]
|
179
200
|
|
180
201
|
See [floating buttons](https://github.com/BrightspaceUI/core/tree/main/components/button/floating-buttons.md).
|
@@ -11,9 +11,9 @@ import { PropertyRequiredMixin } from '../../mixins/property-required/property-r
|
|
11
11
|
import { RtlMixin } from '../../mixins/rtl/rtl-mixin.js';
|
12
12
|
|
13
13
|
const MODE = {
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
icon: 'icon',
|
15
|
+
icon_and_text: 'icon-and-text',
|
16
|
+
icon_when_interacted: 'icon-when-interacted'
|
17
17
|
};
|
18
18
|
|
19
19
|
/**
|
@@ -23,12 +23,12 @@ class ButtonAdd extends RtlMixin(PropertyRequiredMixin(FocusMixin(LocalizeCoreEl
|
|
23
23
|
static get properties() {
|
24
24
|
return {
|
25
25
|
/**
|
26
|
-
* Display mode of the component. Defaults to
|
26
|
+
* Display mode of the component. Defaults to `icon` (plus icon is always visible). Other options are `icon-and-text` (plus icon and text are always visible), and `icon-when-interacted` (plus icon is only visible when hover or focus).
|
27
27
|
* @type {'icon'|'icon-and-text'|'icon-when-interacted'}
|
28
28
|
*/
|
29
29
|
mode: { type: String, reflect: true },
|
30
30
|
/**
|
31
|
-
*
|
31
|
+
* The text associated with the button. When mode is `icon-and-text` this text is displayed next to the icon, otherwise this text is in a tooltip.
|
32
32
|
* @type {string}
|
33
33
|
*/
|
34
34
|
text: { type: String, required: true }
|
@@ -155,7 +155,7 @@ class ButtonAdd extends RtlMixin(PropertyRequiredMixin(FocusMixin(LocalizeCoreEl
|
|
155
155
|
constructor() {
|
156
156
|
super();
|
157
157
|
|
158
|
-
this.mode = MODE.
|
158
|
+
this.mode = MODE.icon;
|
159
159
|
|
160
160
|
this._buttonId = getUniqueId();
|
161
161
|
}
|
@@ -166,13 +166,13 @@ class ButtonAdd extends RtlMixin(PropertyRequiredMixin(FocusMixin(LocalizeCoreEl
|
|
166
166
|
|
167
167
|
render() {
|
168
168
|
const text = this.text || this.localize('components.button-add.addItem');
|
169
|
-
const id = !this.mode !== MODE.
|
170
|
-
const offset = this.mode === MODE.
|
169
|
+
const id = !this.mode !== MODE.icon_and_text ? this._buttonId : undefined;
|
170
|
+
const offset = this.mode === MODE.icon_when_interacted ? 23 : 18;
|
171
171
|
|
172
|
-
const content = this.mode !== MODE.
|
173
|
-
? html`<d2l-button-add-icon-text ?visible-on-ancestor="${this.mode === MODE.
|
172
|
+
const content = this.mode !== MODE.icon_and_text
|
173
|
+
? html`<d2l-button-add-icon-text ?visible-on-ancestor="${this.mode === MODE.icon_when_interacted}" animation-type="opacity"></d2l-button-add-icon-text>`
|
174
174
|
: html`<d2l-button-add-icon-text text="${text}"></d2l-button-add-icon-text>`;
|
175
|
-
const tooltip = this.mode !== MODE.
|
175
|
+
const tooltip = this.mode !== MODE.icon_and_text
|
176
176
|
? html`<d2l-tooltip class="vdiff-target" delay="100" offset="${offset}" for="${this._buttonId}" for-type="label">${text}</d2l-tooltip>`
|
177
177
|
: nothing;
|
178
178
|
|
@@ -69,7 +69,12 @@ class ListItemGenericLayout extends RtlMixin(LitElement) {
|
|
69
69
|
[control-end content-start] minmax(0, auto)
|
70
70
|
[content-end actions-start] minmax(0, min-content)
|
71
71
|
[end actions-end];
|
72
|
-
grid-template-rows:
|
72
|
+
grid-template-rows:
|
73
|
+
[start add-top-start] minmax(0, min-content)
|
74
|
+
[add-top-end main-start] minmax(0, min-content)
|
75
|
+
[main-end add-start] minmax(0, min-content)
|
76
|
+
[add-end nested-start] minmax(0, min-content)
|
77
|
+
[nested-end end];
|
73
78
|
}
|
74
79
|
|
75
80
|
:host([align-nested="control"]) ::slotted([slot="nested"]) {
|
@@ -92,7 +97,7 @@ class ListItemGenericLayout extends RtlMixin(LitElement) {
|
|
92
97
|
::slotted([slot="outside-control-container"]),
|
93
98
|
::slotted([slot="control-container"]),
|
94
99
|
::slotted([slot="drop-target"]) {
|
95
|
-
grid-row:
|
100
|
+
grid-row: 2 / 3;
|
96
101
|
}
|
97
102
|
|
98
103
|
::slotted([slot="outside-control"]) {
|
@@ -169,12 +174,19 @@ class ListItemGenericLayout extends RtlMixin(LitElement) {
|
|
169
174
|
|
170
175
|
::slotted([slot="nested"]) {
|
171
176
|
grid-column: content-start / end;
|
172
|
-
grid-row: nested
|
177
|
+
grid-row: nested;
|
173
178
|
}
|
179
|
+
|
174
180
|
::slotted([slot="add"]) {
|
175
|
-
grid-column: color-start / end;
|
176
181
|
grid-row: add;
|
177
182
|
}
|
183
|
+
::slotted([slot="add-top"]) {
|
184
|
+
grid-row: add-top;
|
185
|
+
}
|
186
|
+
::slotted([slot="add-top"]),
|
187
|
+
::slotted([slot="add"]) {
|
188
|
+
grid-column: color-start / end;
|
189
|
+
}
|
178
190
|
`;
|
179
191
|
}
|
180
192
|
|
@@ -208,6 +220,8 @@ class ListItemGenericLayout extends RtlMixin(LitElement) {
|
|
208
220
|
|
209
221
|
render() {
|
210
222
|
return html`
|
223
|
+
<slot name="add-top" class="d2l-cell" data-cell-num="10"></slot>
|
224
|
+
|
211
225
|
<slot name="control-container"></slot>
|
212
226
|
<slot name="outside-control-container"></slot>
|
213
227
|
|
@@ -60,6 +60,10 @@ export const ListItemMixin = superclass => class extends composeMixins(
|
|
60
60
|
* @type {string}
|
61
61
|
*/
|
62
62
|
color: { type: String },
|
63
|
+
/**
|
64
|
+
* @ignore
|
65
|
+
*/
|
66
|
+
first: { type: Boolean, reflect: true },
|
63
67
|
/**
|
64
68
|
* Whether to allow the drag target to be the handle only rather than the entire cell
|
65
69
|
* @type {boolean}
|
@@ -143,6 +147,7 @@ export const ListItemMixin = superclass => class extends composeMixins(
|
|
143
147
|
:host([selected]:not([selection-disabled]):not([skeleton])) [slot="control-container"]::before,
|
144
148
|
:host([selected]:not([selection-disabled]):not([skeleton])) [slot="control-container"]::after,
|
145
149
|
:host([_show-add-button]) [slot="control-container"]::after,
|
150
|
+
:host([_show-add-button]) [slot="control-container"]::before,
|
146
151
|
:host(:first-of-type[_nested]) [slot="control-container"]::before {
|
147
152
|
border-top-color: transparent;
|
148
153
|
}
|
@@ -380,7 +385,8 @@ export const ListItemMixin = superclass => class extends composeMixins(
|
|
380
385
|
margin-right: -6px;
|
381
386
|
}
|
382
387
|
|
383
|
-
[slot="add"]
|
388
|
+
[slot="add"],
|
389
|
+
[slot="add-top"] {
|
384
390
|
margin-bottom: -4px;
|
385
391
|
margin-top: -3px;
|
386
392
|
}
|
@@ -399,6 +405,7 @@ export const ListItemMixin = superclass => class extends composeMixins(
|
|
399
405
|
|
400
406
|
constructor() {
|
401
407
|
super();
|
408
|
+
this.first = false;
|
402
409
|
this.noPrimaryAction = false;
|
403
410
|
this.paddingType = 'normal';
|
404
411
|
this._contentId = getUniqueId();
|
@@ -553,9 +560,10 @@ export const ListItemMixin = superclass => class extends composeMixins(
|
|
553
560
|
}
|
554
561
|
}
|
555
562
|
|
556
|
-
_handleButtonAddClick() {
|
563
|
+
_handleButtonAddClick(e) {
|
564
|
+
const position = e.target.hasAttribute('data-is-first') ? 'before' : 'after';
|
557
565
|
/** @ignore */
|
558
|
-
this.dispatchEvent(new CustomEvent('d2l-list-item-add-button-click', { bubbles: true }));
|
566
|
+
this.dispatchEvent(new CustomEvent('d2l-list-item-add-button-click', { bubbles: true, detail: { position } }));
|
559
567
|
}
|
560
568
|
|
561
569
|
_isListItem(node) {
|
@@ -608,6 +616,7 @@ export const ListItemMixin = superclass => class extends composeMixins(
|
|
608
616
|
const nestedList = this._getNestedList();
|
609
617
|
if (this._hasNestedList !== !!nestedList) {
|
610
618
|
this._hasNestedList = !!nestedList;
|
619
|
+
this._hasNestedListAddButton = nestedList.hasAttribute('add-button');
|
611
620
|
/** @ignore */
|
612
621
|
this.dispatchEvent(new CustomEvent('d2l-list-item-nested-change', { bubbles: true, composed: true }));
|
613
622
|
}
|
@@ -640,6 +649,11 @@ export const ListItemMixin = superclass => class extends composeMixins(
|
|
640
649
|
data-separators="${ifDefined(this._separators)}"
|
641
650
|
?grid-active="${this.role === 'rowgroup'}"
|
642
651
|
?no-primary-action="${this.noPrimaryAction}">
|
652
|
+
${this._showAddButton && this.first ? html`
|
653
|
+
<div slot="add-top">
|
654
|
+
<d2l-button-add text="${addButtonText}" mode="icon-when-interacted" @click="${this._handleButtonAddClick}" data-is-first></d2l-button-add>
|
655
|
+
</div>
|
656
|
+
` : nothing}
|
643
657
|
<div slot="outside-control-container"></div>
|
644
658
|
${this._renderDropTarget()}
|
645
659
|
${this._renderDragHandle(this._renderOutsideControl)}
|
@@ -682,7 +696,7 @@ export const ListItemMixin = superclass => class extends composeMixins(
|
|
682
696
|
class="d2l-list-item-actions-container">
|
683
697
|
<slot name="actions" class="d2l-list-item-actions">${actions}</slot>
|
684
698
|
</div>
|
685
|
-
${this._showAddButton ? html`
|
699
|
+
${this._showAddButton && !this._hasNestedListAddButton ? html`
|
686
700
|
<div slot="add">
|
687
701
|
<d2l-button-add text="${addButtonText}" mode="icon-when-interacted" @click="${this._handleButtonAddClick}"></d2l-button-add>
|
688
702
|
</div>
|
package/components/list/list.js
CHANGED
@@ -120,6 +120,9 @@ class List extends PageableMixin(SelectionMixin(LitElement)) {
|
|
120
120
|
--d2l-list-item-color-border-radius: 3px;
|
121
121
|
--d2l-list-item-color-width: 3px;
|
122
122
|
}
|
123
|
+
:host([add-button]) ::slotted([slot="controls"]) {
|
124
|
+
margin-bottom: calc(6px + 0.4rem); /* controls section margin-bottom + spacing for add-button */
|
125
|
+
}
|
123
126
|
`;
|
124
127
|
}
|
125
128
|
|
@@ -319,8 +322,12 @@ class List extends PageableMixin(SelectionMixin(LitElement)) {
|
|
319
322
|
|
320
323
|
_handleListItemAddButtonClick(e) {
|
321
324
|
e.stopPropagation();
|
322
|
-
/**
|
323
|
-
|
325
|
+
/**
|
326
|
+
* Dispatched when the add button directly after the item is clicked. Event detail includes position ('before' or 'after') and key.
|
327
|
+
* The key belongs to the list item adjacent to where the new item should be positioned.
|
328
|
+
* The position represents where the new item should be positioned relative to the item with that key.
|
329
|
+
* */
|
330
|
+
this.dispatchEvent(new CustomEvent('d2l-list-add-button-click', { detail: { key: e.target.key, position: e.detail.position } }));
|
324
331
|
}
|
325
332
|
|
326
333
|
_handleListItemNestedChange(e) {
|
@@ -368,6 +375,10 @@ class List extends PageableMixin(SelectionMixin(LitElement)) {
|
|
368
375
|
|
369
376
|
_handleSlotChange() {
|
370
377
|
this._updateItemShowingCount();
|
378
|
+
this.getItems().forEach((item, i) => {
|
379
|
+
if (i === 0) item.first = true;
|
380
|
+
else item.first = false;
|
381
|
+
});
|
371
382
|
|
372
383
|
/** @ignore */
|
373
384
|
this.dispatchEvent(new CustomEvent('d2l-list-item-showing-count-change', {
|
package/custom-elements.json
CHANGED
@@ -350,29 +350,29 @@
|
|
350
350
|
"attributes": [
|
351
351
|
{
|
352
352
|
"name": "text",
|
353
|
-
"description": "
|
353
|
+
"description": "The text associated with the button. When mode is `icon-and-text` this text is displayed next to the icon, otherwise this text is in a tooltip.",
|
354
354
|
"type": "string"
|
355
355
|
},
|
356
356
|
{
|
357
357
|
"name": "mode",
|
358
|
-
"description": "Display mode of the component. Defaults to
|
358
|
+
"description": "Display mode of the component. Defaults to `icon` (plus icon is always visible). Other options are `icon-and-text` (plus icon and text are always visible), and `icon-when-interacted` (plus icon is only visible when hover or focus).",
|
359
359
|
"type": "'icon'|'icon-and-text'|'icon-when-interacted'",
|
360
|
-
"default": "\"
|
360
|
+
"default": "\"icon\""
|
361
361
|
}
|
362
362
|
],
|
363
363
|
"properties": [
|
364
364
|
{
|
365
365
|
"name": "text",
|
366
366
|
"attribute": "text",
|
367
|
-
"description": "
|
367
|
+
"description": "The text associated with the button. When mode is `icon-and-text` this text is displayed next to the icon, otherwise this text is in a tooltip.",
|
368
368
|
"type": "string"
|
369
369
|
},
|
370
370
|
{
|
371
371
|
"name": "mode",
|
372
372
|
"attribute": "mode",
|
373
|
-
"description": "Display mode of the component. Defaults to
|
373
|
+
"description": "Display mode of the component. Defaults to `icon` (plus icon is always visible). Other options are `icon-and-text` (plus icon and text are always visible), and `icon-when-interacted` (plus icon is only visible when hover or focus).",
|
374
374
|
"type": "'icon'|'icon-and-text'|'icon-when-interacted'",
|
375
|
-
"default": "\"
|
375
|
+
"default": "\"icon\""
|
376
376
|
},
|
377
377
|
{
|
378
378
|
"name": "documentLocaleSettings",
|
@@ -8049,6 +8049,11 @@
|
|
8049
8049
|
"description": "A color indicator to appear at the beginning of a list item. Expected value is a valid 3, 4, 6, or 8 character CSS color hex code (e.g., #006fbf).",
|
8050
8050
|
"type": "string"
|
8051
8051
|
},
|
8052
|
+
{
|
8053
|
+
"name": "first",
|
8054
|
+
"type": "boolean",
|
8055
|
+
"default": "false"
|
8056
|
+
},
|
8052
8057
|
{
|
8053
8058
|
"name": "noPrimaryAction",
|
8054
8059
|
"attribute": "no-primary-action",
|
@@ -8397,6 +8402,11 @@
|
|
8397
8402
|
"description": "A color indicator to appear at the beginning of a list item. Expected value is a valid 3, 4, 6, or 8 character CSS color hex code (e.g., #006fbf).",
|
8398
8403
|
"type": "string"
|
8399
8404
|
},
|
8405
|
+
{
|
8406
|
+
"name": "first",
|
8407
|
+
"type": "boolean",
|
8408
|
+
"default": "false"
|
8409
|
+
},
|
8400
8410
|
{
|
8401
8411
|
"name": "noPrimaryAction",
|
8402
8412
|
"attribute": "no-primary-action",
|
@@ -8872,6 +8882,11 @@
|
|
8872
8882
|
"description": "A color indicator to appear at the beginning of a list item. Expected value is a valid 3, 4, 6, or 8 character CSS color hex code (e.g., #006fbf).",
|
8873
8883
|
"type": "string"
|
8874
8884
|
},
|
8885
|
+
{
|
8886
|
+
"name": "first",
|
8887
|
+
"type": "boolean",
|
8888
|
+
"default": "false"
|
8889
|
+
},
|
8875
8890
|
{
|
8876
8891
|
"name": "noPrimaryAction",
|
8877
8892
|
"attribute": "no-primary-action",
|
@@ -9177,7 +9192,7 @@
|
|
9177
9192
|
},
|
9178
9193
|
{
|
9179
9194
|
"name": "d2l-list-add-button-click",
|
9180
|
-
"description": "Dispatched when the add button directly after the item is clicked. Event detail includes
|
9195
|
+
"description": "Dispatched when the add button directly after the item is clicked. Event detail includes position ('before' or 'after') and key.\nThe key belongs to the list item adjacent to where the new item should be positioned.\nThe position represents where the new item should be positioned relative to the item with that key."
|
9181
9196
|
}
|
9182
9197
|
],
|
9183
9198
|
"slots": [
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@brightspace-ui/core",
|
3
|
-
"version": "2.
|
3
|
+
"version": "2.176.0",
|
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",
|