@redvars/peacock 3.5.1 → 3.6.1

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.
Files changed (225) hide show
  1. package/dist/{BaseButton-DuASuVth.js → BaseButton-BNFAYn-S.js} +2 -2
  2. package/dist/{BaseButton-DuASuVth.js.map → BaseButton-BNFAYn-S.js.map} +1 -1
  3. package/dist/BaseInput-14YmcfK7.js +27 -0
  4. package/dist/BaseInput-14YmcfK7.js.map +1 -0
  5. package/dist/banner.js +2 -3
  6. package/dist/banner.js.map +1 -1
  7. package/dist/{button-DouvOfEU.js → button-colors-Ccys3hvS.js} +5 -294
  8. package/dist/button-colors-Ccys3hvS.js.map +1 -0
  9. package/dist/button-group.js +226 -6
  10. package/dist/button-group.js.map +1 -1
  11. package/dist/button.js +294 -8
  12. package/dist/button.js.map +1 -1
  13. package/dist/calendar-column-view.js +634 -0
  14. package/dist/calendar-column-view.js.map +1 -0
  15. package/dist/calendar-event-BrQ_SEKD.js +199 -0
  16. package/dist/calendar-event-BrQ_SEKD.js.map +1 -0
  17. package/dist/calendar-month-view.js +376 -0
  18. package/dist/calendar-month-view.js.map +1 -0
  19. package/dist/calendar.js +339 -0
  20. package/dist/calendar.js.map +1 -0
  21. package/dist/canvas.js +361 -0
  22. package/dist/canvas.js.map +1 -0
  23. package/dist/cb-compound-expression.js +125 -0
  24. package/dist/cb-compound-expression.js.map +1 -0
  25. package/dist/cb-divider.js +150 -0
  26. package/dist/cb-divider.js.map +1 -0
  27. package/dist/cb-expression.js +75 -0
  28. package/dist/cb-expression.js.map +1 -0
  29. package/dist/cb-predicate.js +137 -0
  30. package/dist/cb-predicate.js.map +1 -0
  31. package/dist/code-editor.js +2 -1
  32. package/dist/code-editor.js.map +1 -1
  33. package/dist/code-highlighter.js +1 -1
  34. package/dist/code-highlighter.js.map +1 -1
  35. package/dist/condition-builder.js +58 -0
  36. package/dist/condition-builder.js.map +1 -0
  37. package/dist/custom-elements-jsdocs.json +8479 -3965
  38. package/dist/custom-elements.json +15228 -7544
  39. package/dist/dropdown-button.js +216 -0
  40. package/dist/dropdown-button.js.map +1 -0
  41. package/dist/event-manager-D-QCmUgR.js +113 -0
  42. package/dist/event-manager-D-QCmUgR.js.map +1 -0
  43. package/dist/fab.js +1 -1
  44. package/dist/flow-designer-DvTUrDp5.js +1656 -0
  45. package/dist/flow-designer-DvTUrDp5.js.map +1 -0
  46. package/dist/flow-designer-node-BWrPuxAR.js +548 -0
  47. package/dist/flow-designer-node-BWrPuxAR.js.map +1 -0
  48. package/dist/flow-designer-node.js +4 -0
  49. package/dist/flow-designer-node.js.map +1 -0
  50. package/dist/flow-designer.js +16 -0
  51. package/dist/flow-designer.js.map +1 -0
  52. package/dist/html-editor.js +27516 -0
  53. package/dist/html-editor.js.map +1 -0
  54. package/dist/icon-button-CK1ZuE-2.js +247 -0
  55. package/dist/icon-button-CK1ZuE-2.js.map +1 -0
  56. package/dist/index.js +29 -6
  57. package/dist/index.js.map +1 -1
  58. package/dist/{is-dark-mode-DicqGkCJ.js → is-dark-mode-DOcaw4Yq.js} +2 -27
  59. package/dist/is-dark-mode-DOcaw4Yq.js.map +1 -0
  60. package/dist/modal.js +412 -0
  61. package/dist/modal.js.map +1 -0
  62. package/dist/{navigation-rail-Lxetd5-Z.js → navigation-rail-DTTkqohi.js} +1049 -2391
  63. package/dist/navigation-rail-DTTkqohi.js.map +1 -0
  64. package/dist/notification-manager.js +268 -0
  65. package/dist/notification-manager.js.map +1 -0
  66. package/dist/peacock-loader.js +93 -8
  67. package/dist/peacock-loader.js.map +1 -1
  68. package/dist/popover-NC7b1lTq.js +1971 -0
  69. package/dist/popover-NC7b1lTq.js.map +1 -0
  70. package/dist/popover-content.js +125 -0
  71. package/dist/popover-content.js.map +1 -0
  72. package/dist/popover.js +4 -0
  73. package/dist/popover.js.map +1 -0
  74. package/dist/split-button.js +388 -0
  75. package/dist/split-button.js.map +1 -0
  76. package/dist/src/__controllers/floating-controller.d.ts +35 -0
  77. package/dist/src/calendar/base-event.d.ts +10 -0
  78. package/dist/src/calendar/calendar-column-view.d.ts +41 -0
  79. package/dist/src/calendar/calendar-event.d.ts +7 -0
  80. package/dist/src/calendar/calendar-month-view.d.ts +31 -0
  81. package/dist/src/calendar/calendar.d.ts +65 -0
  82. package/dist/src/calendar/event-manager.d.ts +17 -0
  83. package/dist/src/calendar/index.d.ts +4 -0
  84. package/dist/src/calendar/types.d.ts +13 -0
  85. package/dist/src/calendar/utils.d.ts +31 -0
  86. package/dist/src/canvas/canvas.d.ts +92 -0
  87. package/dist/src/canvas/index.d.ts +2 -0
  88. package/dist/src/condition-builder/cb-compound-expression.d.ts +31 -0
  89. package/dist/src/condition-builder/cb-divider.d.ts +26 -0
  90. package/dist/src/condition-builder/cb-expression.d.ts +31 -0
  91. package/dist/src/condition-builder/cb-predicate.d.ts +30 -0
  92. package/dist/src/condition-builder/condition-builder.d.ts +27 -0
  93. package/dist/src/condition-builder/index.d.ts +5 -0
  94. package/dist/src/dropdown-button/dropdown-button.d.ts +68 -0
  95. package/dist/src/dropdown-button/index.d.ts +1 -0
  96. package/dist/src/flow-designer/commands.d.ts +66 -0
  97. package/dist/src/flow-designer/flow-designer-node.d.ts +46 -0
  98. package/dist/src/flow-designer/flow-designer.d.ts +133 -0
  99. package/dist/src/flow-designer/index.d.ts +7 -0
  100. package/dist/src/flow-designer/layout.d.ts +30 -0
  101. package/dist/src/flow-designer/types.d.ts +142 -0
  102. package/dist/src/flow-designer/validation.d.ts +43 -0
  103. package/dist/src/flow-designer/workflow-utils.d.ts +40 -0
  104. package/dist/src/html-editor/html-editor.d.ts +89 -0
  105. package/dist/src/html-editor/index.d.ts +2 -0
  106. package/dist/src/index.d.ts +15 -0
  107. package/dist/src/list/index.d.ts +2 -0
  108. package/dist/src/list/list-item.d.ts +35 -0
  109. package/dist/src/list/list.d.ts +28 -0
  110. package/dist/src/menu/menu/menu.d.ts +5 -7
  111. package/dist/src/menu/menu-item/menu-item.d.ts +14 -13
  112. package/dist/src/modal/index.d.ts +1 -0
  113. package/dist/src/modal/modal.d.ts +57 -0
  114. package/dist/src/navigation-rail/navigation-rail.d.ts +3 -7
  115. package/dist/src/notification-manager/index.d.ts +1 -0
  116. package/dist/src/notification-manager/notification-manager.d.ts +44 -0
  117. package/dist/src/number-field/number-field.d.ts +2 -2
  118. package/dist/src/popover/index.d.ts +2 -0
  119. package/dist/src/popover/popover-content.d.ts +29 -0
  120. package/dist/src/popover/popover.d.ts +62 -0
  121. package/dist/src/split-button/index.d.ts +1 -0
  122. package/dist/src/split-button/split-button.d.ts +72 -0
  123. package/dist/src/svg/index.d.ts +1 -0
  124. package/dist/src/svg/svg.d.ts +38 -0
  125. package/dist/src/toolbar/toolbar.d.ts +3 -3
  126. package/dist/src/tooltip/tooltip.d.ts +2 -15
  127. package/dist/test/flow-designer.test.d.ts +1 -0
  128. package/dist/toolbar.js +3 -3
  129. package/dist/toolbar.js.map +1 -1
  130. package/dist/tsconfig.tsbuildinfo +1 -1
  131. package/package.json +10 -2
  132. package/readme.md +3 -3
  133. package/src/__controllers/floating-controller.ts +237 -0
  134. package/src/banner/banner.scss +2 -3
  135. package/src/button/button/button.ts +1 -0
  136. package/src/calendar/base-event.ts +49 -0
  137. package/src/calendar/calendar-column-view.scss +326 -0
  138. package/src/calendar/calendar-column-view.ts +392 -0
  139. package/src/calendar/calendar-event.ts +20 -0
  140. package/src/calendar/calendar-month-view.scss +192 -0
  141. package/src/calendar/calendar-month-view.ts +244 -0
  142. package/src/calendar/calendar.scss +71 -0
  143. package/src/calendar/calendar.ts +298 -0
  144. package/src/calendar/event-manager.ts +117 -0
  145. package/src/calendar/index.ts +4 -0
  146. package/src/calendar/types.ts +14 -0
  147. package/src/calendar/utils.ts +180 -0
  148. package/src/canvas/canvas.scss +60 -0
  149. package/src/canvas/canvas.ts +391 -0
  150. package/src/canvas/index.ts +2 -0
  151. package/src/code-highlighter/code-highlighter.ts +1 -1
  152. package/src/condition-builder/cb-compound-expression.scss +37 -0
  153. package/src/condition-builder/cb-compound-expression.ts +80 -0
  154. package/src/condition-builder/cb-divider.scss +93 -0
  155. package/src/condition-builder/cb-divider.ts +56 -0
  156. package/src/condition-builder/cb-expression.scss +14 -0
  157. package/src/condition-builder/cb-expression.ts +49 -0
  158. package/src/condition-builder/cb-predicate.scss +35 -0
  159. package/src/condition-builder/cb-predicate.ts +102 -0
  160. package/src/condition-builder/condition-builder.scss +13 -0
  161. package/src/condition-builder/condition-builder.ts +38 -0
  162. package/src/condition-builder/index.ts +5 -0
  163. package/src/dropdown-button/demo/index.html +110 -0
  164. package/src/dropdown-button/dropdown-button.scss +22 -0
  165. package/src/dropdown-button/dropdown-button.ts +206 -0
  166. package/src/dropdown-button/index.ts +1 -0
  167. package/src/flow-designer/DEMO.md +239 -0
  168. package/src/flow-designer/commands.ts +278 -0
  169. package/src/flow-designer/flow-designer-node.ts +172 -0
  170. package/src/flow-designer/flow-designer.scss +457 -0
  171. package/src/flow-designer/flow-designer.ts +611 -0
  172. package/src/flow-designer/index.ts +41 -0
  173. package/src/flow-designer/layout.ts +357 -0
  174. package/src/flow-designer/types.ts +166 -0
  175. package/src/flow-designer/validation.ts +284 -0
  176. package/src/flow-designer/workflow-utils.ts +282 -0
  177. package/src/html-editor/html-editor.scss +188 -0
  178. package/src/html-editor/html-editor.ts +491 -0
  179. package/src/html-editor/index.ts +3 -0
  180. package/src/index.ts +27 -1
  181. package/src/list/index.ts +2 -0
  182. package/src/list/list-item.scss +111 -0
  183. package/src/list/list-item.ts +175 -0
  184. package/src/list/list.scss +24 -0
  185. package/src/list/list.ts +51 -0
  186. package/src/menu/menu/menu.scss +2 -2
  187. package/src/menu/menu/menu.ts +91 -101
  188. package/src/menu/menu-item/menu-item.scss +4 -0
  189. package/src/menu/menu-item/menu-item.ts +82 -78
  190. package/src/modal/index.ts +1 -0
  191. package/src/modal/modal.scss +206 -0
  192. package/src/modal/modal.ts +195 -0
  193. package/src/navigation-rail/navigation-rail-item.scss +7 -38
  194. package/src/navigation-rail/navigation-rail-item.ts +1 -2
  195. package/src/navigation-rail/navigation-rail.scss +17 -21
  196. package/src/navigation-rail/navigation-rail.ts +6 -9
  197. package/src/notification-manager/index.ts +1 -0
  198. package/src/notification-manager/notification-manager.scss +113 -0
  199. package/src/notification-manager/notification-manager.ts +199 -0
  200. package/src/number-field/number-field.ts +2 -2
  201. package/src/peacock-loader.ts +83 -0
  202. package/src/popover/index.ts +2 -0
  203. package/src/popover/popover-content.scss +69 -0
  204. package/src/popover/popover-content.ts +51 -0
  205. package/src/popover/popover.scss +7 -0
  206. package/src/popover/popover.ts +170 -0
  207. package/src/split-button/index.ts +1 -0
  208. package/src/split-button/split-button-colors.scss +56 -0
  209. package/src/split-button/split-button-sizes.scss +28 -0
  210. package/src/split-button/split-button.scss +79 -0
  211. package/src/split-button/split-button.ts +236 -0
  212. package/src/svg/index.ts +1 -0
  213. package/src/svg/svg.scss +91 -0
  214. package/src/svg/svg.ts +160 -0
  215. package/src/table/table.ts +2 -2
  216. package/src/toolbar/toolbar.ts +3 -3
  217. package/src/tooltip/tooltip.scss +4 -3
  218. package/src/tooltip/tooltip.ts +46 -104
  219. package/dist/button-DouvOfEU.js.map +0 -1
  220. package/dist/button-group-CEdMwvJJ.js +0 -464
  221. package/dist/button-group-CEdMwvJJ.js.map +0 -1
  222. package/dist/is-dark-mode-DicqGkCJ.js.map +0 -1
  223. package/dist/navigation-rail-Lxetd5-Z.js.map +0 -1
  224. package/dist/src/menu/menu/MenuSurfaceController.d.ts +0 -18
  225. package/src/menu/menu/MenuSurfaceController.ts +0 -61
