@brightspace-ui/core 3.145.0 → 3.146.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.
@@ -1,8 +1,12 @@
1
1
  import './breadcrumb.js';
2
2
  import { css, html, LitElement } from 'lit';
3
+ import { getFlag } from '../../helpers/flags.js';
3
4
  import { LocalizeCoreElement } from '../../helpers/localize-core-element.js';
5
+ import { overflowEllipsisDeclarations } from '../../helpers/overflow.js';
4
6
  import { RtlMixin } from '../../mixins/rtl/rtl-mixin.js';
5
7
 
8
+ const overflowClipEnabled = getFlag('GAUD-7887-core-components-overflow-clipping', true);
9
+
6
10
  /**
7
11
  * Help users understand where they are within the application, and provide useful clues about how the space is organized. They also provide a convenient navigation mechanism.
8
12
  * @slot - Breadcrumb items
@@ -21,12 +25,15 @@ class Breadcrumbs extends LocalizeCoreElement(RtlMixin(LitElement)) {
21
25
  static get styles() {
22
26
  return css`
23
27
  :host {
28
+ ${overflowClipEnabled ? css`clip-path: rect(-1em 100% calc(100% + 1em) -1em);` : css``}
24
29
  display: block;
25
30
  font-size: 0.7rem;
26
31
  line-height: 1.05rem;
27
- overflow: hidden;
28
32
  position: relative;
29
- white-space: nowrap;
33
+ ${overflowClipEnabled ? overflowEllipsisDeclarations : css`
34
+ overflow: hidden;
35
+ white-space: nowrap;
36
+ `}
30
37
  }
31
38
  :host([hidden]) {
32
39
  display: none;
@@ -2,9 +2,13 @@ import '../colors/colors.js';
2
2
  import { css, html, LitElement } from 'lit';
3
3
  import { bodySmallStyles } from '../typography/styles.js';
4
4
  import { classMap } from 'lit/directives/class-map.js';
5
+ import { getFlag } from '../../helpers/flags.js';
6
+ import { getOverflowDeclarations } from '../../helpers/overflow.js';
5
7
  import { SkeletonMixin } from '../skeleton/skeleton-mixin.js';
6
8
  import { styleMap } from 'lit/directives/style-map.js';
7
9
 
10
+ const overflowClipEnabled = getFlag('GAUD-7887-core-components-overflow-clipping', true);
11
+
8
12
  /**
9
13
  * A component for a "summary item" child component that describes the content in a collapsible panel.
10
14
  */
@@ -38,10 +42,12 @@ class CollapsiblePanelSummaryItem extends SkeletonMixin(LitElement) {
38
42
  line-height: 1.2rem;
39
43
  }
40
44
  p.truncate {
41
- -webkit-box-orient: vertical;
42
- display: -webkit-box;
43
- overflow: hidden;
44
- overflow-wrap: anywhere;
45
+ ${overflowClipEnabled ? getOverflowDeclarations({ lines: 1 }) : css`
46
+ -webkit-box-orient: vertical;
47
+ display: -webkit-box;
48
+ overflow: hidden;
49
+ overflow-wrap: anywhere;
50
+ `}
45
51
  }
