@redvars/peacock 3.4.0 → 3.5.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 (258) hide show
  1. package/dist/BaseButton-DuASuVth.js +219 -0
  2. package/dist/BaseButton-DuASuVth.js.map +1 -0
  3. package/dist/BaseHyperlinkMixin-BNuwbiEf.js +65 -0
  4. package/dist/BaseHyperlinkMixin-BNuwbiEf.js.map +1 -0
  5. package/dist/assets/components.css +1 -1
  6. package/dist/assets/components.css.map +1 -1
  7. package/dist/assets/styles.css +1 -1
  8. package/dist/assets/styles.css.map +1 -1
  9. package/dist/banner.js +187 -0
  10. package/dist/banner.js.map +1 -0
  11. package/dist/bottom-sheet.js +2 -2
  12. package/dist/{button-COYCtuA8.js → button-DouvOfEU.js} +92 -283
  13. package/dist/button-DouvOfEU.js.map +1 -0
  14. package/dist/{button-group-DsXquZQn.js → button-group-CEdMwvJJ.js} +72 -48
  15. package/dist/button-group-CEdMwvJJ.js.map +1 -0
  16. package/dist/button-group.js +8 -5
  17. package/dist/button-group.js.map +1 -1
  18. package/dist/button.js +7 -4
  19. package/dist/button.js.map +1 -1
  20. package/dist/card.js +29 -74
  21. package/dist/card.js.map +1 -1
  22. package/dist/chart-bar.js +2 -2
  23. package/dist/chart-bar.js.map +1 -1
  24. package/dist/chart-doughnut.js +2 -2
  25. package/dist/chart-doughnut.js.map +1 -1
  26. package/dist/chart-pie.js +2 -2
  27. package/dist/chart-pie.js.map +1 -1
  28. package/dist/chart-stacked-bar.js +2 -2
  29. package/dist/chart-stacked-bar.js.map +1 -1
  30. package/dist/{class-map-3TAnCMAX.js → class-map-YU7g0o3B.js} +2 -2
  31. package/dist/{class-map-3TAnCMAX.js.map → class-map-YU7g0o3B.js.map} +1 -1
  32. package/dist/clock.js.map +1 -1
  33. package/dist/code-editor.js +4 -4
  34. package/dist/code-editor.js.map +1 -1
  35. package/dist/code-highlighter.js +5 -4
  36. package/dist/code-highlighter.js.map +1 -1
  37. package/dist/custom-elements-jsdocs.json +6627 -3477
  38. package/dist/custom-elements.json +10954 -7810
  39. package/dist/directive-ZPhl09Yt.js +9 -0
  40. package/dist/directive-ZPhl09Yt.js.map +1 -0
  41. package/dist/dispatch-event-utils-CuEqjlPT.js +127 -0
  42. package/dist/dispatch-event-utils-CuEqjlPT.js.map +1 -0
  43. package/dist/fab.js +423 -0
  44. package/dist/fab.js.map +1 -0
  45. package/dist/index.js +17 -9
  46. package/dist/index.js.map +1 -1
  47. package/dist/{observe-theme-change-DKAIv5BB.js → is-dark-mode-DicqGkCJ.js} +6 -2
  48. package/dist/is-dark-mode-DicqGkCJ.js.map +1 -0
  49. package/dist/{select-C3XAzenC.js → navigation-rail-Lxetd5-Z.js} +2426 -898
  50. package/dist/navigation-rail-Lxetd5-Z.js.map +1 -0
  51. package/dist/notification.js +418 -0
  52. package/dist/notification.js.map +1 -0
  53. package/dist/number-counter.js +2 -2
  54. package/dist/number-counter.js.map +1 -1
  55. package/dist/observe-slot-change-BGJfgg2E.js +31 -0
  56. package/dist/observe-slot-change-BGJfgg2E.js.map +1 -0
  57. package/dist/peacock-loader.js +48 -13
  58. package/dist/peacock-loader.js.map +1 -1
  59. package/dist/search.js +456 -0
  60. package/dist/search.js.map +1 -0
  61. package/dist/side-sheet.js +2 -2
  62. package/dist/src/__mixins/BaseButtonMixin.d.ts +20 -0
  63. package/dist/src/__mixins/BaseHyperlinkMixin.d.ts +18 -0
  64. package/dist/src/__mixins/MixinConstructor.d.ts +1 -0
  65. package/dist/src/__utils/cache-fetch.d.ts +1 -0
  66. package/dist/src/__utils/is-dark-mode.d.ts +1 -0
  67. package/dist/src/__utils/is-in-viewport.d.ts +1 -0
  68. package/dist/src/__utils/observe-slot-change.d.ts +1 -0
  69. package/dist/src/__utils/sanitize-svg.d.ts +1 -0
  70. package/dist/src/__utils/throttle.d.ts +4 -0
  71. package/dist/src/accordion/accordion-item.d.ts +33 -9
  72. package/dist/src/accordion/accordion.d.ts +21 -5
  73. package/dist/src/banner/banner.d.ts +43 -0
  74. package/dist/src/banner/index.d.ts +1 -0
  75. package/dist/src/button/BaseButton.d.ts +7 -57
  76. package/dist/src/button/button/button.d.ts +32 -3
  77. package/dist/src/button/button-group/button-group.d.ts +4 -4
  78. package/dist/src/button/icon-button/icon-button.d.ts +33 -8
  79. package/dist/src/card/card.d.ts +4 -15
  80. package/dist/src/empty-state/empty-state.d.ts +1 -1
  81. package/dist/src/fab/fab.d.ts +80 -0
  82. package/dist/src/fab/index.d.ts +1 -0
  83. package/dist/src/focus-ring/focus-ring.d.ts +11 -5
  84. package/dist/src/index.d.ts +8 -1
  85. package/dist/src/link/link.d.ts +3 -10
  86. package/dist/src/menu/menu/menu.d.ts +3 -2
  87. package/dist/src/menu/sub-menu/sub-menu.d.ts +1 -0
  88. package/dist/src/navigation-rail/index.d.ts +2 -0
  89. package/dist/src/navigation-rail/navigation-rail-item.d.ts +55 -0
  90. package/dist/src/navigation-rail/navigation-rail.d.ts +71 -0
  91. package/dist/src/notification/index.d.ts +1 -0
  92. package/dist/src/notification/notification.d.ts +69 -0
  93. package/dist/src/pagination/pagination.d.ts +8 -1
  94. package/dist/src/search/index.d.ts +1 -0
  95. package/dist/src/search/search.d.ts +76 -0
  96. package/dist/src/select/select.d.ts +3 -5
  97. package/dist/src/sidebar-menu/index.d.ts +3 -0
  98. package/dist/src/sidebar-menu/sidebar-menu-item.d.ts +58 -0
  99. package/dist/src/sidebar-menu/sidebar-menu.d.ts +38 -0
  100. package/dist/src/sidebar-menu/sidebar-sub-menu.d.ts +35 -0
  101. package/dist/src/slider/slider.d.ts +4 -0
  102. package/dist/src/snackbar/snackbar.d.ts +14 -1
  103. package/dist/src/toolbar/index.d.ts +1 -0
  104. package/dist/src/toolbar/toolbar.d.ts +86 -0
  105. package/dist/src/tooltip/tooltip.d.ts +3 -0
  106. package/dist/src/url-field/index.d.ts +1 -0
  107. package/dist/src/url-field/url-field.d.ts +48 -0
  108. package/dist/{style-map-CRFEoCEg.js → style-map-DVmWOuYy.js} +2 -2
  109. package/dist/{style-map-CRFEoCEg.js.map → style-map-DVmWOuYy.js.map} +1 -1
  110. package/dist/test/banner.test.d.ts +1 -0
  111. package/dist/test/search.test.d.ts +1 -0
  112. package/dist/test/sidebar-menu.test.d.ts +1 -0
  113. package/dist/test/toolbar.test.d.ts +1 -0
  114. package/dist/toolbar.js +306 -0
  115. package/dist/toolbar.js.map +1 -0
  116. package/dist/tsconfig.tsbuildinfo +1 -1
  117. package/dist/{unsafe-html-D3GHRaGQ.js → unsafe-html-BsGUjx94.js} +2 -2
  118. package/dist/{unsafe-html-D3GHRaGQ.js.map → unsafe-html-BsGUjx94.js.map} +1 -1
  119. package/package.json +1 -1
  120. package/readme.md +73 -65
  121. package/scss/mixin.scss +16 -0
  122. package/scss/styles.scss +4 -0
  123. package/src/__mixins/BaseButtonMixin.ts +83 -0
  124. package/src/__mixins/BaseHyperlinkMixin.ts +68 -0
  125. package/src/__mixins/MixinConstructor.ts +1 -0
  126. package/src/__mixins/README.md +19 -0
  127. package/src/__utils/cache-fetch.ts +65 -0
  128. package/src/__utils/is-dark-mode.ts +3 -0
  129. package/src/__utils/is-in-viewport.ts +6 -0
  130. package/src/__utils/observe-slot-change.ts +38 -0
  131. package/src/__utils/sanitize-svg.ts +27 -0
  132. package/src/__utils/throttle.ts +27 -0
  133. package/src/accordion/accordion-item.scss +136 -65
  134. package/src/accordion/accordion-item.ts +117 -44
  135. package/src/accordion/accordion.scss +24 -5
  136. package/src/accordion/accordion.ts +29 -23
  137. package/src/accordion/demo/index.html +74 -35
  138. package/src/banner/banner.scss +83 -0
  139. package/src/banner/banner.ts +101 -0
  140. package/src/banner/index.ts +1 -0
  141. package/src/button/BaseButton.ts +13 -115
  142. package/src/button/button/button-colors.scss +14 -14
  143. package/src/button/button/button-sizes.scss +4 -2
  144. package/src/button/button/button.ts +80 -26
  145. package/src/button/button-group/button-group.ts +5 -5
  146. package/src/button/icon-button/icon-button.ts +79 -44
  147. package/src/card/card.ts +50 -100
  148. package/src/chart-bar/chart-bar.ts +10 -15
  149. package/src/chart-bar/chart-stacked-bar.ts +15 -19
  150. package/src/chart-doughnut/chart-doughnut.ts +24 -28
  151. package/src/chart-pie/chart-pie.ts +20 -24
  152. package/src/checkbox/checkbox.scss +17 -34
  153. package/src/checkbox/checkbox.ts +4 -2
  154. package/src/clock/clock.ts +1 -1
  155. package/src/code-editor/code-editor.ts +4 -4
  156. package/src/code-highlighter/code-highlighter.scss +1 -0
  157. package/src/code-highlighter/code-highlighter.ts +3 -3
  158. package/src/date-picker/date-picker.ts +6 -3
  159. package/src/divider/divider.ts +3 -1
  160. package/src/elevation/elevation.scss +5 -5
  161. package/src/empty-state/empty-state.scss +7 -9
  162. package/src/empty-state/empty-state.ts +1 -1
  163. package/src/fab/fab-colors.scss +49 -0
  164. package/src/fab/fab-sizes.scss +47 -0
  165. package/src/fab/fab.scss +137 -0
  166. package/src/fab/fab.ts +214 -0
  167. package/src/fab/index.ts +1 -0
  168. package/src/field/field.ts +3 -1
  169. package/src/focus-ring/focus-ring.ts +47 -40
  170. package/src/icon/datasource.ts +1 -1
  171. package/src/icon/icon.ts +3 -1
  172. package/src/image/image.ts +3 -2
  173. package/src/index.ts +8 -1
  174. package/src/input/input.ts +8 -3
  175. package/src/link/link.ts +2 -15
  176. package/src/menu/menu/menu.scss +7 -0
  177. package/src/menu/menu/menu.ts +7 -4
  178. package/src/menu/menu-item/menu-item.ts +3 -1
  179. package/src/menu/sub-menu/sub-menu.ts +1 -0
  180. package/src/navigation-rail/index.ts +2 -0
  181. package/src/navigation-rail/navigation-rail-item.scss +216 -0
  182. package/src/navigation-rail/navigation-rail-item.ts +223 -0
  183. package/src/navigation-rail/navigation-rail.scss +72 -0
  184. package/src/navigation-rail/navigation-rail.ts +149 -0
  185. package/src/notification/index.ts +1 -0
  186. package/src/notification/notification.scss +201 -0
  187. package/src/notification/notification.ts +207 -0
  188. package/src/number-counter/number-counter.ts +3 -1
  189. package/src/number-field/number-field.ts +10 -6
  190. package/src/pagination/pagination.scss +33 -24
  191. package/src/pagination/pagination.ts +115 -60
  192. package/src/peacock-loader.ts +42 -5
  193. package/src/radio/radio.ts +3 -1
  194. package/src/search/index.ts +1 -0
  195. package/src/search/search-colors.scss +14 -0
  196. package/src/search/search.scss +204 -0
  197. package/src/search/search.ts +244 -0
  198. package/src/select/option.ts +1 -1
  199. package/src/select/select.scss +5 -0
  200. package/src/select/select.ts +71 -37
  201. package/src/sidebar-menu/demo/index.html +68 -0
  202. package/src/sidebar-menu/index.ts +3 -0
  203. package/src/sidebar-menu/sidebar-menu-item.scss +102 -0
  204. package/src/sidebar-menu/sidebar-menu-item.ts +151 -0
  205. package/src/{tree-view/tree-view.scss → sidebar-menu/sidebar-menu.scss} +1 -1
  206. package/src/sidebar-menu/sidebar-menu.ts +182 -0
  207. package/src/sidebar-menu/sidebar-sub-menu.scss +130 -0
  208. package/src/sidebar-menu/sidebar-sub-menu.ts +160 -0
  209. package/src/skeleton/skeleton.scss +18 -24
  210. package/src/slider/slider.scss +19 -0
  211. package/src/slider/slider.ts +30 -19
  212. package/src/snackbar/snackbar.scss +62 -31
  213. package/src/snackbar/snackbar.ts +91 -11
  214. package/src/switch/switch.ts +3 -1
  215. package/src/table/table.ts +3 -1
  216. package/src/tabs/tab.ts +10 -6
  217. package/src/text/text.css-component.scss +7 -1
  218. package/src/textarea/textarea.ts +4 -2
  219. package/src/time-picker/time-picker.ts +5 -3
  220. package/src/toolbar/index.ts +1 -0
  221. package/src/toolbar/toolbar-colors.scss +16 -0
  222. package/src/toolbar/toolbar.scss +165 -0
  223. package/src/toolbar/toolbar.ts +137 -0
  224. package/src/tooltip/tooltip.ts +24 -0
  225. package/src/url-field/index.ts +1 -0
  226. package/src/url-field/url-field.scss +50 -0
  227. package/src/url-field/url-field.ts +239 -0
  228. package/dist/button-COYCtuA8.js.map +0 -1
  229. package/dist/button-group-DsXquZQn.js.map +0 -1
  230. package/dist/directive-Cuw6h7YA.js +0 -9
  231. package/dist/directive-Cuw6h7YA.js.map +0 -1
  232. package/dist/dispatch-event-utils-B4odODQf.js +0 -277
  233. package/dist/dispatch-event-utils-B4odODQf.js.map +0 -1
  234. package/dist/observe-theme-change-DKAIv5BB.js.map +0 -1
  235. package/dist/select-C3XAzenC.js.map +0 -1
  236. package/dist/src/styleMixins.css.d.ts +0 -9
  237. package/dist/src/tree-view/index.d.ts +0 -2
  238. package/dist/src/tree-view/tree-node.d.ts +0 -69
  239. package/dist/src/tree-view/tree-view.d.ts +0 -40
  240. package/dist/src/tree-view/wc-tree-view.d.ts +0 -6
  241. package/dist/src/utils.d.ts +0 -9
  242. package/dist/test/tree-view.test.d.ts +0 -1
  243. package/src/styleMixins.css.ts +0 -55
  244. package/src/tree-view/demo/index.html +0 -57
  245. package/src/tree-view/index.ts +0 -2
  246. package/src/tree-view/tree-node.scss +0 -101
  247. package/src/tree-view/tree-node.ts +0 -268
  248. package/src/tree-view/tree-view.ts +0 -182
  249. package/src/tree-view/wc-tree-view.ts +0 -9
  250. package/src/utils.ts +0 -193
  251. /package/dist/src/{spread.d.ts → __directive/spread.d.ts} +0 -0
  252. /package/dist/src/{utils → __utils}/copy-to-clipboard.d.ts +0 -0
  253. /package/dist/src/{utils → __utils}/dispatch-event-utils.d.ts +0 -0
  254. /package/dist/src/{utils → __utils}/observe-theme-change.d.ts +0 -0
  255. /package/src/{spread.ts → __directive/spread.ts} +0 -0
  256. /package/src/{utils → __utils}/copy-to-clipboard.ts +0 -0
  257. /package/src/{utils → __utils}/dispatch-event-utils.ts +0 -0
  258. /package/src/{utils → __utils}/observe-theme-change.ts +0 -0
