@api-client/ui 0.2.10 → 0.2.12

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 (154) hide show
  1. package/build/src/elements/http/CertificateAdd.element.d.ts.map +1 -1
  2. package/build/src/elements/http/CertificateAdd.element.js +2 -5
  3. package/build/src/elements/http/CertificateAdd.element.js.map +1 -1
  4. package/build/src/elements/user/internals/UserAvatar.styles.d.ts.map +1 -1
  5. package/build/src/elements/user/internals/UserAvatar.styles.js +0 -1
  6. package/build/src/elements/user/internals/UserAvatar.styles.js.map +1 -1
  7. package/build/src/md/UiElement.d.ts +5 -0
  8. package/build/src/md/UiElement.d.ts.map +1 -1
  9. package/build/src/md/UiElement.js +7 -0
  10. package/build/src/md/UiElement.js.map +1 -1
  11. package/build/src/md/button/ui-elevated-button.d.ts +1 -1
  12. package/build/src/md/button/ui-elevated-button.js +1 -1
  13. package/build/src/md/button/ui-elevated-button.js.map +1 -1
  14. package/build/src/md/button/ui-filled-button.d.ts +1 -1
  15. package/build/src/md/button/ui-filled-button.js +1 -1
  16. package/build/src/md/button/ui-filled-button.js.map +1 -1
  17. package/build/src/md/button/ui-filled-tonal-button.d.ts +3 -3
  18. package/build/src/md/button/ui-filled-tonal-button.d.ts.map +1 -1
  19. package/build/src/md/button/ui-filled-tonal-button.js +6 -6
  20. package/build/src/md/button/ui-filled-tonal-button.js.map +1 -1
  21. package/build/src/md/button/ui-outlined-button.d.ts +1 -1
  22. package/build/src/md/button/ui-outlined-button.js +1 -1
  23. package/build/src/md/button/ui-outlined-button.js.map +1 -1
  24. package/build/src/md/button/ui-text-button.d.ts +1 -1
  25. package/build/src/md/button/ui-text-button.js +1 -1
  26. package/build/src/md/button/ui-text-button.js.map +1 -1
  27. package/build/src/md/checkbox/internals/Checkbox.styles.d.ts.map +1 -1
  28. package/build/src/md/checkbox/internals/Checkbox.styles.js +55 -216
  29. package/build/src/md/checkbox/internals/Checkbox.styles.js.map +1 -1
  30. package/build/src/md/checkbox/internals/CheckboxElement.d.ts +10 -7
  31. package/build/src/md/checkbox/internals/CheckboxElement.d.ts.map +1 -1
  32. package/build/src/md/checkbox/internals/CheckboxElement.js +39 -32
  33. package/build/src/md/checkbox/internals/CheckboxElement.js.map +1 -1
  34. package/build/src/md/checkbox/internals/CheckedElement.d.ts.map +1 -1
  35. package/build/src/md/checkbox/internals/CheckedElement.js +1 -0
  36. package/build/src/md/checkbox/internals/CheckedElement.js.map +1 -1
  37. package/build/src/md/dropdown-list/internals/UiDropdownList.d.ts +13 -2
  38. package/build/src/md/dropdown-list/internals/UiDropdownList.d.ts.map +1 -1
  39. package/build/src/md/dropdown-list/internals/UiDropdownList.js +59 -20
  40. package/build/src/md/dropdown-list/internals/UiDropdownList.js.map +1 -1
  41. package/build/src/md/icon-button/internals/IconButton.d.ts +8 -24
  42. package/build/src/md/icon-button/internals/IconButton.d.ts.map +1 -1
  43. package/build/src/md/icon-button/internals/IconButton.js +35 -63
  44. package/build/src/md/icon-button/internals/IconButton.js.map +1 -1
  45. package/build/src/md/icon-button/internals/{IconButton.styles.d.ts → base.styles.d.ts} +1 -1
  46. package/build/src/md/icon-button/internals/base.styles.d.ts.map +1 -0
  47. package/build/src/md/icon-button/internals/base.styles.js +93 -0
  48. package/build/src/md/icon-button/internals/base.styles.js.map +1 -0
  49. package/build/src/md/icon-button/internals/filled-tonal.styles.d.ts +3 -0
  50. package/build/src/md/icon-button/internals/filled-tonal.styles.d.ts.map +1 -0
  51. package/build/src/md/icon-button/internals/filled-tonal.styles.js +30 -0
  52. package/build/src/md/icon-button/internals/filled-tonal.styles.js.map +1 -0
  53. package/build/src/md/icon-button/internals/filled.styles.d.ts +3 -0
  54. package/build/src/md/icon-button/internals/filled.styles.d.ts.map +1 -0
  55. package/build/src/md/icon-button/internals/filled.styles.js +36 -0
  56. package/build/src/md/icon-button/internals/filled.styles.js.map +1 -0
  57. package/build/src/md/icon-button/internals/outlined.styles.d.ts +3 -0
  58. package/build/src/md/icon-button/internals/outlined.styles.d.ts.map +1 -0
  59. package/build/src/md/icon-button/internals/outlined.styles.js +31 -0
  60. package/build/src/md/icon-button/internals/outlined.styles.js.map +1 -0
  61. package/build/src/md/icon-button/internals/standard.styles.d.ts +3 -0
  62. package/build/src/md/icon-button/internals/standard.styles.d.ts.map +1 -0
  63. package/build/src/md/icon-button/internals/standard.styles.js +18 -0
  64. package/build/src/md/icon-button/internals/standard.styles.js.map +1 -0
  65. package/build/src/md/icon-button/ui-filled-icon-button.d.ts +11 -0
  66. package/build/src/md/icon-button/ui-filled-icon-button.d.ts.map +1 -0
  67. package/build/src/md/icon-button/ui-filled-icon-button.js +28 -0
  68. package/build/src/md/icon-button/ui-filled-icon-button.js.map +1 -0
  69. package/build/src/md/icon-button/ui-filled-tonal-icon-button.d.ts +11 -0
  70. package/build/src/md/icon-button/ui-filled-tonal-icon-button.d.ts.map +1 -0
  71. package/build/src/md/icon-button/ui-filled-tonal-icon-button.js +28 -0
  72. package/build/src/md/icon-button/ui-filled-tonal-icon-button.js.map +1 -0
  73. package/build/src/md/icon-button/ui-icon-button.d.ts.map +1 -1
  74. package/build/src/md/icon-button/ui-icon-button.js +3 -2
  75. package/build/src/md/icon-button/ui-icon-button.js.map +1 -1
  76. package/build/src/md/icon-button/ui-outlined-icon-button.d.ts +11 -0
  77. package/build/src/md/icon-button/ui-outlined-icon-button.d.ts.map +1 -0
  78. package/build/src/md/icon-button/ui-outlined-icon-button.js +28 -0
  79. package/build/src/md/icon-button/ui-outlined-icon-button.js.map +1 -0
  80. package/build/src/md/icons/internals/Icon.d.ts +1 -0
  81. package/build/src/md/icons/internals/Icon.d.ts.map +1 -1
  82. package/build/src/md/icons/internals/Icon.js +13 -0
  83. package/build/src/md/icons/internals/Icon.js.map +1 -1
  84. package/build/src/md/icons/internals/Icon.styles.d.ts.map +1 -1
  85. package/build/src/md/icons/internals/Icon.styles.js +31 -2
  86. package/build/src/md/icons/internals/Icon.styles.js.map +1 -1
  87. package/build/src/md/list/internals/ListItem.d.ts +4 -3
  88. package/build/src/md/list/internals/ListItem.d.ts.map +1 -1
  89. package/build/src/md/list/internals/ListItem.js +20 -18
  90. package/build/src/md/list/internals/ListItem.js.map +1 -1
  91. package/build/src/md/list/internals/ListItem.styles.d.ts.map +1 -1
  92. package/build/src/md/list/internals/ListItem.styles.js +6 -2
  93. package/build/src/md/list/internals/ListItem.styles.js.map +1 -1
  94. package/build/src/md/ripple/internals/ripple.d.ts +2 -1
  95. package/build/src/md/ripple/internals/ripple.d.ts.map +1 -1
  96. package/build/src/md/ripple/internals/ripple.js +42 -12
  97. package/build/src/md/ripple/internals/ripple.js.map +1 -1
  98. package/build/src/md/segmented-button/internals/SegmentedButton.d.ts +1 -1
  99. package/build/src/md/segmented-button/internals/SegmentedButton.d.ts.map +1 -1
  100. package/build/src/md/segmented-button/internals/SegmentedButton.js +1 -1
  101. package/build/src/md/segmented-button/internals/SegmentedButton.js.map +1 -1
  102. package/demo/md/buttons/{button.html → index.html} +1 -1
  103. package/demo/md/{inputs/checkbox.html → checkbox/index.html} +1 -1
  104. package/demo/md/{list/dropdown-list.html → dropdown-list/index.html} +1 -1
  105. package/demo/md/{buttons/icon-button.html → icon-button/index.html} +5 -1
  106. package/demo/md/icon-button/index.ts +236 -0
  107. package/demo/md/index.html +36 -29
  108. package/demo/md/listbox/listbox.html +31 -0
  109. package/demo/md/listbox/listbox.ts +27 -0
  110. package/demo/md/{buttons/segmented-buttons.html → segmented-button/index.html} +1 -1
  111. package/package.json +2 -2
  112. package/src/elements/http/CertificateAdd.element.ts +2 -5
  113. package/src/elements/user/internals/UserAvatar.styles.ts +0 -1
  114. package/src/md/UiElement.ts +8 -0
  115. package/src/md/button/ui-elevated-button.ts +1 -1
  116. package/src/md/button/ui-filled-button.ts +1 -1
  117. package/src/md/button/ui-filled-tonal-button.ts +3 -3
  118. package/src/md/button/ui-outlined-button.ts +1 -1
  119. package/src/md/button/ui-text-button.ts +1 -1
  120. package/src/md/checkbox/internals/Checkbox.styles.ts +55 -216
  121. package/src/md/checkbox/internals/CheckboxElement.ts +39 -26
  122. package/src/md/checkbox/internals/CheckedElement.ts +1 -0
  123. package/src/md/dropdown-list/internals/UiDropdownList.ts +60 -21
  124. package/src/md/icon-button/internals/IconButton.ts +29 -46
  125. package/src/md/icon-button/internals/base.styles.ts +93 -0
  126. package/src/md/icon-button/internals/filled-tonal.styles.ts +30 -0
  127. package/src/md/icon-button/internals/filled.styles.ts +36 -0
  128. package/src/md/icon-button/internals/outlined.styles.ts +31 -0
  129. package/src/md/icon-button/internals/standard.styles.ts +18 -0
  130. package/src/md/icon-button/ui-filled-icon-button.ts +16 -0
  131. package/src/md/icon-button/ui-filled-tonal-icon-button.ts +16 -0
  132. package/src/md/icon-button/ui-icon-button.ts +3 -2
  133. package/src/md/icon-button/ui-outlined-icon-button.ts +16 -0
  134. package/src/md/icons/internals/Icon.styles.ts +31 -2
  135. package/src/md/icons/internals/Icon.ts +14 -0
  136. package/src/md/list/internals/ListItem.styles.ts +6 -2
  137. package/src/md/list/internals/ListItem.ts +16 -21
  138. package/src/md/ripple/internals/ripple.ts +47 -13
  139. package/src/md/segmented-button/internals/SegmentedButton.ts +2 -2
  140. package/test/ui/button/UiIconButton.test.ts +1 -8
  141. package/build/src/lib/UserCache.d.ts +0 -13
  142. package/build/src/lib/UserCache.d.ts.map +0 -1
  143. package/build/src/lib/UserCache.js +0 -30
  144. package/build/src/lib/UserCache.js.map +0 -1
  145. package/build/src/md/icon-button/internals/IconButton.styles.d.ts.map +0 -1
  146. package/build/src/md/icon-button/internals/IconButton.styles.js +0 -614
  147. package/build/src/md/icon-button/internals/IconButton.styles.js.map +0 -1
  148. package/demo/md/buttons/icon-button.ts +0 -184
  149. package/src/lib/UserCache.ts +0 -33
  150. package/src/md/icon-button/internals/IconButton.styles.ts +0 -614
  151. /package/demo/md/buttons/{button.ts → index.ts} +0 -0
  152. /package/demo/md/{inputs/checkbox.ts → checkbox/index.ts} +0 -0
  153. /package/demo/md/{list/dropdown-list.ts → dropdown-list/index.ts} +0 -0
  154. /package/demo/md/{buttons/segmented-buttons.ts → segmented-button/index.ts} +0 -0
