@api-client/ui 0.2.9 → 0.2.11

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 (141) hide show
  1. package/build/src/md/UiElement.d.ts +5 -0
  2. package/build/src/md/UiElement.d.ts.map +1 -1
  3. package/build/src/md/UiElement.js +7 -0
  4. package/build/src/md/UiElement.js.map +1 -1
  5. package/build/src/md/button/ui-elevated-button.d.ts +1 -1
  6. package/build/src/md/button/ui-elevated-button.js +1 -1
  7. package/build/src/md/button/ui-elevated-button.js.map +1 -1
  8. package/build/src/md/button/ui-filled-button.d.ts +1 -1
  9. package/build/src/md/button/ui-filled-button.js +1 -1
  10. package/build/src/md/button/ui-filled-button.js.map +1 -1
  11. package/build/src/md/button/ui-filled-tonal-button.d.ts +3 -3
  12. package/build/src/md/button/ui-filled-tonal-button.d.ts.map +1 -1
  13. package/build/src/md/button/ui-filled-tonal-button.js +6 -6
  14. package/build/src/md/button/ui-filled-tonal-button.js.map +1 -1
  15. package/build/src/md/button/ui-outlined-button.d.ts +1 -1
  16. package/build/src/md/button/ui-outlined-button.js +1 -1
  17. package/build/src/md/button/ui-outlined-button.js.map +1 -1
  18. package/build/src/md/button/ui-text-button.d.ts +1 -1
  19. package/build/src/md/button/ui-text-button.js +1 -1
  20. package/build/src/md/button/ui-text-button.js.map +1 -1
  21. package/build/src/md/checkbox/internals/Checkbox.styles.d.ts.map +1 -1
  22. package/build/src/md/checkbox/internals/Checkbox.styles.js +55 -216
  23. package/build/src/md/checkbox/internals/Checkbox.styles.js.map +1 -1
  24. package/build/src/md/checkbox/internals/CheckboxElement.d.ts +10 -7
  25. package/build/src/md/checkbox/internals/CheckboxElement.d.ts.map +1 -1
  26. package/build/src/md/checkbox/internals/CheckboxElement.js +39 -32
  27. package/build/src/md/checkbox/internals/CheckboxElement.js.map +1 -1
  28. package/build/src/md/checkbox/internals/CheckedElement.d.ts.map +1 -1
  29. package/build/src/md/checkbox/internals/CheckedElement.js +1 -0
  30. package/build/src/md/checkbox/internals/CheckedElement.js.map +1 -1
  31. package/build/src/md/dropdown-list/internals/UiDropdownList.d.ts +13 -2
  32. package/build/src/md/dropdown-list/internals/UiDropdownList.d.ts.map +1 -1
  33. package/build/src/md/dropdown-list/internals/UiDropdownList.js +59 -20
  34. package/build/src/md/dropdown-list/internals/UiDropdownList.js.map +1 -1
  35. package/build/src/md/icon-button/internals/IconButton.d.ts +8 -24
  36. package/build/src/md/icon-button/internals/IconButton.d.ts.map +1 -1
  37. package/build/src/md/icon-button/internals/IconButton.js +35 -63
  38. package/build/src/md/icon-button/internals/IconButton.js.map +1 -1
  39. package/build/src/md/icon-button/internals/{IconButton.styles.d.ts → base.styles.d.ts} +1 -1
  40. package/build/src/md/icon-button/internals/base.styles.d.ts.map +1 -0
  41. package/build/src/md/icon-button/internals/base.styles.js +93 -0
  42. package/build/src/md/icon-button/internals/base.styles.js.map +1 -0
  43. package/build/src/md/icon-button/internals/filled-tonal.styles.d.ts +3 -0
  44. package/build/src/md/icon-button/internals/filled-tonal.styles.d.ts.map +1 -0
  45. package/build/src/md/icon-button/internals/filled-tonal.styles.js +30 -0
  46. package/build/src/md/icon-button/internals/filled-tonal.styles.js.map +1 -0
  47. package/build/src/md/icon-button/internals/filled.styles.d.ts +3 -0
  48. package/build/src/md/icon-button/internals/filled.styles.d.ts.map +1 -0
  49. package/build/src/md/icon-button/internals/filled.styles.js +36 -0
  50. package/build/src/md/icon-button/internals/filled.styles.js.map +1 -0
  51. package/build/src/md/icon-button/internals/outlined.styles.d.ts +3 -0
  52. package/build/src/md/icon-button/internals/outlined.styles.d.ts.map +1 -0
  53. package/build/src/md/icon-button/internals/outlined.styles.js +31 -0
  54. package/build/src/md/icon-button/internals/outlined.styles.js.map +1 -0
  55. package/build/src/md/icon-button/internals/standard.styles.d.ts +3 -0
  56. package/build/src/md/icon-button/internals/standard.styles.d.ts.map +1 -0
  57. package/build/src/md/icon-button/internals/standard.styles.js +18 -0
  58. package/build/src/md/icon-button/internals/standard.styles.js.map +1 -0
  59. package/build/src/md/icon-button/ui-filled-icon-button.d.ts +11 -0
  60. package/build/src/md/icon-button/ui-filled-icon-button.d.ts.map +1 -0
  61. package/build/src/md/icon-button/ui-filled-icon-button.js +28 -0
  62. package/build/src/md/icon-button/ui-filled-icon-button.js.map +1 -0
  63. package/build/src/md/icon-button/ui-filled-tonal-icon-button.d.ts +11 -0
  64. package/build/src/md/icon-button/ui-filled-tonal-icon-button.d.ts.map +1 -0
  65. package/build/src/md/icon-button/ui-filled-tonal-icon-button.js +28 -0
  66. package/build/src/md/icon-button/ui-filled-tonal-icon-button.js.map +1 -0
  67. package/build/src/md/icon-button/ui-icon-button.d.ts.map +1 -1
  68. package/build/src/md/icon-button/ui-icon-button.js +3 -2
  69. package/build/src/md/icon-button/ui-icon-button.js.map +1 -1
  70. package/build/src/md/icon-button/ui-outlined-icon-button.d.ts +11 -0
  71. package/build/src/md/icon-button/ui-outlined-icon-button.d.ts.map +1 -0
  72. package/build/src/md/icon-button/ui-outlined-icon-button.js +28 -0
  73. package/build/src/md/icon-button/ui-outlined-icon-button.js.map +1 -0
  74. package/build/src/md/icons/internals/Icon.d.ts +1 -0
  75. package/build/src/md/icons/internals/Icon.d.ts.map +1 -1
  76. package/build/src/md/icons/internals/Icon.js +13 -0
  77. package/build/src/md/icons/internals/Icon.js.map +1 -1
  78. package/build/src/md/icons/internals/Icon.styles.d.ts.map +1 -1
  79. package/build/src/md/icons/internals/Icon.styles.js +31 -2
  80. package/build/src/md/icons/internals/Icon.styles.js.map +1 -1
  81. package/build/src/md/list/internals/ListItem.d.ts +4 -3
  82. package/build/src/md/list/internals/ListItem.d.ts.map +1 -1
  83. package/build/src/md/list/internals/ListItem.js +55 -15
  84. package/build/src/md/list/internals/ListItem.js.map +1 -1
  85. package/build/src/md/list/internals/ListItem.styles.d.ts.map +1 -1
  86. package/build/src/md/list/internals/ListItem.styles.js +6 -2
  87. package/build/src/md/list/internals/ListItem.styles.js.map +1 -1
  88. package/build/src/md/ripple/internals/ripple.d.ts +2 -1
  89. package/build/src/md/ripple/internals/ripple.d.ts.map +1 -1
  90. package/build/src/md/ripple/internals/ripple.js +42 -12
  91. package/build/src/md/ripple/internals/ripple.js.map +1 -1
  92. package/build/src/md/segmented-button/internals/SegmentedButton.d.ts +1 -1
  93. package/build/src/md/segmented-button/internals/SegmentedButton.d.ts.map +1 -1
  94. package/build/src/md/segmented-button/internals/SegmentedButton.js +1 -1
  95. package/build/src/md/segmented-button/internals/SegmentedButton.js.map +1 -1
  96. package/demo/md/buttons/{button.html → index.html} +1 -1
  97. package/demo/md/{inputs/checkbox.html → checkbox/index.html} +1 -1
  98. package/demo/md/{list/dropdown-list.html → dropdown-list/index.html} +1 -1
  99. package/demo/md/{buttons/icon-button.html → icon-button/index.html} +5 -1
  100. package/demo/md/icon-button/index.ts +236 -0
  101. package/demo/md/index.html +36 -29
  102. package/demo/md/listbox/listbox.html +31 -0
  103. package/demo/md/listbox/listbox.ts +27 -0
  104. package/demo/md/{buttons/segmented-buttons.html → segmented-button/index.html} +1 -1
  105. package/package.json +1 -1
  106. package/src/md/UiElement.ts +8 -0
  107. package/src/md/button/ui-elevated-button.ts +1 -1
  108. package/src/md/button/ui-filled-button.ts +1 -1
  109. package/src/md/button/ui-filled-tonal-button.ts +3 -3
  110. package/src/md/button/ui-outlined-button.ts +1 -1
  111. package/src/md/button/ui-text-button.ts +1 -1
  112. package/src/md/checkbox/internals/Checkbox.styles.ts +55 -216
  113. package/src/md/checkbox/internals/CheckboxElement.ts +39 -26
  114. package/src/md/checkbox/internals/CheckedElement.ts +1 -0
  115. package/src/md/dropdown-list/internals/UiDropdownList.ts +60 -21
  116. package/src/md/icon-button/internals/IconButton.ts +29 -46
  117. package/src/md/icon-button/internals/base.styles.ts +93 -0
  118. package/src/md/icon-button/internals/filled-tonal.styles.ts +30 -0
  119. package/src/md/icon-button/internals/filled.styles.ts +36 -0
  120. package/src/md/icon-button/internals/outlined.styles.ts +31 -0
  121. package/src/md/icon-button/internals/standard.styles.ts +18 -0
  122. package/src/md/icon-button/ui-filled-icon-button.ts +16 -0
  123. package/src/md/icon-button/ui-filled-tonal-icon-button.ts +16 -0
  124. package/src/md/icon-button/ui-icon-button.ts +3 -2
  125. package/src/md/icon-button/ui-outlined-icon-button.ts +16 -0
  126. package/src/md/icons/internals/Icon.styles.ts +31 -2
  127. package/src/md/icons/internals/Icon.ts +14 -0
  128. package/src/md/list/internals/ListItem.styles.ts +6 -2
  129. package/src/md/list/internals/ListItem.ts +51 -18
  130. package/src/md/ripple/internals/ripple.ts +47 -13
  131. package/src/md/segmented-button/internals/SegmentedButton.ts +2 -2
  132. package/test/ui/button/UiIconButton.test.ts +1 -8
  133. package/build/src/md/icon-button/internals/IconButton.styles.d.ts.map +0 -1
  134. package/build/src/md/icon-button/internals/IconButton.styles.js +0 -614
  135. package/build/src/md/icon-button/internals/IconButton.styles.js.map +0 -1
  136. package/demo/md/buttons/icon-button.ts +0 -184
  137. package/src/md/icon-button/internals/IconButton.styles.ts +0 -614
  138. /package/demo/md/buttons/{button.ts → index.ts} +0 -0
  139. /package/demo/md/{inputs/checkbox.ts → checkbox/index.ts} +0 -0
  140. /package/demo/md/{list/dropdown-list.ts → dropdown-list/index.ts} +0 -0
  141. /package/demo/md/{buttons/segmented-buttons.ts → segmented-button/index.ts} +0 -0