46
52
  `];
47
53
  }
@@ -23,10 +23,12 @@ import '../tooltip/tooltip.js';
23
23
 
24
24
  import { bodyCompactStyles, bodySmallStyles, bodyStandardStyles, heading4Styles } from '../typography/styles.js';
25
25
  import { css, html, LitElement, nothing } from 'lit';
26
+ import { getOverflowDeclarations, overflowEllipsisDeclarations } from '../../helpers/overflow.js';
26
27
  import { announce } from '../../helpers/announce.js';
27
28
  import { classMap } from 'lit/directives/class-map.js';
28
29
  import { FocusMixin } from '../../mixins/focus/focus-mixin.js';
29
30
  import { formatNumber } from '@brightspace-ui/intl/lib/number.js';
31
+ import { getFlag } from '../../helpers/flags.js';
30
32
  import { ifDefined } from 'lit/directives/if-defined.js';
31
33
  import { LocalizeCoreElement } from '../../helpers/localize-core-element.js';
32
34
  import { offscreenStyles } from '../offscreen/offscreen.js';
@@ -38,6 +40,8 @@ const ESCAPE_KEY_CODE = 27;
38
40
  const FILTER_CONTENT_CLASS = 'd2l-filter-dropdown-content';
39
41
  const SET_DIMENSION_ID_PREFIX = 'list-';
40
42
 
43
+ const overflowClipEnabled = getFlag('GAUD-7887-core-components-overflow-clipping', true);
44
+
41
45
  let hasDisplayedKeyboardTooltip = false;
42
46
 
43
47
  export function resetHasDisplayedKeyboardTooltip() {
@@ -143,26 +147,24 @@ class Filter extends FocusMixin(LocalizeCoreElement(RtlMixin(LitElement))) {
143
147
  flex-grow: 1;
144
148
  padding-right: calc(2rem + 2px);
145
149
  text-align: center;
146
- text-overflow: ellipsis;
147
- white-space: nowrap;
150
+ ${overflowClipEnabled ? overflowEllipsisDeclarations : css`
151
+ overflow: hidden;
152
+ text-overflow: ellipsis;
153
+ white-space: nowrap;
154
+ `}
148
155
  }
149
156
  :host([dir="rtl"]) .d2l-filter-dimension-header-text {
150
157
  padding-left: calc(2rem + 2px);
151
158
  padding-right: 0;
152
159
  }
153
160
 
154
- .d2l-filter-dimension-header-text,
155
- .d2l-filter-dimension-set-value-text {
156
- overflow: hidden;
157
- }
158
-
159
161
  .d2l-filter-dimension-set-value {
160
162
  align-items: center;
161
163
  color: var(--d2l-color-ferrite);
162
164
  display: flex;
163
165
  gap: 0.45rem;
164
166
  line-height: unset;
165
- overflow: hidden;
167
+ ${overflowClipEnabled ? css`` : css`overflow: hidden;`}
166
168
  }
167
169
  .d2l-filter-dimension-set-value d2l-icon {
168
170
  flex-shrink: 0;
@@ -176,11 +178,14 @@ class Filter extends FocusMixin(LocalizeCoreElement(RtlMixin(LitElement))) {
176
178
  }
177
179
 
178
180
  .d2l-filter-dimension-set-value-text {
179
- -webkit-box-orient: vertical;
180
- display: -webkit-box;
181
181
  hyphens: auto;
182
- -webkit-line-clamp: 2;
183
- overflow-wrap: anywhere;
182
+ ${overflowClipEnabled ? getOverflowDeclarations({ lines: 2 }) : css`
183
+ -webkit-box-orient: vertical;
184
+ display: -webkit-box;
185
+ -webkit-line-clamp: 2;
186
+ overflow: hidden;
187
+ overflow-wrap: anywhere;
188
+ `}
184
189
  }
185
190
 
186
191
  d2l-list-item[selection-disabled] .d2l-filter-dimension-set-value,
@@ -637,8 +642,8 @@ class Filter extends FocusMixin(LocalizeCoreElement(RtlMixin(LitElement))) {
637
642
  ${item.additionalContent ? html`<d2l-icon icon="${item.selected ? 'tier1:arrow-collapse-small' : 'tier1:arrow-expand-small'}" aria-hidden="true"></d2l-icon>` : nothing}
638
643
  </div>
639
644
  ${item.additionalContent ? html`
640
- <d2l-expand-collapse-content
641
- ?expanded="${item.selected}"
645
+ <d2l-expand-collapse-content
646
+ ?expanded="${item.selected}"
642
647
  @d2l-expand-collapse-content-collapse="${this._handleExpandCollapse}"
643
648
  @d2l-expand-collapse-content-expand="${this._handleExpandCollapse}">
644
649
  ${item.additionalContent()}
@@ -3,12 +3,16 @@ import '../icons/icon.js';
3
3
  import { css, html, LitElement, nothing } from 'lit';
4
4
  import { classMap } from 'lit/directives/class-map.js';
5
5
  import { FocusMixin } from '../../mixins/focus/focus-mixin.js';
6
+ import { getFlag } from '../../helpers/flags.js';
6
7
  import { getFocusRingStyles } from '../../helpers/focus.js';
8
+ import { getOverflowDeclarations } from '../../helpers/overflow.js';
7
9
  import { ifDefined } from 'lit/directives/if-defined.js';
8
10
  import { LocalizeCoreElement } from '../../helpers/localize-core-element.js';
