@redvars/peacock 3.3.3 → 3.4.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/dist/IndividualComponent-DUINtMGK.js +67 -0
- package/dist/IndividualComponent-DUINtMGK.js.map +1 -0
- package/dist/assets/images/empty-state/no-document.svg +11 -12
- package/dist/assets/images/empty-state/page.svg +15 -9
- package/dist/bottom-sheet.js +238 -0
- package/dist/bottom-sheet.js.map +1 -0
- package/dist/{button-ClzS8JLq.js → button-COYCtuA8.js} +306 -149
- package/dist/button-COYCtuA8.js.map +1 -0
- package/dist/button-group-DsXquZQn.js +440 -0
- package/dist/button-group-DsXquZQn.js.map +1 -0
- package/dist/button-group.js +6 -4
- package/dist/button-group.js.map +1 -1
- package/dist/button.js +5 -3
- package/dist/button.js.map +1 -1
- package/dist/card-content.js +29 -0
- package/dist/card-content.js.map +1 -0
- package/dist/card.js +418 -44
- package/dist/card.js.map +1 -1
- package/dist/{chart-bar-DbnXQgvS.js → chart-bar-cn6rrna-.js} +2 -2
- package/dist/{chart-bar-DbnXQgvS.js.map → chart-bar-cn6rrna-.js.map} +1 -1
- package/dist/chart-bar.js +4 -3
- package/dist/chart-bar.js.map +1 -1
- package/dist/chart-doughnut.js +2 -1
- package/dist/chart-doughnut.js.map +1 -1
- package/dist/chart-pie.js +2 -1
- package/dist/chart-pie.js.map +1 -1
- package/dist/chart-stacked-bar.js +4 -3
- package/dist/chart-stacked-bar.js.map +1 -1
- package/dist/{class-map-59YGWLnx.js → class-map-3TAnCMAX.js} +3 -9
- package/dist/class-map-3TAnCMAX.js.map +1 -0
- package/dist/clock.js +2 -1
- package/dist/clock.js.map +1 -1
- package/dist/code-editor.js +6 -4
- package/dist/code-editor.js.map +1 -1
- package/dist/code-highlighter.js +5 -3
- package/dist/code-highlighter.js.map +1 -1
- package/dist/custom-elements-jsdocs.json +2458 -2753
- package/dist/custom-elements.json +2742 -757
- package/dist/dispatch-event-utils-B4odODQf.js.map +1 -1
- package/dist/index.js +14 -10
- package/dist/index.js.map +1 -1
- package/dist/number-counter.js +3 -2
- package/dist/number-counter.js.map +1 -1
- package/dist/{observe-theme-change-pALI5fmV.js → observe-theme-change-DKAIv5BB.js} +3 -2
- package/dist/observe-theme-change-DKAIv5BB.js.map +1 -0
- package/dist/peacock-loader.js +34 -8
- package/dist/peacock-loader.js.map +1 -1
- package/dist/property-1psGvXOq.js +10 -0
- package/dist/property-1psGvXOq.js.map +1 -0
- package/dist/{radio-b70_Ie9n.js → select-C3XAzenC.js} +1706 -192
- package/dist/select-C3XAzenC.js.map +1 -0
- package/dist/side-sheet.js +186 -0
- package/dist/side-sheet.js.map +1 -0
- package/dist/src/bottom-sheet/bottom-sheet.d.ts +42 -0
- package/dist/src/bottom-sheet/index.d.ts +1 -0
- package/dist/src/button/BaseButton.d.ts +4 -3
- package/dist/src/button/button/button.d.ts +4 -0
- package/dist/src/button/button-group/button-group.d.ts +32 -3
- package/dist/src/button/icon-button/icon-button.d.ts +4 -0
- package/dist/src/card/card-content.d.ts +15 -0
- package/dist/src/card/card.d.ts +37 -3
- package/dist/src/card/index.d.ts +1 -0
- package/dist/src/container/container.d.ts +1 -1
- package/dist/src/empty-state/empty-state.d.ts +1 -1
- package/dist/src/focus-ring/focus-ring.d.ts +4 -1
- package/dist/src/index.d.ts +6 -1
- package/dist/src/menu/menu/menu.d.ts +1 -0
- package/dist/src/menu/menu-item/menu-item.d.ts +0 -1
- package/dist/src/ripple/ripple.d.ts +19 -3
- package/dist/src/segmented-button/index.d.ts +2 -0
- package/dist/src/segmented-button/segmented-button-group.d.ts +46 -0
- package/dist/src/segmented-button/segmented-button.d.ts +65 -0
- package/dist/src/select/index.d.ts +3 -0
- package/dist/src/select/option.d.ts +55 -0
- package/dist/src/select/select.d.ts +116 -0
- package/dist/src/side-sheet/index.d.ts +1 -0
- package/dist/src/side-sheet/side-sheet.d.ts +41 -0
- package/dist/src/tabs/tab-group.d.ts +0 -1
- package/dist/src/tabs/tab.d.ts +8 -2
- package/dist/src/tabs/tabs.d.ts +13 -1
- package/dist/state-DwbEjqVk.js +10 -0
- package/dist/state-DwbEjqVk.js.map +1 -0
- package/dist/{style-map-DcB52w-l.js → style-map-CRFEoCEg.js} +2 -2
- package/dist/{style-map-DcB52w-l.js.map → style-map-CRFEoCEg.js.map} +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/{unsafe-html-C2r3PyzF.js → unsafe-html-D3GHRaGQ.js} +2 -2
- package/dist/{unsafe-html-C2r3PyzF.js.map → unsafe-html-D3GHRaGQ.js.map} +1 -1
- package/package.json +1 -1
- package/readme.md +2 -2
- package/src/bottom-sheet/bottom-sheet.scss +88 -0
- package/src/bottom-sheet/bottom-sheet.ts +135 -0
- package/src/bottom-sheet/index.ts +1 -0
- package/src/button/BaseButton.ts +16 -7
- package/src/button/button/button-colors.scss +76 -5
- package/src/button/button/button-sizes.scss +39 -19
- package/src/button/button/button.scss +117 -116
- package/src/button/button/button.ts +23 -1
- package/src/button/button-group/button-group.scss +25 -22
- package/src/button/button-group/button-group.ts +121 -4
- package/src/button/icon-button/icon-button-sizes.scss +35 -15
- package/src/button/icon-button/icon-button.ts +21 -1
- package/src/card/card-colors.scss +10 -0
- package/src/card/card-content.ts +26 -0
- package/src/card/card.scss +221 -41
- package/src/card/card.ts +240 -7
- package/src/card/index.ts +1 -0
- package/src/code-editor/code-editor.ts +1 -1
- package/src/container/container.ts +1 -1
- package/src/empty-state/empty-state.scss +8 -0
- package/src/empty-state/empty-state.ts +2 -2
- package/src/focus-ring/focus-ring.ts +37 -19
- package/src/index.ts +7 -1
- package/src/menu/menu/menu.scss +24 -3
- package/src/menu/menu/menu.ts +23 -2
- package/src/menu/menu-item/menu-item.scss +1 -0
- package/src/menu/menu-item/menu-item.ts +1 -9
- package/src/peacock-loader.ts +28 -0
- package/src/ripple/ripple.ts +19 -3
- package/src/segmented-button/index.ts +2 -0
- package/src/segmented-button/segmented-button-group.scss +21 -0
- package/src/segmented-button/segmented-button-group.ts +110 -0
- package/src/segmented-button/segmented-button.scss +115 -0
- package/src/segmented-button/segmented-button.ts +175 -0
- package/src/select/index.ts +3 -0
- package/src/select/option.ts +109 -0
- package/src/select/select.scss +120 -0
- package/src/select/select.ts +486 -0
- package/src/side-sheet/index.ts +1 -0
- package/src/side-sheet/side-sheet.scss +79 -0
- package/src/side-sheet/side-sheet.ts +100 -0
- package/src/slider/slider.scss +0 -1
- package/src/tabs/demo/index.html +90 -0
- package/src/tabs/tab-group.ts +0 -3
- package/src/tabs/tab.scss +237 -25
- package/src/tabs/tab.ts +85 -11
- package/src/tabs/tabs.scss +37 -3
- package/src/tabs/tabs.ts +118 -2
- package/src/utils/dispatch-event-utils.ts +1 -0
- package/dist/IndividualComponent-Dt5xirYG.js +0 -73
- package/dist/IndividualComponent-Dt5xirYG.js.map +0 -1
- package/dist/button-ClzS8JLq.js.map +0 -1
- package/dist/button-group-BMS5WvaF.js +0 -292
- package/dist/button-group-BMS5WvaF.js.map +0 -1
- package/dist/chart-donut.js +0 -309
- package/dist/chart-donut.js.map +0 -1
- package/dist/class-map-59YGWLnx.js.map +0 -1
- package/dist/observe-theme-change-pALI5fmV.js.map +0 -1
- package/dist/radio-b70_Ie9n.js.map +0 -1
- package/dist/src/chart-donut/chart-donut.d.ts +0 -53
- package/dist/src/chart-donut/index.d.ts +0 -1
- package/dist/test/card.test.d.ts +0 -1
- package/src/chart-donut/chart-donut.scss +0 -37
- package/src/chart-donut/chart-donut.ts +0 -287
- package/src/chart-donut/demo/index.html +0 -51
- package/src/chart-donut/index.ts +0 -1
package/src/card/card.ts
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
import { LitElement, html } from 'lit';
|
|
2
|
-
import { property } from 'lit/decorators.js';
|
|
1
|
+
import { LitElement, html, nothing, PropertyValues } from 'lit';
|
|
2
|
+
import { property, query, state } from 'lit/decorators.js';
|
|
3
|
+
import { classMap } from 'lit/directives/class-map.js';
|
|
4
|
+
import { dispatchActivationClick, isActivationClick } from '../utils/dispatch-event-utils.js';
|
|
5
|
+
import { observerSlotChangesWithCallback, throttle } from '../utils.js';
|
|
3
6
|
import IndividualComponent from '../IndividualComponent.js';
|
|
4
7
|
import styles from './card.scss';
|
|
8
|
+
import colorStyles from './card-colors.scss';
|
|
5
9
|
|
|
6
10
|
type CardVariant = 'elevated' | 'filled' | 'outlined';
|
|
7
|
-
|
|
11
|
+
|
|
8
12
|
/**
|
|
9
13
|
* @label Card
|
|
10
14
|
* @tag wc-card
|
|
@@ -24,15 +28,244 @@ type CardElevation = 0 | 1 | 2 | 3 | 4 | 5;
|
|
|
24
28
|
*/
|
|
25
29
|
@IndividualComponent
|
|
26
30
|
export class Card extends LitElement {
|
|
27
|
-
static styles = [styles];
|
|
31
|
+
static styles = [styles, colorStyles];
|
|
28
32
|
|
|
33
|
+
#id = crypto.randomUUID();
|
|
34
|
+
|
|
29
35
|
@property({ type: String, reflect: true })
|
|
30
36
|
variant: CardVariant = 'elevated';
|
|
31
37
|
|
|
32
|
-
@property({
|
|
33
|
-
|
|
38
|
+
@property({type: Boolean, reflect: true})
|
|
39
|
+
disabled: boolean = false;
|
|
40
|
+
|
|
41
|
+
@property({ type: Boolean, reflect: true })
|
|
42
|
+
actionable: boolean = false;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* If button is disabled, the reason why it is disabled.
|
|
46
|
+
*/
|
|
47
|
+
@property({ attribute: 'disabled-reason' })
|
|
48
|
+
disabledReason: string = '';
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Hyperlink to navigate to on click.
|
|
52
|
+
*/
|
|
53
|
+
@property({ reflect: true }) href?: string;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Sets or retrieves the window or frame at which to target content.
|
|
57
|
+
*/
|
|
58
|
+
@property() target: string = '_self';
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Sets the delay for throttle in milliseconds. Defaults to 200 milliseconds.
|
|
63
|
+
*/
|
|
64
|
+
@property() throttleDelay = 200;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* States
|
|
68
|
+
*/
|
|
69
|
+
@state()
|
|
70
|
+
isPressed = false;
|
|
71
|
+
|
|
72
|
+
@state()
|
|
73
|
+
private slotHasContent = false;
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
@query('.card') readonly cardElement!: HTMLElement | null;
|
|
77
|
+
|
|
78
|
+
@query('slot') readonly contentSlot!: HTMLSlotElement | null;
|
|
79
|
+
|
|
80
|
+
#tabindex?: number = 0;
|
|
81
|
+
|
|
82
|
+
#slottedTabIndexMap = new WeakMap<HTMLElement, string | null>();
|
|
83
|
+
|
|
84
|
+
override firstUpdated() {
|
|
85
|
+
this.__dispatchClickWithThrottle = throttle(
|
|
86
|
+
this.__dispatchClick,
|
|
87
|
+
this.throttleDelay,
|
|
88
|
+
);
|
|
89
|
+
observerSlotChangesWithCallback(
|
|
90
|
+
this.renderRoot.querySelector('slot'),
|
|
91
|
+
hasContent => {
|
|
92
|
+
this.slotHasContent = hasContent;
|
|
93
|
+
this.__syncSlottedChildrenTabIndex();
|
|
94
|
+
this.requestUpdate();
|
|
95
|
+
},
|
|
96
|
+
);
|
|
97
|
+
this.__syncSlottedChildrenTabIndex();
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
override updated(changedProperties: PropertyValues<this>) {
|
|
101
|
+
if (changedProperties.has('actionable') || changedProperties.has('href')) {
|
|
102
|
+
this.__syncSlottedChildrenTabIndex();
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
__syncSlottedChildrenTabIndex() {
|
|
107
|
+
if (!this.contentSlot) return;
|
|
108
|
+
|
|
109
|
+
const shouldDisableTabbing = this.actionable || this.__isLink();
|
|
110
|
+
const assignedChildren = this.contentSlot.assignedElements({ flatten: true });
|
|
111
|
+
|
|
112
|
+
assignedChildren.forEach(node => {
|
|
113
|
+
if (!(node instanceof HTMLElement)) return;
|
|
114
|
+
|
|
115
|
+
if (shouldDisableTabbing) {
|
|
116
|
+
if (!this.#slottedTabIndexMap.has(node)) {
|
|
117
|
+
this.#slottedTabIndexMap.set(node, node.getAttribute('tabindex'));
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (node.getAttribute('tabindex') !== '-1') {
|
|
121
|
+
node.setAttribute('tabindex', '-1');
|
|
122
|
+
}
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const originalTabIndex = this.#slottedTabIndexMap.get(node);
|
|
127
|
+
if (originalTabIndex === null) {
|
|
128
|
+
if (node.hasAttribute('tabindex')) {
|
|
129
|
+
node.removeAttribute('tabindex');
|
|
130
|
+
}
|
|
131
|
+
} else if (originalTabIndex !== undefined) {
|
|
132
|
+
if (node.getAttribute('tabindex') !== originalTabIndex) {
|
|
133
|
+
node.setAttribute('tabindex', originalTabIndex);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
this.#slottedTabIndexMap.delete(node);
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
__dispatchClickWithThrottle: (event: MouseEvent | KeyboardEvent) => void =
|
|
142
|
+
event => {
|
|
143
|
+
this.__dispatchClick(event);
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
__dispatchClick = (event: MouseEvent | KeyboardEvent) => {
|
|
147
|
+
// If the button is soft-disabled or a disabled link, we need to explicitly
|
|
148
|
+
// prevent the click from propagating to other event listeners as well as
|
|
149
|
+
// prevent the default action.
|
|
150
|
+
if (this.disabled && this.href) {
|
|
151
|
+
event.stopImmediatePropagation();
|
|
152
|
+
event.preventDefault();
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (!isActivationClick(event) || !this.cardElement) {
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
this.focus();
|
|
161
|
+
dispatchActivationClick(this.cardElement);
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
__isLink() {
|
|
165
|
+
return !!this.href;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
__getDisabledReasonID() {
|
|
169
|
+
return this.disabled && this.disabledReason
|
|
170
|
+
? `disabled-reason-${this.#id}`
|
|
171
|
+
: nothing;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
__renderDisabledReason() {
|
|
175
|
+
const disabledReasonID = this.__getDisabledReasonID();
|
|
176
|
+
if (disabledReasonID)
|
|
177
|
+
return html`<div
|
|
178
|
+
id="disabled-reason-${this.#id}"
|
|
179
|
+
role="tooltip"
|
|
180
|
+
aria-label=${this.disabledReason}
|
|
181
|
+
class="screen-reader-only"
|
|
182
|
+
>
|
|
183
|
+
${this.disabledReason}
|
|
184
|
+
</div>`;
|
|
185
|
+
return nothing;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
__handlePress = (event: KeyboardEvent | MouseEvent) => {
|
|
189
|
+
if (this.disabled) return;
|
|
190
|
+
if (
|
|
191
|
+
event instanceof KeyboardEvent &&
|
|
192
|
+
event.type === 'keydown' &&
|
|
193
|
+
(event.key === 'Enter' || event.key === ' ')
|
|
194
|
+
) {
|
|
195
|
+
this.isPressed = true;
|
|
196
|
+
} else if (event.type === 'mousedown') {
|
|
197
|
+
this.isPressed = true;
|
|
198
|
+
} else {
|
|
199
|
+
this.isPressed = false;
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
|
|
34
205
|
|
|
35
206
|
render() {
|
|
36
|
-
|
|
207
|
+
|
|
208
|
+
const isLink = this.__isLink();
|
|
209
|
+
|
|
210
|
+
const cssClasses = {
|
|
211
|
+
card: true,
|
|
212
|
+
'card-element': true,
|
|
213
|
+
[`variant-${this.variant}`]: true,
|
|
214
|
+
actionable: (this.actionable && !this.disabled) || isLink,
|
|
215
|
+
disabled: this.disabled,
|
|
216
|
+
pressed: this.isPressed,
|
|
217
|
+
'has-content': this.slotHasContent,
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
if (!isLink) {
|
|
221
|
+
return html`<button
|
|
222
|
+
class=${classMap(cssClasses)}
|
|
223
|
+
id="button"
|
|
224
|
+
tabindex=${this.#tabindex}
|
|
225
|
+
@click=${this.__dispatchClickWithThrottle}
|
|
226
|
+
@mousedown=${this.__handlePress}
|
|
227
|
+
@keydown=${this.__handlePress}
|
|
228
|
+
@keyup=${this.__handlePress}
|
|
229
|
+
?aria-describedby=${this.__getDisabledReasonID()}
|
|
230
|
+
aria-disabled=${`${this.disabled}`}
|
|
231
|
+
?disabled=${this.disabled}
|
|
232
|
+
>
|
|
233
|
+
${this.renderCardContent()}
|
|
234
|
+
</button>`;
|
|
235
|
+
}
|
|
236
|
+
return html`<a
|
|
237
|
+
class=${classMap(cssClasses)}
|
|
238
|
+
id="button"
|
|
239
|
+
tabindex=${this.#tabindex}
|
|
240
|
+
href=${this.href}
|
|
241
|
+
target=${this.target}
|
|
242
|
+
@click=${this.__dispatchClickWithThrottle}
|
|
243
|
+
@mousedown=${this.__handlePress}
|
|
244
|
+
@keydown=${this.__handlePress}
|
|
245
|
+
@keyup=${this.__handlePress}
|
|
246
|
+
role="button"
|
|
247
|
+
?aria-describedby=${this.__getDisabledReasonID()}
|
|
248
|
+
aria-disabled=${`${this.disabled}`}
|
|
249
|
+
>
|
|
250
|
+
${this.renderCardContent()}
|
|
251
|
+
</a>`;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
renderCardContent() {
|
|
255
|
+
return html`
|
|
256
|
+
<wc-focus-ring class="focus-ring" .control=${this} .forElement=${this.cardElement}></wc-focus-ring>
|
|
257
|
+
<wc-elevation class="elevation"></wc-elevation>
|
|
258
|
+
<div class="background"></div>
|
|
259
|
+
<div class="outline"></div>
|
|
260
|
+
<wc-ripple class="ripple"></wc-ripple>
|
|
261
|
+
|
|
262
|
+
<div class="card-content">
|
|
263
|
+
|
|
264
|
+
<div class="slot-container">
|
|
265
|
+
<slot @slotchange=${this.__syncSlottedChildrenTabIndex}></slot>
|
|
266
|
+
</div>
|
|
267
|
+
|
|
268
|
+
</div>
|
|
269
|
+
`;
|
|
37
270
|
}
|
|
38
271
|
}
|
package/src/card/index.ts
CHANGED
|
@@ -21,7 +21,7 @@ import styles from './code-editor.scss';
|
|
|
21
21
|
*
|
|
22
22
|
* @example
|
|
23
23
|
* ```html
|
|
24
|
-
* <wc-code-editor language="javascript"></wc-code-editor>
|
|
24
|
+
* <wc-code-editor language="javascript" style="width: 80%;--code-editor-height: 9rem;height: 9rem;" ></wc-code-editor>
|
|
25
25
|
* ```
|
|
26
26
|
*/
|
|
27
27
|
|
|
@@ -16,7 +16,7 @@ type ContainerSize = 'max' | 'xl' | 'lg' | 'md' | 'sm' | 'full';
|
|
|
16
16
|
*
|
|
17
17
|
* @example
|
|
18
18
|
* ```html
|
|
19
|
-
* <wc-container size="
|
|
19
|
+
* <wc-container style="width: 80%; border: 1px dotted black;" size="md">Content</wc-container>
|
|
20
20
|
* ```
|
|
21
21
|
*/
|
|
22
22
|
export class Container extends LitElement {
|
|
@@ -64,6 +64,10 @@
|
|
|
64
64
|
.content {
|
|
65
65
|
width: 50%;
|
|
66
66
|
}
|
|
67
|
+
|
|
68
|
+
.headline {
|
|
69
|
+
@include mixin.get-typography(title-medium);
|
|
70
|
+
}
|
|
67
71
|
}
|
|
68
72
|
}
|
|
69
73
|
|
|
@@ -79,6 +83,10 @@
|
|
|
79
83
|
justify-content: center;
|
|
80
84
|
}
|
|
81
85
|
}
|
|
86
|
+
|
|
87
|
+
.headline {
|
|
88
|
+
@include mixin.get-typography(title-small);
|
|
89
|
+
}
|
|
82
90
|
}
|
|
83
91
|
}
|
|
84
92
|
|
|
@@ -12,7 +12,7 @@ import styles from './empty-state.scss';
|
|
|
12
12
|
*
|
|
13
13
|
* @example
|
|
14
14
|
* ```html
|
|
15
|
-
* <wc-empty-state headline="No items found"></wc-empty-state>
|
|
15
|
+
* <wc-empty-state width="80%" headline="No items found"></wc-empty-state>
|
|
16
16
|
* ```
|
|
17
17
|
*/
|
|
18
18
|
export class EmptyState extends LitElement {
|
|
@@ -52,7 +52,7 @@ export class EmptyState extends LitElement {
|
|
|
52
52
|
|
|
53
53
|
__renderTitle() {
|
|
54
54
|
if (!this.headline) return nothing;
|
|
55
|
-
return html`<div class="
|
|
55
|
+
return html`<div class="headline">${this.headline}</div>`;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
__renderDescription() {
|
|
@@ -18,7 +18,7 @@ export class FocusRing extends LitElement {
|
|
|
18
18
|
|
|
19
19
|
@property({ type: Boolean, reflect: true }) visible: boolean = false;
|
|
20
20
|
|
|
21
|
-
@property({ type: String})
|
|
21
|
+
@property({ type: String }) for = '';
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
render() {
|
|
@@ -27,6 +27,8 @@ export class FocusRing extends LitElement {
|
|
|
27
27
|
|
|
28
28
|
_control?: HTMLElement;
|
|
29
29
|
|
|
30
|
+
_focusTarget?: HTMLElement;
|
|
31
|
+
|
|
30
32
|
get control() {
|
|
31
33
|
return this._control || null;
|
|
32
34
|
}
|
|
@@ -39,6 +41,15 @@ export class FocusRing extends LitElement {
|
|
|
39
41
|
}
|
|
40
42
|
}
|
|
41
43
|
|
|
44
|
+
set forElement(value: HTMLElement | null) {
|
|
45
|
+
if (value) {
|
|
46
|
+
this._focusTarget = value;
|
|
47
|
+
this.attach();
|
|
48
|
+
} else {
|
|
49
|
+
this.detach();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
42
53
|
connectedCallback() {
|
|
43
54
|
super.connectedCallback();
|
|
44
55
|
this.attach();
|
|
@@ -50,8 +61,8 @@ export class FocusRing extends LitElement {
|
|
|
50
61
|
}
|
|
51
62
|
|
|
52
63
|
__focusin() {
|
|
53
|
-
|
|
54
|
-
this.visible =
|
|
64
|
+
const focusTarget = this.__getFocusTarget();
|
|
65
|
+
this.visible = focusTarget?.matches(':focus-visible') ?? false;
|
|
55
66
|
}
|
|
56
67
|
|
|
57
68
|
__focusout() {
|
|
@@ -62,27 +73,34 @@ export class FocusRing extends LitElement {
|
|
|
62
73
|
this.visible = false;
|
|
63
74
|
}
|
|
64
75
|
|
|
76
|
+
__getFocusTarget(): HTMLElement | undefined {
|
|
77
|
+
|
|
78
|
+
if (this._focusTarget) {
|
|
79
|
+
return this._focusTarget;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const focusTarget = document.getElementById(this.for);
|
|
83
|
+
if (focusTarget) {
|
|
84
|
+
return focusTarget
|
|
85
|
+
}
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
|
88
|
+
|
|
65
89
|
attach() {
|
|
66
|
-
|
|
67
|
-
if (
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
this._control[this.element].addEventListener('focusout', this.__focusin.bind(this));
|
|
72
|
-
// @ts-ignore
|
|
73
|
-
this._control[this.element].addEventListener('pointerdown', this.__focusin.bind(this));
|
|
90
|
+
const focusTarget = this.__getFocusTarget();
|
|
91
|
+
if (focusTarget) {
|
|
92
|
+
focusTarget.addEventListener('focusin', this.__focusin.bind(this));
|
|
93
|
+
focusTarget.addEventListener('focusout', this.__focusout.bind(this));
|
|
94
|
+
focusTarget.addEventListener('pointerdown', this.__pointerdown.bind(this));
|
|
74
95
|
}
|
|
75
96
|
}
|
|
76
97
|
|
|
77
98
|
detach() {
|
|
78
|
-
|
|
79
|
-
if (
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
this._control[this.element].removeEventListener('focusout', this.__focusout);
|
|
84
|
-
// @ts-ignore
|
|
85
|
-
this._control[this.element].removeEventListener('pointerdown', this.__pointerdown);
|
|
99
|
+
const focusTarget = this.__getFocusTarget();
|
|
100
|
+
if (focusTarget) {
|
|
101
|
+
focusTarget.removeEventListener('focusin', this.__focusin.bind(this));
|
|
102
|
+
focusTarget.removeEventListener('focusout', this.__focusout.bind(this));
|
|
103
|
+
focusTarget.removeEventListener('pointerdown', this.__pointerdown.bind(this));
|
|
86
104
|
}
|
|
87
105
|
this._control = undefined;
|
|
88
106
|
}
|
package/src/index.ts
CHANGED
|
@@ -5,6 +5,7 @@ export { Divider } from './divider/index.js';
|
|
|
5
5
|
export { Clock } from './clock/index.js';
|
|
6
6
|
export { Elevation } from './elevation/index.js';
|
|
7
7
|
export { Button, ButtonGroup, IconButton } from './button/index.js';
|
|
8
|
+
export { SegmentedButton, SegmentedButtonGroup } from './segmented-button/index.js';
|
|
8
9
|
|
|
9
10
|
export { FocusRing } from './focus-ring/index.js';
|
|
10
11
|
export { Ripple } from './ripple/index.js';
|
|
@@ -37,7 +38,6 @@ export { CodeEditor } from './code-editor/index.js';
|
|
|
37
38
|
export { Image } from './image/index.js';
|
|
38
39
|
export { Tab, TabGroup, TabPanel, Tabs } from './tabs/index.js';
|
|
39
40
|
export { Slider } from './slider/index.js';
|
|
40
|
-
export { ChartDonut } from './chart-donut/index.js';
|
|
41
41
|
export { ChartDoughnut } from './chart-doughnut/index.js';
|
|
42
42
|
export { ChartPie } from './chart-pie/index.js';
|
|
43
43
|
export { ChartBar, ChartStackedBar } from './chart-bar/index.js';
|
|
@@ -47,3 +47,9 @@ export { TreeView, TreeNode } from './tree-view/index.js';
|
|
|
47
47
|
export { Card } from './card/index.js';
|
|
48
48
|
export { Snackbar } from './snackbar/index.js';
|
|
49
49
|
export { Radio } from './radio/index.js';
|
|
50
|
+
export { BottomSheet } from './bottom-sheet/index.js';
|
|
51
|
+
export { SideSheet } from './side-sheet/index.js';
|
|
52
|
+
export { Select } from './select/index.js';
|
|
53
|
+
export type { SelectOption } from './select/index.js';
|
|
54
|
+
export { SelectOptionElement } from './select/index.js';
|
|
55
|
+
|
package/src/menu/menu/menu.scss
CHANGED
|
@@ -4,23 +4,37 @@
|
|
|
4
4
|
|
|
5
5
|
.menu {
|
|
6
6
|
display: flex;
|
|
7
|
-
position:
|
|
7
|
+
position: fixed;
|
|
8
8
|
z-index: var(--menu-z-index, 1000);
|
|
9
9
|
min-width: 112px;
|
|
10
10
|
padding-block: var(--spacing-050);
|
|
11
|
+
transform-origin: top center;
|
|
12
|
+
|
|
13
|
+
--_menu-enter-duration: var(--duration-medium1, 250ms);
|
|
14
|
+
--_menu-exit-duration: var(--duration-short4, 200ms);
|
|
15
|
+
--_menu-enter-easing: cubic-bezier(0.05, 0.7, 0.1, 1);
|
|
16
|
+
--_menu-exit-easing: cubic-bezier(0.3, 0, 0.8, 0.15);
|
|
17
|
+
|
|
18
|
+
transition-property: opacity, transform, visibility;
|
|
19
|
+
transition-duration: var(--_menu-exit-duration), var(--_menu-exit-duration), 0ms;
|
|
20
|
+
transition-delay: 0ms, 0ms, var(--_menu-exit-duration);
|
|
21
|
+
transition-timing-function: var(--_menu-exit-easing), var(--_menu-exit-easing), linear;
|
|
11
22
|
|
|
12
23
|
&.closed {
|
|
13
|
-
display: none;
|
|
14
24
|
opacity: 0;
|
|
15
25
|
visibility: hidden;
|
|
16
26
|
pointer-events: none;
|
|
27
|
+
transform: translateY(-4px) scale(0.97);
|
|
17
28
|
}
|
|
18
29
|
|
|
19
30
|
&.open {
|
|
20
|
-
display: flex;
|
|
21
31
|
opacity: 1;
|
|
22
32
|
visibility: visible;
|
|
23
33
|
pointer-events: auto;
|
|
34
|
+
transform: translateY(0) scale(1);
|
|
35
|
+
transition-duration: var(--_menu-enter-duration), var(--_menu-enter-duration), 0ms;
|
|
36
|
+
transition-delay: 0ms, 0ms, 0ms;
|
|
37
|
+
transition-timing-function: var(--_menu-enter-easing), var(--_menu-enter-easing), linear;
|
|
24
38
|
}
|
|
25
39
|
|
|
26
40
|
.menu-content {
|
|
@@ -73,6 +87,13 @@
|
|
|
73
87
|
}
|
|
74
88
|
}
|
|
75
89
|
|
|
90
|
+
@media (prefers-reduced-motion: reduce) {
|
|
91
|
+
.menu {
|
|
92
|
+
transition: none;
|
|
93
|
+
transform: none;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
76
97
|
.menu {
|
|
77
98
|
--_container-shape-start-start: var(--shape-corner-large);
|
|
78
99
|
--_container-shape-start-end: var(--shape-corner-large);
|
package/src/menu/menu/menu.ts
CHANGED
|
@@ -181,7 +181,6 @@ export class Menu extends LitElement {
|
|
|
181
181
|
for (let index = 0; index < enabledItems.length; index += 1) {
|
|
182
182
|
const currentItem = enabledItems[index];
|
|
183
183
|
currentItem.tabIndex = index === this.activeIndex ? 0 : -1;
|
|
184
|
-
currentItem.selected = index === this.activeIndex;
|
|
185
184
|
}
|
|
186
185
|
}
|
|
187
186
|
|
|
@@ -226,10 +225,23 @@ export class Menu extends LitElement {
|
|
|
226
225
|
return this._enabledItems()[0] ?? null;
|
|
227
226
|
}
|
|
228
227
|
|
|
228
|
+
private _ownsKeyboardEvent(event: KeyboardEvent) {
|
|
229
|
+
const path = event.composedPath();
|
|
230
|
+
const ownedItems = this.items;
|
|
231
|
+
|
|
232
|
+
return path.some(target => target instanceof MenuItem && ownedItems.includes(target));
|
|
233
|
+
}
|
|
234
|
+
|
|
229
235
|
private _onItemActivate = (event: Event) => {
|
|
230
236
|
const customEvent = event as CustomEvent<{ item: MenuItem }>;
|
|
237
|
+
const { item } = customEvent.detail;
|
|
238
|
+
const ownedItems = this.items;
|
|
239
|
+
if (!ownedItems.includes(item)) {
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
|
|
231
243
|
const enabledItems = this._enabledItems();
|
|
232
|
-
const nextIndex = enabledItems.indexOf(
|
|
244
|
+
const nextIndex = enabledItems.indexOf(item);
|
|
233
245
|
if (nextIndex >= 0) {
|
|
234
246
|
this.activeIndex = nextIndex;
|
|
235
247
|
this._syncRovingTabIndex();
|
|
@@ -238,10 +250,15 @@ export class Menu extends LitElement {
|
|
|
238
250
|
|
|
239
251
|
private _onItemRequestClose = (event: Event) => {
|
|
240
252
|
const customEvent = event as CustomEvent<{
|
|
253
|
+
item: MenuItem;
|
|
241
254
|
reason: 'click-selection' | 'keydown';
|
|
242
255
|
key?: string;
|
|
243
256
|
}>;
|
|
244
257
|
|
|
258
|
+
if (!this.items.includes(customEvent.detail.item)) {
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
|
|
245
262
|
if (customEvent.defaultPrevented) {
|
|
246
263
|
return;
|
|
247
264
|
}
|
|
@@ -259,6 +276,10 @@ export class Menu extends LitElement {
|
|
|
259
276
|
return;
|
|
260
277
|
}
|
|
261
278
|
|
|
279
|
+
if (!this._ownsKeyboardEvent(event)) {
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
|
|
262
283
|
switch (event.key) {
|
|
263
284
|
case 'ArrowDown':
|
|
264
285
|
event.preventDefault();
|
|
@@ -138,10 +138,6 @@ export class MenuItem extends LitElement {
|
|
|
138
138
|
return !!this.href;
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
-
get focusTarget() {
|
|
142
|
-
return this;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
141
|
render() {
|
|
146
142
|
const isLink = this.__isLink();
|
|
147
143
|
|
|
@@ -180,11 +176,7 @@ export class MenuItem extends LitElement {
|
|
|
180
176
|
|
|
181
177
|
renderContent() {
|
|
182
178
|
return html`
|
|
183
|
-
<wc-focus-ring
|
|
184
|
-
class="focus-ring"
|
|
185
|
-
.control=${this}
|
|
186
|
-
element="focusTarget"
|
|
187
|
-
></wc-focus-ring>
|
|
179
|
+
<wc-focus-ring class="focus-ring" .control=${this} .forElement=${this}></wc-focus-ring>
|
|
188
180
|
<div class="background"></div>
|
|
189
181
|
<wc-ripple class="ripple"></wc-ripple>
|
|
190
182
|
|
package/src/peacock-loader.ts
CHANGED
|
@@ -11,6 +11,8 @@ import { Divider } from './divider/divider.js';
|
|
|
11
11
|
import { Button } from './button/button/button.js';
|
|
12
12
|
import { ButtonGroup } from './button/button-group/button-group.js';
|
|
13
13
|
import { IconButton } from './button/icon-button/icon-button.js';
|
|
14
|
+
import { SegmentedButton } from './segmented-button/segmented-button.js';
|
|
15
|
+
import { SegmentedButtonGroup } from './segmented-button/segmented-button-group.js';
|
|
14
16
|
import { Input } from './input/input.js';
|
|
15
17
|
import { Field } from './field/field.js';
|
|
16
18
|
import { NumberField } from './number-field/number-field.js';
|
|
@@ -53,7 +55,12 @@ import { Table } from './table/table.js';
|
|
|
53
55
|
import { Pagination } from './pagination/pagination.js';
|
|
54
56
|
import { TreeView } from './tree-view/tree-view.js';
|
|
55
57
|
import { Card } from './card/card.js';
|
|
58
|
+
import { CardContent } from './card/card-content.js';
|
|
56
59
|
import { Snackbar } from './snackbar/snackbar.js';
|
|
60
|
+
import { BottomSheet } from './bottom-sheet/bottom-sheet.js';
|
|
61
|
+
import { SideSheet } from './side-sheet/side-sheet.js';
|
|
62
|
+
import { Select } from './select/select.js';
|
|
63
|
+
import { SelectOptionElement } from './select/option.js';
|
|
57
64
|
|
|
58
65
|
const distDirectory = `${import.meta.url}/..`;
|
|
59
66
|
await loadCSS(`${distDirectory}/assets/styles.css`);
|
|
@@ -102,6 +109,12 @@ const loaderConfig: LoaderConfig = {
|
|
|
102
109
|
'wc-button-group': {
|
|
103
110
|
CustomElementClass: ButtonGroup,
|
|
104
111
|
},
|
|
112
|
+
'wc-segmented-button': {
|
|
113
|
+
CustomElementClass: SegmentedButton,
|
|
114
|
+
},
|
|
115
|
+
'wc-segmented-button-group': {
|
|
116
|
+
CustomElementClass: SegmentedButtonGroup,
|
|
117
|
+
},
|
|
105
118
|
'wc-divider': {
|
|
106
119
|
CustomElementClass: Divider,
|
|
107
120
|
},
|
|
@@ -141,6 +154,9 @@ const loaderConfig: LoaderConfig = {
|
|
|
141
154
|
'wc-card': {
|
|
142
155
|
CustomElementClass: Card,
|
|
143
156
|
},
|
|
157
|
+
'wc-card-content': {
|
|
158
|
+
CustomElementClass: CardContent,
|
|
159
|
+
},
|
|
144
160
|
'wc-tag': {
|
|
145
161
|
CustomElementClass: Tag,
|
|
146
162
|
},
|
|
@@ -238,6 +254,18 @@ const loaderConfig: LoaderConfig = {
|
|
|
238
254
|
'wc-snackbar': {
|
|
239
255
|
CustomElementClass: Snackbar,
|
|
240
256
|
},
|
|
257
|
+
'wc-bottom-sheet': {
|
|
258
|
+
CustomElementClass: BottomSheet,
|
|
259
|
+
},
|
|
260
|
+
'wc-side-sheet': {
|
|
261
|
+
CustomElementClass: SideSheet,
|
|
262
|
+
},
|
|
263
|
+
'wc-select': {
|
|
264
|
+
CustomElementClass: Select,
|
|
265
|
+
},
|
|
266
|
+
'wc-option': {
|
|
267
|
+
CustomElementClass: SelectOptionElement,
|
|
268
|
+
},
|
|
241
269
|
'wc-chart-doughnut': {
|
|
242
270
|
importPath: `${distDirectory}/chart-doughnut.js`,
|
|
243
271
|
},
|
package/src/ripple/ripple.ts
CHANGED
|
@@ -91,10 +91,26 @@ const FORCED_COLORS = window.matchMedia('(forced-colors: active)');
|
|
|
91
91
|
*
|
|
92
92
|
* @example
|
|
93
93
|
* ```html
|
|
94
|
-
* <
|
|
94
|
+
* <style>
|
|
95
|
+
* .ripple-surface {
|
|
96
|
+
* position: relative;
|
|
97
|
+
* display: inline-flex;
|
|
98
|
+
* align-items: center;
|
|
99
|
+
* justify-content: center;
|
|
100
|
+
* width: 220px;
|
|
101
|
+
* height: 64px;
|
|
102
|
+
* border-radius: 12px;
|
|
103
|
+
* background: var(--color-surface-container-high);
|
|
104
|
+
* color: var(--color-on-surface);
|
|
105
|
+
* overflow: hidden;
|
|
106
|
+
* cursor: pointer;
|
|
107
|
+
* user-select: none;
|
|
108
|
+
* }
|
|
109
|
+
* </style>
|
|
110
|
+
* <div class="ripple-surface">
|
|
95
111
|
* <wc-ripple></wc-ripple>
|
|
96
|
-
*
|
|
97
|
-
* </
|
|
112
|
+
* Ripple Effect
|
|
113
|
+
* </div>
|
|
98
114
|
* ```
|
|
99
115
|
* @tags display
|
|
100
116
|
*/
|