@@ -0,0 +1,49 @@
1
+ import { html, LitElement } from 'lit';
2
+ import { property } from 'lit/decorators.js';
3
+ import IndividualComponent from '@/IndividualComponent.js';
4
+ import styles from './cb-expression.scss';
5
+
6
+ /**
7
+ * @label CB Expression
8
+ * @tag wc-cb-expression
9
+ * @rawTag cb-expression
10
+ * @summary An expression row within a condition builder, containing an operator select and a slot for value inputs.
11
+ * @tags condition-builder
12
+ * @parentRawTag compound-builder
13
+ *
14
+ * @example
15
+ * ```html
16
+ * <wc-cb-expression>
17
+ * <wc-input placeholder="Enter value"></wc-input>
18
+ * </wc-cb-expression>
19
+ * ```
20
+ */
21
+ @IndividualComponent
22
+ export class CbExpression extends LitElement {
23
+ static styles = [styles];
24
+
25
+ /**
26
+ * The list of operator options to display in the operator select.
27
+ * Each item should have at least `label` and `value` properties.
28
+ */
29
+ @property({ type: Array })
30
+ operators: { label: string; value: string; icon?: string }[] = [];
31
+
32
+ /** The currently selected operator value. */
33
+ @property({ type: String, attribute: 'operator-value' })
34
+ operatorValue = '';
35
+
36
+ render() {
37
+ return html`
38
+ <div class="expression">
39
+ <wc-select
40
+ inline
41
+ .value=${this.operatorValue}
42
+ placeholder="Select Operator"
43
+ .options=${this.operators}
44
+ ></wc-select>
45
+ <slot></slot>
46
+ </div>
47
+ `;
48
+ }
49
+ }
@@ -0,0 +1,35 @@
1
+ @use '../../scss/mixin';
2
+
3
+ @include mixin.base-styles;
4
+
5
+ :host {
6
+ display: block;
7
+ }
8
+
9
+ .predicate:not(.vertical) {
10
+ .predicate-body {
11
+ padding-top: var(--spacing-200);
12
+ }
13
+
14
+ .predicate-condition-operator {
15
+ padding: var(--spacing-200) var(--spacing-400) 0 var(--spacing-400);
16
+ }
17
+ }
18
+
19
+ .predicate.vertical {
20
+ display: flex;
21
+ align-items: stretch;
22
+
23
+ .predicate-condition-operator {
24
+ padding: var(--spacing-400) 0 var(--spacing-200) 0;
25
+ padding-inline-end: var(--spacing-200);
26
+ }
27
+
28
+ .predicate-body {
29
+ flex: 1;
30
+ }
31
+ }
32
+
33
+ .slot-end {
34
+ display: block;
35
+ }
@@ -0,0 +1,102 @@
1
+ import { html, LitElement, nothing } from 'lit';
2
+ import { property } from 'lit/decorators.js';
3
+ import { classMap } from 'lit/directives/class-map.js';
4
+ import IndividualComponent from '@/IndividualComponent.js';
5
+ import styles from './cb-predicate.scss';
6
+
7
+ /**
8
+ * @label CB Predicate
9
+ * @tag wc-cb-predicate
10
+ * @rawTag cb-predicate
11
+ * @summary A predicate container in a condition builder that can display conditions in horizontal or vertical layout with an optional logical operator divider.
12
+ * @tags condition-builder
13
+ * @parentRawTag compound-expression
14
+ *
15
+ * @example
16
+ * ```html
17
+ * <wc-cb-predicate condition-operator="and" vertical>
18
+ * <wc-cb-compound-expression field-label="Age">
19
+ * <wc-cb-expression></wc-cb-expression>
20
+ * </wc-cb-compound-expression>
21
+ * </wc-cb-predicate>
22
+ * ```
23
+ */
24
+ @IndividualComponent
25
+ export class CbPredicate extends LitElement {
26
+ static styles = [styles];
27
+
28
+ /** The logical operator shown between predicates ('and' or 'or'). */
29
+ @property({ type: String, attribute: 'condition-operator', reflect: true })
30
+ conditionOperator?: 'and' | 'or';
31
+
32
+ /** Whether to render the predicate in vertical layout. */
33
+ @property({ type: Boolean, reflect: true })
34
+ vertical = false;
35
+
36
+ override updated() {
37
+ if (this.vertical) {
38
+ this.__adjustSlotEndPadding();
39
+ }
40
+ }
41
+
42
+ private __adjustSlotEndPadding() {
43
+ const slotEnd = this.renderRoot.querySelector<HTMLElement>('.slot-end');
44
+ const operatorElm = this.renderRoot.querySelector<HTMLElement>(
45
+ '.predicate-condition-operator',
46
+ );
47
+ if (slotEnd && operatorElm) {
48
+ slotEnd.style.paddingInlineStart =
49
+ operatorElm.getBoundingClientRect().width + 'px';
50
+ }
51
+ }
52
+
53
+ private __renderHorizontalOperator() {
54
+ if (!this.conditionOperator) return nothing;
55
+ return html`
56
+ <wc-cb-divider vertical class="predicate-condition-operator">
57
+ <wc-tag color="yellow" size="sm">${this.conditionOperator}</wc-tag>
58
+ </wc-cb-divider>
59
+ `;
60
+ }
61
+
62
+ private __renderVerticalOperator() {
63
+ if (!this.conditionOperator) return nothing;
64
+ return html`
65
+ <div class="predicate-condition-operator">
66
+ <wc-cb-divider connect-start connect-end>
67
+ <wc-tag color="green" size="sm">${this.conditionOperator}</wc-tag>
68
+ </wc-cb-divider>
69
+ </div>
70
+ `;
71
+ }
72
+
73
+ render() {
74
+ const classes = {
75
+ predicate: true,
76
+ vertical: this.vertical,
77
+ };
78
+
79
+ if (this.vertical) {
80
+ return html`
81
+ <div class=${classMap(classes)}>
82
+ ${this.__renderVerticalOperator()}
83
+ <div class="predicate-body">
84
+ <slot></slot>
85
+ </div>
86
+ </div>
87
+ <div class="slot-end">
88
+ <slot name="end"></slot>
89
+ </div>
90
+ `;
91
+ }
92
+
93
+ return html`
94
+ <div class=${classMap(classes)}>
95
+ <div class="predicate-body">
96
+ <slot></slot>
97
+ </div>
98
+ ${this.__renderHorizontalOperator()}
99
+ </div>
100
+ `;
101
+ }
102
+ }
@@ -0,0 +1,13 @@
1
+ @use '../../scss/mixin';
2
+
3
+ @include mixin.base-styles;
4
+
5
+ :host {
6
+ display: block;
7
+ }
8
+
9
+ .condition-builder {
10
+ display: flex;
11
+ flex-direction: column;
12
+ gap: var(--spacing-200);
13
+ }
@@ -0,0 +1,38 @@
1
+ import { html, LitElement } from 'lit';
2
+ import IndividualComponent from '@/IndividualComponent.js';
3
+ import styles from './condition-builder.scss';
4
+
5
+ /**
6
+ * @label Condition Builder
7
+ * @tag wc-condition-builder
8
+ * @rawTag condition-builder
9
+ * @summary A condition builder component that allows users to construct complex filter conditions using a visual rule-based interface with predicates, compound expressions, and logical operators.
10
+ * @tags condition-builder
11
+ *
12
+ * @example
13
+ * ```html
14
+ * <wc-condition-builder>
15
+ * <wc-cb-predicate condition-operator="or">
16
+ * <wc-cb-predicate vertical condition-operator="and">
17
+ * <wc-cb-compound-expression field-label="Age" condition-operator="or">
18
+ * <wc-cb-expression>
19
+ * <wc-input inline placeholder="Enter value"></wc-input>
20
+ * </wc-cb-expression>
21
+ * </wc-cb-compound-expression>
22
+ * </wc-cb-predicate>
23
+ * </wc-cb-predicate>
24
+ * </wc-condition-builder>
25
+ * ```
26
+ */
27
+ @IndividualComponent
28
+ export class ConditionBuilder extends LitElement {
29
+ static styles = [styles];
30
+
31
+ render() {
32
+ return html`
33
+ <div class="condition-builder">
34
+ <slot></slot>
35
+ </div>
36
+ `;
37
+ }
38
+ }
@@ -0,0 +1,5 @@
1
+ export { ConditionBuilder } from './condition-builder.js';
2
+ export { CbPredicate } from './cb-predicate.js';
3
+ export { CbCompoundExpression } from './cb-compound-expression.js';
4
+ export { CbExpression } from './cb-expression.js';
5
+ export { CbDivider } from './cb-divider.js';
@@ -0,0 +1,110 @@
1
+ <!doctype html>
2
+ <html lang='en-GB'>
3
+ <head>
4
+ <meta charset='utf-8'>
5
+ <meta name='viewport' content='width=device-width, initial-scale=1.0, viewport-fit=cover' />
6
+ <link rel='stylesheet' href='/dist/assets/styles/tokens.css' />
7
+ <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+Mono:wght@100..900&family=Noto+Sans:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
8
+
9
+ <style>
10
+ body {
11
+ background: var(--color-surface);
12
+ padding: 2rem;
13
+ display: flex;
14
+ flex-wrap: wrap;
15
+ gap: 1rem;
16
+ align-items: flex-start;
17
+ font-family: var(--font-family-sans);
18
+ }
19
+ </style>
20
+ </head>
21
+ <body>
22
+
23
+ <!-- Basic usage -->
24
+ <wc-dropdown-button>
25
+ Actions
26
+ <wc-menu-item slot="menu">Edit</wc-menu-item>
27
+ <wc-menu-item slot="menu">Duplicate</wc-menu-item>
28
+ <wc-menu-item slot="menu">Delete</wc-menu-item>
29
+ </wc-dropdown-button>
30
+
31
+ <!-- Variants -->
32
+ <wc-dropdown-button variant="filled">
33
+ Filled
34
+ <wc-menu-item slot="menu">Option A</wc-menu-item>
35
+ <wc-menu-item slot="menu">Option B</wc-menu-item>
36
+ </wc-dropdown-button>
37
+ <wc-dropdown-button variant="tonal">
38
+ Tonal
39
+ <wc-menu-item slot="menu">Option A</wc-menu-item>
40
+ <wc-menu-item slot="menu">Option B</wc-menu-item>
41
+ </wc-dropdown-button>
42
+ <wc-dropdown-button variant="outlined">
43
+ Outlined
44
+ <wc-menu-item slot="menu">Option A</wc-menu-item>
45
+ <wc-menu-item slot="menu">Option B</wc-menu-item>
46
+ </wc-dropdown-button>
47
+ <wc-dropdown-button variant="text">
48
+ Text
49
+ <wc-menu-item slot="menu">Option A</wc-menu-item>
50
+ <wc-menu-item slot="menu">Option B</wc-menu-item>
51
+ </wc-dropdown-button>
52
+ <wc-dropdown-button variant="elevated">
53
+ Elevated
54
+ <wc-menu-item slot="menu">Option A</wc-menu-item>
55
+ <wc-menu-item slot="menu">Option B</wc-menu-item>
56
+ </wc-dropdown-button>
57
+
58
+ <!-- Colors -->
59
+ <wc-dropdown-button color="primary">
60
+ Primary
61
+ <wc-menu-item slot="menu">Option A</wc-menu-item>
62
+ <wc-menu-item slot="menu">Option B</wc-menu-item>
63
+ </wc-dropdown-button>
64
+ <wc-dropdown-button color="success">
65
+ Success
66
+ <wc-menu-item slot="menu">Option A</wc-menu-item>
67
+ <wc-menu-item slot="menu">Option B</wc-menu-item>
68
+ </wc-dropdown-button>
69
+ <wc-dropdown-button color="danger">
70
+ Danger
71
+ <wc-menu-item slot="menu">Option A</wc-menu-item>
72
+ <wc-menu-item slot="menu">Option B</wc-menu-item>
73
+ </wc-dropdown-button>
74
+
75
+ <!-- Sizes -->
76
+ <wc-dropdown-button size="xs">
77
+ Extra small
78
+ <wc-menu-item slot="menu">Option A</wc-menu-item>
79
+ <wc-menu-item slot="menu">Option B</wc-menu-item>
80
+ </wc-dropdown-button>
81
+ <wc-dropdown-button size="sm">
82
+ Small
83
+ <wc-menu-item slot="menu">Option A</wc-menu-item>
84
+ <wc-menu-item slot="menu">Option B</wc-menu-item>
85
+ </wc-dropdown-button>
86
+ <wc-dropdown-button size="md">
87
+ Medium
88
+ <wc-menu-item slot="menu">Option A</wc-menu-item>
89
+ <wc-menu-item slot="menu">Option B</wc-menu-item>
90
+ </wc-dropdown-button>
91
+
92
+ <!-- Disabled -->
93
+ <wc-dropdown-button disabled>
94
+ Disabled
95
+ <wc-menu-item slot="menu">Option A</wc-menu-item>
96
+ <wc-menu-item slot="menu">Option B</wc-menu-item>
97
+ </wc-dropdown-button>
98
+
99
+ <!-- Placement -->
100
+ <wc-dropdown-button placement="bottom-end">
101
+ Bottom End
102
+ <wc-menu-item slot="menu">Option 1</wc-menu-item>
103
+ <wc-menu-item slot="menu">Option 2</wc-menu-item>
104
+ </wc-dropdown-button>
105
+
106
+ <script type='module'>
107
+ import '/dist/peacock-loader.js';
108
+ </script>
109
+ </body>
110
+ </html>
@@ -0,0 +1,22 @@
1
+ @use '../../scss/mixin';
2
+
3
+ @include mixin.base-styles;
4
+
5
+ :host {
6
+ display: inline-flex;
7
+ position: relative;
8
+
9
+ --dropdown-button-container-shape: var(--shape-corner-medium);
10
+ }
11
+
12
+ .trigger-button {
13
+ --button-container-shape: var(--dropdown-button-container-shape);
14
+ }
15
+
16
+ .dropdown-icon {
17
+ transition: transform 200ms ease;
18
+ }
19
+
20
+ .trigger-button.active .dropdown-icon {
21
+ transform: rotate(180deg);
22
+ }
@@ -0,0 +1,206 @@
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 './dropdown-button.scss';
6
+
7
+ /**
8
+ * @label Dropdown Button
9
+ * @tag wc-dropdown-button
10
+ * @rawTag dropdown-button
11
+ *
12
+ * @summary A button that opens a dropdown menu when clicked.
13
+ * @overview
14
+ * <p>The dropdown button combines a single button with a dropdown menu. Clicking the button toggles a menu of actions or options. It follows M3 Material Design, keeping a compact control while exposing related actions on demand.</p>
15
+ *
16
+ * @cssprop --dropdown-button-container-shape: Defines the border radius of the dropdown button container shape.
17
+ *
18
+ * @fires {CustomEvent} toggle-menu - Dispatched when the dropdown menu is opened or closed.
19
+ *
20
+ * @example
21
+ * ```html
22
+ * <wc-dropdown-button>
23
+ * Actions
24
+ * <wc-menu-item slot="menu">Edit</wc-menu-item>
25
+ * <wc-menu-item slot="menu">Delete</wc-menu-item>
26
+ * </wc-dropdown-button>
27
+ * ```
28
+ * @tags controls
29
+ */
30
+ @IndividualComponent
31
+ export class DropdownButton extends LitElement {
32
+ static override styles = [styles];
33
+
34
+ /**
35
+ * Button size.
36
+ * Possible values are `"xs"`, `"sm"`, `"md"`, `"lg"`, `"xl"`. Defaults to `"sm"`.
37
+ */
38
+ @property({ reflect: true }) size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'sm';
39
+
40
+ /**
41
+ * The visual style of the dropdown button.
42
+ *
43
+ * Possible variant values:
44
+ * `"filled"` is a filled button.
45
+ * `"outlined"` is an outlined button.
46
+ * `"text"` is a transparent button.
47
+ * `"tonal"` is a light color button.
48
+ * `"elevated"` is an elevated button.
49
+ */
50
+ @property({ reflect: true }) variant:
51
+ | 'elevated'
52
+ | 'filled'
53
+ | 'tonal'
54
+ | 'outlined'
55
+ | 'text' = 'filled';
56
+
57
+ /**
58
+ * Defines the primary color of the dropdown button.
59
+ */
60
+ @property({ reflect: true }) color:
61
+ | 'primary'
62
+ | 'secondary'
63
+ | 'tertiary'
64
+ | 'success'
65
+ | 'danger'
66
+ | 'warning'
67
+ | 'surface'
68
+ | 'on-surface' = 'primary';
69
+
70
+ /**
71
+ * Whether the dropdown button is disabled.
72
+ */
73
+ @property({ type: Boolean, reflect: true }) disabled = false;
74
+
75
+ /**
76
+ * Menu placement relative to the button.
77
+ * Possible values are `"bottom-start"`, `"bottom-end"`, `"top-start"`, `"top-end"`. Defaults to `"bottom-start"`.
78
+ */
79
+ @property({ reflect: true }) placement:
80
+ | 'bottom-start'
81
+ | 'bottom-end'
82
+ | 'top-start'
83
+ | 'top-end' = 'bottom-start';
84
+
85
+ @state() private _menuOpen = false;
86
+
87
+ @query('.trigger-button') private readonly _triggerButton!: HTMLElement & {
88
+ focus: () => void;
89
+ };
90
+
91
+ @query('wc-menu') private readonly _menu!: HTMLElement & {
92
+ open: boolean;
93
+ anchorElement: HTMLElement | null;
94
+ show: () => void;
95
+ close: () => void;
96
+ focus: () => void;
97
+ };
98
+
99
+ private _menuId = `dropdown-menu-${Math.random().toString(36).slice(2, 9)}`;
100
+
101
+ override focus() {
102
+ this._triggerButton?.focus();
103
+ }
104
+
105
+ private _onButtonClick(event: MouseEvent) {
106
+ event.stopPropagation();
107
+ if (this.disabled) return;
108
+
109
+ if (this._menuOpen) {
110
+ this._menu?.close();
111
+ } else {
112
+ this._menu.anchorElement = this;
113
+ this._menu?.show();
114
+ }
115
+ }
116
+
117
+ private _onMenuOpened = () => {
118
+ this._menuOpen = true;
119
+ this.dispatchEvent(
120
+ new CustomEvent('toggle-menu', {
121
+ detail: { open: true },
122
+ bubbles: true,
123
+ composed: true,
124
+ }),
125
+ );
126
+ };
127
+
128
+ private _onMenuClosed = () => {
129
+ this._menuOpen = false;
130
+ this.dispatchEvent(
131
+ new CustomEvent('toggle-menu', {
132
+ detail: { open: false },
133
+ bubbles: true,
134
+ composed: true,
135
+ }),
136
+ );
137
+ };
138
+
139
+ private _onKeyDown = (event: KeyboardEvent) => {
140
+ if (this.disabled) return;
141
+
142
+ if (event.key === 'ArrowDown' && !this._menuOpen) {
143
+ event.preventDefault();
144
+ this._menu.anchorElement = this;
145
+ this._menu?.show();
146
+ requestAnimationFrame(() => this._menu?.focus());
147
+ }
148
+
149
+ if (event.key === 'Escape' && this._menuOpen) {
150
+ this._menu?.close();
151
+ this._triggerButton?.focus();
152
+ }
153
+ };
154
+
155
+ override connectedCallback() {
156
+ super.connectedCallback();
157
+ this.addEventListener('keydown', this._onKeyDown);
158
+ }
159
+
160
+ override disconnectedCallback() {
161
+ this.removeEventListener('keydown', this._onKeyDown);
162
+ super.disconnectedCallback();
163
+ }
164
+
165
+ override render() {
166
+ const buttonClasses = {
167
+ 'trigger-button': true,
168
+ active: this._menuOpen,
169
+ disabled: this.disabled,
170
+ };
171
+
172
+ return html`
173
+ <wc-button
174
+ class=${classMap(buttonClasses)}
175
+ size=${this.size}
176
+ variant=${this.variant}
177
+ color=${this.color}
178
+ icon-align="end"
179
+ ?disabled=${this.disabled}
180
+ .configAria=${{
181
+ 'aria-haspopup': 'menu',
182
+ 'aria-expanded': String(this._menuOpen),
183
+ 'aria-controls': this._menuId,
184
+ }}
185
+ @click=${this._onButtonClick}
186
+ >
187
+ <slot></slot>
188
+ <wc-icon
189
+ slot="icon"
190
+ name="arrow_drop_down"
191
+ class="dropdown-icon"
192
+ aria-hidden="true"
193
+ ></wc-icon>
194
+ </wc-button>
195
+
196
+ <wc-menu
197
+ id=${this._menuId}
198
+ placement=${this.placement}
199
+ @opened=${this._onMenuOpened}
200
+ @closed=${this._onMenuClosed}
201
+ >
202
+ <slot name="menu"></slot>
203
+ </wc-menu>
204
+ `;
205
+ }
206
+ }
@@ -0,0 +1 @@
1
+ export { DropdownButton } from './dropdown-button.js';