@@ -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 {
@@ -6,6 +6,8 @@ import { BeginPressConfig, EndPressConfig } from '../../../controllers/ActionCon
6
6
  import UiRipple from '../../ripple/internals/ripple.js'
7
7
  import { setDisabled } from '../../../lib/disabled.js'
8
8
  import { ripple } from '../../effects/rippleDirective.js'
9
+
10
+ import '@material/web/focus/md-focus-ring.js'
9
11
  import '../../ripple/ui-ripple.js'
10
12
 
11
13
  export enum ListItemLines {
@@ -60,6 +62,8 @@ export default class UiListItem extends UiElement {
60
62
  */
61
63
  @property({ type: Boolean, reflect: true }) accessor static = false
62
64
 
65
+ @property({ type: Number, reflect: true }) override accessor tabIndex = -1
66
+
63
67
  constructor() {
64
68
  super()
65
69
 
@@ -71,11 +75,17 @@ export default class UiListItem extends UiElement {
71
75
  this.addEventListener('pointerup', this.handlePointerUp.bind(this))
72
76
  this.addEventListener('pointercancel', this.handlePointerCancel.bind(this))
73
77
  this.addEventListener('pointerleave', this.handlePointerLeave.bind(this))
78
+ this.addEventListener('pointerenter', this.handlePointerEnter.bind(this))
74
79
  this.addEventListener('contextmenu', this.handleContextMenu.bind(this))
75
80
  this.addEventListener('keydown', this.handleKeyDown.bind(this))
76
81
  this.addEventListener('keyup', this.handleKeyUp.bind(this))
77
- this.addEventListener('focus', this.handleFocus.bind(this))
78
- this.addEventListener('blur', this.handleBlur.bind(this))
82
+ }
83
+
84
+ protected override updated(changedProperties: PropertyValues<this>): void {
85
+ super.updated(changedProperties)
86
+ if (changedProperties.has('tabIndex') && (this.tabIndex === -1 || this.tabIndex === null)) {
87
+ this.ripple?.endPress()
88
+ }
79
89
  }
80
90
 
81
91
  override connectedCallback(): void {
@@ -98,8 +108,7 @@ export default class UiListItem extends UiElement {
98
108
  return
99
109
  }
100
110
  if (e.key !== ' ' && e.key !== 'Enter') return
101
-
102
- e.preventDefault()
111
+ // do not prevent default, so that parent elements can handle the key event
103
112
  this.beginPress({ positionEvent: e })
104
113
  }
105
114
 
@@ -111,7 +120,7 @@ export default class UiListItem extends UiElement {
111
120
  }
112
121
  if (e.key !== ' ' && e.key !== 'Enter') return
113
122
 
114
- e.preventDefault()
123
+ // do not prevent default, so that parent elements can handle the key event
115
124
  this.endPress({ cancelled: false, actionData: { item: this } })
116
125
  }
117
126
 
@@ -131,7 +140,7 @@ export default class UiListItem extends UiElement {
131
140
  this.ripple.endPress()
132
141
  }
133
142
 
134
- protected handlePointerEnter(e: PointerEvent): void {
143
+ override handlePointerEnter(e: PointerEvent): void {
135
144
  if (this.disabled || this.static) {
136
145
  e.stopPropagation()
137
146
  e.preventDefault()
@@ -151,20 +160,6 @@ export default class UiListItem extends UiElement {
151
160
  this.ripple.endHover()
152
161
  }
153
162
 
154
- protected handleFocus(): void {
155
- if (this.disabled || this.static) {
156
- return
157
- }
158
- this.ripple.beginFocus()
159
- }
160
-
161
- protected handleBlur(): void {
162
- if (this.disabled || this.static) {
163
- return
164
- }
165
- this.ripple.endFocus()
166
- }
167
-
168
163
  /**
169
164
  * Focuses list item and makes list item focusable via keyboard.
170
165
  */
@@ -174,7 +169,6 @@ export default class UiListItem extends UiElement {
174
169
  }
175
170
  this.setAttribute('tabindex', '0')
176
171
  this.focus()
177
- this.ripple.beginFocus()
178
172
  }
179
173
 
180
174
  /**
@@ -209,6 +203,7 @@ export default class UiListItem extends UiElement {
209
203
  })
210
204
 
211
205
  return html`
206
+ <md-focus-ring part="focus-ring" .control="${this as HTMLElement}" inward></md-focus-ring>
212
207
  <div class="${surfaceClasses}" ${ripple(() => this.ripple)}>
213
208
  <div class="container"></div>
214
209
  <div class="state"></div>