@shortfuse/materialdesignweb 0.9.0 → 0.9.2

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 (282) hide show
  1. package/README.md +50 -206
  2. package/components/Badge.js +5 -2
  3. package/components/Body.js +4 -0
  4. package/components/BottomAppBar.js +6 -2
  5. package/components/BottomSheet.js +62 -14
  6. package/components/Button.js +20 -0
  7. package/components/Card.js +20 -3
  8. package/components/Checkbox.js +8 -0
  9. package/components/CheckboxIcon.js +9 -3
  10. package/components/Chip.js +5 -2
  11. package/components/Dialog.js +22 -3
  12. package/components/DialogActions.js +4 -0
  13. package/components/Display.js +9 -0
  14. package/components/Divider.js +5 -0
  15. package/components/Fab.js +11 -0
  16. package/components/FabContainer.js +9 -0
  17. package/components/FilterChip.js +9 -0
  18. package/components/Grid.js +11 -0
  19. package/components/Headline.js +4 -0
  20. package/components/Icon.js +27 -3
  21. package/components/IconButton.js +8 -2
  22. package/components/Input.js +87 -14
  23. package/components/InputChip.js +33 -1
  24. package/components/Label.js +4 -0
  25. package/components/List.js +10 -0
  26. package/components/ListItem.js +53 -0
  27. package/components/ListOption.js +62 -1
  28. package/components/Listbox.js +44 -13
  29. package/components/Menu.js +31 -9
  30. package/components/MenuItem.js +24 -10
  31. package/components/NavBar.js +14 -3
  32. package/components/NavBarItem.js +5 -0
  33. package/components/NavDrawer.js +17 -0
  34. package/components/NavDrawerItem.js +5 -0
  35. package/components/NavItem.js +22 -2
  36. package/components/NavRail.js +9 -0
  37. package/components/NavRailItem.js +5 -0
  38. package/components/Page.js +15 -1
  39. package/components/Pane.js +7 -1
  40. package/components/Popup.js +6 -0
  41. package/components/Progress.js +25 -5
  42. package/components/Radio.js +6 -2
  43. package/components/RadioIcon.js +14 -1
  44. package/components/Ripple.js +14 -0
  45. package/components/Root.js +16 -0
  46. package/components/Scrim.js +10 -2
  47. package/components/Search.js +18 -5
  48. package/components/SegmentedButton.js +22 -6
  49. package/components/SegmentedButtonGroup.js +7 -10
  50. package/components/Select.js +13 -3
  51. package/components/Shape.js +4 -0
  52. package/components/SideSheet.js +31 -2
  53. package/components/Slider.js +22 -2
  54. package/components/Snackbar.js +30 -4
  55. package/components/SnackbarContainer.js +9 -0
  56. package/components/Surface.js +5 -0
  57. package/components/Switch.js +18 -2
  58. package/components/SwitchIcon.js +22 -1
  59. package/components/Tab.js +21 -0
  60. package/components/TabContent.js +32 -12
  61. package/components/TabList.js +36 -3
  62. package/components/TabPanel.js +9 -0
  63. package/components/Table.js +38 -3
  64. package/components/TextArea.js +32 -1
  65. package/components/Title.js +4 -0
  66. package/components/Tooltip.js +9 -2
  67. package/components/TopAppBar.js +15 -0
  68. package/core/Composition.js +45 -16
  69. package/core/CompositionAdapter.js +24 -6
  70. package/core/CustomElement.js +77 -49
  71. package/core/customTypes.js +43 -26
  72. package/core/dom.js +1 -0
  73. package/core/jsonMergePatch.js +15 -1
  74. package/core/observe.js +28 -21
  75. package/dist/CustomElement.min.js +2 -0
  76. package/dist/CustomElement.min.js.map +7 -0
  77. package/dist/core/CustomElement.min.js +2 -0
  78. package/dist/core/CustomElement.min.js.map +7 -0
  79. package/dist/index.min.js +9 -9
  80. package/dist/index.min.js.map +3 -3
  81. package/dist/meta.json +1 -1
  82. package/dom/HTMLOptionsCollectionProxy.js +5 -3
  83. package/mixins/AriaReflectorMixin.js +22 -13
  84. package/mixins/AriaToolbarMixin.js +3 -0
  85. package/mixins/ControlMixin.js +3 -0
  86. package/mixins/DelegatesFocusMixin.js +9 -1
  87. package/mixins/DensityMixin.js +5 -1
  88. package/mixins/ElevationMixin.js +1 -2
  89. package/mixins/FlexableMixin.js +21 -2
  90. package/mixins/FormAssociatedMixin.js +19 -5
  91. package/mixins/HyperlinkMixin.js +11 -1
  92. package/mixins/InputMixin.js +22 -0
  93. package/mixins/KeyboardNavMixin.js +3 -1
  94. package/mixins/PopupMixin.js +41 -12
  95. package/mixins/RTLObserverMixin.js +2 -0
  96. package/mixins/ResizeObserverMixin.js +2 -0
  97. package/mixins/RippleMixin.js +3 -1
  98. package/mixins/ScrollListenerMixin.js +13 -1
  99. package/mixins/SemiStickyMixin.js +7 -0
  100. package/mixins/ShapeMaskedMixin.js +9 -1
  101. package/mixins/ShapeMixin.js +9 -0
  102. package/mixins/StateMixin.js +4 -0
  103. package/mixins/TextFieldMixin.js +21 -2
  104. package/mixins/ThemableMixin.js +13 -0
  105. package/mixins/TooltipTriggerMixin.js +17 -3
  106. package/mixins/TouchTargetMixin.js +4 -1
  107. package/mixins/TypographyMixin.js +8 -1
  108. package/package.json +53 -45
  109. package/services/theme.js +4 -5
  110. package/types/components/BottomAppBar.d.ts +3 -4
  111. package/types/components/BottomSheet.d.ts +33 -7
  112. package/types/components/BottomSheet.d.ts.map +1 -1
  113. package/types/components/Button.d.ts +3 -472
  114. package/types/components/Button.d.ts.map +1 -1
  115. package/types/components/Card.d.ts +9 -274
  116. package/types/components/Card.d.ts.map +1 -1
  117. package/types/components/Checkbox.d.ts +2 -0
  118. package/types/components/Checkbox.d.ts.map +1 -1
  119. package/types/components/Chip.d.ts +3 -1180
  120. package/types/components/Dialog.d.ts +8 -191
  121. package/types/components/Dialog.d.ts.map +1 -1
  122. package/types/components/Display.d.ts +5 -4
  123. package/types/components/Display.d.ts.map +1 -1
  124. package/types/components/Fab.d.ts +2 -470
  125. package/types/components/FilterChip.d.ts +5 -4032
  126. package/types/components/Grid.d.ts +1 -0
  127. package/types/components/Grid.d.ts.map +1 -1
  128. package/types/components/Headline.d.ts +3 -4
  129. package/types/components/Icon.d.ts +1 -49
  130. package/types/components/Icon.d.ts.map +1 -1
  131. package/types/components/IconButton.d.ts +3 -1205
  132. package/types/components/Input.d.ts +1485 -50245
  133. package/types/components/Input.d.ts.map +1 -1
  134. package/types/components/InputChip.d.ts +2 -160
  135. package/types/components/List.d.ts +8 -4
  136. package/types/components/List.d.ts.map +1 -1
  137. package/types/components/ListItem.d.ts +10 -235
  138. package/types/components/ListItem.d.ts.map +1 -1
  139. package/types/components/ListOption.d.ts +17 -1352
  140. package/types/components/ListOption.d.ts.map +1 -1
  141. package/types/components/Listbox.d.ts +199 -11448
  142. package/types/components/Listbox.d.ts.map +1 -1
  143. package/types/components/Menu.d.ts +21 -10
  144. package/types/components/Menu.d.ts.map +1 -1
  145. package/types/components/MenuItem.d.ts +17 -2894
  146. package/types/components/MenuItem.d.ts.map +1 -1
  147. package/types/components/NavBar.d.ts +2 -0
  148. package/types/components/NavBar.d.ts.map +1 -1
  149. package/types/components/NavBarItem.d.ts +1 -90
  150. package/types/components/NavDrawer.d.ts +3 -4
  151. package/types/components/NavDrawerItem.d.ts +1 -90
  152. package/types/components/NavItem.d.ts +1 -92
  153. package/types/components/NavItem.d.ts.map +1 -1
  154. package/types/components/NavRail.d.ts +3 -4
  155. package/types/components/NavRailItem.d.ts +1 -90
  156. package/types/components/Page.d.ts +1 -0
  157. package/types/components/Page.d.ts.map +1 -1
  158. package/types/components/Popup.d.ts +5 -3
  159. package/types/components/Popup.d.ts.map +1 -1
  160. package/types/components/Progress.d.ts +2 -0
  161. package/types/components/Progress.d.ts.map +1 -1
  162. package/types/components/Radio.d.ts +2 -0
  163. package/types/components/Radio.d.ts.map +1 -1
  164. package/types/components/Ripple.d.ts +1 -0
  165. package/types/components/Ripple.d.ts.map +1 -1
  166. package/types/components/Root.d.ts +1 -1
  167. package/types/components/Root.d.ts.map +1 -1
  168. package/types/components/Search.d.ts +502 -2
  169. package/types/components/Search.d.ts.map +1 -1
  170. package/types/components/SegmentedButton.d.ts +4 -470
  171. package/types/components/SegmentedButton.d.ts.map +1 -1
  172. package/types/components/SegmentedButtonGroup.d.ts +3 -4
  173. package/types/components/SegmentedButtonGroup.d.ts.map +1 -1
  174. package/types/components/Select.d.ts +5 -1208
  175. package/types/components/Select.d.ts.map +1 -1
  176. package/types/components/SideSheet.d.ts +9 -4
  177. package/types/components/SideSheet.d.ts.map +1 -1
  178. package/types/components/Slider.d.ts +10 -189
  179. package/types/components/Slider.d.ts.map +1 -1
  180. package/types/components/Snackbar.d.ts +13 -5
  181. package/types/components/Snackbar.d.ts.map +1 -1
  182. package/types/components/Switch.d.ts +4 -0
  183. package/types/components/Switch.d.ts.map +1 -1
  184. package/types/components/SwitchIcon.d.ts +2 -110
  185. package/types/components/SwitchIcon.d.ts.map +1 -1
  186. package/types/components/Tab.d.ts +12 -752
  187. package/types/components/Tab.d.ts.map +1 -1
  188. package/types/components/TabContent.d.ts +23 -21
  189. package/types/components/TabContent.d.ts.map +1 -1
  190. package/types/components/TabList.d.ts +646 -5801
  191. package/types/components/TabList.d.ts.map +1 -1
  192. package/types/components/TabPanel.d.ts +4 -4
  193. package/types/components/TabPanel.d.ts.map +1 -1
  194. package/types/components/Table.d.ts +24 -1
  195. package/types/components/Table.d.ts.map +1 -1
  196. package/types/components/TextArea.d.ts +15 -1208
  197. package/types/components/TextArea.d.ts.map +1 -1
  198. package/types/components/Title.d.ts +3 -4
  199. package/types/components/Tooltip.d.ts +4 -4
  200. package/types/components/Tooltip.d.ts.map +1 -1
  201. package/types/components/TopAppBar.d.ts +4 -5
  202. package/types/components/TopAppBar.d.ts.map +1 -1
  203. package/types/constants/shapes.d.ts.map +1 -1
  204. package/types/core/Composition.d.ts +19 -11
  205. package/types/core/Composition.d.ts.map +1 -1
  206. package/types/core/CompositionAdapter.d.ts +30 -8
  207. package/types/core/CompositionAdapter.d.ts.map +1 -1
  208. package/types/core/CustomElement.d.ts +27 -25
  209. package/types/core/CustomElement.d.ts.map +1 -1
  210. package/types/core/customTypes.d.ts +2 -6
  211. package/types/core/customTypes.d.ts.map +1 -1
  212. package/types/core/dom.d.ts.map +1 -1
  213. package/types/core/jsonMergePatch.d.ts.map +1 -1
  214. package/types/core/observe.d.ts +20 -19
  215. package/types/core/observe.d.ts.map +1 -1
  216. package/types/core/template.d.ts.map +1 -1
  217. package/types/dom/HTMLOptionsCollectionProxy.d.ts +4 -4
  218. package/types/dom/HTMLOptionsCollectionProxy.d.ts.map +1 -1
  219. package/types/mixins/AriaReflectorMixin.d.ts +18 -10
  220. package/types/mixins/AriaReflectorMixin.d.ts.map +1 -1
  221. package/types/mixins/AriaToolbarMixin.d.ts +6 -4
  222. package/types/mixins/AriaToolbarMixin.d.ts.map +1 -1
  223. package/types/mixins/ControlMixin.d.ts +1 -1
  224. package/types/mixins/ControlMixin.d.ts.map +1 -1
  225. package/types/mixins/DelegatesFocusMixin.d.ts +9 -1
  226. package/types/mixins/DelegatesFocusMixin.d.ts.map +1 -1
  227. package/types/mixins/DensityMixin.d.ts +4 -1
  228. package/types/mixins/DensityMixin.d.ts.map +1 -1
  229. package/types/mixins/ElevationMixin.d.ts +1 -2
  230. package/types/mixins/ElevationMixin.d.ts.map +1 -1
  231. package/types/mixins/FlexableMixin.d.ts +1 -0
  232. package/types/mixins/FlexableMixin.d.ts.map +1 -1
  233. package/types/mixins/FormAssociatedMixin.d.ts +3 -2
  234. package/types/mixins/FormAssociatedMixin.d.ts.map +1 -1
  235. package/types/mixins/HyperlinkMixin.d.ts +4 -1
  236. package/types/mixins/HyperlinkMixin.d.ts.map +1 -1
  237. package/types/mixins/InputMixin.d.ts +1 -7
  238. package/types/mixins/InputMixin.d.ts.map +1 -1
  239. package/types/mixins/KeyboardNavMixin.d.ts +4 -5
  240. package/types/mixins/KeyboardNavMixin.d.ts.map +1 -1
  241. package/types/mixins/PopupMixin.d.ts +22 -6
  242. package/types/mixins/PopupMixin.d.ts.map +1 -1
  243. package/types/mixins/RTLObserverMixin.d.ts +1 -0
  244. package/types/mixins/RTLObserverMixin.d.ts.map +1 -1
  245. package/types/mixins/ResizeObserverMixin.d.ts +1 -0
  246. package/types/mixins/ResizeObserverMixin.d.ts.map +1 -1
  247. package/types/mixins/RippleMixin.d.ts +3 -1
  248. package/types/mixins/RippleMixin.d.ts.map +1 -1
  249. package/types/mixins/ScrollListenerMixin.d.ts +7 -2
  250. package/types/mixins/ScrollListenerMixin.d.ts.map +1 -1
  251. package/types/mixins/SemiStickyMixin.d.ts +1 -1
  252. package/types/mixins/SemiStickyMixin.d.ts.map +1 -1
  253. package/types/mixins/ShapeMaskedMixin.d.ts +4 -1
  254. package/types/mixins/ShapeMaskedMixin.d.ts.map +1 -1
  255. package/types/mixins/ShapeMixin.d.ts +1 -0
  256. package/types/mixins/ShapeMixin.d.ts.map +1 -1
  257. package/types/mixins/StateMixin.d.ts +2 -0
  258. package/types/mixins/StateMixin.d.ts.map +1 -1
  259. package/types/mixins/TextFieldMixin.d.ts +7 -1208
  260. package/types/mixins/TextFieldMixin.d.ts.map +1 -1
  261. package/types/mixins/ThemableMixin.d.ts +1 -0
  262. package/types/mixins/ThemableMixin.d.ts.map +1 -1
  263. package/types/mixins/TooltipTriggerMixin.d.ts +12 -4
  264. package/types/mixins/TooltipTriggerMixin.d.ts.map +1 -1
  265. package/types/mixins/TouchTargetMixin.d.ts +4 -1
  266. package/types/mixins/TouchTargetMixin.d.ts.map +1 -1
  267. package/types/mixins/TypographyMixin.d.ts +4 -1
  268. package/types/mixins/TypographyMixin.d.ts.map +1 -1
  269. package/types/services/theme.d.ts.map +1 -1
  270. package/types/utils/jsx-runtime.d.ts +3 -3
  271. package/types/utils/jsx-runtime.d.ts.map +1 -1
  272. package/types/utils/material-color/hct/Hct.d.ts.map +1 -1
  273. package/types/utils/material-color/palettes/CorePalette.d.ts +1 -1
  274. package/types/utils/material-color/palettes/CorePalette.d.ts.map +1 -1
  275. package/types/utils/material-color/scheme/Scheme.d.ts.map +1 -1
  276. package/types/utils/pixelmatch.d.ts +3 -3
  277. package/types/utils/pixelmatch.d.ts.map +1 -1
  278. package/types/utils/searchParams.d.ts.map +1 -1
  279. package/utils/jsx-runtime.js +9 -4
  280. package/utils/pixelmatch.js +10 -7
  281. package/utils/searchParams.js +3 -0
  282. package/components/Button.md +0 -61