@@ -104,6 +104,7 @@ export default class CheckedElement extends UiElement {
104
104
  this.addEventListener('pointerdown', this.handlePointerDown.bind(this))
105
105
  this.addEventListener('pointerup', this.handlePointerUp.bind(this))
106
106
  this.addEventListener('pointercancel', this.handlePointerCancel.bind(this))
107
+ this.addEventListener('pointerenter', this.handlePointerEnter.bind(this))
107
108
  this.addEventListener('pointerleave', this.handlePointerLeave.bind(this))
108
109
  this.addEventListener('contextmenu', this.handleContextMenu.bind(this))
109
110
  this.addEventListener('keydown', this.handleKeyDown.bind(this))
@@ -156,6 +156,22 @@ export default class UiDropdownList extends LitElement {
156
156
  this.close()
157
157
  }
158
158
 
159
+ protected override willUpdate(cp: PropertyValues<this>): void {
160
+ super.willUpdate(cp)
161
+ if ((cp.has('noOverlap') || cp.has('verticalAlign') || cp.has('horizontalAlign') || cp.has('open')) && this.open) {
162
+ this.computePositioning()
163
+ }
164
+ }
165
+
166
+ protected override updated(cp: PropertyValues<this>): void {
167
+ super.updated(cp)
168
+ if (cp.has('open')) {
169
+ this.toggleOpened()
170
+ this.updateExpanded()
171
+ // this.manageTabindex()
172
+ }
173
+ }
174
+
159
175
  protected updateExpanded(): void {
160
176
  this.setAttribute('aria-expanded', String(this.open))
161
177
  }
@@ -202,7 +218,6 @@ export default class UiDropdownList extends LitElement {
202
218
 
203
219
  protected triggerClickHandler(): void {
204
220
  this.open = !this.open
205
- this.updateExpanded()
206
221
  this.notifyOpen()
207
222
  }
208
223
 
@@ -210,7 +225,6 @@ export default class UiDropdownList extends LitElement {
210
225
  if (['Enter', 'Space', 'ArrowDown', 'ArrowUp'].includes(e.code)) {
211
226
  e.preventDefault()
212
227
  this.open = true
213
- this.updateExpanded()
214
228
  this.notifyOpen()
215
229
  }
216
230
  }
@@ -236,7 +250,6 @@ export default class UiDropdownList extends LitElement {
236
250
 
237
251
  close(): void {
238
252
  this.open = false
239
- this.updateExpanded()
240
253
  this.notifyOpen()
241
254
  }
242
255
 
@@ -245,20 +258,6 @@ export default class UiDropdownList extends LitElement {
245
258
  this.close()
246
259
  }
247
260
 
248
- protected override willUpdate(cp: PropertyValues<this>): void {
249
- super.willUpdate(cp)
250
- if ((cp.has('noOverlap') || cp.has('verticalAlign') || cp.has('horizontalAlign') || cp.has('open')) && this.open) {
251
- this.computePositioning()
252
- }
253
- }
254
-
255
- protected override updated(cp: PropertyValues<this>): void {
256
- super.updated(cp)
257
- if (cp.has('open')) {
258
- this.toggleOpened()
259
- }
260
- }
261
-
262
261
  /**
263
262
  * Since the container for the dropdown content is positioned as fixed
264
263
  * we need to position the dropdown according to the configured rules.
@@ -304,12 +303,49 @@ export default class UiDropdownList extends LitElement {
304
303
  }
305
304
  }
306
305
 
306
+ /**
307
+ * When set, it is the last active child of the dropdown
308
+ * before the tabindex was removed from it. It is used to restore focus
309
+ * when the dropdown is re-opened.
310
+ */
311
+ lastActiveChild?: HTMLElement
312
+
313
+ /**
314
+ * When the list is closed, the tabindex of the dropdown is removed to prevent
315
+ * it from being focused while invisible.
316
+ */
317
+ protected manageTabindex(): void {
318
+ const { dropdown } = this
319
+ if (!dropdown) {
320
+ return
321
+ }
322
+ if (this.open) {
323
+ if (this.lastActiveChild) {
324
+ this.lastActiveChild.setAttribute('tabindex', '0')
325
+ this.lastActiveChild.focus()
326
+ this.lastActiveChild = undefined
327
+ } else {
328
+ // If no last active child, focus the dropdown itself
329
+ dropdown.setAttribute('tabindex', '0')
330
+ }
331
+ } else {
332
+ // const activeChild = dropdown.querySelector(':focus') || dropdown
333
+ // this.lastActiveChild = activeChild as HTMLElement
334
+ // activeChild.removeAttribute('tabindex')
335
+ // this.trigger?.focus()
336
+ }
337
+ }
338
+
307
339
  protected handleOpened(): void {
308
340
  const { trigger, dropdown } = this
309
341
  if (trigger) {
310
342
  trigger.removeAttribute('tabindex')
311
343
  }
312
- if (dropdown) {
344
+ if (this.lastActiveChild) {
345
+ this.lastActiveChild.setAttribute('tabindex', '0')
346
+ this.lastActiveChild.focus()
347
+ this.lastActiveChild = undefined
348
+ } else if (dropdown) {
313
349
  dropdown.setAttribute('tabindex', '0')
314
350
  dropdown.focus()
315
351
  }
@@ -319,11 +355,14 @@ export default class UiDropdownList extends LitElement {
319
355
  const { trigger, dropdown } = this
320
356
  if (trigger) {
321
357
  trigger.setAttribute('tabindex', '0')
322
- if (this.matches(':focus-within')) {
323
- trigger.focus()
324
- }
358
+ trigger.focus()
325
359
  }
326
360
  if (dropdown) {
361
+ const activeChild = dropdown.querySelector('[tabindex="0"]')
362
+ if (activeChild) {
363
+ this.lastActiveChild = activeChild as HTMLElement
364
+ activeChild.removeAttribute('tabindex')
365
+ }
327
366
  dropdown.removeAttribute('tabindex')
328
367
  }
329
368
  }
@@ -1,38 +1,19 @@
1
1
  /* eslint-disable max-len */
2
2
  import { html, PropertyValues, TemplateResult } from 'lit'
3
- import { property, queryAsync, state } from 'lit/decorators.js'
3
+ import { property, query } from 'lit/decorators.js'
4
4
  import { classMap } from 'lit/directives/class-map.js'
5
- import { when } from 'lit/directives/when.js'
6
5
  import { BeginPressConfig, EndPressConfig } from '../../../controllers/ActionController.js'
7
- import UiRipple from '../../ripple/internals/ripple.js'
8
- import { ripple } from '../../effects/rippleDirective.js'
9
6
  import { UiElement } from '../../UiElement.js'
10
7
  import { isDisabled, setDisabled } from '../../../lib/disabled.js'
8
+ import UiRipple from '../../ripple/internals/ripple.js'
11
9
 
12
10
  import '../../ripple/ui-ripple.js'
13
-
14
- /**
15
- * The type of the icon button rendered.
16
- */
17
- export enum IconButtonType {
18
- 'filled' = 'filled',
19
- 'tonal' = 'tonal',
20
- 'outlined' = 'outlined',
21
- 'standard' = 'standard',
22
- }
11
+ import '@material/web/focus/md-focus-ring.js'
23
12
 
24
13
  /**
25
14
  * @fires active - An event dispatched when the `active` state has changed. This only happens when the button is `toggle`.
26
15
  */
27
- export default class UiIconButton extends UiElement {
28
- /**
29
- * The type of the rendered button according to Material 3 spec.
30
- *
31
- * @default {ButtonType.filled}
32
- * @attribute
33
- */
34
- @property({ type: String, reflect: true }) accessor type: IconButtonType
35
-
16
+ export default class IconButton extends UiElement {
36
17
  /**
37
18
  * Whether the button can be toggled.
38
19
  * A toggle button behaves different as it gets the `aria-pressed` attribute
@@ -53,10 +34,6 @@ export default class UiIconButton extends UiElement {
53
34
  */
54
35
  @property({ type: Boolean, reflect: true }) accessor active: boolean | undefined
55
36
 
56
- @queryAsync('ui-ripple') protected accessor ripple!: Promise<UiRipple | null>
57
-
58
- @state() protected accessor showRipple = false
59
-
60
37
  get disabled(): boolean {
61
38
  return isDisabled(this)
62
39
  }
@@ -72,15 +49,11 @@ export default class UiIconButton extends UiElement {
72
49
  this.requestUpdate('disabled', old)
73
50
  }
74
51
 
75
- protected readonly getRipple = (): Promise<UiRipple | null> => {
76
- this.showRipple = true
77
- return this.ripple
78
- }
52
+ @query('ui-ripple') protected accessor ripple!: UiRipple | null
79
53
 
80
54
  constructor() {
81
55
  super()
82
56
 
83
- this.type = IconButtonType.standard
84
57
  this.actionController.cancelKeyboardEvents = true
85
58
  this.addEventListener('keydown', this.handleKeyDown.bind(this))
86
59
  this.addEventListener('keyup', this.handleKeyUp.bind(this))
@@ -89,6 +62,7 @@ export default class UiIconButton extends UiElement {
89
62
  this.addEventListener('pointerup', this.handlePointerUp.bind(this))
90
63
  this.addEventListener('pointercancel', this.handlePointerCancel.bind(this))
91
64
  this.addEventListener('pointerleave', this.handlePointerLeave.bind(this))
65
+ this.addEventListener('pointerenter', this.handlePointerEnter.bind(this))
92
66
  this.addEventListener('contextmenu', this.handleContextMenu.bind(this))
93
67
  }
94
68
 
@@ -109,21 +83,20 @@ export default class UiIconButton extends UiElement {
109
83
  super.update(changedProperties)
110
84
  }
111
85
 
112
- protected async pressRipple(): Promise<void> {
113
- const element = await this.getRipple()
86
+ protected pressRipple(options: BeginPressConfig): void {
87
+ const element = this.ripple
114
88
  if (element && !element.isPressed) {
115
- element.beginPress()
89
+ element.beginPress(options.positionEvent as PointerEvent)
116
90
  }
117
91
  }
118
92
 
119
- protected async endRipple(): Promise<void> {
120
- const element = await this.getRipple()
121
- element?.endPress()
93
+ protected endRipple(): void {
94
+ this.ripple?.endPress()
122
95
  }
123
96
 
124
97
  override beginPress(options: BeginPressConfig): void {
125
98
  super.beginPress(options)
126
- this.pressRipple()
99
+ this.pressRipple(options)
127
100
  }
128
101
 
129
102
  override endPress(config: EndPressConfig): void {
@@ -147,6 +120,20 @@ export default class UiIconButton extends UiElement {
147
120
  }
148
121
  }
149
122
 
123
+ override handlePointerEnter(e: PointerEvent): void {
124
+ super.handlePointerEnter(e)
125
+ if (this.ripple) {
126
+ this.ripple.beginHover(e)
127
+ }
128
+ }
129
+
130
+ override handlePointerLeave(e: PointerEvent): void {
131
+ super.handlePointerLeave(e)
132
+ if (this.ripple) {
133
+ this.ripple.endHover()
134
+ }
135
+ }
136
+
150
137
  protected override render(): TemplateResult {
151
138
  const { pressed = false } = this
152
139
  const containerClasses = classMap({
@@ -154,19 +141,15 @@ export default class UiIconButton extends UiElement {
154
141
  pressed,
155
142
  })
156
143
  return html`
157
- <div class="${containerClasses}" ${ripple(this.getRipple)}>
144
+ <md-focus-ring part="focus-ring" .control="${this as HTMLElement}"></md-focus-ring>
145
+ <ui-ripple class="ripple" ?disabled="${this.disabled}"></ui-ripple>
146
+ <div class="${containerClasses}">
158
147
  <div class="container"></div>
159
148
  <div class="state"></div>
160
- ${when(this.showRipple, this.renderRipple)}
161
149
  <div class="content">
162
150
  <slot></slot>
163
151
  </div>
164
152
  </div>
165
153
  `
166
154
  }
167
-
168
- protected renderRipple = (): TemplateResult => {
169
- const { disabled } = this
170
- return html`<ui-ripple class="ripple" ?disabled="${disabled}"></ui-ripple>`
171
- }
172
155
  }
@@ -0,0 +1,93 @@
1
+ import { css } from 'lit'
2
+
3
+ export default css`
4
+ :host {
5
+ display: inline-flex;
6
+ vertical-align: middle;
7
+ box-sizing: content-box;
8
+ writing-mode: horizontal-tb !important;
9
+ text-rendering: auto;
10
+ cursor: default;
11
+ user-select: none;
12
+ height: 40px;
13
+ width: 40px;
14
+ border-radius: var(--md-sys-shape-corner-full);
15
+ --md-ripple-state-layer-shape: var(--md-sys-shape-corner-full);
16
+ align-items: center;
17
+ justify-content: center;
18
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
19
+
20
+ position: relative;
21
+ outline: none;
22
+
23
+ --_content-color: inherit;
24
+ --_content-opacity: 1;
25
+ --_container-background-color: initial;
26
+ --_container-opacity: 1;
27
+ --_container-border: none;
28
+ --_state-opacity: 0;
29
+ --_state-background-color: initial;
30
+ }
31
+
32
+ .content ::slotted(*) {
33
+ width: 24px !important;
34
+ height: 24px !important;
35
+
36
+ color: var(--_content-color);
37
+ fill: var(--_content-color);
38
+ opacity: var(--_content-opacity);
39
+ }
40
+
41
+ .surface {
42
+ height: inherit;
43
+ width: inherit;
44
+ position: relative;
45
+ border-radius: var(--md-sys-shape-corner-full);
46
+ display: flex;
47
+ justify-content: center;
48
+ align-items: center;
49
+ cursor: pointer;
50
+ }
51
+
52
+ .container,
53
+ .state {
54
+ position: absolute;
55
+ top: 0;
56
+ left: 0;
57
+ right: 0;
58
+ bottom: 0;
59
+ border-radius: var(--md-sys-shape-corner-full);
60
+ }
61
+
62
+ .container {
63
+ z-index: 1;
64
+ pointer-events: none;
65
+ background-color: var(--_container-background-color);
66
+ opacity: var(--_container-opacity);
67
+ border: var(--_container-border);
68
+ }
69
+
70
+ .state {
71
+ z-index: 2;
72
+ pointer-events: none;
73
+ opacity: var(--_state-opacity);
74
+ background-color: var(--_state-background-color);
75
+ }
76
+
77
+ .content {
78
+ z-index: 3;
79
+ display: flex;
80
+ align-items: center;
81
+ justify-content: center;
82
+ color: var(--_content-color);
83
+ }
84
+
85
+ :host([disabled]) {
86
+ pointer-events: none;
87
+ }
88
+
89
+ .ripple {
90
+ border-radius: inherit;
91
+ z-index: 3;
92
+ }
93
+ `
@@ -0,0 +1,30 @@
1
+ import { css } from 'lit'
2
+
3
+ export default css`
4
+ :host {
5
+ --md-ripple-hover-state-layer-color: var(--md-sys-color-on-secondary-container);
6
+ --md-ripple-focus-state-layer-color: var(--md-sys-color-on-secondary-container);
7
+ --md-ripple-pressed-state-layer-color: var(--md-sys-color-on-secondary-container);
8
+
9
+ --_container-background-color: var(--md-sys-color-secondary-container);
10
+ --_surface-color: var(--md-sys-color-on-secondary-container);
11
+ --_content-color: var(--md-sys-color-on-secondary-container);
12
+ }
13
+
14
+ :host([disabled]) {
15
+ --_container-background-color: var(--md-sys-color-on-surface);
16
+ --_container-opacity: 0.12;
17
+ --_content-color: var(--md-sys-color-on-surface);
18
+ --_content-opacity: 0.38;
19
+ }
20
+
21
+ :host([toggle]) {
22
+ --_container-background-color: var(--md-sys-color-surface-variant);
23
+ --_content-color: var(--md-sys-color-on-surface-variant);
24
+ }
25
+
26
+ :host([toggle][active]) {
27
+ --_container-background-color: var(--md-sys-color-secondary-container);
28
+ --_content-color: var(--md-sys-color-on-secondary-container);
29
+ }
30
+ `
@@ -0,0 +1,36 @@
1
+ import { css } from 'lit'
2
+
3
+ export default css`
4
+ :host {
5
+ --md-ripple-hover-state-layer-color: var(--md-sys-color-on-primary);
6
+ --md-ripple-focus-state-layer-color: var(--md-sys-color-on-primary);
7
+ --md-ripple-pressed-state-layer-color: var(--md-sys-color-on-primary);
8
+
9
+ --_container-background-color: var(--md-sys-color-primary);
10
+ --_surface-color: var(--md-sys-color-on-primary);
11
+ --_content-color: var(--md-sys-color-on-primary);
12
+ }
13
+
14
+ :host([disabled]) {
15
+ --_container-background-color: var(--md-sys-color-on-surface);
16
+ --_container-opacity: 0.12;
17
+ --_content-color: var(--md-sys-color-on-surface);
18
+ --_content-opacity: 0.38;
19
+ }
20
+
21
+ :host([toggle]) {
22
+ --_content-color: var(--md-sys-color-primary);
23
+ --_container-background-color: var(--md-sys-color-surface-variant);
24
+ }
25
+
26
+ :host([toggle][active]) {
27
+ --_container-background-color: var(--md-sys-color-primary);
28
+ --_content-color: var(--md-sys-color-on-primary);
29
+ }
30
+
31
+ :host([toggle]:not([active])) {
32
+ --_state-background-color: var(--md-sys-color-primary);
33
+ --_state-opacity: var(--md-sys-state-hover-state-layer-opacity);
34
+ --_content-color: var(--md-sys-color-primary);
35
+ }
36
+ `
@@ -0,0 +1,31 @@
1
+ import { css } from 'lit'
2
+
3
+ export default css`
4
+ :host {
5
+ --_container-border: 1px var(--md-sys-color-outline) solid;
6
+
7
+ --md-ripple-hover-state-layer-color: var(--md-sys-color-on-surface-variant);
8
+ --md-ripple-focus-state-layer-color: var(--md-sys-color-on-surface-variant);
9
+ --md-ripple-pressed-state-layer-color: var(--md-sys-color-on-surface-variant);
10
+
11
+ --_container-background-color: transparent;
12
+ --_surface-color: var(--md-sys-color-on-surface-variant);
13
+ --_content-color: var(--md-sys-color-on-surface-variant);
14
+ }
15
+
16
+ :host([disabled]) {
17
+ --_container-background-color: var(--md-sys-color-on-surface);
18
+ --_container-opacity: 0.12;
19
+ --_content-color: var(--md-sys-color-on-surface);
20
+ --_content-opacity: 0.38;
21
+ }
22
+
23
+ :host([toggle][active]) {
24
+ --_container-background-color: var(--md-sys-color-inverse-surface);
25
+ --_content-color: var(--md-sys-color-inverse-on-surface);
26
+
27
+ --md-ripple-hover-state-layer-color: var(--md-sys-color-inverse-on-surface);
28
+ --md-ripple-focus-state-layer-color: var(--md-sys-color-inverse-on-surface);
29
+ --md-ripple-pressed-state-layer-color: var(--md-sys-color-inverse-on-surface);
30
+ }
31
+ `
@@ -0,0 +1,18 @@
1
+ import { css } from 'lit'
2
+
3
+ export default css`
4
+ :host {
5
+ --md-ripple-hover-state-layer-color: var(--md-sys-color-on-surface-variant);
6
+ --md-ripple-focus-state-layer-color: var(--md-sys-color-on-surface-variant);
7
+ --md-ripple-pressed-state-layer-color: var(--md-sys-color-on-surface-variant);
8
+ --_container-background-color: transparent;
9
+ --_content-color: var(--md-sys-color-on-surface-variant);
10
+ }
11
+
12
+ :host([toggle][active]) {
13
+ --md-ripple-hover-state-layer-color: var(--md-sys-color-primary);
14
+ --md-ripple-focus-state-layer-color: var(--md-sys-color-primary);
15
+ --md-ripple-pressed-state-layer-color: var(--md-sys-color-primary);
16
+ --_content-color: var(--md-sys-color-primary);
17
+ }
18
+ `
@@ -0,0 +1,16 @@
1
+ import type { CSSResultOrNative } from 'lit'
2
+ import { customElement } from 'lit/decorators.js'
3
+ import Element from './internals/IconButton.js'
4
+ import base from './internals/base.styles.js'
5
+ import styles from './internals/filled.styles.js'
6
+
7
+ @customElement('ui-filled-icon-button')
8
+ export class UiFilledIconButtonElement extends Element {
9
+ static override styles: CSSResultOrNative[] = [base, styles]
10
+ }
11
+
12
+ declare global {
13
+ interface HTMLElementTagNameMap {
14
+ 'ui-filled-icon-button': UiFilledIconButtonElement
15
+ }
16
+ }
@@ -0,0 +1,16 @@
1
+ import type { CSSResultOrNative } from 'lit'
2
+ import { customElement } from 'lit/decorators.js'
3
+ import Element from './internals/IconButton.js'
4
+ import base from './internals/base.styles.js'
5
+ import styles from './internals/filled-tonal.styles.js'
6
+
7
+ @customElement('ui-filled-tonal-icon-button')
8
+ export class UiFilledTonalIconButtonElement extends Element {
9
+ static override styles: CSSResultOrNative[] = [base, styles]
10
+ }
11
+
12
+ declare global {
13
+ interface HTMLElementTagNameMap {
14
+ 'ui-filled-tonal-icon-button': UiFilledTonalIconButtonElement
15
+ }
16
+ }
@@ -1,11 +1,12 @@
1
1
  import type { CSSResultOrNative } from 'lit'
2
2
  import { customElement } from 'lit/decorators.js'
3
3
  import Element from './internals/IconButton.js'
4
- import styles from './internals/IconButton.styles.js'
4
+ import base from './internals/base.styles.js'
5
+ import styles from './internals/standard.styles.js'
5
6
 
6
7
  @customElement('ui-icon-button')
7
8
  export class UiIconButtonElement extends Element {
8
- static override styles: CSSResultOrNative[] = [styles]
9
+ static override styles: CSSResultOrNative[] = [base, styles]
9
10
  }
10
11
 
11
12
  declare global {
@@ -0,0 +1,16 @@
1
+ import type { CSSResultOrNative } from 'lit'
2
+ import { customElement } from 'lit/decorators.js'
3
+ import Element from './internals/IconButton.js'
4
+ import base from './internals/base.styles.js'
5
+ import styles from './internals/outlined.styles.js'
6
+
7
+ @customElement('ui-outlined-icon-button')
8
+ export class UiOutlinedIconButtonElement extends Element {
9
+ static override styles: CSSResultOrNative[] = [base, styles]
10
+ }
11
+
12
+ declare global {
13
+ interface HTMLElementTagNameMap {
14
+ 'ui-outlined-icon-button': UiOutlinedIconButtonElement
15
+ }
16
+ }
@@ -3,8 +3,37 @@ import { css } from 'lit'
3
3
  export default css`
4
4
  :host {
5
5
  display: inline-block;
6
- width: 24px;
7
- height: 24px;
6
+ font-size: var(--md-icon-size, 24px);
7
+ width: var(--md-icon-size, 24px);
8
+ height: var(--md-icon-size, 24px);
9
+ color: inherit;
8
10
  fill: currentColor;
11
+ font-variation-settings: inherit;
12
+ font-weight: 400;
13
+ font-family: var(--md-icon-font, Material Symbols Outlined);
14
+ display: inline-flex;
15
+ font-style: normal;
16
+ place-items: center;
17
+ place-content: center;
18
+ line-height: 1;
19
+ overflow: hidden;
20
+ letter-spacing: normal;
21
+ text-transform: none;
22
+ user-select: none;
23
+ white-space: nowrap;
24
+ word-wrap: normal;
25
+ flex-shrink: 0;
26
+ -webkit-font-smoothing: antialiased;
27
+ text-rendering: optimizeLegibility;
28
+ -moz-osx-font-smoothing: grayscale;
29
+ }
30
+
31
+ ::slotted(svg) {
32
+ fill: currentColor;
33
+ }
34
+
35
+ ::slotted(*) {
36
+ height: 100%;
37
+ width: 100%;
9
38
  }
10
39
  `
@@ -26,6 +26,20 @@ export default class UiIcon extends LitElement {
26
26
  return this.hasIconInternal
27
27
  }
28
28
 
29
+ override connectedCallback() {
30
+ super.connectedCallback()
31
+ const ariaHidden = this.getAttribute('aria-hidden')
32
+ if (ariaHidden === 'false') {
33
+ // Allow the user to set `aria-hidden="false"` to create an icon that is
34
+ // announced by screen readers.
35
+ this.removeAttribute('aria-hidden')
36
+ return
37
+ }
38
+ // Needed for VoiceOver, which will create a "group" if the element is a
39
+ // sibling to other content.
40
+ this.setAttribute('aria-hidden', 'true')
41
+ }
42
+
29
43
  protected override willUpdate(cp: PropertyValues<this>): void {
30
44
  if (cp.has('icon')) {
31
45
  this.updateIcon(this.icon)
@@ -6,6 +6,12 @@ export default css`
6
6
  height: 56px;
7
7
  outline: none;
8
8
  cursor: default;
9
+ position: relative;
10
+
11
+ --md-focus-ring-shape-end-end: 0px;
12
+ --md-focus-ring-shape-end-start: 0px;
13
+ --md-focus-ring-shape-start-end: 0px;
14
+ --md-focus-ring-shape-start-start: 0px;
9
15
  }
10
16
 
11
17
  :host([disabled]) {
@@ -43,8 +49,6 @@ export default css`
43
49
  position: absolute;
44
50
  inset: 0;
45
51
  z-index: 1;
46
-
47
- /* background-color: var(--md-sys-color-surface); */
48
52
  }
49
53
 
50
54
  .content {