@@ -1,12 +1,14 @@
1
1
  import { html } from 'lit';
2
2
  import { property, state } from 'lit/decorators.js';
3
3
  import { classMap } from 'lit/directives/class-map.js';
4
- import IndividualComponent from 'src/IndividualComponent.js';
4
+ import { ifDefined } from 'lit/directives/if-defined.js';
5
+ import IndividualComponent from '@/IndividualComponent.js';
5
6
  import styles from './button.scss';
6
7
  import colorStyles from './button-colors.scss';
7
8
  import sizeStyles from './button-sizes.scss';
8
- import { observerSlotChangesWithCallback, throttle } from '../../utils.js';
9
- import { spread } from '../../spread.js';
9
+ import { observerSlotChangesWithCallback } from '@/__utils/observe-slot-change.js';
10
+ import { throttle } from '@/__utils/throttle.js';
11
+ import { spread } from '@/__directive/spread.js';
10
12
  import { BaseButton } from '../BaseButton.js';
11
13
 
12
14
  /**
@@ -55,8 +57,6 @@ import { BaseButton } from '../BaseButton.js';
55
57
  export class Button extends BaseButton {
56
58
  static override styles = [styles, colorStyles, sizeStyles];
57
59
 
58
- #tabindex?: number = 0;
59
-
60
60
  /**
61
61
  * Icon alignment.
62
62
  * Possible values are `"start"`, `"end"`. Defaults to `"end"`.
@@ -64,6 +64,53 @@ export class Button extends BaseButton {
64
64
  @property({ attribute: 'icon-align' })
65
65
  iconAlign: 'start' | 'end' = 'end';
66
66
 
67
+ /**
68
+ * Button size.
69
+ * Possible values are `"xs"`, `"sm"`, `"md"`, `"lg"`, `"xl"`. Defaults to `"sm"`.
70
+ */
71
+ @property({ reflect: true }) size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'sm';
72
+
73
+ /**
74
+ * Type is preset of color and variant. Type will be only applied.
75
+ *
76
+ */
77
+ @property({ type: String }) type?: 'primary' | 'secondary' | 'tertiary';
78
+
79
+ /**
80
+ * The visual style of the button.
81
+ *
82
+ * Possible variant values:
83
+ * `"filled"` is a filled button.
84
+ * `"outlined"` is an outlined button.
85
+ * `"text"` is a transparent button.
86
+ * `"tonal"` is a light color button.
87
+ * `"elevated"` is elevated button
88
+ */
89
+ @property() variant:
90
+ | 'elevated'
91
+ | 'filled'
92
+ | 'tonal'
93
+ | 'outlined'
94
+ | 'text'
95
+ | 'neo' = 'filled';
96
+
97
+ /**
98
+ * Defines the primary color of the button. This can be set to predefined color names to apply specific color themes.
99
+ */
100
+ @property({ reflect: true }) color:
101
+ | 'primary'
102
+ | 'success'
103
+ | 'danger'
104
+ | 'warning'
105
+ | 'surface'
106
+ | 'on-surface' = 'primary';
107
+
108
+ /**
109
+ * Additional ARIA attributes to pass to the inner button/anchor element.
110
+ */
111
+ @property({ reflect: true })
112
+ configAria?: { [key: string]: any };
113
+
67
114
  @state()