@@ -91,6 +91,10 @@ CustomElement
91
91
  })
92
92
  .autoRegister('mdw-bottom-sheet-handle');
93
93
 
94
+ /**
95
+ * Bottom sheets show secondary content anchored to the bottom of the screen
96
+ * @see https://m3.material.io/components/bottom-sheets/specs
97
+ */
94
98
  export default CustomElement
95
99
  .extend()
96
100
  .mixin(ThemableMixin)
@@ -100,35 +104,51 @@ export default CustomElement
100
104
  .mixin(DelegatesFocusMixin)
101
105
  .mixin(ResizeObserverMixin)
102
106
  .observe({
107
+ /** Overrides default of shape top to be true */
103
108
  shapeTop: {
104
109
  type: 'boolean',
105
110
  empty: true,
106
111
  },
112
+ /** Whether the bottom sheet displays as a modal and shows a scrim. */
107
113
  modal: 'boolean',
114
+ /** If true, the sheet is fixed (not translated) and anchors to layout. */
115
+ fixed: 'boolean',
116
+ /** Whether the bottom sheet is currently open. */
108
117
  open: 'boolean',
118
+ /** Whether the bottom sheet is expanded to show full content. */
109
119
  expanded: 'boolean',
120
+ /** Last measured block size in pixels (used for layout calculations). */
110
121
  _lastComputedBlockSize: {
111
122
  type: 'float',
112
123
  nullable: false,
113
124
  },
125
+ /** Last measured offsetTop in pixels. */
114
126
  _lastOffsetTop: {
115
127
  type: 'float',
116
128
  nullable: false,
117
129
  },
130
+ /** Current animation duration (milliseconds). */
118
131
  _animationDuration: {
119
132
  type: 'integer',
120
133
  value: 0,
121
134
  },
135
+ /** Current animation easing string for transitions. */
122
136
  _animationEasing: {
123
137
  value: 'ease-out',
124
138
  },
139
+ /** Current CSS translateY value applied to the sheet. */
125
140
  _translateY: { value: '100%' },
141
+ /** Timestamp of last child scroll event (used to debounce drag). */
126
142
  _lastChildScrollTime: 'float',
143
+ /** ARIA `valuenow` value used by the drag handle for accessibility. */
127
144
  _ariaValueNow: {
128
145
  type: 'integer',
129
146
  },
147
+ /** When true, a drag handle is rendered to allow pointer dragging. */
130
148
  dragHandle: 'boolean',
149
+ /** Event handler: called when the sheet opens. */
131
150
  onopen: EVENT_HANDLER_TYPE,
151
+ /** Event handler: called when the sheet closes. */
132
152
  onclose: EVENT_HANDLER_TYPE,
133
153
  })
