@redvars/peacock 3.5.1 → 3.6.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/{BaseButton-DuASuVth.js → BaseButton-BNFAYn-S.js} +2 -2
- package/dist/{BaseButton-DuASuVth.js.map → BaseButton-BNFAYn-S.js.map} +1 -1
- package/dist/BaseInput-14YmcfK7.js +27 -0
- package/dist/BaseInput-14YmcfK7.js.map +1 -0
- package/dist/banner.js +2 -3
- package/dist/banner.js.map +1 -1
- package/dist/{button-DouvOfEU.js → button-colors-Ccys3hvS.js} +5 -294
- package/dist/button-colors-Ccys3hvS.js.map +1 -0
- package/dist/button-group.js +226 -6
- package/dist/button-group.js.map +1 -1
- package/dist/button.js +294 -8
- package/dist/button.js.map +1 -1
- package/dist/calendar-column-view.js +634 -0
- package/dist/calendar-column-view.js.map +1 -0
- package/dist/calendar-event-BrQ_SEKD.js +199 -0
- package/dist/calendar-event-BrQ_SEKD.js.map +1 -0
- package/dist/calendar-month-view.js +376 -0
- package/dist/calendar-month-view.js.map +1 -0
- package/dist/calendar.js +339 -0
- package/dist/calendar.js.map +1 -0
- package/dist/canvas.js +361 -0
- package/dist/canvas.js.map +1 -0
- package/dist/cb-compound-expression.js +125 -0
- package/dist/cb-compound-expression.js.map +1 -0
- package/dist/cb-divider.js +150 -0
- package/dist/cb-divider.js.map +1 -0
- package/dist/cb-expression.js +75 -0
- package/dist/cb-expression.js.map +1 -0
- package/dist/cb-predicate.js +137 -0
- package/dist/cb-predicate.js.map +1 -0
- package/dist/code-editor.js +2 -1
- package/dist/code-editor.js.map +1 -1
- package/dist/condition-builder.js +58 -0
- package/dist/condition-builder.js.map +1 -0
- package/dist/custom-elements-jsdocs.json +7976 -4294
- package/dist/custom-elements.json +14358 -7589
- package/dist/dropdown-button.js +216 -0
- package/dist/dropdown-button.js.map +1 -0
- package/dist/event-manager-D-QCmUgR.js +113 -0
- package/dist/event-manager-D-QCmUgR.js.map +1 -0
- package/dist/fab.js +1 -1
- package/dist/flow-designer-dZnLJOQT.js +1656 -0
- package/dist/flow-designer-dZnLJOQT.js.map +1 -0
- package/dist/flow-designer-node-XMe-jlKg.js +548 -0
- package/dist/flow-designer-node-XMe-jlKg.js.map +1 -0
- package/dist/flow-designer-node.js +4 -0
- package/dist/flow-designer-node.js.map +1 -0
- package/dist/flow-designer.js +16 -0
- package/dist/flow-designer.js.map +1 -0
- package/dist/html-editor.js +358 -0
- package/dist/html-editor.js.map +1 -0
- package/dist/icon-button-CK1ZuE-2.js +247 -0
- package/dist/icon-button-CK1ZuE-2.js.map +1 -0
- package/dist/index.js +29 -6
- package/dist/index.js.map +1 -1
- package/dist/{is-dark-mode-DicqGkCJ.js → is-dark-mode-DOcaw4Yq.js} +2 -27
- package/dist/is-dark-mode-DOcaw4Yq.js.map +1 -0
- package/dist/modal.js +418 -0
- package/dist/modal.js.map +1 -0
- package/dist/{navigation-rail-Lxetd5-Z.js → navigation-rail-DyO0oAZU.js} +306 -2197
- package/dist/navigation-rail-DyO0oAZU.js.map +1 -0
- package/dist/notification-manager.js +268 -0
- package/dist/notification-manager.js.map +1 -0
- package/dist/peacock-loader.js +84 -8
- package/dist/peacock-loader.js.map +1 -1
- package/dist/popover-NC7b1lTq.js +1971 -0
- package/dist/popover-NC7b1lTq.js.map +1 -0
- package/dist/popover-content.js +125 -0
- package/dist/popover-content.js.map +1 -0
- package/dist/popover.js +4 -0
- package/dist/popover.js.map +1 -0
- package/dist/split-button.js +388 -0
- package/dist/split-button.js.map +1 -0
- package/dist/src/__controllers/floating-controller.d.ts +35 -0
- package/dist/src/calendar/base-event.d.ts +10 -0
- package/dist/src/calendar/calendar-column-view.d.ts +41 -0
- package/dist/src/calendar/calendar-event.d.ts +7 -0
- package/dist/src/calendar/calendar-month-view.d.ts +31 -0
- package/dist/src/calendar/calendar.d.ts +65 -0
- package/dist/src/calendar/event-manager.d.ts +17 -0
- package/dist/src/calendar/index.d.ts +4 -0
- package/dist/src/calendar/types.d.ts +13 -0
- package/dist/src/calendar/utils.d.ts +31 -0
- package/dist/src/canvas/canvas.d.ts +92 -0
- package/dist/src/canvas/index.d.ts +2 -0
- package/dist/src/condition-builder/cb-compound-expression.d.ts +31 -0
- package/dist/src/condition-builder/cb-divider.d.ts +26 -0
- package/dist/src/condition-builder/cb-expression.d.ts +31 -0
- package/dist/src/condition-builder/cb-predicate.d.ts +30 -0
- package/dist/src/condition-builder/condition-builder.d.ts +27 -0
- package/dist/src/condition-builder/index.d.ts +5 -0
- package/dist/src/dropdown-button/dropdown-button.d.ts +68 -0
- package/dist/src/dropdown-button/index.d.ts +1 -0
- package/dist/src/flow-designer/commands.d.ts +66 -0
- package/dist/src/flow-designer/flow-designer-node.d.ts +46 -0
- package/dist/src/flow-designer/flow-designer.d.ts +133 -0
- package/dist/src/flow-designer/index.d.ts +7 -0
- package/dist/src/flow-designer/layout.d.ts +30 -0
- package/dist/src/flow-designer/types.d.ts +142 -0
- package/dist/src/flow-designer/validation.d.ts +43 -0
- package/dist/src/flow-designer/workflow-utils.d.ts +40 -0
- package/dist/src/html-editor/html-editor.d.ts +56 -0
- package/dist/src/html-editor/index.d.ts +2 -0
- package/dist/src/index.d.ts +13 -0
- package/dist/src/menu/menu/menu.d.ts +5 -7
- package/dist/src/menu/menu-item/menu-item.d.ts +14 -13
- package/dist/src/modal/index.d.ts +1 -0
- package/dist/src/modal/modal.d.ts +63 -0
- package/dist/src/notification-manager/index.d.ts +1 -0
- package/dist/src/notification-manager/notification-manager.d.ts +44 -0
- package/dist/src/popover/index.d.ts +2 -0
- package/dist/src/popover/popover-content.d.ts +29 -0
- package/dist/src/popover/popover.d.ts +62 -0
- package/dist/src/split-button/index.d.ts +1 -0
- package/dist/src/split-button/split-button.d.ts +72 -0
- package/dist/src/tooltip/tooltip.d.ts +2 -15
- package/dist/test/flow-designer.test.d.ts +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -2
- package/readme.md +2 -2
- package/src/__controllers/floating-controller.ts +237 -0
- package/src/banner/banner.scss +2 -3
- package/src/button/button/button.ts +1 -0
- package/src/calendar/base-event.ts +49 -0
- package/src/calendar/calendar-column-view.scss +326 -0
- package/src/calendar/calendar-column-view.ts +392 -0
- package/src/calendar/calendar-event.ts +20 -0
- package/src/calendar/calendar-month-view.scss +192 -0
- package/src/calendar/calendar-month-view.ts +244 -0
- package/src/calendar/calendar.scss +71 -0
- package/src/calendar/calendar.ts +298 -0
- package/src/calendar/event-manager.ts +117 -0
- package/src/calendar/index.ts +4 -0
- package/src/calendar/types.ts +14 -0
- package/src/calendar/utils.ts +180 -0
- package/src/canvas/canvas.scss +60 -0
- package/src/canvas/canvas.ts +391 -0
- package/src/canvas/index.ts +2 -0
- package/src/condition-builder/cb-compound-expression.scss +37 -0
- package/src/condition-builder/cb-compound-expression.ts +80 -0
- package/src/condition-builder/cb-divider.scss +93 -0
- package/src/condition-builder/cb-divider.ts +56 -0
- package/src/condition-builder/cb-expression.scss +14 -0
- package/src/condition-builder/cb-expression.ts +49 -0
- package/src/condition-builder/cb-predicate.scss +35 -0
- package/src/condition-builder/cb-predicate.ts +102 -0
- package/src/condition-builder/condition-builder.scss +13 -0
- package/src/condition-builder/condition-builder.ts +38 -0
- package/src/condition-builder/index.ts +5 -0
- package/src/dropdown-button/demo/index.html +110 -0
- package/src/dropdown-button/dropdown-button.scss +22 -0
- package/src/dropdown-button/dropdown-button.ts +206 -0
- package/src/dropdown-button/index.ts +1 -0
- package/src/flow-designer/DEMO.md +239 -0
- package/src/flow-designer/commands.ts +278 -0
- package/src/flow-designer/flow-designer-node.ts +172 -0
- package/src/flow-designer/flow-designer.scss +457 -0
- package/src/flow-designer/flow-designer.ts +611 -0
- package/src/flow-designer/index.ts +41 -0
- package/src/flow-designer/layout.ts +357 -0
- package/src/flow-designer/types.ts +166 -0
- package/src/flow-designer/validation.ts +284 -0
- package/src/flow-designer/workflow-utils.ts +282 -0
- package/src/html-editor/html-editor.scss +146 -0
- package/src/html-editor/html-editor.ts +276 -0
- package/src/html-editor/index.ts +3 -0
- package/src/index.ts +25 -0
- package/src/menu/menu/menu.scss +2 -2
- package/src/menu/menu/menu.ts +91 -101
- package/src/menu/menu-item/menu-item.scss +4 -0
- package/src/menu/menu-item/menu-item.ts +82 -78
- package/src/modal/index.ts +1 -0
- package/src/modal/modal.scss +206 -0
- package/src/modal/modal.ts +201 -0
- package/src/notification-manager/index.ts +1 -0
- package/src/notification-manager/notification-manager.scss +113 -0
- package/src/notification-manager/notification-manager.ts +199 -0
- package/src/peacock-loader.ts +71 -0
- package/src/popover/index.ts +2 -0
- package/src/popover/popover-content.scss +69 -0
- package/src/popover/popover-content.ts +51 -0
- package/src/popover/popover.scss +7 -0
- package/src/popover/popover.ts +170 -0
- package/src/split-button/index.ts +1 -0
- package/src/split-button/split-button-colors.scss +56 -0
- package/src/split-button/split-button-sizes.scss +28 -0
- package/src/split-button/split-button.scss +79 -0
- package/src/split-button/split-button.ts +236 -0
- package/src/table/table.ts +2 -2
- package/src/tooltip/tooltip.scss +4 -3
- package/src/tooltip/tooltip.ts +46 -104
- package/dist/button-DouvOfEU.js.map +0 -1
- package/dist/button-group-CEdMwvJJ.js +0 -464
- package/dist/button-group-CEdMwvJJ.js.map +0 -1
- package/dist/is-dark-mode-DicqGkCJ.js.map +0 -1
- package/dist/navigation-rail-Lxetd5-Z.js.map +0 -1
- package/dist/src/menu/menu/MenuSurfaceController.d.ts +0 -18
- package/src/menu/menu/MenuSurfaceController.ts +0 -61
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { html, LitElement } from 'lit';
|
|
2
|
+
import { property } from 'lit/decorators.js';
|
|
3
|
+
import type { Placement } from '@floating-ui/dom';
|
|
4
|
+
import IndividualComponent from '@/IndividualComponent.js';
|
|
5
|
+
import { FloatingController } from '../__controllers/floating-controller.js';
|
|
6
|
+
import styles from './popover.scss';
|
|
7
|
+
import type { PopoverContent } from './popover-content.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @label Popover
|
|
11
|
+
* @tag wc-popover
|
|
12
|
+
* @rawTag popover
|
|
13
|
+
* @summary Displays additional information in a floating panel anchored to a trigger element.
|
|
14
|
+
* @overview
|
|
15
|
+
* <p>The Popover component wraps a trigger element and a <code>wc-popover-content</code> child. It uses
|
|
16
|
+
* floating-ui to compute position, keeping the panel visible inside the viewport even on scroll.</p>
|
|
17
|
+
* @tags display
|
|
18
|
+
*
|
|
19
|
+
* @fires {CustomEvent} wc-popover--open - Fired when the popover opens.
|
|
20
|
+
* @fires {CustomEvent} wc-popover--close - Fired when the popover closes.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```html
|
|
24
|
+
* <wc-popover trigger="click">
|
|
25
|
+
* <wc-button>Open popover</wc-button>
|
|
26
|
+
* <wc-popover-content>
|
|
27
|
+
* <p>Popover body text goes here.</p>
|
|
28
|
+
* </wc-popover-content>
|
|
29
|
+
* </wc-popover>
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
@IndividualComponent
|
|
33
|
+
export class Popover extends LitElement {
|
|
34
|
+
static styles = [styles];
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Determines how the popover is triggered.
|
|
38
|
+
* Possible values are `"click"`, `"hover"`, `"manual"`.
|
|
39
|
+
*/
|
|
40
|
+
@property({ reflect: true }) trigger: 'click' | 'hover' | 'manual' = 'click';
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Preferred placement of the popover relative to the trigger element.
|
|
44
|
+
* Accepts any floating-ui `Placement` string such as `"bottom"`, `"top-start"`, `"right"`, etc.
|
|
45
|
+
*/
|
|
46
|
+
@property({ reflect: true }) placement: Placement = 'bottom';
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Whether the popover is open.
|
|
50
|
+
*/
|
|
51
|
+
@property({ type: Boolean, reflect: true }) open = false;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Distance in pixels between the trigger element and the popover panel.
|
|
55
|
+
*/
|
|
56
|
+
@property({ type: Number }) offset = 8;
|
|
57
|
+
|
|
58
|
+
private _floating: FloatingController | null = null;
|
|
59
|
+
|
|
60
|
+
private _contentEl: PopoverContent | null = null;
|
|
61
|
+
|
|
62
|
+
private _triggerEl: HTMLElement | null = null;
|
|
63
|
+
|
|
64
|
+
private _setupFloating() {
|
|
65
|
+
// Tear down any existing controller
|
|
66
|
+
if (this._floating) {
|
|
67
|
+
this._floating = null;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Resolve the content element
|
|
71
|
+
this._contentEl = this.querySelector<PopoverContent>('wc-popover-content');
|
|
72
|
+
|
|
73
|
+
// Resolve the trigger element: first light-DOM child that is NOT wc-popover-content
|
|
74
|
+
this._triggerEl =
|
|
75
|
+
(Array.from(this.children).find(
|
|
76
|
+
(c) => c.tagName.toLowerCase() !== 'wc-popover-content',
|
|
77
|
+
) as HTMLElement) ?? null;
|
|
78
|
+
|
|
79
|
+
if (!this._triggerEl || !this._contentEl) return;
|
|
80
|
+
|
|
81
|
+
const triggerMode =
|
|
82
|
+
this.trigger === 'manual'
|
|
83
|
+
? 'manual'
|
|
84
|
+
: (this.trigger as 'click' | 'hover');
|
|
85
|
+
|
|
86
|
+
this._floating = new FloatingController(this, {
|
|
87
|
+
placement: this.placement,
|
|
88
|
+
strategy: 'fixed',
|
|
89
|
+
offset: this.offset,
|
|
90
|
+
trigger: triggerMode,
|
|
91
|
+
closeOnClickOutside: true,
|
|
92
|
+
onOpenChange: (isOpen) => {
|
|
93
|
+
this.open = isOpen;
|
|
94
|
+
if (this._contentEl) {
|
|
95
|
+
this._contentEl.open = isOpen;
|
|
96
|
+
}
|
|
97
|
+
this.dispatchEvent(
|
|
98
|
+
new CustomEvent(isOpen ? 'wc-popover--open' : 'wc-popover--close', {
|
|
99
|
+
bubbles: true,
|
|
100
|
+
composed: true,
|
|
101
|
+
}),
|
|
102
|
+
);
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
this._floating.setElements(
|
|
107
|
+
this._triggerEl,
|
|
108
|
+
this._contentEl as unknown as HTMLElement,
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
if (this.open) {
|
|
112
|
+
this._floating.open();
|
|
113
|
+
this._contentEl.open = true;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
connectedCallback() {
|
|
118
|
+
super.connectedCallback();
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
firstUpdated() {
|
|
122
|
+
this._setupFloating();
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
updated(changedProps: Map<string, unknown>) {
|
|
126
|
+
if (
|
|
127
|
+
changedProps.has('trigger') ||
|
|
128
|
+
changedProps.has('placement') ||
|
|
129
|
+
changedProps.has('offset')
|
|
130
|
+
) {
|
|
131
|
+
this._setupFloating();
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (changedProps.has('open') && this._floating) {
|
|
135
|
+
if (this.open && !this._floating.isOpen) {
|
|
136
|
+
this._floating.open();
|
|
137
|
+
if (this._contentEl) this._contentEl.open = true;
|
|
138
|
+
} else if (!this.open && this._floating.isOpen) {
|
|
139
|
+
this._floating.close();
|
|
140
|
+
if (this._contentEl) this._contentEl.open = false;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Programmatically opens the popover.
|
|
147
|
+
*/
|
|
148
|
+
show() {
|
|
149
|
+
if (this._floating && !this._floating.isOpen) {
|
|
150
|
+
this._floating.open();
|
|
151
|
+
} else if (!this._floating) {
|
|
152
|
+
this.open = true;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Programmatically closes the popover.
|
|
158
|
+
*/
|
|
159
|
+
hide() {
|
|
160
|
+
if (this._floating && this._floating.isOpen) {
|
|
161
|
+
this._floating.close();
|
|
162
|
+
} else if (!this._floating) {
|
|
163
|
+
this.open = false;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
render() {
|
|
168
|
+
return html`<slot></slot>`;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SplitButton } from './split-button.js';
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
@mixin _split-button-color($color) {
|
|
2
|
+
--filled-split-button-container-color: var(--color-#{$color});
|
|
3
|
+
--filled-split-button-label-text-color: var(--color-on-#{$color});
|
|
4
|
+
|
|
5
|
+
--tonal-split-button-container-color: var(--color-#{$color}-container);
|
|
6
|
+
--tonal-split-button-label-text-color: var(--color-on-#{$color}-container);
|
|
7
|
+
|
|
8
|
+
--outlined-split-button-outline-color: var(--color-#{$color});
|
|
9
|
+
--outlined-split-button-label-text-color: var(--color-#{$color});
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
:host([color=primary]) {
|
|
13
|
+
@include _split-button-color(primary);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
:host([color=secondary]) {
|
|
17
|
+
@include _split-button-color(secondary);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
:host([color=tertiary]) {
|
|
21
|
+
@include _split-button-color(tertiary);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
:host([color=success]) {
|
|
25
|
+
@include _split-button-color(success);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
:host([color=danger]) {
|
|
29
|
+
@include _split-button-color(error);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
:host([color=warning]) {
|
|
33
|
+
@include _split-button-color(warning);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
:host([color=on-surface]) {
|
|
37
|
+
--filled-split-button-container-color: var(--color-on-surface);
|
|
38
|
+
--filled-split-button-label-text-color: var(--color-surface);
|
|
39
|
+
|
|
40
|
+
--tonal-split-button-container-color: var(--color-on-surface-container);
|
|
41
|
+
--tonal-split-button-label-text-color: var(--color-surface-container-high);
|
|
42
|
+
|
|
43
|
+
--outlined-split-button-outline-color: var(--color-on-surface);
|
|
44
|
+
--outlined-split-button-label-text-color: var(--color-on-surface);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
:host([color=surface]) {
|
|
48
|
+
--filled-split-button-container-color: var(--color-surface-container-high);
|
|
49
|
+
--filled-split-button-label-text-color: var(--color-on-surface);
|
|
50
|
+
|
|
51
|
+
--tonal-split-button-container-color: var(--color-surface-container-high);
|
|
52
|
+
--tonal-split-button-label-text-color: var(--color-on-surface-container);
|
|
53
|
+
|
|
54
|
+
--outlined-split-button-outline-color: var(--color-on-surface);
|
|
55
|
+
--outlined-split-button-label-text-color: var(--color-on-surface);
|
|
56
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
:host([size='xs']),
|
|
2
|
+
:host([size='extra-small']) {
|
|
3
|
+
--split-button-icon-size: 1rem;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
:host([size='sm']),
|
|
8
|
+
:host([size='small']) {
|
|
9
|
+
--split-button-icon-size: 1.125rem;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
:host([size='md']),
|
|
14
|
+
:host([size='medium']) {
|
|
15
|
+
--split-button-icon-size: 1.25rem;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
:host([size='lg']),
|
|
20
|
+
:host([size='large']) {
|
|
21
|
+
--split-button-icon-size: 1.5rem;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
:host([size='xl']),
|
|
26
|
+
:host([size='extra-large']) {
|
|
27
|
+
--split-button-icon-size: 2rem;
|
|
28
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
@use '../../scss/mixin';
|
|
2
|
+
|
|
3
|
+
@include mixin.base-styles;
|
|
4
|
+
|
|
5
|
+
:host {
|
|
6
|
+
display: inline-flex;
|
|
7
|
+
position: relative;
|
|
8
|
+
|
|
9
|
+
--split-button-container-shape: var(--shape-corner-medium);
|
|
10
|
+
--split-button-gap: 0.125rem;
|
|
11
|
+
--split-button-icon-size: 1.125rem;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.split-button {
|
|
15
|
+
display: inline-flex;
|
|
16
|
+
align-items: center;
|
|
17
|
+
gap: var(--split-button-gap);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.action-button {
|
|
21
|
+
--button-container-shape: var(--split-button-container-shape);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.dropdown-trigger {
|
|
25
|
+
--button-container-shape: var(--split-button-container-shape);
|
|
26
|
+
--button-icon-size: var(--split-button-icon-size);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.dropdown-icon {
|
|
30
|
+
transition: transform 200ms ease;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.dropdown-trigger.active .dropdown-icon {
|
|
34
|
+
transform: rotate(180deg);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/* ── Variant: Filled ────────────────────────────────────── */
|
|
38
|
+
|
|
39
|
+
.split-button.variant-filled {
|
|
40
|
+
.action-button,
|
|
41
|
+
.dropdown-trigger {
|
|
42
|
+
--filled-button-container-color: var(--filled-split-button-container-color);
|
|
43
|
+
--filled-button-label-text-color: var(--filled-split-button-label-text-color);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
/* ── Variant: Tonal ─────────────────────────────────────── */
|
|
49
|
+
|
|
50
|
+
.split-button.variant-tonal {
|
|
51
|
+
.action-button,
|
|
52
|
+
.dropdown-trigger {
|
|
53
|
+
--tonal-button-container-color: var(--tonal-split-button-container-color);
|
|
54
|
+
--tonal-button-label-text-color: var(--tonal-split-button-label-text-color);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
/* ── Variant: Outlined ──────────────────────────────────── */
|
|
60
|
+
|
|
61
|
+
.split-button.variant-outlined {
|
|
62
|
+
.action-button,
|
|
63
|
+
.dropdown-trigger {
|
|
64
|
+
--outlined-button-outline-color: var(--outlined-split-button-outline-color, var(--color-outline));
|
|
65
|
+
--outlined-button-label-text-color: var(--outlined-split-button-label-text-color);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
:host([block]) {
|
|
70
|
+
width: 100%;
|
|
71
|
+
|
|
72
|
+
.split-button {
|
|
73
|
+
width: 100%;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.action-button {
|
|
77
|
+
flex: 1;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import { html, LitElement } from 'lit';
|
|
2
|
+
import { property, query, state } from 'lit/decorators.js';
|
|
3
|
+
import { classMap } from 'lit/directives/class-map.js';
|
|
4
|
+
import IndividualComponent from '@/IndividualComponent.js';
|
|
5
|
+
import styles from './split-button.scss';
|
|
6
|
+
import colorStyles from './split-button-colors.scss';
|
|
7
|
+
import sizeStyles from './split-button-sizes.scss';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @label Split Button
|
|
11
|
+
* @tag wc-split-button
|
|
12
|
+
* @rawTag split-button
|
|
13
|
+
*
|
|
14
|
+
* @summary A split button lets users perform a default action or choose from a set of related actions via a dropdown menu.
|
|
15
|
+
* @overview
|
|
16
|
+
* <p>A split button combines a primary action button with a dropdown arrow that opens a menu. Following M3 Material Design, the split button provides a default action alongside a set of secondary options, reducing clutter while keeping alternative actions accessible.</p>
|
|
17
|
+
*
|
|
18
|
+
* @cssprop --split-button-container-shape: Defines the border radius of the split button container shape.
|
|
19
|
+
*
|
|
20
|
+
* @cssprop --filled-split-button-container-color: Color of the filled split button container.
|
|
21
|
+
* @cssprop --filled-split-button-label-text-color: Text color of the filled split button label.
|
|
22
|
+
*
|
|
23
|
+
* @cssprop --outlined-split-button-container-color: Color of the outlined split button container.
|
|
24
|
+
* @cssprop --outlined-split-button-label-text-color: Text color of the outlined split button label.
|
|
25
|
+
*
|
|
26
|
+
* @cssprop --tonal-split-button-container-color: Color of the tonal split button container.
|
|
27
|
+
* @cssprop --tonal-split-button-label-text-color: Text color of the tonal split button label.
|
|
28
|
+
*
|
|
29
|
+
* @fires {MouseEvent} click - Dispatched when the primary action button is clicked.
|
|
30
|
+
* @fires {CustomEvent} toggle-menu - Dispatched when the dropdown menu is opened or closed.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```html
|
|
34
|
+
* <wc-split-button>
|
|
35
|
+
* Save
|
|
36
|
+
* <wc-menu-item slot="menu">Save as draft</wc-menu-item>
|
|
37
|
+
* <wc-menu-item slot="menu">Save and publish</wc-menu-item>
|
|
38
|
+
* </wc-split-button>
|
|
39
|
+
* ```
|
|
40
|
+
* @tags controls
|
|
41
|
+
*/
|
|
42
|
+
@IndividualComponent
|
|
43
|
+
export class SplitButton extends LitElement {
|
|
44
|
+
static override styles = [styles, colorStyles, sizeStyles];
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Button size.
|
|
48
|
+
* Possible values are `"xs"`, `"sm"`, `"md"`, `"lg"`, `"xl"`. Defaults to `"sm"`.
|
|
49
|
+
*/
|
|
50
|
+
@property({ reflect: true }) size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'sm';
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* The visual style of the split button.
|
|
54
|
+
*
|
|
55
|
+
* Possible variant values:
|
|
56
|
+
* `"filled"` is a filled button.
|
|
57
|
+
* `"outlined"` is an outlined button.
|
|
58
|
+
* `"tonal"` is a light color button.
|
|
59
|
+
*/
|
|
60
|
+
@property({ reflect: true }) variant: 'filled' | 'tonal' | 'outlined' =
|
|
61
|
+
'filled';
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Defines the primary color of the split button.
|
|
65
|
+
*/
|
|
66
|
+
@property({ reflect: true }) color:
|
|
67
|
+
| 'primary'
|
|
68
|
+
| 'secondary'
|
|
69
|
+
| 'tertiary'
|
|
70
|
+
| 'success'
|
|
71
|
+
| 'danger'
|
|
72
|
+
| 'warning'
|
|
73
|
+
| 'surface'
|
|
74
|
+
| 'on-surface' = 'primary';
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Whether the split button is disabled.
|
|
78
|
+
*/
|
|
79
|
+
@property({ type: Boolean, reflect: true }) disabled = false;
|
|
80
|
+
|
|
81
|
+
@state() private _menuOpen = false;
|
|
82
|
+
|
|
83
|
+
@query('.dropdown-trigger') private readonly _dropdownButton!: HTMLElement;
|
|
84
|
+
|
|
85
|
+
@query('wc-menu') private readonly _menu!: HTMLElement & {
|
|
86
|
+
open: boolean;
|
|
87
|
+
anchorElement: HTMLElement | null;
|
|
88
|
+
show: () => void;
|
|
89
|
+
close: () => void;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
private _menuId = `split-menu-${Math.random().toString(36).slice(2, 9)}`;
|
|
93
|
+
|
|
94
|
+
override focus() {
|
|
95
|
+
const btn =
|
|
96
|
+
this.shadowRoot?.querySelector<HTMLElement>('.action-button');
|
|
97
|
+
btn?.focus();
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
private _onActionClick(event: MouseEvent) {
|
|
101
|
+
if (this.disabled) {
|
|
102
|
+
event.stopImmediatePropagation();
|
|
103
|
+
event.preventDefault();
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Close menu if open
|
|
108
|
+
if (this._menuOpen) {
|
|
109
|
+
this._menu?.close();
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
private _onDropdownClick(event: MouseEvent) {
|
|
114
|
+
event.stopPropagation();
|
|
115
|
+
if (this.disabled) return;
|
|
116
|
+
|
|
117
|
+
if (this._menuOpen) {
|
|
118
|
+
this._menu?.close();
|
|
119
|
+
} else {
|
|
120
|
+
this._menu.anchorElement = this;
|
|
121
|
+
this._menu?.show();
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
private _onMenuOpened = () => {
|
|
126
|
+
this._menuOpen = true;
|
|
127
|
+
this.dispatchEvent(
|
|
128
|
+
new CustomEvent('toggle-menu', {
|
|
129
|
+
detail: { open: true },
|
|
130
|
+
bubbles: true,
|
|
131
|
+
composed: true,
|
|
132
|
+
}),
|
|
133
|
+
);
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
private _onMenuClosed = () => {
|
|
137
|
+
this._menuOpen = false;
|
|
138
|
+
this.dispatchEvent(
|
|
139
|
+
new CustomEvent('toggle-menu', {
|
|
140
|
+
detail: { open: false },
|
|
141
|
+
bubbles: true,
|
|
142
|
+
composed: true,
|
|
143
|
+
}),
|
|
144
|
+
);
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
private _onKeyDown = (event: KeyboardEvent) => {
|
|
148
|
+
if (this.disabled) return;
|
|
149
|
+
|
|
150
|
+
if (
|
|
151
|
+
event.key === 'ArrowDown' &&
|
|
152
|
+
event.target === this._dropdownButton
|
|
153
|
+
) {
|
|
154
|
+
event.preventDefault();
|
|
155
|
+
if (!this._menuOpen) {
|
|
156
|
+
this._menu.anchorElement = this;
|
|
157
|
+
this._menu?.show();
|
|
158
|
+
}
|
|
159
|
+
// Focus the menu so keyboard nav works
|
|
160
|
+
requestAnimationFrame(() => this._menu?.focus());
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (event.key === 'Escape' && this._menuOpen) {
|
|
164
|
+
this._menu?.close();
|
|
165
|
+
this._dropdownButton?.focus();
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
override connectedCallback() {
|
|
170
|
+
super.connectedCallback();
|
|
171
|
+
this.addEventListener('keydown', this._onKeyDown);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
override disconnectedCallback() {
|
|
175
|
+
this.removeEventListener('keydown', this._onKeyDown);
|
|
176
|
+
super.disconnectedCallback();
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
override render() {
|
|
180
|
+
const actionClasses = {
|
|
181
|
+
'action-button': true,
|
|
182
|
+
disabled: this.disabled,
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
const dropdownClasses = {
|
|
186
|
+
'dropdown-trigger': true,
|
|
187
|
+
active: this._menuOpen,
|
|
188
|
+
disabled: this.disabled,
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
const containerClasses = {
|
|
192
|
+
'split-button': true,
|
|
193
|
+
[`variant-${this.variant}`]: true,
|
|
194
|
+
disabled: this.disabled,
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
return html`
|
|
198
|
+
<div class=${classMap(containerClasses)}>
|
|
199
|
+
<wc-button
|
|
200
|
+
class=${classMap(actionClasses)}
|
|
201
|
+
size=${this.size}
|
|
202
|
+
variant=${this.variant}
|
|
203
|
+
?disabled=${this.disabled}
|
|
204
|
+
@click=${this._onActionClick}
|
|
205
|
+
>
|
|
206
|
+
<slot></slot>
|
|
207
|
+
</wc-button>
|
|
208
|
+
|
|
209
|
+
<wc-icon-button
|
|
210
|
+
class=${classMap(dropdownClasses)}
|
|
211
|
+
size=${this.size}
|
|
212
|
+
variant=${this.variant}
|
|
213
|
+
?disabled=${this.disabled}
|
|
214
|
+
.configAria=${{
|
|
215
|
+
'aria-haspopup': 'menu',
|
|
216
|
+
'aria-expanded': String(this._menuOpen),
|
|
217
|
+
'aria-controls': this._menuId,
|
|
218
|
+
'aria-label': 'Open split button menu',
|
|
219
|
+
}}
|
|
220
|
+
@click=${this._onDropdownClick}
|
|
221
|
+
>
|
|
222
|
+
<wc-icon class="dropdown-icon" name="arrow_drop_down" aria-hidden="true"></wc-icon>
|
|
223
|
+
</wc-icon-button>
|
|
224
|
+
</div>
|
|
225
|
+
|
|
226
|
+
<wc-menu
|
|
227
|
+
id=${this._menuId}
|
|
228
|
+
placement="bottom-end"
|
|
229
|
+
@opened=${this._onMenuOpened}
|
|
230
|
+
@closed=${this._onMenuClosed}
|
|
231
|
+
>
|
|
232
|
+
<slot name="menu"></slot>
|
|
233
|
+
</wc-menu>
|
|
234
|
+
`;
|
|
235
|
+
}
|
|
236
|
+
}
|
package/src/table/table.ts
CHANGED
|
@@ -218,7 +218,7 @@ export class Table extends LitElement {
|
|
|
218
218
|
}
|
|
219
219
|
|
|
220
220
|
private getTotalItems(): number {
|
|
221
|
-
if (this.paginate && !this.managed) return this.data.length;
|
|
221
|
+
if (this.paginate && !this.managed && this.data) return this.data.length;
|
|
222
222
|
return this.totalItems ?? 0;
|
|
223
223
|
}
|
|
224
224
|
|
|
@@ -468,7 +468,7 @@ export class Table extends LitElement {
|
|
|
468
468
|
<div class=${classMap(tableClasses)}>
|
|
469
469
|
<div class="table-scroll-container" @scroll=${this.onScrollContainer}>
|
|
470
470
|
${this.renderHeader()}
|
|
471
|
-
${this.data.length ? this.renderBody() : this.renderEmptyState()}
|
|
471
|
+
${this.data && this.data.length ? this.renderBody() : this.renderEmptyState()}
|
|
472
472
|
</div>
|
|
473
473
|
<div class="table-footer">${this.renderPagination()}</div>
|
|
474
474
|
</div>
|
package/src/tooltip/tooltip.scss
CHANGED
|
@@ -5,13 +5,14 @@
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
:host(:not([preview])) {
|
|
8
|
+
position: absolute;
|
|
9
|
+
top: 0;
|
|
10
|
+
left: 0;
|
|
11
|
+
|
|
8
12
|
.tooltip {
|
|
9
13
|
pointer-events: none;
|
|
10
14
|
transition: transform var(--duration-short2) ease-in-out, opacity var(--duration-short2) ease-in-out;
|
|
11
15
|
transform: scale(0);
|
|
12
|
-
position: absolute;
|
|
13
|
-
top: 0;
|
|
14
|
-
left: 0;
|
|
15
16
|
opacity: 0;
|
|
16
17
|
}
|
|
17
18
|
|