9
11
  import { offscreenStyles } from '../offscreen/offscreen.js';
10
12
  import { styleMap } from 'lit/directives/style-map.js';
11
13
 
14
+ const overflowClipEnabled = getFlag('GAUD-7887-core-components-overflow-clipping', true);
15
+
12
16
  export const linkStyles = css`
13
17
  .d2l-link, .d2l-link:visited, .d2l-link:active, .d2l-link:link {
14
18
  --d2l-focus-ring-offset: 1px;
@@ -109,10 +113,12 @@ class Link extends LocalizeCoreElement(FocusMixin(LitElement)) {
109
113
  display: inherit;
110
114
  }
111
115
  a.truncate {
112
- -webkit-box-orient: vertical;
113
- display: -webkit-box;
114
- overflow: hidden;
115
- overflow-wrap: anywhere;
116
+ ${overflowClipEnabled ? getOverflowDeclarations({ lines: 1 }) : css`
117
+ -webkit-box-orient: vertical;
118
+ display: -webkit-box;
119
+ overflow: hidden;
120
+ overflow-wrap: anywhere;
121
+ `}
116
122
  }
117
123
  d2l-icon {
118
124
  color: var(--d2l-color-celestine);
@@ -1,6 +1,9 @@
1
1
  import '../colors/colors.js';
2
2
  import { bodyCompactStyles, bodySmallStyles } from '../typography/styles.js';
3
3
  import { css, html, LitElement } from 'lit';
4
+ import { getFlag } from '../../helpers/flags.js';
5
+
6
+ const overflowClipEnabled = getFlag('GAUD-7887-core-components-overflow-clipping', true);
4
7
 
5
8
  /**
6
9
  * A component for consistent layout of primary and secondary text in a list item.
@@ -33,14 +36,18 @@ class ListItemContent extends LitElement {
33
36
 
34
37
  .d2l-list-item-content-text-secondary {
35
38
  color: var(--d2l-list-item-content-text-secondary-color, var(--d2l-color-tungsten));
36
- margin: 0;
37
- overflow: hidden;
39
+ ${overflowClipEnabled ? css`` : css`
40
+ margin: 0;
41
+ overflow: hidden;
42
+ `}
38
43
  }
39
44
 
40
45
  .d2l-list-item-content-text-supporting-info {
41
46
  color: var(--d2l-color-ferrite);
42
- margin: 0;
43
- overflow: hidden;
47
+ ${overflowClipEnabled ? css`` : css`
48
+ margin: 0;
49
+ overflow: hidden;
50
+ `}
44
51
  }
45
52
 
46
53
  .d2l-list-item-content-text-secondary ::slotted(*),
@@ -3,14 +3,17 @@ import { css, html, LitElement } from 'lit';
3
3
  import { getComposedChildren, isComposedAncestor } from '../../helpers/dom.js';
4
4
  import { classMap } from 'lit/directives/class-map.js';
5
5
  import { getComposedActiveElement } from '../../helpers/focus.js';
6
+ import { getFlag } from '../../helpers/flags.js';
6
7
  import { getUniqueId } from '../../helpers/uniqueId.js';
7
8
  import { ifDefined } from 'lit/directives/if-defined.js';
8
9
  import { LocalizeCoreElement } from '../../helpers/localize-core-element.js';
10
+ import { overflowHiddenDeclarations } from '../../helpers/overflow.js';
9
11
  import ResizeObserver from 'resize-observer-polyfill/dist/ResizeObserver.es.js';
10
12
  import { styleMap } from 'lit/directives/style-map.js';
11
13
 
12
- const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
13
14
  const transitionDur = matchMedia('(prefers-reduced-motion: reduce)').matches ? 0 : 400;
15
+ const overflowClipEnabled = getFlag('GAUD-7887-core-components-overflow-clipping', true);
16
+ const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
14
17
 
15
18
  /**
16
19
  * A component used to minimize the display of long content, while providing a way to reveal the full content.
@@ -51,11 +54,18 @@ class MoreLess extends LocalizeCoreElement(LitElement) {
51
54
  static get styles() {
52
55
  return css`
53
56
  :host {
54
- display: block;
57
+ ${overflowClipEnabled ? css`display: flow-root;` : css`display: block;`}
55
58
  }
56
59
 