68
115
  private slotHasContent = false;
69
116
 
@@ -75,18 +122,6 @@ export class Button extends BaseButton {
75
122
  this.buttonElement?.blur();
76
123
  }
77
124
 
78
- override connectedCallback() {
79
- super.connectedCallback();
80
- this.addEventListener('click', this.__dispatchClickWithThrottle);
81
- window.addEventListener('mouseup', this.__handlePress);
82
- }
83
-
84
- override disconnectedCallback() {
85
- window.removeEventListener('mouseup', this.__handlePress);
86
- this.removeEventListener('click', this.__dispatchClickWithThrottle);
87
- super.disconnectedCallback();
88
- }
89
-
90
125
  override firstUpdated() {
91
126
  this.__dispatchClickWithThrottle = throttle(
92
127
  this.__dispatchClick,
@@ -103,6 +138,22 @@ export class Button extends BaseButton {
103
138
  this.__convertTypeToVariantAndColor();
104
139
  }
105
140
 
141
+ __convertTypeToVariantAndColor() {
142
+ if (this.type === 'primary') {
143
+ this.color = 'primary';
144
+ this.variant = 'filled';
145
+ } else if (this.type === 'secondary') {
146
+ this.color = 'surface';
147
+ this.variant = 'filled';
148
+ } else if (this.type === 'tertiary') {
149
+ this.color = 'primary';
150
+ this.variant = 'text';
151
+ } else if (this.type === 'danger') {
152
+ this.color = 'danger';
153
+ this.variant = 'filled';
154
+ }
155
+ }
156
+
106
157
  override render() {
107
158
  const isLink = this.__isLink();
108
159
 
@@ -123,14 +174,15 @@ export class Button extends BaseButton {
123
174
  return html`<button
124
175
  class=${classMap(cssClasses)}
125
176
  id="button"
126
- tabindex=${this.#tabindex}
127
177
  type=${this.htmlType}
128
178
  @click=${this.__dispatchClickWithThrottle}
129
179
  @mousedown=${this.__handlePress}
130
180
  @keydown=${this.__handlePress}
131
181
  @keyup=${this.__handlePress}
132
- ?aria-describedby=${this.__getDisabledReasonID()}
133
- aria-disabled=${`${this.disabled || this.softDisabled}`}
182
+
183
+ aria-describedby=${ifDefined(this.softDisabled ? BaseButton.DISABLED_REASON_ID : undefined)}
184
+ ?aria-disabled=${this.softDisabled}
185
+
134
186
  ?disabled=${this.disabled}
135
187
  ${spread(this.configAria)}
136
188
  >
@@ -141,16 +193,18 @@ export class Button extends BaseButton {
141
193
  return html`<a
142
194
  class=${classMap(cssClasses)}
143
195
  id="button"
144
- tabindex=${this.#tabindex}
145
196
  href=${this.href}
146
197
  target=${this.target}
147
- @click=${this.__dispatchClickWithThrottle}
198
+ tabindex=${this.disabled ? '-1' : '0'}
199
+ @click=${this.__dispatchClick}
148
200
  @mousedown=${this.__handlePress}
149
201
  @keydown=${this.__handlePress}
150
202
  @keyup=${this.__handlePress}
151
203
  role="button"
152
- ?aria-describedby=${this.__getDisabledReasonID()}
153
- aria-disabled=${`${this.disabled}`}
204
+
205
+ aria-describedby=${ifDefined(this.softDisabled ? BaseButton.DISABLED_REASON_ID : undefined)}
206
+ ?aria-disabled=${this.softDisabled}
207
+
154
208
  ${spread(this.configAria)}
155
209
  >
156
210
  ${this.renderButtonContent()}
@@ -160,7 +214,7 @@ export class Button extends BaseButton {
160
214
 
161
215
  renderButtonContent() {
162
216
  return html`
163
- <wc-focus-ring class="focus-ring" .control=${this} .forElement=${this.buttonElement}></wc-focus-ring>
217
+ <wc-focus-ring class="focus-ring" for='button'></wc-focus-ring>
164
218
  <wc-elevation class="elevation"></wc-elevation>
165
219
  <div class="neo-background"></div>
166
220
  <div class="background"></div>
@@ -176,7 +230,7 @@ export class Button extends BaseButton {
176
230
  <slot name="icon"></slot>
177
231
  </div>
178
232
 
179
- ${this.__renderDisabledReason()}
233
+ ${this.__renderDisabledReason(this.softDisabled)}
180
234
  `;
181
235
  }
182
236
  }
@@ -1,7 +1,7 @@
1
1
  import { html, LitElement } from 'lit';
2
2
  import { property } from 'lit/decorators.js';
3
3
  import { classMap } from 'lit/directives/class-map.js';
4
- import IndividualComponent from 'src/IndividualComponent.js';
4
+ import IndividualComponent from '@/IndividualComponent.js';
5
5
  import styles from './button-group.scss';
6
6
  import { Button } from '../button/button.js';
7
7
  import { IconButton } from '../icon-button/icon-button.js';
@@ -17,8 +17,8 @@ import { BaseButton } from '../BaseButton.js';
17
17
  * @example
18
18
  * ```html
19
19
  * <wc-button-group variant="connected">
20
- * <wc-icon-button name="home" toggle selected></wc-icon-button>
21
- * <wc-icon-button name="alarm" toggle></wc-icon-button>
20
+ * <wc-icon-button toggle selected><wc-icon name="home"></wc-icon></wc-icon-button>
21
+ * <wc-icon-button toggle><wc-icon name="alarm"></wc-icon></wc-icon-button>
22
22
  * </wc-button-group>
23
23
  * ```
24
24
  *
@@ -61,9 +61,9 @@ export class ButtonGroup extends LitElement {
61
61
 
62
62
  /**
63
63
  * Color applied to all buttons in the group.
64
- * Possible values are `"primary"`, `"success"`, `"danger"`, `"warning"`, `"light"`, `"dark"`.
64
+ * Possible values are `"primary"`, `"success"`, `"danger"`, `"warning"`, `"surface"`, `"on-surface"`.
65
65
  */
66
- @property({ reflect: true }) color?: 'primary' | 'success' | 'danger' | 'warning' | 'light' | 'dark';
66
+ @property({ reflect: true }) color?: 'primary' | 'success' | 'danger' | 'warning' | 'surface' | 'on-surface';
67
67
 
68
68
  /**
69
69
  * Visual style applied to all buttons in the group.
@@ -1,13 +1,13 @@
1
1
  import { html } from 'lit';
2
2
  import { property } from 'lit/decorators.js';
3
3
  import { classMap } from 'lit/directives/class-map.js';
4
+ import { ifDefined } from 'lit/directives/if-defined.js';
4
5
  import styles from '../button/button.scss';
5
6
  import colorStyles from '../button/button-colors.scss';
6
7
  import sizeStyles from './icon-button-sizes.scss';
7
- import { spread } from '../../spread.js';
8
+ import { spread } from '@/__directive/spread.js';
9
+ import { throttle } from '@/__utils/throttle.js';
8
10
  import { BaseButton } from '../BaseButton.js';
9
- import { IconProvider } from '../../icon/icon.js';
10
- import { throttle } from '../../utils.js';
11
11
 
12
12
  /**
13
13
  * @label Icon Button
@@ -48,22 +48,59 @@ import { throttle } from '../../utils.js';
48
48
  *
49
49
  * @example
50
50
  * ```html
51
- * <wc-icon-button name="home"></wc-icon-button>
51
+ * <wc-icon-button><wc-icon name="home"></wc-icon></wc-icon-button>
52
52
  * ```
53
53
  * @tags display
54
54
  */
55
55
  export class IconButton extends BaseButton {
56
56
  static override styles = [styles, colorStyles, sizeStyles];
57
57
 
58
- #id = crypto.randomUUID();
59
-
60
- #tabindex?: number = 0;
61
-
62
- @property({ type: String, reflect: true }) name?: string;
63
-
64
- @property({ type: String, reflect: true }) src?: string;
65
-
66
- @property({ type: String }) provider: IconProvider = 'material-symbols';
58
+ /**
59
+ * Button size.
60
+ * Possible values are `"xs"`, `"sm"`, `"md"`, `"lg"`, `"xl"`. Defaults to `"sm"`.
61
+ */
62
+ @property({ reflect: true }) size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'sm';
63
+
64
+ /**
65
+ * Type is preset of color and variant. Type will be only applied.
66
+ *
67
+ */
68
+ @property({ type: String }) type?: 'primary' | 'secondary' | 'tertiary';
69
+
70
+ /**
71
+ * The visual style of the button.
72
+ *
73
+ * Possible variant values:
74
+ * `"filled"` is a filled button.
75
+ * `"outlined"` is an outlined button.
76
+ * `"text"` is a transparent button.
77
+ * `"tonal"` is a light color button.
78
+ * `"elevated"` is elevated button
79
+ */
80
+ @property() variant:
81
+ | 'elevated'
82
+ | 'filled'
83
+ | 'tonal'
84
+ | 'outlined'
85
+ | 'text'
86
+ | 'neo' = 'filled';
87
+
88
+ /**
89
+ * Defines the primary color of the button. This can be set to predefined color names to apply specific color themes.
90
+ */
91
+ @property({ reflect: true }) color:
92
+ | 'primary'
93
+ | 'success'
94
+ | 'danger'
95
+ | 'warning'
96
+ | 'surface'
97
+ | 'on-surface' = 'primary';
98
+
99
+ /**
100
+ * Additional ARIA attributes to pass to the inner button/anchor element.
101
+ */
102
+ @property({ reflect: true })
103
+ configAria?: { [key: string]: any };
67
104
 
68
105
  override focus() {
69
106
  this.buttonElement?.focus();
@@ -72,18 +109,6 @@ export class IconButton extends BaseButton {
72
109
  override blur() {
73
110
  this.buttonElement?.blur();
74
111
  }
75
-
76
- override connectedCallback() {
77
- super.connectedCallback();
78
- this.addEventListener('click', this.__dispatchClickWithThrottle);
79
- window.addEventListener('mouseup', this.__handlePress);
80
- }
81
-
82
- override disconnectedCallback() {
83
- window.removeEventListener('mouseup', this.__handlePress);
84
- this.removeEventListener('click', this.__dispatchClickWithThrottle);
85
- super.disconnectedCallback();
86
- }
87
112
 
88
113
  override firstUpdated() {
89
114
  this.__dispatchClickWithThrottle = throttle(
@@ -93,6 +118,22 @@ export class IconButton extends BaseButton {
93
118
  this.__convertTypeToVariantAndColor();
94
119
  }
95
120
 
121
+ __convertTypeToVariantAndColor() {
122
+ if (this.type === 'primary') {
123
+ this.color = 'primary';
124
+ this.variant = 'filled';
125
+ } else if (this.type === 'secondary') {
126
+ this.color = 'surface';
127
+ this.variant = 'filled';
128
+ } else if (this.type === 'tertiary') {
129
+ this.color = 'primary';
130
+ this.variant = 'text';
131
+ } else if (this.type === 'danger') {
132
+ this.color = 'danger';
133
+ this.variant = 'filled';
134
+ }
135
+ }
136
+
96
137
  override render() {
97
138
  const isLink = this.__isLink();
98
139
 
@@ -111,17 +152,15 @@ export class IconButton extends BaseButton {
111
152
  return html`<button
112
153
  class=${classMap(cssClasses)}
113
154
  id="button"
114
- tabindex=${this.#tabindex}
115
155
  type=${this.htmlType}
116
156
  @click=${this.__dispatchClickWithThrottle}
117
157
  @mousedown=${this.__handlePress}
118
158
  @keydown=${this.__handlePress}
119
159
  @keyup=${this.__handlePress}
120
- ?aria-describedby=${(this.disabled || this.softDisabled) &&
121
- this.disabledReason
122
- ? `disabled-reason-${this.#id}`
123
- : null}
124
- aria-disabled=${`${this.disabled || this.softDisabled}`}
160
+
161
+ aria-describedby=${ifDefined(this.softDisabled ? BaseButton.DISABLED_REASON_ID : undefined)}
162
+ ?aria-disabled=${this.softDisabled}
163
+
125
164
  ?disabled=${this.disabled}
126
165
  ${spread(this.configAria)}
127
166
  >
@@ -132,18 +171,18 @@ export class IconButton extends BaseButton {
132
171
  return html`<a
133
172
  class=${classMap(cssClasses)}
134
173
  id="button"
135
- tabindex=${this.#tabindex}
136
174
  href=${this.href}
137
175
  target=${this.target}
138
- @click=${this.__dispatchClickWithThrottle}
176
+ tabindex=${this.disabled ? '-1' : '0'}
177
+ @click=${this.__dispatchClick}
139
178
  @mousedown=${this.__handlePress}
140
179
  @keydown=${this.__handlePress}
141
180
  @keyup=${this.__handlePress}
142
181
  role="button"
143
- aria-describedby=${this.disabled && this.disabledReason
144
- ? `disabled-reason-${this.#id}`
145
- : null}
146
- aria-disabled=${`${this.disabled}`}
182
+
183
+ aria-describedby=${ifDefined(this.softDisabled ? BaseButton.DISABLED_REASON_ID : undefined)}
184
+ ?aria-disabled=${this.softDisabled}
185
+
147
186
  ${spread(this.configAria)}
148
187
  >
149
188
  ${this.renderButtonContent()}
@@ -153,7 +192,7 @@ export class IconButton extends BaseButton {
153
192
 
154
193
  renderButtonContent() {
155
194
  return html`
156
- <wc-focus-ring class="focus-ring" .control=${this} .forElement=${this.buttonElement}></wc-focus-ring>
195
+ <wc-focus-ring class="focus-ring" for='button'></wc-focus-ring>
157
196
  <wc-elevation class="elevation"></wc-elevation>
158
197
  <div class="neo-background"></div>
159
198
  <div class="background"></div>
@@ -162,14 +201,10 @@ export class IconButton extends BaseButton {
162
201
  <wc-skeleton class="skeleton"></wc-skeleton>
163
202
 
164
203
  <div class="button-content">
165
- <wc-icon
166
- name=${this.name}
167
- src=${this.src}
168
- provider=${this.provider}
169
- ></wc-icon>
204
+ <slot></slot>
170
205
  </div>
171
206
 
172
- ${this.__renderDisabledReason()}
207
+ ${this.__renderDisabledReason(this.softDisabled)}
173
208
  `;
174
209
  }
175
210
  }
package/src/card/card.ts CHANGED
@@ -1,11 +1,13 @@
1
- import { LitElement, html, nothing, PropertyValues } from 'lit';
1
+ import { LitElement, html, nothing } from 'lit';
2
2
  import { property, query, state } from 'lit/decorators.js';
3
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';
6
- import IndividualComponent from '../IndividualComponent.js';
4
+ import { dispatchActivationClick, isActivationClick } from '../__utils/dispatch-event-utils.js';
5
+ import { observerSlotChangesWithCallback } from '@/__utils/observe-slot-change.js';
6
+ import { throttle } from '@/__utils/throttle.js';
7
+ import IndividualComponent from '@/IndividualComponent.js';
7
8
  import styles from './card.scss';
8
9
  import colorStyles from './card-colors.scss';
10
+ import BaseHyperlinkMixin from '@/__mixins/BaseHyperlinkMixin.js';
9
11
 
10
12
  type CardVariant = 'elevated' | 'filled' | 'outlined';
11
13
 
@@ -27,37 +29,26 @@ type CardVariant = 'elevated' | 'filled' | 'outlined';
27
29
  * ```
28
30
  */
29
31
  @IndividualComponent
30
- export class Card extends LitElement {
32
+ export class Card extends BaseHyperlinkMixin(LitElement) {
31
33
  static styles = [styles, colorStyles];
32
34
 
33
- #id = crypto.randomUUID();
34
-
35
+ #id = crypto.randomUUID();
36
+
35
37
  @property({ type: String, reflect: true })
36
38
  variant: CardVariant = 'elevated';
37
39
 
38
- @property({type: Boolean, reflect: true})
40
+ @property({ type: Boolean, reflect: true })
39
41
  disabled: boolean = false;
40
42
 
41
43
  @property({ type: Boolean, reflect: true })
42
44
  actionable: boolean = false;
43
45
 
44
- /**
45
- * If button is disabled, the reason why it is disabled.
46
- */
46
+ /**
47
+ * If button is disabled, the reason why it is disabled.
48
+ */
47
49
  @property({ attribute: 'disabled-reason' })
48
50
  disabledReason: string = '';
49
51
 
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
52
  /**
62
53
  * Sets the delay for throttle in milliseconds. Defaults to 200 milliseconds.
63
54
  */
@@ -75,12 +66,8 @@ export class Card extends LitElement {
75
66
 
76
67
  @query('.card') readonly cardElement!: HTMLElement | null;
77
68
 
78
- @query('slot') readonly contentSlot!: HTMLSlotElement | null;
79
-
80
69
  #tabindex?: number = 0;
81
70
 
82
- #slottedTabIndexMap = new WeakMap<HTMLElement, string | null>();
83
-
84
71
  override firstUpdated() {
85
72
  this.__dispatchClickWithThrottle = throttle(
86
73
  this.__dispatchClick,
@@ -90,52 +77,9 @@ export class Card extends LitElement {
90
77
  this.renderRoot.querySelector('slot'),
91
78
  hasContent => {
92
79
  this.slotHasContent = hasContent;
93
- this.__syncSlottedChildrenTabIndex();
94
80
  this.requestUpdate();
95
81
  },
96
82
  );
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
83
  }
140
84
 
141
85
  __dispatchClickWithThrottle: (event: MouseEvent | KeyboardEvent) => void =
@@ -144,26 +88,22 @@ export class Card extends LitElement {
144
88
  };
145
89
 
146
90
  __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
- };
91
+ // If the button is soft-disabled or a disabled link, we need to explicitly
92
+ // prevent the click from propagating to other event listeners as well as
93
+ // prevent the default action.
94
+ if (this.disabled && this.href) {
95
+ event.stopImmediatePropagation();
96
+ event.preventDefault();
97
+ return;
98
+ }
163
99
 
164
- __isLink() {
165
- return !!this.href;
166
- }
100
+ if (!isActivationClick(event) || !this.cardElement) {
101
+ return;
102
+ }
103
+
104
+ this.focus();
105
+ dispatchActivationClick(this.cardElement);
106
+ };
167
107
 
168
108
  __getDisabledReasonID() {
169
109
  return this.disabled && this.disabledReason
@@ -201,11 +141,12 @@ export class Card extends LitElement {
201
141
  };
202
142
 
203
143
 
204
-
144
+
205
145
 
206
146
  render() {
207
147
 
208
148
  const isLink = this.__isLink();
149
+ const disableSlotTabbing = this.actionable || isLink;
209
150
 
210
151
  const cssClasses = {
211
152
  card: true,
@@ -217,10 +158,19 @@ export class Card extends LitElement {
217
158
  'has-content': this.slotHasContent,
218
159
  };
219
160
 
161
+ if (!this.actionable && !isLink) {
162
+ return html`<div
163
+ class=${classMap(cssClasses)}
164
+ id="card"
165
+ >
166
+ ${this.renderCardContent(disableSlotTabbing)}
167
+ </div>`;
168
+ }
169
+
220
170
  if (!isLink) {
221
- return html`<button
171
+ return html`<button
222
172
  class=${classMap(cssClasses)}
223
- id="button"
173
+ id="card"
224
174
  tabindex=${this.#tabindex}
225
175
  @click=${this.__dispatchClickWithThrottle}
226
176
  @mousedown=${this.__handlePress}
@@ -230,12 +180,12 @@ export class Card extends LitElement {
230
180
  aria-disabled=${`${this.disabled}`}
231
181
  ?disabled=${this.disabled}
232
182
  >
233
- ${this.renderCardContent()}
183
+ ${this.renderCardContent(disableSlotTabbing)}
234
184
  </button>`;
235
- }
236
- return html`<a
185
+ }
186
+ return html`<a
237
187
  class=${classMap(cssClasses)}
238
- id="button"
188
+ id="card"
239
189
  tabindex=${this.#tabindex}
240
190
  href=${this.href}
241
191
  target=${this.target}
@@ -247,13 +197,13 @@ export class Card extends LitElement {
247
197
  ?aria-describedby=${this.__getDisabledReasonID()}
248
198
  aria-disabled=${`${this.disabled}`}
249
199
  >
250
- ${this.renderCardContent()}
200
+ ${this.renderCardContent(disableSlotTabbing)}
251
201
  </a>`;
252
202
  }
253
203
 
254
- renderCardContent() {
204
+ renderCardContent(disableSlotTabbing: boolean) {
255
205
  return html`
256
- <wc-focus-ring class="focus-ring" .control=${this} .forElement=${this.cardElement}></wc-focus-ring>
206
+ <wc-focus-ring class="focus-ring" for='card'></wc-focus-ring>
257
207
  <wc-elevation class="elevation"></wc-elevation>
258
208
  <div class="background"></div>
259
209
  <div class="outline"></div>
@@ -261,8 +211,8 @@ export class Card extends LitElement {
261
211
 
262
212
  <div class="card-content">
263
213
 
264
- <div class="slot-container">
265
- <slot @slotchange=${this.__syncSlottedChildrenTabIndex}></slot>
214
+ <div class="slot-container" ?inert=${disableSlotTabbing}>
215
+ <slot></slot>
266
216
  </div>
267
217
 
268
218
  </div>