134
154
  .set({
@@ -145,14 +165,14 @@ export default CustomElement
145
165
  hostStyles: {
146
166
  ...ELEMENT_ANIMATION_TYPE,
147
167
  get({
148
- open, modal, _lastComputedBlockSize, _translateY,
168
+ open, fixed, _lastComputedBlockSize, _translateY,
149
169
  _animationDuration, _animationEasing,
150
170
  }) {
151
- const computedMargin = (open || modal) ? 0 : `${-1 * _lastComputedBlockSize}px`;
171
+ const computedMargin = (fixed) ? `${-1 * _lastComputedBlockSize}px` : 0;
152
172
  return {
153
173
  styles: {
154
174
  marginBottom: computedMargin,
155
- transform: modal ? `translateY(${_translateY})` : 'none',
175
+ transform: fixed ? 'none' : `translateY(${_translateY})`,
156
176
  },
157
177
  timing: {
158
178
  duration: _animationDuration,
@@ -168,6 +188,11 @@ export default CustomElement
168
188
  <slot id=slot></slot>
169
189
  `
170
190
  .methods({
191
+ /**
192
+ * Ensure a scrim is present when the sheet is modal and open.
193
+ * @param {boolean} [animate=false] - If true, animate scrim changes.
194
+ * @return {void}
195
+ */
171
196
  checkForScrim(animate = false) {
172
197
  let { open, modal, _scrim } = this;
173
198
  if (open && modal) {
@@ -191,9 +216,13 @@ export default CustomElement
191
216
  _scrim.hidden = true;
192
217
  }
193
218
  },
219
+ /**
220
+ * Evaluate drag state and settle the sheet (close or snap open).
221
+ * @return {void}
222
+ */
194
223
  checkDragFinished() {
195
- const { open, _dragStartY, _dragDeltaY, _lastComputedBlockSize, modal, _lastOffsetTop } = this;
196
- if (!open || !modal || _dragStartY == null || _dragDeltaY == null) return;
224
+ const { open, _dragStartY, _dragDeltaY, _lastComputedBlockSize, modal, fixed, _lastOffsetTop } = this;
225
+ if (!open || fixed || _dragStartY == null || _dragDeltaY == null) return;
197
226
  const containerHeight = _lastOffsetTop + _lastComputedBlockSize - 72;
198
227
  const min = (_lastComputedBlockSize > containerHeight)
199
228
  ? _lastComputedBlockSize - containerHeight
@@ -201,7 +230,7 @@ export default CustomElement
201
230
  // visiblity = (max - position) / range
202
231
  const visibility = (_lastComputedBlockSize - _dragDeltaY) / (_lastComputedBlockSize - min);
203
232
  this._dragStartY = null;
204
- if (visibility < 0.5) {
233
+ if (modal && visibility < 0.5) {
205
234
  // Should close
206
235
  this._animationDuration = 200 * visibility;
207
236
  this._animationEasing = 'ease-out';
@@ -218,7 +247,11 @@ export default CustomElement
218
247
  this.expanded = true;
219
248
  }
220
249
  },
221
- /** @param {PointerEvent} event */
250
+ /**
251
+ * Pointer active on the drag handle; registers the pointer for dragging.
252
+ * @param {PointerEvent} event
253
+ * @return {void}
254
+ */
222
255
  onDragHandleActive(event) {
223
256
  if (!event.isTrusted) return;
224
257
  if (!event.isPrimary) return;
@@ -226,7 +259,11 @@ export default CustomElement
226
259
  if (event.buttons !== 1) return;
227
260
  dragHandleEvent.add(event);
228
261
  },
229
- /** @param {PointerEvent} event */
262
+ /**
263
+ * Pointer inactive on the drag handle; finalizes potential drag.
264
+ * @param {PointerEvent} event
265
+ * @return {void}
266
+ */
230
267
  onDragHandleInactive(event) {
231
268
  if (!event.isTrusted) return;
232
269
  if (!event.isPrimary) return;
@@ -234,7 +271,11 @@ export default CustomElement
234
271
  if (event.type !== 'pointerup' && event.buttons !== 1) return;
235
272
  this.checkDragFinished();
236
273
  },
237
- /** @param {PointerEvent|TouchEvent} event */
274
+ /**
275
+ * Handle pointer or touch move events during dragging.
276
+ * @param {PointerEvent|TouchEvent} event
277
+ * @return {void}
278
+ */
238
279
  onPointerOrTouchMove(event) {
239
280
  /** @type {{clientY:number,pageY:number}} */
240
281
  let source;
@@ -277,6 +318,11 @@ export default CustomElement
277
318
  },
278
319
  })
279
320
  .overrides({
321
+ /**
322
+ * Called by ResizeObserverMixin when the element's size changes.
323
+ * @param {ResizeObserverEntry} entry
324
+ * @return {void}
325
+ */
280
326
  onResizeObserved(entry) {
281
327
  this._lastComputedBlockSize = entry.borderBoxSize[0]?.blockSize;
282
328
  this._lastOffsetTop = this.offsetTop;
@@ -310,7 +356,7 @@ export default CustomElement
310
356
  '~touchend': 'checkDragFinished',
311
357
  /** Scroll events do no bubble but can be captured, passively */
312
358
  '*~scroll'() {
313
- if (!this.modal) return;
359
+ if (this.fixed) return;
314
360
  this.checkDragFinished();
315
361
  this._lastChildScrollTime = performance.now();
316
362
  // Wiping touch state
@@ -318,7 +364,7 @@ export default CustomElement
318
364
  this._dragDeltaY = null;
319
365
  },
320
366
  '*scrollend'() {
321
- if (!this.modal) return;
367
+ if (this.fixed) return;
322
368
  this._lastChildScrollTime = null;
323
369
  },
324
370
  })
@@ -337,7 +383,7 @@ export default CustomElement
337
383
  this._animationDuration = open ? 250 : 200;
338
384
  if (open) {
339
385
  let y = 0;
340
- if (this.modal) {
386
+ if (!this.fixed) {
341
387
  const { _lastComputedBlockSize } = this;
342
388
  const containerHeight = _lastOffsetTop + _lastComputedBlockSize;
343
389
  if (_lastComputedBlockSize > containerHeight / 2) {
@@ -353,7 +399,9 @@ export default CustomElement
353
399
  }
354
400
  this._animationEasing = open ? 'ease-in' : 'ease-out';
355
401
  this.checkForScrim(true);
356
- if (open) this.focus();
402
+ if (open) {
403
+ this.focus();
404
+ }
357
405
  },
358
406
  modalChanged() {
359
407
  this._animationDuration = 0;
@@ -403,7 +451,7 @@ export default CustomElement
403
451
  transition: visibility 0s;
404
452
  }
405
453
 
406
- :host(:where([modal])) {
454
+ :host(:where(:not([fixed]))) {
407
455
  position: fixed;
408
456
 
409
457
  max-block-size: calc(100% - 72px);
@@ -11,6 +11,10 @@ import ThemableMixin from '../mixins/ThemableMixin.js';
11
11
 
12
12
  /* https://m3.material.io/components/buttons/specs */
13
13
 
14
+ /**
15
+ * Buttons prompt most actions in a UI.
16
+ * @see https://m3.material.io/components/buttons/specs
17
+ */
14
18
  export default CustomElement
15
19
  .extend()
16
20
  .mixin(ThemableMixin)
@@ -22,6 +26,11 @@ export default CustomElement
22
26
  .mixin(InputMixin)
23
27
  .mixin(HyperlinkMixin)
24
28
  .define({
29
+ /**
30
+ * Returns the element used as the state target for visual states
31
+ * (e.g., pressed/hover). Typically the internal control element.
32
+ * @return {HTMLElement}
33
+ */
25
34
  stateTargetElement() { return this.refs.control; },
26
35
  })
27
36
  .set({
@@ -29,6 +38,7 @@ export default CustomElement
29
38
  _allowedTypes: ['button', 'submit', 'reset', 'file'],
30
39
  })
31
40
  .observe({
41
+ /** The underlying control `type` (button, submit, reset, file). */
32
42
  type: {
33
43
  empty: 'button',
34
44
  /**
@@ -44,14 +54,24 @@ export default CustomElement
44
54
  );
45
55
  },
46
56
  },
57
+ /** Bound to [elevated] specifying whether the element should be elevated. */
47
58
  elevated: 'boolean',
59
+ /** Visual filled variant; may be "tonal" or boolean-filled token. */
48
60
  filled: 'string',
61
+ /** Whether the button should render an outline. */
49
62
  outlined: 'boolean',
63
+ /** Icon name (uses internal `mdw-icon` when set). */
50
64
  icon: 'string',
65
+ /** Ink color override for the icon. */
51
66
  iconInk: 'string',
67
+ // Overrides to string instead of DOMString
68
+ /** Image source URL for an icon. */
52
69
  src: 'string',
70
+ /** Inline SVG markup to render as icon. */
53
71
  svg: 'string',
72
+ /** SVG `viewBox` attribute for inline SVG icons. */
54
73
  viewBox: 'string',
74
+ /** Path data for an inline SVG icon. */
55
75
  svgPath: 'string',
56
76
  })
57
77
  .expressions({
@@ -9,10 +9,12 @@ import StateMixin from '../mixins/StateMixin.js';
9
9
 
10
10
  import Box from './Box.js';
11
11
 
12
- /* https://m3.material.io/components/cards/specs */
13
-
14
12
  const SUPPORTS_INERT = 'inert' in HTMLElement.prototype;
15
13
 
14
+ /**
15
+ * Cards display content and actions about a single subject.
16
+ * @see https://m3.material.io/components/cards/specs
17
+ */
16
18
  export default Box
17
19
  .extend()
18
20
  .mixin(StateMixin)
@@ -26,13 +28,23 @@ export default Box
26
28
  _ariaRole: 'figure',
27
29
  })
28
30
  .observe({
31
+ /** Whether the card displays an elevated surface. */
29
32
  elevated: 'boolean',
33
+ /** Whether the card uses a filled surface style. */
30
34
  filled: 'boolean',
35
+ /** When true, card renders an actionable control (clickable). */
31
36
  actionable: 'boolean',
37
+ /** Label for the action control used for accessibility. */
32
38
  actionLabel: 'string',
39
+ /** Event handler called when the card action is triggered. */
33
40
  onaction: EVENT_HANDLER_TYPE,
34
41
  })
35
42
  .define({
43
+ /**
44
+ * Element used as the target for state styling (pressed/focus).
45
+ * Returns the internal action control when actionable, otherwise the host.
46
+ * @return {HTMLElement}
47
+ */
36
48
  stateTargetElement() { return this.actionable ? this.refs.action : this; },
37
49
  })
38
50
  .expressions({
@@ -40,9 +52,14 @@ export default Box
40
52
  showButton: ({ actionable, href }) => Boolean(actionable || href),
41
53
  })
42
54
  .methods({
55
+ /**
56
+ * Focuses the internal action control if the card is actionable and not disabled.
57
+ * @return {void}
58
+ */
43
59
  focus() {
44
60
  if (this.disabledState) return;
45
- if (this.actionable) this.refs.action.focus();
61
+ if (!this.actionable) return;
62
+ this.refs.action.focus();
46
63
  },
47
64
  })
48
65
  .html`
@@ -7,6 +7,10 @@ import StateMixin from '../mixins/StateMixin.js';
7
7
  import ThemableMixin from '../mixins/ThemableMixin.js';
8
8
  import TouchTargetMixin from '../mixins/TouchTargetMixin.js';
9
9
 
10
+ /**
11
+ * Checkboxes let users select one or more items from a list, or turn an item on or off.
12
+ * @see https://m3.material.io/components/checkbox/specs
13
+ */
10
14
  export default CustomElement
11
15
  .extend()
12
16
  .mixin(ThemableMixin)
@@ -15,11 +19,15 @@ export default CustomElement
15
19
  .mixin(InputMixin)
16
20
  .mixin(TouchTargetMixin)
17
21
  .set({
22
+ /** Whether the element renders a state layer for interaction feedback. */
18
23
  stateLayer: true,
24
+ /** The underlying control input `type` value. */
19
25
  type: 'checkbox',
20
26
  })
21
27
  .observe({
28
+ /** Icon name to show for the checked state. */
22
29
  icon: { value: 'check' },
30
+ /** Icon name to show when the control is indeterminate. */
23
31
  indeterminateIcon: { value: 'check_indeterminate_small' },
24
32
  })
25
33
  .expressions({
@@ -3,26 +3,32 @@ import CustomElement from '../core/CustomElement.js';
3
3
  import ShapeMixin from '../mixins/ShapeMixin.js';
4
4
  import ThemableMixin from '../mixins/ThemableMixin.js';
5
5
 
6
+ /**
7
+ * CheckboxIcon is a visual helper for checkboxes, rendering the box and checkmark.
8
+ * @see https://m3.material.io/components/checkbox/specs
9
+ */
6
10
  export default CustomElement
7
11
  .extend()
8
12
  .mixin(ThemableMixin)
9
13
  .mixin(ShapeMixin)
10
14
  .observe({
15
+ /** Whether the icon is selected (checked). */
11
16
  selected: 'boolean',
17
+ /** Icon name to render inside the checkbox icon. */
12
18
  icon: 'string',
19
+ /** Whether the associated control is in an error state. */
13
20
  errored: 'boolean',
21
+ /** Whether the associated control is disabled. */
14
22
  disabled: 'boolean',
15
23
  })
16
24
  .define({
17
- /** Alias for Selected (QoL) */
25
+ /** Alias for `selected` (quality-of-life property). */
18
26
  checked: {
19
27
  get() { return this.selected; },
20
28
  set(value) { this.selected = value; },
21
29
  },
22
30
  })
23
31
  .css`
24
- /* https://m3.material.io/components/checkbox/specs */
25
-
26
32
  :host {
27
33
  --mdw-ink: var(--mdw-color__on-primary);
28
34
  --mdw-bg: var(--mdw-color__primary);
@@ -1,8 +1,13 @@
1
1
  import Button from './Button.js';
2
2
 
3
+ /**
4
+ * Chips help people enter information, make selections, filter content, or trigger actions.
5
+ * @see https://m3.material.io/components/chips/specs
6
+ */
3
7
  export default Button
4
8
  .extend()
5
9
  .observe({
10
+ /** When true, renders the chip as a suggestion variant. */
6
11
  suggestion: 'boolean',
7
12
  })
8
13
  .expressions({
@@ -11,8 +16,6 @@ export default Button
11
16
  },
12
17
  })
13
18
  .css`
14
- /* https://m3.material.io/components/chips/specs */
15
-
16
19
  :host {
17
20
  --mdw-shape__size: 8px;
18
21
  --mdw-ink: var(--mdw-color__on-surface);
@@ -59,20 +59,26 @@ function focusOnTree(root, autofocus, forward = true) {
59
59
  if (attemptFocus(el)) return true;
60
60
  continue;
61
61
  }
62
+ // @ts-ignore Valid as long tabIndex isn't negative
62
63
  if (el.tabIndex >= 0) {
63
64
  // Can focus, add to later in case we find an autofocusable
64
65
  if (autofocus || !forward) {
65
66
  focusables.push(node);
66
- } else if (attemptFocus(node)) return true;
67
+ } else if (attemptFocus(node)) {
68
+ return true;
69
+ }
67
70
  }
68
71
  if (focusOnTree(el, autofocus, forward)) return true;
69
72
  }
70
73
  // Step through
71
74
  }
75
+ // @ts-ignore Valid as long tabIndex isn't negative
72
76
  if (node.tabIndex >= 0) {
73
77
  if (autofocus || !forward) {
74
78
  focusables.push(node);
75
- } else if (attemptFocus(node)) return true;
79
+ } else if (attemptFocus(node)) {
80
+ return true;
81
+ }
76
82
  }
77
83
  }
78
84
  for (const el of forward ? focusables : focusables.reverse()) {
@@ -81,25 +87,36 @@ function focusOnTree(root, autofocus, forward = true) {
81
87
  return false;
82
88
  }
83
89
 
90
+ /**
91
+ * Dialogs provide important prompts in a user flow.
92
+ * @see https://m3.material.io/components/dialogs/specs
93
+ */
84
94
  export default CustomElement
85
95
  .extend()
86
96
  .mixin(ThemableMixin)
87
97
  .mixin(ShapeMixin)
88
98
  .mixin(PopupMixin)
89
99
  .define({
100
+ /** Return the `returnValue` from the internal dialog element. */
90
101
  returnValue() {
91
102
  return /** @type {HTMLDialogElement} */ (this.refs.dialog).returnValue;
92
103
  },
93
104
  })
94
105
  .observe({
106
+ /** Divider style for the dialog: 'full', 'inset', or empty. */
95
107
  dividers: {
96
108
  /** @type {'full'|''|'inset'} */
97
109
  value: null,
98
110
  },
111
+ /** Headline text displayed in the dialog header. */
99
112
  headline: 'string',
113
+ /** Optional icon name shown in the dialog header. */
100
114
  icon: 'string',
115
+ /** Default action (value) for the dialog when submitting. */
101
116
  default: { value: 'confirm' },
117
+ /** Label for the cancel action button. */
102
118
  cancel: { value: 'Cancel' },
119
+ /** Label for the confirm action button. */
103
120
  confirm: { value: 'Confirm' },
104
121
  })
105
122
  .define({
@@ -124,6 +141,7 @@ export default CustomElement
124
141
  || (node.nodeType === node.TEXT_NODE && node.nodeValue.trim().length));
125
142
  currentTarget.toggleAttribute('slotted', hasContent);
126
143
  },
144
+ /** Focus the first autofocusable or focusable element inside the dialog. */
127
145
  focus() {
128
146
  focusOnTree(this.shadowRoot, true, true);
129
147
  },
@@ -349,7 +367,8 @@ export default CustomElement
349
367
  const form = event.target;
350
368
  if (form instanceof HTMLFormElement === false) return;
351
369
  if (form.method !== 'dialog') return;
352
- const returnValue = event.submitter?.value;
370
+ const submitter = /** @type {HTMLInputElement|HTMLButtonElement} */ (event.submitter);
371
+ const returnValue = submitter?.value;
353
372
  this.close(returnValue);
354
373
  },
355
374
  })
@@ -1,5 +1,9 @@
1
1
  import CustomElement from '../core/CustomElement.js';
2
2
 
3
+ /**
4
+ * Dialog action regions contain primary and secondary actions for dialogs.
5
+ * @see https://m3.material.io/components/dialogs/specs
6
+ */
3
7
  export default CustomElement
4
8
  .extend()
5
9
  .css`
@@ -3,16 +3,24 @@ import TypographyMixin from '../mixins/TypographyMixin.js';
3
3
 
4
4
  import Box from './Box.js';
5
5
 
6
+ /**
7
+ * Material Design Type scale: Display
8
+ * @see https://m3.material.io/styles/typography/type-scale-tokens
9
+ */
6
10
  export default Box
7
11
  .extend()
8
12
  .mixin(AriaReflectorMixin)
9
13
  .mixin(TypographyMixin)
10
14
  .set({
15
+ /** ARIA role applied to the host (default: 'heading'). */
11
16
  _ariaRole: 'heading',
17
+ /** Base aria level used when computing the heading level. */
12
18
  _baseAriaLevel: 1,
13
19
  })
14
20
  .observe({
21
+ /** Explicit aria-level; if set, overrides the computed level. */
15
22
  ariaLevel: 'string',
23
+ /** Display size controlling typographic scale: 'large'|'medium'|'small'. */
16
24
  size: {
17
25
  type: 'string',
18
26
  /** @type {'large'|'medium'|'small'} */
@@ -20,6 +28,7 @@ export default Box
20
28
  },
21
29
  })
22
30
  .observe({
31
+ /** Computed aria-level (string) derived from `ariaLevel` and `size`. */
23
32
  _computedAriaLevel({ ariaLevel, size, _baseAriaLevel }) {
24
33
  if (ariaLevel) return ariaLevel;
25
34
  if (size === 'medium') return `${_baseAriaLevel + 1}`;
@@ -3,10 +3,15 @@
3
3
  import CustomElement from '../core/CustomElement.js';
4
4
  import ThemableMixin from '../mixins/ThemableMixin.js';
5
5
 
6
+ /**
7
+ * Dividers are thin lines that group content in lists or other containers
8
+ * @see https://m3.material.io/components/divider/specs
9
+ */
6
10
  export default CustomElement
7
11
  .extend()
8
12
  .mixin(ThemableMixin)
9
13
  .observe({
14
+ /** When true, render the divider vertically instead of horizontally. */
10
15
  vertical: 'boolean',
11
16
  })
12
17
  .css`
package/components/Fab.js CHANGED
@@ -2,20 +2,31 @@ import TooltipTriggerMixin from '../mixins/TooltipTriggerMixin.js';
2
2
 
3
3
  import Button from './Button.js';
4
4
 
5
+ /**
6
+ * Floating action buttons (FABs) help people take primary actions.
7
+ * @see https://m3.material.io/components/floating-action-button/specs
8
+ * @see https://m3.material.io/components/extended-fab/specs
9
+ */
5
10
  export default Button
6
11
  .extend()
7
12
  .mixin(TooltipTriggerMixin)
8
13
  .observe({
14
+ /** When true, render the lowered FAB variant (reduced elevation). */
9
15
  lowered: 'boolean',
16
+ /** When true, the FAB is extended and shows a text label. */
10
17
  extended: 'boolean',
18
+ /** FAB size: `null` (default), 'small' or 'large'. */
11
19
  fabSize: {
12
20
  /** @type {null|'small'|'large'} */
13
21
  value: null,
14
22
  },
23
+ /** Filled variant; default is 'tonal' when omitted. */
15
24
  filled: { empty: 'tonal' },
25
+ /** Whether the FAB uses elevated styling. */
16
26
  elevated: { type: 'boolean', empty: true },
17
27
  })
18
28
  .observe({
29
+ /** Whether to show the tooltip automatically (true when not extended). */
19
30
  autoTooltip({ extended }) {
20
31
  return !extended;
21
32
  },
@@ -2,13 +2,22 @@ import CustomElement from '../core/CustomElement.js';
2
2
  import { ELEMENT_STYLE_TYPE } from '../core/customTypes.js';
3
3
  import DelegatesFocusMixin from '../mixins/DelegatesFocusMixin.js';
4
4
 
5
+ /**
6
+ * Container for Floating Action Buttons (FAB) used to position FABs.
7
+ * @see https://m3.material.io/components/floating-action-button/specs
8
+ */
5
9
  export default CustomElement
6
10
  .extend()
7
11
  .mixin(DelegatesFocusMixin)
8
12
  .observe({
13
+ /** Hide the FAB container at this min-width (pixels). */
9
14
  hideBreakpoint: { value: 728 },
10
15
  })
11
16
  .observe({
17
+ /**
18
+ * Computed element styles. Generates a media query that hides the
19
+ * container when `hideBreakpoint` is set.
20
+ */
12
21
  _styles: {
13
22
  ...ELEMENT_STYLE_TYPE,
14
23
  get({ hideBreakpoint }) {
@@ -2,12 +2,21 @@ import './Icon.js';
2
2
 
3
3
  import Chip from './Chip.js';
4
4
 
5
+ /**
6
+ * Filter chips use tags or descriptive words to filter content.
7
+ * They can be a good alternative to toggle buttons or checkboxes.
8
+ * @see https://m3.material.io/components/chips/specs
9
+ */
5
10
  export default Chip
6
11
  .extend()
7
12
  .observe({
13
+ /** Type of the chip; defaults to 'checkbox' for filter behavior. */
8
14
  type: { empty: 'checkbox' },
15
+ /** When true, shows a dropdown caret as the trailing icon. */
9
16
  dropdown: 'boolean',
17
+ /** Source URL for a trailing image/icon. */
10
18
  trailingSrc: 'string',
19
+ /** Name of the trailing icon to show. */
11
20
  trailingIcon: 'string',
12
21
  })
13
22
  .expressions({
@@ -3,19 +3,28 @@ import ResizeObserverMixin from '../mixins/ResizeObserverMixin.js';
3
3
 
4
4
  import Box from './Box.js';
5
5
 
6
+ /**
7
+ * Grid layout for arranging content into responsive columns.
8
+ * @see https://m3.material.io/foundations/layout/understanding-layout/parts-of-layout
9
+ */
6
10
  export default Box
7
11
  .extend()
8
12
  .mixin(ResizeObserverMixin)
9
13
  .observe({
14
+ /** Enable CSS grid layout for children. */
10
15
  grid: 'boolean',
16
+ /** Explicit number of columns; when set, disables auto column calculation. */
11
17
  columns: 'integer',
18
+ /** Auto-calculated column count when `columns` is not provided. */
12
19
  _autoColumns: {
13
20
  type: 'integer',
14
21
  empty: 4,
15
22
  },
23
+ /** Last measured inline size (px) from ResizeObserver. */
16
24
  _lastInlineSize: 'float',
17
25
  })
18
26
  .observe({
27
+ /** Whether resize observer should be active (disabled when explicit columns set). */
19
28
  _resizeObserverEnabled: {
20
29
  type: 'boolean',
21
30
  get({ columns }) {
@@ -24,6 +33,7 @@ export default Box
24
33
  return !columns;
25
34
  },
26
35
  },
36
+ /** Computed number of columns (either `columns` or `_autoColumns`). */
27
37
  _computedColumns({ columns, _autoColumns }) {
28
38
  if (columns) return columns;
29
39
  if (_autoColumns) return _autoColumns;
@@ -31,6 +41,7 @@ export default Box
31
41
  },
32
42
  })
33
43
  .overrides({
44
+ /** Update last observed inline size from ResizeObserver entry. */
34
45
  onResizeObserved(entry) {
35
46
  const { contentBoxSize } = entry;
36
47
  if (!contentBoxSize.length) return;