57
60
  .d2l-more-less-content {
58
- overflow: hidden;
61
+ ${overflowClipEnabled ? css`
62
+ display: flow-root;
63
+ margin: -1em -1em 0;
64
+ padding: 1em 1em 0;
65
+ ${overflowHiddenDeclarations}
66
+ ` : css`
67
+ overflow: hidden;
68
+ `}
59
69
  }
60
70
  .d2l-more-less-transition {
61
71
  transition: max-height ${transitionDur}ms cubic-bezier(0, 0.7, 0.5, 1);
@@ -228,18 +238,27 @@ class MoreLess extends LocalizeCoreElement(LitElement) {
228
238
 
229
239
  const target = e.composedPath()[0] || e.target;
230
240
 
231
- if (isSafari) {
232
- target.scrollIntoViewIfNeeded?.();
233
- setTimeout(() => this.__content.scrollTo({ top: 0, behavior: 'instant' }), 1);
234
- }
241
+ if (overflowClipEnabled) {
242
+ const em = parseInt(getComputedStyle(this.__content).getPropertyValue('font-size'));
243
+ const { y: contentY, height: contentHeight } = this.__content.getBoundingClientRect();
244
+ const { y: targetY, height: targetHeight } = target.getBoundingClientRect();
235
245
 
236
- if (this.__content.scrollTop) {
237
- this.__content.scrollTo({ top: 0, behavior: 'instant' });
238
- this.__expand();
239
- this.__autoExpanded = true;
240
- await (transitionDur && new Promise(r => setTimeout(r, transitionDur)));
241
- if (target.getRootNode().activeElement === target) {
242
- target.scrollIntoView({ block: 'center', inline: 'center', behavior: 'instant' });
246
+ if (targetY + targetHeight > contentY + contentHeight - em) {
247
+ this.__expand();
248
+ this.__autoExpanded = true;
249
+ await (transitionDur && new Promise(r => setTimeout(r, transitionDur)));
250
+ }
251
+ } else {
252
+ if (isSafari) {
253
+ target.scrollIntoViewIfNeeded?.();
254
+ setTimeout(() => this.__content.scrollTo({ top: 0, behavior: 'instant' }), 1);
255
+ }
256
+
257
+ if (this.__content.scrollTop) {
258
+ this.__content.scrollTo({ top: 0, behavior: 'instant' });
259
+ this.__expand();
260
+ this.__autoExpanded = true;
261
+ await (transitionDur && new Promise(r => setTimeout(r, transitionDur)));
243
262
  }
244
263
  }
245
264
  }
@@ -8,6 +8,7 @@ Object property lists are simple dot-separated lists of text, displayed sequenti
8
8
  import '@brightspace-ui/core/components/object-property-list/object-property-list.js';
9
9
  import '@brightspace-ui/core/components/object-property-list/object-property-list-item.js';
10
10
  import '@brightspace-ui/core/components/object-property-list/object-property-list-item-link.js';
11
+ import '@brightspace-ui/core/components/object-property-list/object-property-list-item-tooltip-help.js';
11
12
  import '@brightspace-ui/core/components/status-indicator/status-indicator.js';
12
13
  </script>
13
14
 
@@ -17,6 +18,9 @@ Object property lists are simple dot-separated lists of text, displayed sequenti
17
18
  <d2l-object-property-list-item text="Example item with icon" icon="tier1:grade"></d2l-object-property-list-item>
18
19
  <d2l-object-property-list-item-link text="Example link" href="https://www.d2l.com/"></d2l-object-property-list-item-link>
19
20
  <d2l-object-property-list-item-link text="Example link with icon" href="https://www.d2l.com/" icon="tier1:alert"></d2l-object-property-list-item-link>
21
+ <d2l-object-property-list-item-tooltip-help text="Example tooltip help with icon" icon="tier1:grade">
22
+ These are extra details
23
+ </d2l-object-property-list-item-tooltip-help>
20
24
  </d2l-object-property-list>
21
25
  ```
22
26
 
@@ -42,11 +46,15 @@ An object property list can be defined using `d2l-object-property-list` and a co
42
46
  import '@brightspace-ui/core/components/object-property-list/object-property-list.js';
43
47
  import '@brightspace-ui/core/components/object-property-list/object-property-list-item.js';
44
48
  import '@brightspace-ui/core/components/object-property-list/object-property-list-item-link.js';
49
+ import '@brightspace-ui/core/components/object-property-list/object-property-list-item-tooltip-help.js';
45
50
  </script>
46
51
 
47
52
  <d2l-object-property-list>
48
53
  <d2l-object-property-list-item text="Example item"></d2l-object-property-list-item>
49
54
  <d2l-object-property-list-item-link text="Example link" href="https://www.d2l.com/"></d2l-object-property-list-item-link>
55
+ <d2l-object-property-list-item-tooltip-help text="Example link">
56
+ These are extra details
57
+ </d2l-object-property-list-item-tooltip-help>
50
58
  </d2l-object-property-list>
51
59
  ```
52
60
 
@@ -130,6 +138,52 @@ The `d2l-object-property-list-item-link` component is a link item for the object
130
138
  | `target` | String | Where to display the linked URL |
131
139
  <!-- docs: end hidden content -->
132
140
 
141
+ ## Help Tooltip Item [d2l-object-property-list-item-tooltip-help]
142
+
143
+ The `d2l-object-property-list-item-tooltip-help` component is an item for the object property list which is used to also display additional information for users. It displays text as a help tooltip, with an optional leading icon.
144
+
145
+ <!-- docs: demo code properties name:d2l-object-property-list-item-tooltip-help sandboxTitle:'Object Property List Help Tooltip Item' -->
146
+ ```html
147
+ <script type="module">
148
+ import '@brightspace-ui/core/components/object-property-list/object-property-list.js';
149
+ import '@brightspace-ui/core/components/object-property-list/object-property-list-item-tooltip-help.js';
150
+ </script>
151
+
152
+ <d2l-object-property-list>
153
+ <d2l-object-property-list-item-tooltip-help text="Example item">
154
+ These are extra details
155
+ </d2l-object-property-list-item-tooltip-help>
156
+ <d2l-object-property-list-item-tooltip-help text="Example item with icon" icon="tier1:grade">
157
+ These are extra details
158
+ </d2l-object-property-list-item-tooltip-help>
159
+ <d2l-object-property-list-item-tooltip-help text="Example item with custom icon">
160
+ These are extra details
161
+ <d2l-icon-custom slot="icon">
162
+ <svg xmlns="http://www.w3.org/2000/svg" mirror-in-rtl="true">
163
+ <path fill="#494c4e" d="M18 12v5a1 1 0 0 1-1 1H1a1 1 0 0 1-1-1v-5a1 1 0 0 1 2 0v4h14v-4a1 1 0 0 1 2 0z"/>
164
+ <path fill="#494c4e" d="M13.85 3.15l-2.99-3A.507.507 0 0 0 10.5 0H5.4A1.417 1.417 0 0 0 4 1.43v11.14A1.417 1.417 0 0 0 5.4 14h7.2a1.417 1.417 0 0 0 1.4-1.43V3.5a.47.47 0 0 0-.15-.35zM7 2h1a1 1 0 0 1 0 2H7a1 1 0 0 1 0-2zm4 10H7a1 1 0 0 1 0-2h4a1 1 0 0 1 0 2zm0-4H7a1 1 0 0 1 0-2h4a1 1 0 0 1 0 2z"/>
165
+ </svg>
166
+ </d2l-icon-custom>
167
+ </d2l-object-property-list-item-tooltip-help>
168
+ </d2l-object-property-list>
169
+ ```
170
+
171
+ <!-- docs: start hidden content -->
172
+ ### Slots
173
+
174
+ | Slot | Type | Description |
175
+ |--|--|--|
176
+ | `default` | required | Default content placed inside of the tooltip |
177
+ | `icon` | optional | Optional slot for a custom icon |
178
+
179
+ ### Properties
180
+
181
+ | Property | Type | Description |
182
+ |--|--|--|
183
+ | `text` | String, required | Text displayed by the item |
184
+ | `icon` | String | [Preset icon key](../icons#preset-icons) (e.g. `tier1:gear`) |
185
+ <!-- docs: end hidden content -->
186
+
133
187
  ## Status Slot
134
188
 
135
189
  Object property lists can optionally contain a single `d2l-status-indicator` inserted into the `status` slot.
@@ -8,6 +8,7 @@ import { ObjectPropertyListItem } from './object-property-list-item.js';
8
8
  * A single object property, to be used within an object-property-list,
9
9
  * rendered as a help tooltip and with an optional icon.
10
10
  * @slot - Default content placed inside of the tooltip
11
+ * @slot icon - Optional slot for a custom icon
11
12
  */
12
13
  class ObjectPropertyListItemTooltipHelp extends FocusMixin(ObjectPropertyListItem) {
13
14
  static get properties() {
@@ -155,7 +155,7 @@ Promise.resolve(tabs.hideTab((tab))).then(() => {
155
155
 
156
156
  The `TabMixin` can be used to create custom tabs. It is IMPORTANT to call the `dispatchContentChangeEvent` function in `TabMixin` when content changes in the consumer in order to properly trigger calculations. Ensure that there is only one element in any custom tab to focus on, else the focus and keyboard navigation behaviors become confusing for users. Note that the parent `d2l-tabs` element handles `tabindex` focus management, and so consumers should not be rendering focusable elements within custom tabs.
157
157
 
158
- Before creating a custom tab, ensure that the case is not covered by using a standard `d2l-tab` with content in the `before` and/or `after` slot(s).
158
+ Before creating a custom tab, ensure that the case is not covered by using a standard `d2l-tab` with content in the `before` and/or `after` slot(s).
159
159
 
160
160
  <!-- docs: demo code sandboxTitle:'TabMixin' display:block-->
161
161
  ```html
@@ -170,7 +170,8 @@ Before creating a custom tab, ensure that the case is not covered by using a sta
170
170
  const styles = [ css`
171
171
  .d2l-tab-custom-content {
172
172
  margin: 0.5rem;
173
- overflow: hidden;
173
+ overflow: clip;
174
+ overflow-clip-margin: 1em;
174
175
  padding: 0.1rem;
175
176
  white-space: nowrap;
176
177
  }
@@ -269,4 +270,4 @@ The `tabs` components were built following [W3C best practices for Tabs](https:/
269
270
  - Following recommended keyboard control patterns (with the exception of the "Optional" Home, End, and Delete key patterns)
270
271
  - Using the roles of `tablist` and `tab` appropriately in order to facilitate screen reader information (e.g., "tab, 2 of 7") and adding an `aria-label` to the `tablist`
271
272
  - Using `aria-selected` to indicate `tab` selection state
272
- - Using `aria-labelledby` and `aria-controls` in order to match the `tab` with the `tabpanel` for screen reader users
273
+ - Using `aria-labelledby` and `aria-controls` in order to match the `tab` with the `tabpanel` for screen reader users
@@ -9,7 +9,8 @@ class TabCustom extends TabMixin(LitElement) {
9
9
  .d2l-tab-custom-content {
10
10
  --d2l-focus-ring-offset: 0;
11
11
  margin: 0.5rem;
12
- overflow: hidden;
12
+ overflow: clip;
13
+ overflow-clip-margin: 1em;
13
14
  padding: 0.1rem;
14
15
  white-space: nowrap;
15
16
  }
@@ -1,9 +1,13 @@
1
1
  import '../colors/colors.js';
2
2
  import { css, html, LitElement } from 'lit';
3
3
  import { classMap } from 'lit/directives/class-map.js';
4
+ import { getFlag } from '../../helpers/flags.js';
4
5
  import { getFocusRingStyles } from '../../helpers/focus.js';
6
+ import { overflowEllipsisDeclarations } from '../../helpers/overflow.js';
5
7
  import { SkeletonMixin } from '../skeleton/skeleton-mixin.js';
6
8
 
9
+ const overflowClipEnabled = getFlag('GAUD-7887-core-components-overflow-clipping', true);
10
+
7
11
  const keyCodes = {
8
12
  ENTER: 13,
9
13
  SPACE: 32
@@ -34,10 +38,12 @@ class Tab extends SkeletonMixin(LitElement) {
34
38
  .d2l-tab-text {
35
39
  --d2l-focus-ring-offset: 0;
36
40
  margin: 0.5rem;
37
- overflow: hidden;
38
41
  padding: 0.1rem;
39
- text-overflow: ellipsis;
40
- white-space: nowrap;
42
+ ${overflowClipEnabled ? overflowEllipsisDeclarations : css`
43
+ overflow: hidden;
44
+ text-overflow: ellipsis;
45
+ white-space: nowrap;
46
+ `}
41
47
  }
42
48
  :host([skeleton]) .d2l-tab-text.d2l-skeletize::before {
43
49
  bottom: 0.15rem;
@@ -1,8 +1,12 @@
1
1
  import { css, html, LitElement, unsafeCSS } from 'lit';
2
2
  import { getFocusPseudoClass, getFocusRingStyles } from '../../helpers/focus.js';
3
3
  import { classMap } from 'lit/directives/class-map.js';
4
+ import { getFlag } from '../../helpers/flags.js';
5
+ import { overflowEllipsisDeclarations } from '../../helpers/overflow.js';
4
6
  import { TabMixin } from './tab-mixin.js';
5
7
 
8
+ const overflowClipEnabled = getFlag('GAUD-7887-core-components-overflow-clipping', true);
9
+
6
10
  const focusRingStyles = getFocusRingStyles(
7
11
  pseudoClass => `:host(:${pseudoClass}) .d2l-tab-text-inner-content`,
8
12
  { extraStyles: css`border-radius: 0.3rem; color: var(--d2l-color-celestine);` }
@@ -51,9 +55,11 @@ class Tab extends TabMixin(LitElement) {
51
55
  color: var(--d2l-color-celestine);
52
56
  }
53
57
  span {
54
- overflow: hidden;
55
- text-overflow: ellipsis;
56
- white-space: nowrap;
58
+ ${overflowClipEnabled ? overflowEllipsisDeclarations : css`
59
+ overflow: hidden;
60
+ text-overflow: ellipsis;
61
+ white-space: nowrap;
62
+ `}
57
63
  }
58
64
  .d2l-tab-text-skeletize-override {
59
65
  min-width: 50px;
@@ -8,6 +8,8 @@ import { getFocusPseudoClass, getFocusRingStyles } from '../../helpers/focus.js'
8
8
  import { ArrowKeysMixin } from '../../mixins/arrow-keys/arrow-keys-mixin.js';
9
9
  import { bodyCompactStyles } from '../typography/styles.js';
10
10
  import { classMap } from 'lit/directives/class-map.js';
11
+ import { getFlag } from '../../helpers/flags.js';
12
+ import { getOverflowDeclarations } from '../../helpers/overflow.js';
11
13
  import { ifDefined } from 'lit/directives/if-defined.js';
12
14
  import { LocalizeCoreElement } from '../../helpers/localize-core-element.js';
13
15
  import { repeat } from 'lit/directives/repeat.js';
@@ -16,6 +18,7 @@ import { SkeletonMixin } from '../skeleton/skeleton-mixin.js';
16
18
  import { styleMap } from 'lit/directives/style-map.js';
17
19
 
18
20
  const reduceMotion = matchMedia('(prefers-reduced-motion: reduce)').matches;
21
+ const overflowClipEnabled = getFlag('GAUD-7887-core-components-overflow-clipping', true);
19
22
 
20
23
  const scrollButtonWidth = 56;
21
24
 
@@ -87,13 +90,15 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(SkeletonMixin(LitElement))
87
90
  box-sizing: border-box;
88
91
  flex: auto;
89
92
  margin-left: -3px;
90
- overflow: hidden;
91
- overflow-x: hidden;
92
93
  padding-left: 3px;
93
94
  position: relative;
94
95
  -webkit-transition: max-width 200ms ease-in;
95
96
  transition: max-width 200ms ease-in;
96
- white-space: nowrap;
97
+ ${overflowClipEnabled ? getOverflowDeclarations({ textOverflow: 'clip' }) : css`
98
+ overflow: hidden;
99
+ overflow-x: hidden;
100
+ white-space: nowrap;
101
+ `}
97
102
  }
98
103
  .d2l-tabs-container-ext {
99
104
  flex: none;
@@ -110,6 +115,7 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(SkeletonMixin(LitElement))
110
115
  .d2l-tabs-scroll-next-container {
111
116
  background-color: var(--d2l-tabs-background-color);
112
117
  box-shadow: 0 0 12px 18px var(--d2l-tabs-background-color);
118
+ ${overflowClipEnabled ? css`clip-path: rect(0% 200% 100% -100%);` : css``}
113
119
  display: none;
114
120
  height: 100%;
115
121
  position: absolute;
@@ -117,6 +117,7 @@ The `d2l-tooltip` component is used to display additional information when users
117
117
  | `disable-focus-lock` | Boolean, default: `false` | Disables focus lock so that the tooltip will automatically close when no longer hovered even if it still has focus |
118
118
  | `force-show` | Boolean, default: `false` | Force the tooltip to stay open as long as it remains `true` |
119
119
  | `for-type` | String, default: `descriptor` | Accessibility type for the tooltip to specify whether it is the primary label for the target or a secondary descriptor. Valid values are: `label` and `descriptor`. |
120
+ | `icon` | String | [Preset icon key](../../components/icons#preset-icons) (e.g. `tier1:gear`) |
120
121
  | `show-truncated-only` | Boolean, default: `false` | Only show the tooltip if we detect the target element is truncated |
121
122
  | `position` | String | Optionally force the tooltip to open in a certain direction. Valid values are: `top`, `bottom`, `left` and `right`. If no position is provided, the tooltip will open in the first position that has enough space for it in the order: bottom, top, right, left. |
122
123
 
@@ -215,6 +216,13 @@ The `d2l-tooltip-help` component is used to display additional information when
215
216
  ```
216
217
 
217
218
  <!-- docs: start hidden content -->
219
+ ### Slots
220
+
221
+ | Slot | Type | Description |
222
+ |--|--|--|
223
+ | `default` | required | Default content placed inside of the tooltip |
224
+ | `icon` | optional | Optional slot for a custom icon |
225
+
218
226
  ### Properties
219
227
 
220
228
  | Property | Type | Description |
@@ -12,6 +12,7 @@ import { SlottedIconMixin } from '../icons/slotted-icon-mixin.js';
12
12
  /**
13
13
  * A component used to display additional information when users focus or hover over some text.
14
14
  * @slot - Default content placed inside of the tooltip
15
+ * @slot icon - Optional slot for a custom icon
15
16
  */
16
17
  class TooltipHelp extends SlottedIconMixin(SkeletonMixin(FocusMixin(LitElement))) {
17
18
 
@@ -11295,6 +11295,10 @@
11295
11295
  {
11296
11296
  "name": "",
11297
11297
  "description": "Default content placed inside of the tooltip"
11298
+ },
11299
+ {
11300
+ "name": "icon",
11301
+ "description": "Optional slot for a custom icon"
11298
11302
  }
11299
11303
  ]
11300
11304
  },
@@ -14273,6 +14277,10 @@
14273
14277
  {
14274
14278
  "name": "",
14275
14279
  "description": "Default content placed inside of the tooltip"
14280
+ },
14281
+ {
14282
+ "name": "icon",
14283
+ "description": "Optional slot for a custom icon"
14276
14284
  }
14277
14285
  ]
14278
14286
  },
@@ -0,0 +1,34 @@
1
+ import { set } from './template-tags.js';
2
+ import { unsafeCSS } from 'lit';
3
+
4
+ export const overflowHiddenDeclarations = getOverflowDeclarations({});
5
+ export const overflowEllipsisDeclarations = getOverflowDeclarations({ textOverflow: 'ellipsis' });
6
+
7
+ export function getOverflowDeclarations({ textOverflow = '', lines = 0, lit = true } = {}) {
8
+ if (!arguments.length) return overflowHiddenDeclarations;
9
+
10
+ const declarations = set`
11
+ min-width: 0; /* clamps width of flex items */
12
+ overflow-x: clip;
13
+ ${lines
14
+ ? set`
15
+ display: -webkit-box;
16
+ overflow-clip-margin: 0.2em;
17
+ overflow-wrap: anywhere;
18
+ overflow-y: clip;
19
+ text-overflow: ${textOverflow || 'ellipsis'};
20
+ -webkit-box-orient: vertical;
21
+ -webkit-line-clamp: ${lines};`
22
+ : set`
23
+ overflow-clip-margin: 1em;
24
+ ${textOverflow
25
+ ? set`
26
+ overflow-y: visible;
27
+ text-overflow: ${textOverflow};
28
+ white-space: nowrap;`
29
+ :
30
+ 'overflow-y: clip;'}
31
+ `}
32
+ `;
33
+ return lit ? unsafeCSS(declarations) : declarations;
34
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brightspace-ui/core",
3
- "version": "3.145.0",
3
+ "version": "3.146.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",