@material/web 1.0.0-pre.15 → 1.0.0-pre.17

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 (381) hide show
  1. package/README.md +26 -21
  2. package/all.d.ts +4 -2
  3. package/all.js +4 -2
  4. package/all.js.map +1 -1
  5. package/button/internal/_elevation.scss +4 -0
  6. package/button/internal/_filled-button.scss +0 -1
  7. package/button/internal/_outlined-button.scss +6 -0
  8. package/button/internal/_shared.scss +12 -2
  9. package/button/internal/button.d.ts +15 -14
  10. package/button/internal/button.js +41 -39
  11. package/button/internal/button.js.map +1 -1
  12. package/button/internal/elevated-styles.css.js +1 -1
  13. package/button/internal/elevated-styles.css.js.map +1 -1
  14. package/button/internal/filled-styles.css.js +1 -1
  15. package/button/internal/filled-styles.css.js.map +1 -1
  16. package/button/internal/filled-tonal-styles.css.js +1 -1
  17. package/button/internal/filled-tonal-styles.css.js.map +1 -1
  18. package/button/internal/outlined-styles.css.js +1 -1
  19. package/button/internal/outlined-styles.css.js.map +1 -1
  20. package/button/internal/shared-elevation-styles.css.js +1 -1
  21. package/button/internal/shared-elevation-styles.css.js.map +1 -1
  22. package/button/internal/shared-styles.css.js +1 -1
  23. package/button/internal/shared-styles.css.js.map +1 -1
  24. package/button/internal/text-styles.css.js +1 -1
  25. package/button/internal/text-styles.css.js.map +1 -1
  26. package/checkbox/internal/_checkbox.scss +2 -1
  27. package/checkbox/internal/checkbox-styles.css.js +1 -1
  28. package/checkbox/internal/checkbox-styles.css.js.map +1 -1
  29. package/checkbox/internal/checkbox.d.ts +2 -2
  30. package/checkbox/internal/checkbox.js +18 -14
  31. package/checkbox/internal/checkbox.js.map +1 -1
  32. package/chips/assist-chip.js +1 -2
  33. package/chips/assist-chip.js.map +1 -1
  34. package/chips/filter-chip.js +1 -3
  35. package/chips/filter-chip.js.map +1 -1
  36. package/chips/input-chip.js +1 -5
  37. package/chips/input-chip.js.map +1 -1
  38. package/chips/internal/_assist-chip.scss +6 -0
  39. package/chips/internal/_elevated.scss +1 -5
  40. package/chips/internal/_filter-chip.scss +6 -0
  41. package/chips/internal/_input-chip.scss +32 -0
  42. package/chips/internal/_selectable.scss +17 -13
  43. package/chips/internal/_shared.scss +27 -11
  44. package/chips/internal/_suggestion-chip.scss +6 -0
  45. package/chips/internal/_trailing-icon.scss +24 -24
  46. package/chips/internal/assist-chip.d.ts +3 -1
  47. package/chips/internal/assist-chip.js +11 -8
  48. package/chips/internal/assist-chip.js.map +1 -1
  49. package/chips/internal/assist-styles.css.js +1 -1
  50. package/chips/internal/assist-styles.css.js.map +1 -1
  51. package/chips/internal/chip.d.ts +18 -10
  52. package/chips/internal/chip.js +38 -33
  53. package/chips/internal/chip.js.map +1 -1
  54. package/chips/internal/elevated-styles.css.js +1 -1
  55. package/chips/internal/elevated-styles.css.js.map +1 -1
  56. package/chips/internal/filter-chip.d.ts +6 -7
  57. package/chips/internal/filter-chip.js +13 -14
  58. package/chips/internal/filter-chip.js.map +1 -1
  59. package/chips/internal/filter-styles.css.js +1 -1
  60. package/chips/internal/filter-styles.css.js.map +1 -1
  61. package/chips/internal/input-chip.d.ts +4 -2
  62. package/chips/internal/input-chip.js +16 -12
  63. package/chips/internal/input-chip.js.map +1 -1
  64. package/chips/internal/input-styles.css.js +1 -1
  65. package/chips/internal/input-styles.css.js.map +1 -1
  66. package/chips/internal/multi-action-chip.d.ts +2 -3
  67. package/chips/internal/multi-action-chip.js +3 -3
  68. package/chips/internal/multi-action-chip.js.map +1 -1
  69. package/chips/internal/selectable-styles.css.js +1 -1
  70. package/chips/internal/selectable-styles.css.js.map +1 -1
  71. package/chips/internal/shared-styles.css.js +1 -1
  72. package/chips/internal/shared-styles.css.js.map +1 -1
  73. package/chips/internal/suggestion-styles.css.js +1 -1
  74. package/chips/internal/suggestion-styles.css.js.map +1 -1
  75. package/chips/internal/trailing-icon-styles.css.js +1 -1
  76. package/chips/internal/trailing-icon-styles.css.js.map +1 -1
  77. package/chips/suggestion-chip.js +1 -2
  78. package/chips/suggestion-chip.js.map +1 -1
  79. package/color/_color.scss +193 -0
  80. package/common.d.ts +2 -2
  81. package/common.js +2 -2
  82. package/common.js.map +1 -1
  83. package/dialog/internal/_dialog.scss +19 -4
  84. package/dialog/internal/dialog-styles.css.js +1 -1
  85. package/dialog/internal/dialog-styles.css.js.map +1 -1
  86. package/dialog/internal/dialog.d.ts +6 -0
  87. package/dialog/internal/dialog.js +36 -4
  88. package/dialog/internal/dialog.js.map +1 -1
  89. package/elevation/internal/_elevation.scss +14 -7
  90. package/elevation/internal/elevation-styles.css.js +1 -1
  91. package/elevation/internal/elevation-styles.css.js.map +1 -1
  92. package/elevation/internal/elevation.d.ts +1 -0
  93. package/elevation/internal/elevation.js +6 -0
  94. package/elevation/internal/elevation.js.map +1 -1
  95. package/fab/branded-fab.d.ts +0 -1
  96. package/fab/internal/_fab.scss +11 -10
  97. package/fab/internal/_shared.scss +8 -2
  98. package/fab/internal/fab-branded-styles.css.js +1 -1
  99. package/fab/internal/fab-branded-styles.css.js.map +1 -1
  100. package/fab/internal/fab-styles.css.js +1 -1
  101. package/fab/internal/fab-styles.css.js.map +1 -1
  102. package/fab/internal/fab.d.ts +0 -1
  103. package/fab/internal/shared-styles.css.js +1 -1
  104. package/fab/internal/shared-styles.css.js.map +1 -1
  105. package/fab/internal/shared.d.ts +0 -9
  106. package/fab/internal/shared.js +2 -18
  107. package/fab/internal/shared.js.map +1 -1
  108. package/field/internal/_content.scss +9 -1
  109. package/field/internal/_filled-field.scss +12 -0
  110. package/field/internal/_label.scss +4 -1
  111. package/field/internal/_outlined-field.scss +33 -0
  112. package/field/internal/_shared.scss +14 -6
  113. package/field/internal/_supporting-text.scss +4 -1
  114. package/field/internal/field.d.ts +2 -0
  115. package/field/internal/field.js +19 -0
  116. package/field/internal/field.js.map +1 -1
  117. package/field/internal/filled-styles.css.js +1 -1
  118. package/field/internal/filled-styles.css.js.map +1 -1
  119. package/field/internal/outlined-styles.css.js +1 -1
  120. package/field/internal/outlined-styles.css.js.map +1 -1
  121. package/field/internal/shared-styles.css.js +1 -1
  122. package/field/internal/shared-styles.css.js.map +1 -1
  123. package/focus/internal/focus-ring.d.ts +3 -1
  124. package/focus/internal/focus-ring.js +9 -0
  125. package/focus/internal/focus-ring.js.map +1 -1
  126. package/icon/internal/_icon.scss +10 -5
  127. package/icon/internal/icon-styles.css.js +1 -1
  128. package/icon/internal/icon-styles.css.js.map +1 -1
  129. package/icon/internal/icon.js +4 -0
  130. package/icon/internal/icon.js.map +1 -1
  131. package/iconbutton/internal/_icon-button.scss +12 -0
  132. package/iconbutton/internal/_shared.scss +9 -0
  133. package/iconbutton/internal/icon-button.d.ts +19 -6
  134. package/iconbutton/internal/icon-button.js +35 -11
  135. package/iconbutton/internal/icon-button.js.map +1 -1
  136. package/iconbutton/internal/shared-styles.css.js +1 -1
  137. package/iconbutton/internal/shared-styles.css.js.map +1 -1
  138. package/iconbutton/internal/standard-styles.css.js +1 -1
  139. package/iconbutton/internal/standard-styles.css.js.map +1 -1
  140. package/internal/aria/aria.d.ts +52 -1
  141. package/internal/aria/aria.js +146 -0
  142. package/internal/aria/aria.js.map +1 -1
  143. package/internal/controller/attachable-controller.d.ts +5 -4
  144. package/internal/controller/attachable-controller.js +8 -0
  145. package/internal/controller/attachable-controller.js.map +1 -1
  146. package/internal/controller/form-submitter.d.ts +12 -0
  147. package/internal/controller/form-submitter.js +3 -1
  148. package/internal/controller/form-submitter.js.map +1 -1
  149. package/labs/badge/internal/_badge.scss +16 -9
  150. package/labs/badge/internal/badge-styles.css.js +1 -1
  151. package/labs/badge/internal/badge-styles.css.js.map +1 -1
  152. package/labs/navigationbar/internal/_navigation-bar.scss +11 -9
  153. package/labs/navigationbar/internal/navigation-bar-styles.css.js +1 -1
  154. package/labs/navigationbar/internal/navigation-bar-styles.css.js.map +1 -1
  155. package/labs/navigationdrawer/internal/_navigation-drawer-modal.scss +11 -8
  156. package/labs/navigationdrawer/internal/_navigation-drawer.scss +11 -8
  157. package/labs/navigationdrawer/internal/navigation-drawer-modal-styles.css.js +1 -1
  158. package/labs/navigationdrawer/internal/navigation-drawer-modal-styles.css.js.map +1 -1
  159. package/labs/navigationdrawer/internal/navigation-drawer-styles.css.js +1 -1
  160. package/labs/navigationdrawer/internal/navigation-drawer-styles.css.js.map +1 -1
  161. package/labs/navigationtab/internal/_navigation-tab.scss +14 -11
  162. package/labs/navigationtab/internal/navigation-tab-styles.css.js +1 -1
  163. package/labs/navigationtab/internal/navigation-tab-styles.css.js.map +1 -1
  164. package/labs/segmentedbutton/internal/_outlined-segmented-button.scss +1 -3
  165. package/labs/segmentedbutton/internal/_shared.scss +4 -1
  166. package/labs/segmentedbutton/internal/outlined-styles.css.js +1 -1
  167. package/labs/segmentedbutton/internal/outlined-styles.css.js.map +1 -1
  168. package/labs/segmentedbutton/internal/shared-styles.css.js +1 -1
  169. package/labs/segmentedbutton/internal/shared-styles.css.js.map +1 -1
  170. package/labs/segmentedbuttonset/internal/outlined-styles.css.js +1 -1
  171. package/labs/segmentedbuttonset/internal/outlined-styles.css.js.map +1 -1
  172. package/list/harness.js +1 -1
  173. package/list/harness.js.map +1 -1
  174. package/list/internal/_list.scss +7 -6
  175. package/list/internal/list-styles.css.js +1 -1
  176. package/list/internal/list-styles.css.js.map +1 -1
  177. package/list/internal/list.d.ts +1 -2
  178. package/list/internal/list.js +4 -6
  179. package/list/internal/list.js.map +1 -1
  180. package/list/internal/listitem/_list-item.scss +96 -94
  181. package/list/internal/listitem/forced-colors-styles.css.js +1 -1
  182. package/list/internal/listitem/forced-colors-styles.css.js.map +1 -1
  183. package/list/internal/listitem/forced-colors-styles.scss +6 -6
  184. package/list/internal/listitem/list-item-styles.css.js +1 -1
  185. package/list/internal/listitem/list-item-styles.css.js.map +1 -1
  186. package/menu/harness.d.ts +1 -1
  187. package/menu/harness.js +3 -4
  188. package/menu/harness.js.map +1 -1
  189. package/menu/internal/_menu.scss +37 -28
  190. package/menu/internal/menu-styles.css.js +1 -1
  191. package/menu/internal/menu-styles.css.js.map +1 -1
  192. package/menu/internal/menu.d.ts +15 -4
  193. package/menu/internal/menu.js +33 -10
  194. package/menu/internal/menu.js.map +1 -1
  195. package/menu/internal/menuitem/_menu-item.scss +7 -4
  196. package/menu/internal/menuitem/menu-item-styles.css.js +1 -1
  197. package/menu/internal/menuitem/menu-item-styles.css.js.map +1 -1
  198. package/menu/internal/menuitem/menu-item.js +1 -1
  199. package/menu/internal/menuitem/menu-item.js.map +1 -1
  200. package/menu/internal/submenuitem/sub-menu-item.d.ts +3 -0
  201. package/menu/internal/submenuitem/sub-menu-item.js +42 -12
  202. package/menu/internal/submenuitem/sub-menu-item.js.map +1 -1
  203. package/menu/internal/typeaheadController.js +2 -1
  204. package/menu/internal/typeaheadController.js.map +1 -1
  205. package/menu/menu.d.ts +12 -5
  206. package/menu/menu.js +12 -5
  207. package/menu/menu.js.map +1 -1
  208. package/menu/sub-menu-item.d.ts +3 -4
  209. package/menu/sub-menu-item.js +3 -4
  210. package/menu/sub-menu-item.js.map +1 -1
  211. package/package.json +10 -2
  212. package/progress/harness.js +2 -4
  213. package/progress/harness.js.map +1 -1
  214. package/progress/internal/_circular-progress.scss +8 -6
  215. package/progress/internal/_linear-progress.scss +95 -134
  216. package/progress/internal/circular-progress-styles.css.js +1 -1
  217. package/progress/internal/circular-progress-styles.css.js.map +1 -1
  218. package/progress/internal/circular-progress.js +1 -1
  219. package/progress/internal/circular-progress.js.map +1 -1
  220. package/progress/internal/linear-progress-styles.css.js +1 -1
  221. package/progress/internal/linear-progress-styles.css.js.map +1 -1
  222. package/progress/internal/linear-progress.d.ts +0 -11
  223. package/progress/internal/linear-progress.js +4 -48
  224. package/progress/internal/linear-progress.js.map +1 -1
  225. package/radio/harness.d.ts +1 -1
  226. package/radio/harness.js +1 -1
  227. package/radio/harness.js.map +1 -1
  228. package/radio/internal/_radio.scss +4 -4
  229. package/radio/internal/radio-styles.css.js +1 -1
  230. package/radio/internal/radio-styles.css.js.map +1 -1
  231. package/radio/internal/radio.d.ts +4 -6
  232. package/radio/internal/radio.js +37 -32
  233. package/radio/internal/radio.js.map +1 -1
  234. package/radio/internal/single-selection-controller.js +4 -3
  235. package/radio/internal/single-selection-controller.js.map +1 -1
  236. package/ripple/internal/_ripple.scss +1 -1
  237. package/ripple/internal/ripple-styles.css.js +1 -1
  238. package/ripple/internal/ripple-styles.css.js.map +1 -1
  239. package/ripple/internal/ripple.d.ts +3 -1
  240. package/ripple/internal/ripple.js +9 -0
  241. package/ripple/internal/ripple.js.map +1 -1
  242. package/select/harness.d.ts +1 -1
  243. package/select/harness.js +1 -3
  244. package/select/harness.js.map +1 -1
  245. package/select/internal/_filled-select.scss +13 -4
  246. package/select/internal/_outlined-select.scss +13 -4
  247. package/select/internal/_shared.scss +0 -1
  248. package/select/internal/filled-select-styles.css.js +1 -1
  249. package/select/internal/filled-select-styles.css.js.map +1 -1
  250. package/select/internal/outlined-select-styles.css.js +1 -1
  251. package/select/internal/outlined-select-styles.css.js.map +1 -1
  252. package/select/internal/select.d.ts +8 -2
  253. package/select/internal/select.js +21 -8
  254. package/select/internal/select.js.map +1 -1
  255. package/slider/internal/_slider.scss +42 -32
  256. package/slider/internal/forced-colors-styles.css.js +1 -1
  257. package/slider/internal/forced-colors-styles.css.js.map +1 -1
  258. package/slider/internal/forced-colors-styles.scss +31 -4
  259. package/slider/internal/slider-styles.css.js +1 -1
  260. package/slider/internal/slider-styles.css.js.map +1 -1
  261. package/slider/internal/slider.d.ts +22 -8
  262. package/slider/internal/slider.js +113 -22
  263. package/slider/internal/slider.js.map +1 -1
  264. package/switch/harness.d.ts +1 -1
  265. package/switch/harness.js +1 -1
  266. package/switch/harness.js.map +1 -1
  267. package/switch/internal/_handle.scss +22 -21
  268. package/switch/internal/_icon.scss +12 -12
  269. package/switch/internal/_switch.scss +17 -17
  270. package/switch/internal/_track.scss +12 -12
  271. package/switch/internal/forced-colors-styles.css.js +1 -1
  272. package/switch/internal/forced-colors-styles.css.js.map +1 -1
  273. package/switch/internal/forced-colors-styles.scss +1 -0
  274. package/switch/internal/switch-styles.css.js +1 -1
  275. package/switch/internal/switch-styles.css.js.map +1 -1
  276. package/switch/internal/switch.d.ts +73 -3
  277. package/switch/internal/switch.js +146 -32
  278. package/switch/internal/switch.js.map +1 -1
  279. package/tabs/{_tab.scss → _primary-tab.scss} +1 -1
  280. package/tabs/_secondary-tab.scss +6 -0
  281. package/tabs/harness.d.ts +2 -2
  282. package/tabs/harness.js +1 -2
  283. package/tabs/harness.js.map +1 -1
  284. package/tabs/internal/_primary-tab.scss +70 -0
  285. package/tabs/internal/_secondary-tab.scss +61 -0
  286. package/tabs/internal/_tab.scss +21 -114
  287. package/tabs/internal/_tabs.scss +9 -10
  288. package/tabs/internal/primary-tab-styles.css.js +9 -0
  289. package/tabs/internal/primary-tab-styles.css.js.map +1 -0
  290. package/tabs/internal/primary-tab-styles.scss +10 -0
  291. package/tabs/internal/primary-tab.d.ts +20 -0
  292. package/tabs/internal/primary-tab.js +30 -0
  293. package/tabs/internal/primary-tab.js.map +1 -0
  294. package/tabs/internal/secondary-tab-styles.css.js +9 -0
  295. package/tabs/internal/secondary-tab-styles.css.js.map +1 -0
  296. package/tabs/internal/secondary-tab-styles.scss +10 -0
  297. package/tabs/internal/secondary-tab.d.ts +12 -0
  298. package/tabs/internal/secondary-tab.js +16 -0
  299. package/tabs/internal/secondary-tab.js.map +1 -0
  300. package/tabs/internal/tab-styles.css.js +1 -1
  301. package/tabs/internal/tab-styles.css.js.map +1 -1
  302. package/tabs/internal/tab.d.ts +16 -34
  303. package/tabs/internal/tab.js +81 -81
  304. package/tabs/internal/tab.js.map +1 -1
  305. package/tabs/internal/tabs-styles.css.js +1 -1
  306. package/tabs/internal/tabs-styles.css.js.map +1 -1
  307. package/tabs/internal/tabs.d.ts +6 -20
  308. package/tabs/internal/tabs.js +33 -66
  309. package/tabs/internal/tabs.js.map +1 -1
  310. package/tabs/{tab.d.ts → primary-tab.d.ts} +3 -4
  311. package/tabs/primary-tab.js +23 -0
  312. package/tabs/primary-tab.js.map +1 -0
  313. package/tabs/secondary-tab.d.ts +18 -0
  314. package/tabs/secondary-tab.js +23 -0
  315. package/tabs/secondary-tab.js.map +1 -0
  316. package/tabs/tabs.d.ts +0 -2
  317. package/tabs/tabs.js +0 -2
  318. package/tabs/tabs.js.map +1 -1
  319. package/textfield/internal/_filled-text-field.scss +12 -3
  320. package/textfield/internal/_outlined-text-field.scss +12 -3
  321. package/textfield/internal/filled-styles.css.js +1 -1
  322. package/textfield/internal/filled-styles.css.js.map +1 -1
  323. package/textfield/internal/outlined-styles.css.js +1 -1
  324. package/textfield/internal/outlined-styles.css.js.map +1 -1
  325. package/textfield/internal/text-field.d.ts +30 -10
  326. package/textfield/internal/text-field.js +80 -32
  327. package/textfield/internal/text-field.js.map +1 -1
  328. package/tokens/_index.scss +5 -6
  329. package/tokens/_md-comp-assist-chip.scss +6 -14
  330. package/tokens/_md-comp-badge.scss +1 -14
  331. package/tokens/{_md-comp-circular-progress-indicator.scss → _md-comp-circular-progress.scss} +3 -1
  332. package/tokens/_md-comp-dialog.scss +10 -17
  333. package/tokens/_md-comp-elevated-button.scss +5 -13
  334. package/tokens/_md-comp-fab-branded.scss +9 -10
  335. package/tokens/_md-comp-fab.scss +9 -10
  336. package/tokens/_md-comp-filled-button.scss +5 -13
  337. package/tokens/_md-comp-filled-field.scss +27 -8
  338. package/tokens/_md-comp-filled-select.scss +18 -15
  339. package/tokens/_md-comp-filled-text-field.scss +17 -19
  340. package/tokens/_md-comp-filled-tonal-button.scss +5 -13
  341. package/tokens/_md-comp-filter-chip.scss +5 -13
  342. package/tokens/_md-comp-input-chip.scss +5 -13
  343. package/tokens/_md-comp-list-item.scss +117 -122
  344. package/tokens/_md-comp-menu-item.scss +3 -3
  345. package/tokens/_md-comp-outlined-button.scss +5 -13
  346. package/tokens/_md-comp-outlined-field.scss +27 -7
  347. package/tokens/_md-comp-outlined-segmented-button.scss +5 -13
  348. package/tokens/_md-comp-outlined-select.scss +23 -15
  349. package/tokens/_md-comp-outlined-text-field.scss +17 -19
  350. package/tokens/_md-comp-primary-tab.scss +132 -0
  351. package/tokens/_md-comp-secondary-tab.scss +139 -0
  352. package/tokens/_md-comp-slider.scss +16 -16
  353. package/tokens/_md-comp-suggestion-chip.scss +5 -13
  354. package/tokens/_md-comp-test-table.scss +13 -2
  355. package/tokens/_md-comp-text-button.scss +5 -13
  356. package/tokens/_md-ref-palette.scss +101 -1
  357. package/tokens/_md-ref-typeface.scss +3 -0
  358. package/tokens/_md-sys-color.scss +57 -2
  359. package/tokens/_md-sys-typescale.scss +66 -5
  360. package/chips/internal/assist-forced-colors-styles.css.js +0 -9
  361. package/chips/internal/assist-forced-colors-styles.css.js.map +0 -1
  362. package/chips/internal/assist-forced-colors-styles.scss +0 -27
  363. package/chips/internal/filter-forced-colors-styles.css.js +0 -9
  364. package/chips/internal/filter-forced-colors-styles.css.js.map +0 -1
  365. package/chips/internal/filter-forced-colors-styles.scss +0 -34
  366. package/chips/internal/input-forced-colors-styles.css.d.ts +0 -1
  367. package/chips/internal/input-forced-colors-styles.css.js +0 -9
  368. package/chips/internal/input-forced-colors-styles.css.js.map +0 -1
  369. package/chips/internal/input-forced-colors-styles.scss +0 -39
  370. package/chips/internal/suggestion-forced-colors-styles.css.d.ts +0 -1
  371. package/chips/internal/suggestion-forced-colors-styles.css.js +0 -9
  372. package/chips/internal/suggestion-forced-colors-styles.css.js.map +0 -1
  373. package/chips/internal/suggestion-forced-colors-styles.scss +0 -27
  374. package/internal/sass/_theme.scss +0 -249
  375. package/tabs/tab.js +0 -22
  376. package/tabs/tab.js.map +0 -1
  377. package/tokens/_md-comp-tab.scss +0 -285
  378. /package/{chips/internal/assist-forced-colors-styles.css.d.ts → tabs/internal/primary-tab-styles.css.d.ts} +0 -0
  379. /package/{chips/internal/filter-forced-colors-styles.css.d.ts → tabs/internal/secondary-tab-styles.css.d.ts} +0 -0
  380. /package/tokens/{_md-comp-linear-progress-indicator.scss → _md-comp-linear-progress.scss} +0 -0
  381. /package/tokens/{_md-comp-radio-button.scss → _md-comp-radio.scss} +0 -0
@@ -8,88 +8,75 @@ import '../../elevation/elevation.js';
8
8
  import '../../focus/md-focus-ring.js';
9
9
  import '../../ripple/ripple.js';
10
10
  import { html, isServer, LitElement, nothing } from 'lit';
11
- import { property, query } from 'lit/decorators.js';
11
+ import { property, query, queryAssignedElements, queryAssignedNodes, state } from 'lit/decorators.js';
12
12
  import { classMap } from 'lit/directives/class-map.js';
13
- import { requestUpdateOnAriaChange } from '../../internal/aria/delegate.js';
14
- import { dispatchActivationClick, isActivationClick } from '../../internal/controller/events.js';
13
+ import { polyfillElementInternalsAria, setupHostAria } from '../../internal/aria/aria.js';
14
+ import { EASING } from '../../internal/motion/animation.js';
15
15
  /**
16
16
  * Tab component.
17
17
  */
18
18
  export class Tab extends LitElement {
19
19
  constructor() {
20
20
  super();
21
- /**
22
- * Styling variant to display, 'primary' (default) or 'secondary'.
23
- */
24
- this.variant = 'primary';
25
- /**
26
- * Whether or not the tab is `disabled`.
27
- */
28
- this.disabled = false;
29
21
  /**
30
22
  * Whether or not the tab is `selected`.
31
23
  **/
32
24
  this.selected = false;
33
25
  /**
34
- * Whether or not the tab is `focusable`.
26
+ * In SSR, set this to true when an icon is present.
35
27
  */
36
- this.focusable = false;
28
+ this.hasIcon = false;
37
29
  /**
38
- * Whether or not the icon renders inline with label or stacked vertically.
30
+ * In SSR, set this to true when there is no label and only an icon.
39
31
  */
40
- this.inlineIcon = false;
41
- this.handleActivationClick = (event) => {
42
- if (!isActivationClick((event)) || !this.button) {
43
- return;
44
- }
45
- this.focus();
46
- dispatchActivationClick(this.button);
47
- };
32
+ this.iconOnly = false;
33
+ this.fullWidthIndicator = false;
34
+ this.internals = polyfillElementInternalsAria(this, this /* needed for closure */.attachInternals());
48
35
  if (!isServer) {
49
- this.addEventListener('click', this.handleActivationClick);
36
+ this.internals.role = 'tab';
37
+ this.addEventListener('keydown', this.handleKeydown.bind(this));
50
38
  }
51
39
  }
52
- focus() {
53
- this.button?.focus();
54
- }
55
- blur() {
56
- this.button?.blur();
57
- }
58
40
  render() {
59
- const contentClasses = {
60
- 'inline-icon': this.inlineIcon,
61
- };
62
- // Needed for closure conformance
63
- const { ariaLabel } = this;
41
+ const indicator = html `<div class="indicator"></div>`;
64
42
  return html `
65
- <button
66
- class="button"
67
- role="tab"
68
- .tabIndex=${this.focusable && !this.disabled ? 0 : -1}
69
- aria-selected=${this.selected ? 'true' : 'false'}
70
- ?disabled=${this.disabled}
71
- aria-label=${ariaLabel || nothing}
72
- >
73
- <md-focus-ring part="focus-ring" inward></md-focus-ring>
43
+ <div class="button" role="presentation">
44
+ <md-focus-ring part="focus-ring" inward
45
+ .control=${this}></md-focus-ring>
74
46
  <md-elevation></md-elevation>
75
- <md-ripple ?disabled=${this.disabled}></md-ripple>
76
- <span class="touch"></span>
77
- <div class="content ${classMap(contentClasses)}">
78
- <slot name="icon"></slot>
79
- <span class="label">
80
- <slot></slot>
81
- </span>
82
- <div class="indicator"></div>
47
+ <md-ripple .control=${this}></md-ripple>
48
+ <div class="content ${classMap(this.getContentClasses())}"
49
+ role="presentation">
50
+ <slot name="icon" @slotchange=${this.handleIconSlotChange}></slot>
51
+ <slot @slotchange=${this.handleSlotChange}></slot>
52
+ ${this.fullWidthIndicator ? nothing : indicator}
83
53
  </div>
84
- </button>`;
54
+ ${this.fullWidthIndicator ? indicator : nothing}
55
+ </div>`;
56
+ }
57
+ getContentClasses() {
58
+ return {
59
+ 'has-icon': this.hasIcon,
60
+ 'has-label': !this.iconOnly,
61
+ };
85
62
  }
86
63
  updated(changed) {
87
- if (changed.has('selected') && !this.disabled) {
64
+ if (changed.has('selected')) {
65
+ this.internals.ariaSelected = String(this.selected);
88
66
  this.animateSelected();
89
67
  }
90
68
  }
91
- get tabs() {
92
- return this.parentElement;
69
+ async handleKeydown(event) {
70
+ // Allow event to bubble.
71
+ await 0;
72
+ if (event.defaultPrevented) {
73
+ return;
74
+ }
75
+ if (event.key === 'Enter' || event.key === ' ') {
76
+ // Prevent default behavior such as scrolling when pressing spacebar.
77
+ event.preventDefault();
78
+ this.click();
79
+ }
93
80
  }
94
81
  animateSelected() {
95
82
  this.indicator.getAnimations().forEach(a => {
@@ -97,7 +84,7 @@ export class Tab extends LitElement {
97
84
  });
98
85
  const frames = this.getKeyframes();
99
86
  if (frames !== null) {
100
- this.indicator.animate(frames, { duration: 400, easing: 'ease-out' });
87
+ this.indicator.animate(frames, { duration: 250, easing: EASING.EMPHASIZED });
101
88
  }
102
89
  }
103
90
  getKeyframes() {
@@ -105,21 +92,20 @@ export class Tab extends LitElement {
105
92
  if (!this.selected) {
106
93
  return reduceMotion ? [{ 'opacity': 1 }, { 'transform': 'none' }] : null;
107
94
  }
95
+ // TODO(b/298105040): avoid hardcoding selector
96
+ const tabs = this.closest('md-tabs');
108
97
  const from = {};
109
- // TODO(b/293506179): remove vertical logic
110
- const isVertical = false;
111
- const fromRect = (this.tabs?.previousSelectedItem?.indicator.getBoundingClientRect() ??
98
+ const fromRect = (tabs?.previousSelectedItem?.indicator.getBoundingClientRect() ??
112
99
  {});
113
- const fromPos = isVertical ? fromRect.top : fromRect.left;
114
- const fromExtent = isVertical ? fromRect.height : fromRect.width;
100
+ const fromPos = fromRect.left;
101
+ const fromExtent = fromRect.width;
115
102
  const toRect = this.indicator.getBoundingClientRect();
116
- const toPos = isVertical ? toRect.top : toRect.left;
117
- const toExtent = isVertical ? toRect.height : toRect.width;
118
- const axis = isVertical ? 'Y' : 'X';
103
+ const toPos = toRect.left;
104
+ const toExtent = toRect.width;
119
105
  const scale = fromExtent / toExtent;
120
106
  if (!reduceMotion && fromPos !== undefined && toPos !== undefined &&
121
107
  !isNaN(scale)) {
122
- from['transform'] = `translate${axis}(${(fromPos - toPos).toFixed(4)}px) scale${axis}(${scale.toFixed(4)})`;
108
+ from['transform'] = `translateX(${(fromPos - toPos).toFixed(4)}px) scaleX(${scale.toFixed(4)})`;
123
109
  }
124
110
  else {
125
111
  from['opacity'] = 0;
@@ -128,33 +114,47 @@ export class Tab extends LitElement {
128
114
  // that can hide the animation.
129
115
  return [from, { 'transform': 'none' }];
130
116
  }
117
+ handleSlotChange() {
118
+ this.iconOnly = false;
119
+ // Check if there's any label text or elements. If not, then there is only
120
+ // an icon.
121
+ for (const node of this.assignedDefaultNodes) {
122
+ const hasTextContent = node.nodeType === Node.TEXT_NODE &&
123
+ !!node.wholeText.match(/\S/);
124
+ if (node.nodeType === Node.ELEMENT_NODE || hasTextContent) {
125
+ return;
126
+ }
127
+ }
128
+ this.iconOnly = true;
129
+ }
130
+ handleIconSlotChange() {
131
+ this.hasIcon = this.assignedIcons.length > 0;
132
+ }
131
133
  }
132
134
  (() => {
133
- requestUpdateOnAriaChange(Tab);
135
+ setupHostAria(Tab);
134
136
  })();
135
- /** @nocollapse */
136
- Tab.shadowRootOptions = { mode: 'open', delegatesFocus: true };
137
- __decorate([
138
- property({ reflect: true })
139
- ], Tab.prototype, "variant", void 0);
140
- __decorate([
141
- property({ type: Boolean, reflect: true })
142
- ], Tab.prototype, "disabled", void 0);
143
137
  __decorate([
144
138
  property({ type: Boolean, reflect: true })
145
139
  ], Tab.prototype, "selected", void 0);
146
140
  __decorate([
147
- property({ type: Boolean })
148
- ], Tab.prototype, "focusable", void 0);
149
- __decorate([
150
- property({ type: Boolean, attribute: 'inline-icon' })
151
- ], Tab.prototype, "inlineIcon", void 0);
141
+ property({ type: Boolean, attribute: 'has-icon' })
142
+ ], Tab.prototype, "hasIcon", void 0);
152
143
  __decorate([
153
- query('.button')
154
- ], Tab.prototype, "button", void 0);
144
+ property({ type: Boolean, attribute: 'icon-only' })
145
+ ], Tab.prototype, "iconOnly", void 0);
155
146
  __decorate([
156
147
  query('.indicator')
157
148
  ], Tab.prototype, "indicator", void 0);
149
+ __decorate([
150
+ state()
151
+ ], Tab.prototype, "fullWidthIndicator", void 0);
152
+ __decorate([
153
+ queryAssignedNodes({ flatten: true })
154
+ ], Tab.prototype, "assignedDefaultNodes", void 0);
155
+ __decorate([
156
+ queryAssignedElements({ slot: 'icon', flatten: true })
157
+ ], Tab.prototype, "assignedIcons", void 0);
158
158
  function shouldReduceMotion() {
159
159
  return window.matchMedia('(prefers-reduced-motion: reduce)').matches;
160
160
  }
@@ -1 +1 @@
1
- {"version":3,"file":"tab.js","sourceRoot":"","sources":["tab.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2023 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport '../../elevation/elevation.js';\nimport '../../focus/md-focus-ring.js';\nimport '../../ripple/ripple.js';\n\nimport {html, isServer, LitElement, nothing, PropertyValues} from 'lit';\nimport {property, query} from 'lit/decorators.js';\nimport {classMap} from 'lit/directives/class-map.js';\n\nimport {ARIAMixinStrict} from '../../internal/aria/aria.js';\nimport {requestUpdateOnAriaChange} from '../../internal/aria/delegate.js';\nimport {dispatchActivationClick, isActivationClick} from '../../internal/controller/events.js';\n\n/**\n * An element that can select items.\n */\nexport interface Tabs extends HTMLElement {\n selected?: number;\n selectedItem?: Tab;\n previousSelectedItem?: Tab;\n}\n\n/**\n * Tab variant can be `primary` or `secondary`.\n */\nexport type TabVariant = 'primary'|'secondary';\n\n/**\n * Tab component.\n */\nexport class Tab extends LitElement {\n static {\n requestUpdateOnAriaChange(Tab);\n }\n\n /** @nocollapse */\n static override shadowRootOptions:\n ShadowRootInit = {mode: 'open', delegatesFocus: true};\n\n /**\n * Styling variant to display, 'primary' (default) or 'secondary'.\n */\n @property({reflect: true}) variant: TabVariant = 'primary';\n\n /**\n * Whether or not the tab is `disabled`.\n */\n @property({type: Boolean, reflect: true}) disabled = false;\n\n /**\n * Whether or not the tab is `selected`.\n **/\n @property({type: Boolean, reflect: true}) selected = false;\n\n /**\n * Whether or not the tab is `focusable`.\n */\n @property({type: Boolean}) focusable = false;\n\n /**\n * Whether or not the icon renders inline with label or stacked vertically.\n */\n @property({type: Boolean, attribute: 'inline-icon'}) inlineIcon = false;\n\n @query('.button') private readonly button!: HTMLElement|null;\n\n // note, this is public so it can participate in selection animation.\n /**\n * Selection indicator element.\n */\n @query('.indicator') readonly indicator!: HTMLElement;\n\n constructor() {\n super();\n if (!isServer) {\n this.addEventListener('click', this.handleActivationClick);\n }\n }\n\n override focus() {\n this.button?.focus();\n }\n\n override blur() {\n this.button?.blur();\n }\n\n protected override render() {\n const contentClasses = {\n 'inline-icon': this.inlineIcon,\n };\n // Needed for closure conformance\n const {ariaLabel} = this as ARIAMixinStrict;\n return html`\n <button\n class=\"button\"\n role=\"tab\"\n .tabIndex=${this.focusable && !this.disabled ? 0 : -1}\n aria-selected=${this.selected ? 'true' : 'false'}\n ?disabled=${this.disabled}\n aria-label=${ariaLabel || nothing}\n >\n <md-focus-ring part=\"focus-ring\" inward></md-focus-ring>\n <md-elevation></md-elevation>\n <md-ripple ?disabled=${this.disabled}></md-ripple>\n <span class=\"touch\"></span>\n <div class=\"content ${classMap(contentClasses)}\">\n <slot name=\"icon\"></slot>\n <span class=\"label\">\n <slot></slot>\n </span>\n <div class=\"indicator\"></div>\n </div>\n </button>`;\n }\n\n protected override updated(changed: PropertyValues) {\n if (changed.has('selected') && !this.disabled) {\n this.animateSelected();\n }\n }\n\n private readonly handleActivationClick = (event: MouseEvent) => {\n if (!isActivationClick((event)) || !this.button) {\n return;\n }\n this.focus();\n dispatchActivationClick(this.button);\n };\n\n private get tabs() {\n return this.parentElement as Tabs;\n }\n\n private animateSelected() {\n this.indicator.getAnimations().forEach(a => {\n a.cancel();\n });\n const frames = this.getKeyframes();\n if (frames !== null) {\n this.indicator.animate(frames, {duration: 400, easing: 'ease-out'});\n }\n }\n\n private getKeyframes() {\n const reduceMotion = shouldReduceMotion();\n if (!this.selected) {\n return reduceMotion ? [{'opacity': 1}, {'transform': 'none'}] : null;\n }\n const from: Keyframe = {};\n // TODO(b/293506179): remove vertical logic\n const isVertical = false;\n const fromRect =\n (this.tabs?.previousSelectedItem?.indicator.getBoundingClientRect() ??\n ({} as DOMRect));\n const fromPos = isVertical ? fromRect.top : fromRect.left;\n const fromExtent = isVertical ? fromRect.height : fromRect.width;\n const toRect = this.indicator.getBoundingClientRect();\n const toPos = isVertical ? toRect.top : toRect.left;\n const toExtent = isVertical ? toRect.height : toRect.width;\n const axis = isVertical ? 'Y' : 'X';\n const scale = fromExtent / toExtent;\n if (!reduceMotion && fromPos !== undefined && toPos !== undefined &&\n !isNaN(scale)) {\n from['transform'] = `translate${axis}(${\n (fromPos - toPos).toFixed(4)}px) scale${axis}(${scale.toFixed(4)})`;\n } else {\n from['opacity'] = 0;\n }\n // note, including `transform: none` avoids quirky Safari behavior\n // that can hide the animation.\n return [from, {'transform': 'none'}];\n }\n}\n\nfunction shouldReduceMotion() {\n return window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n}\n"]}
1
+ {"version":3,"file":"tab.js","sourceRoot":"","sources":["tab.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2023 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport '../../elevation/elevation.js';\nimport '../../focus/md-focus-ring.js';\nimport '../../ripple/ripple.js';\n\nimport {html, isServer, LitElement, nothing, PropertyValues} from 'lit';\nimport {property, query, queryAssignedElements, queryAssignedNodes, state} from 'lit/decorators.js';\nimport {classMap} from 'lit/directives/class-map.js';\n\nimport {polyfillElementInternalsAria, setupHostAria} from '../../internal/aria/aria.js';\nimport {EASING} from '../../internal/motion/animation.js';\n\ninterface Tabs extends HTMLElement {\n selected?: number;\n selectedItem?: Tab;\n previousSelectedItem?: Tab;\n}\n\n/**\n * Tab component.\n */\nexport class Tab extends LitElement {\n static {\n setupHostAria(Tab);\n }\n\n /**\n * Whether or not the tab is `selected`.\n **/\n @property({type: Boolean, reflect: true}) selected = false;\n\n /**\n * In SSR, set this to true when an icon is present.\n */\n @property({type: Boolean, attribute: 'has-icon'}) hasIcon = false;\n\n /**\n * In SSR, set this to true when there is no label and only an icon.\n */\n @property({type: Boolean, attribute: 'icon-only'}) iconOnly = false;\n\n // note, this is public so it can participate in selection animation.\n /** @private */\n @query('.indicator') readonly indicator!: HTMLElement;\n @state() protected fullWidthIndicator = false;\n @queryAssignedNodes({flatten: true})\n private readonly assignedDefaultNodes!: Node[];\n @queryAssignedElements({slot: 'icon', flatten: true})\n private readonly assignedIcons!: HTMLElement[];\n private readonly internals = polyfillElementInternalsAria(\n this, (this as HTMLElement /* needed for closure */).attachInternals());\n\n constructor() {\n super();\n if (!isServer) {\n this.internals.role = 'tab';\n this.addEventListener('keydown', this.handleKeydown.bind(this));\n }\n }\n\n protected override render() {\n const indicator = html`<div class=\"indicator\"></div>`;\n return html`\n <div class=\"button\" role=\"presentation\">\n <md-focus-ring part=\"focus-ring\" inward\n .control=${this}></md-focus-ring>\n <md-elevation></md-elevation>\n <md-ripple .control=${this}></md-ripple>\n <div class=\"content ${classMap(this.getContentClasses())}\"\n role=\"presentation\">\n <slot name=\"icon\" @slotchange=${this.handleIconSlotChange}></slot>\n <slot @slotchange=${this.handleSlotChange}></slot>\n ${this.fullWidthIndicator ? nothing : indicator}\n </div>\n ${this.fullWidthIndicator ? indicator : nothing}\n </div>`;\n }\n\n protected getContentClasses() {\n return {\n 'has-icon': this.hasIcon,\n 'has-label': !this.iconOnly,\n };\n }\n\n protected override updated(changed: PropertyValues) {\n if (changed.has('selected')) {\n this.internals.ariaSelected = String(this.selected);\n this.animateSelected();\n }\n }\n\n private async handleKeydown(event: KeyboardEvent) {\n // Allow event to bubble.\n await 0;\n if (event.defaultPrevented) {\n return;\n }\n\n if (event.key === 'Enter' || event.key === ' ') {\n // Prevent default behavior such as scrolling when pressing spacebar.\n event.preventDefault();\n this.click();\n }\n }\n\n private animateSelected() {\n this.indicator.getAnimations().forEach(a => {\n a.cancel();\n });\n const frames = this.getKeyframes();\n if (frames !== null) {\n this.indicator.animate(\n frames, {duration: 250, easing: EASING.EMPHASIZED});\n }\n }\n\n private getKeyframes() {\n const reduceMotion = shouldReduceMotion();\n if (!this.selected) {\n return reduceMotion ? [{'opacity': 1}, {'transform': 'none'}] : null;\n }\n\n // TODO(b/298105040): avoid hardcoding selector\n const tabs = this.closest<Tabs>('md-tabs');\n const from: Keyframe = {};\n const fromRect =\n (tabs?.previousSelectedItem?.indicator.getBoundingClientRect() ??\n ({} as DOMRect));\n const fromPos = fromRect.left;\n const fromExtent = fromRect.width;\n const toRect = this.indicator.getBoundingClientRect();\n const toPos = toRect.left;\n const toExtent = toRect.width;\n const scale = fromExtent / toExtent;\n if (!reduceMotion && fromPos !== undefined && toPos !== undefined &&\n !isNaN(scale)) {\n from['transform'] = `translateX(${\n (fromPos - toPos).toFixed(4)}px) scaleX(${scale.toFixed(4)})`;\n } else {\n from['opacity'] = 0;\n }\n // note, including `transform: none` avoids quirky Safari behavior\n // that can hide the animation.\n return [from, {'transform': 'none'}];\n }\n\n private handleSlotChange() {\n this.iconOnly = false;\n // Check if there's any label text or elements. If not, then there is only\n // an icon.\n for (const node of this.assignedDefaultNodes) {\n const hasTextContent = node.nodeType === Node.TEXT_NODE &&\n !!(node as Text).wholeText.match(/\\S/);\n if (node.nodeType === Node.ELEMENT_NODE || hasTextContent) {\n return;\n }\n }\n\n this.iconOnly = true;\n }\n\n private handleIconSlotChange() {\n this.hasIcon = this.assignedIcons.length > 0;\n }\n}\n\nfunction shouldReduceMotion() {\n return window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n}\n"]}
@@ -4,6 +4,6 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
  import { css } from 'lit';
7
- export const styles = css `:host{box-sizing:border-box;display:flex;justify-content:space-between;align-items:end;overflow:auto;scroll-behavior:smooth;scrollbar-width:none;position:relative}:host([hidden]){display:none}:host([variant~=vertical]:not([hidden])){display:inline-flex;flex-direction:column;align-items:stretch;gap:0px}:host::-webkit-scrollbar{display:none}::slotted(*){flex:1}::slotted([selected]){z-index:1}/*# sourceMappingURL=tabs-styles.css.map */
7
+ export const styles = css `:host{box-sizing:border-box;display:flex;flex-direction:column;overflow:auto;scroll-behavior:smooth;scrollbar-width:none;position:relative}:host([hidden]){display:none}:host::-webkit-scrollbar{display:none}.tabs{align-items:end;display:flex;height:100%;justify-content:space-between;width:100%}::slotted(*){flex:1}::slotted([selected]){z-index:1}/*# sourceMappingURL=tabs-styles.css.map */
8
8
  `;
9
9
  //# sourceMappingURL=tabs-styles.css.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tabs-styles.css.js","sourceRoot":"","sources":["tabs-styles.css.ts"],"names":[],"mappings":"AAAA;;;;IAII;AACH,OAAO,EAAC,GAAG,EAAC,MAAM,KAAK,CAAC;AACxB,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAA;CACzB,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2022 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n import {css} from 'lit';\n export const styles = css`:host{box-sizing:border-box;display:flex;justify-content:space-between;align-items:end;overflow:auto;scroll-behavior:smooth;scrollbar-width:none;position:relative}:host([hidden]){display:none}:host([variant~=vertical]:not([hidden])){display:inline-flex;flex-direction:column;align-items:stretch;gap:0px}:host::-webkit-scrollbar{display:none}::slotted(*){flex:1}::slotted([selected]){z-index:1}/*# sourceMappingURL=tabs-styles.css.map */\n`;\n "]}
1
+ {"version":3,"file":"tabs-styles.css.js","sourceRoot":"","sources":["tabs-styles.css.ts"],"names":[],"mappings":"AAAA;;;;IAII;AACH,OAAO,EAAC,GAAG,EAAC,MAAM,KAAK,CAAC;AACxB,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAA;CACzB,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2022 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n import {css} from 'lit';\n export const styles = css`:host{box-sizing:border-box;display:flex;flex-direction:column;overflow:auto;scroll-behavior:smooth;scrollbar-width:none;position:relative}:host([hidden]){display:none}:host::-webkit-scrollbar{display:none}.tabs{align-items:end;display:flex;height:100%;justify-content:space-between;width:100%}::slotted(*){flex:1}::slotted([selected]){z-index:1}/*# sourceMappingURL=tabs-styles.css.map */\n`;\n "]}
@@ -3,8 +3,9 @@
3
3
  * Copyright 2023 Google LLC
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
+ import '../../divider/divider.js';
6
7
  import { LitElement, PropertyValues } from 'lit';
7
- import { Tab, TabVariant } from './tab.js';
8
+ import { Tab } from './tab.js';
8
9
  /**
9
10
  * @fires change Fired when the selected tab changes. The target's selected or
10
11
  * selectedItem and previousSelected or previousSelectedItem provide information
@@ -30,20 +31,6 @@ import { Tab, TabVariant } from './tab.js';
30
31
  *
31
32
  */
32
33
  export declare class Tabs extends LitElement {
33
- /** @nocollapse */
34
- static readonly shadowRootOptions: {
35
- delegatesFocus: boolean;
36
- mode: ShadowRootMode;
37
- slotAssignment?: SlotAssignmentMode;
38
- };
39
- /**
40
- * Styling variant to display, 'primary' (default) or 'secondary'.
41
- */
42
- variant: TabVariant;
43
- /**
44
- * Whether or not the item is `disabled`.
45
- */
46
- disabled: boolean;
47
34
  /**
48
35
  * Index of the selected item.
49
36
  */
@@ -54,9 +41,9 @@ export declare class Tabs extends LitElement {
54
41
  selectOnFocus: boolean;
55
42
  private previousSelected;
56
43
  private readonly scrollMargin;
57
- private readonly items;
44
+ private readonly maybeTabItems;
45
+ private get items();
58
46
  private itemsDirty;
59
- private readonly selectedAttribute;
60
47
  /**
61
48
  * The item currently selected.
62
49
  */
@@ -68,13 +55,12 @@ export declare class Tabs extends LitElement {
68
55
  /**
69
56
  * The item currently focused.
70
57
  */
71
- protected get focusedItem(): Tab;
58
+ private get focusedItem();
59
+ private readonly internals;
72
60
  constructor();
73
- connectedCallback(): void;
74
61
  private readonly handleKeydown;
75
62
  private readonly handleKeyup;
76
63
  private readonly handleFocusout;
77
- private findFocusableItem;
78
64
  private wasEventPrevented;
79
65
  private dispatchInteraction;
80
66
  protected willUpdate(changed: PropertyValues): void;
@@ -4,13 +4,14 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
  import { __decorate } from "tslib";
7
+ import '../../divider/divider.js';
7
8
  import { html, isServer, LitElement } from 'lit';
8
9
  import { property, queryAssignedElements, state } from 'lit/decorators.js';
9
- // TODO(b/293506179): remove vertical logic
10
+ import { polyfillElementInternalsAria, setupHostAria } from '../../internal/aria/aria.js';
11
+ import { Tab } from './tab.js';
10
12
  const NAVIGATION_KEYS = new Map([
11
13
  ['default', new Set(['Home', 'End'])],
12
14
  ['horizontal', new Set(['ArrowLeft', 'ArrowRight'])],
13
- ['vertical', new Set(['ArrowUp', 'ArrowDown'])]
14
15
  ]);
15
16
  /**
16
17
  * @fires change Fired when the selected tab changes. The target's selected or
@@ -37,6 +38,9 @@ const NAVIGATION_KEYS = new Map([
37
38
  *
38
39
  */
39
40
  export class Tabs extends LitElement {
41
+ get items() {
42
+ return this.maybeTabItems.filter(isTab);
43
+ }
40
44
  /**
41
45
  * The item currently selected.
42
46
  */
@@ -57,14 +61,6 @@ export class Tabs extends LitElement {
57
61
  }
58
62
  constructor() {
59
63
  super();
60
- /**
61
- * Styling variant to display, 'primary' (default) or 'secondary'.
62
- */
63
- this.variant = 'primary';
64
- /**
65
- * Whether or not the item is `disabled`.
66
- */
67
- this.disabled = false;
68
64
  /**
69
65
  * Index of the selected item.
70
66
  */
@@ -78,15 +74,14 @@ export class Tabs extends LitElement {
78
74
  // this tracks if items have changed, which triggers rendering so they can
79
75
  // be kept in sync
80
76
  this.itemsDirty = false;
81
- this.selectedAttribute = `selected`;
77
+ this.internals = polyfillElementInternalsAria(this, this /* needed for closure */.attachInternals());
82
78
  // focus item on keydown and optionally select it
83
79
  this.handleKeydown = async (event) => {
84
80
  const { key } = event;
85
81
  const shouldHandleKey = NAVIGATION_KEYS.get('default').has(key) ||
86
82
  NAVIGATION_KEYS.get('horizontal').has(key);
87
83
  // await to after user may cancel event.
88
- if (!shouldHandleKey || (await this.wasEventPrevented(event, true)) ||
89
- this.disabled) {
84
+ if (!shouldHandleKey || (await this.wasEventPrevented(event, true))) {
90
85
  return;
91
86
  }
92
87
  let indexToFocus = -1;
@@ -105,8 +100,7 @@ export class Tabs extends LitElement {
105
100
  indexToFocus =
106
101
  indexToFocus < 0 ? itemCount - 1 : indexToFocus % itemCount;
107
102
  }
108
- const itemToFocus = this.findFocusableItem(indexToFocus, key === 'End' || isPrevKey);
109
- indexToFocus = this.items.indexOf(itemToFocus);
103
+ const itemToFocus = this.items[indexToFocus];
110
104
  if (itemToFocus !== null && itemToFocus !== focused) {
111
105
  this.updateFocusableItem(itemToFocus);
112
106
  itemToFocus.focus();
@@ -129,29 +123,12 @@ export class Tabs extends LitElement {
129
123
  }
130
124
  };
131
125
  if (!isServer) {
126
+ this.internals.role = 'tablist';
132
127
  this.addEventListener('keydown', this.handleKeydown);
133
128
  this.addEventListener('keyup', this.handleKeyup);
134
129
  this.addEventListener('focusout', this.handleFocusout);
135
130
  }
136
131
  }
137
- connectedCallback() {
138
- super.connectedCallback();
139
- this.setAttribute('role', 'tablist');
140
- }
141
- findFocusableItem(i = -1, prev = false, tries = 0) {
142
- const itemCount = this.items.length - 1;
143
- while (this.items[i]?.disabled && tries <= itemCount) {
144
- tries++;
145
- i = (i + (prev ? -1 : 1));
146
- if (i > itemCount) {
147
- return this.findFocusableItem(0, false, tries);
148
- }
149
- else if (i < 0) {
150
- return this.findFocusableItem(itemCount, true, tries);
151
- }
152
- }
153
- return this.items[i] ?? null;
154
- }
155
132
  // Note, this is async to allow the event to bubble to user code, which
156
133
  // may call `preventDefault`. If it does, avoid performing the tabs action
157
134
  // which is selecting a new tab. Sometimes, the native event must be
@@ -200,19 +177,17 @@ export class Tabs extends LitElement {
200
177
  }
201
178
  }
202
179
  async updated(changed) {
203
- const itemsOrVariantChanged = changed.has('itemsDirty') || changed.has('variant');
180
+ const itemsChanged = changed.has('itemsDirty');
204
181
  // sync state with items.
205
- if (itemsOrVariantChanged || changed.has('disabled')) {
182
+ if (itemsChanged) {
206
183
  this.items.forEach((item, i) => {
207
184
  item.selected = this.selected === i;
208
- item.variant = this.variant;
209
- item.disabled = this.disabled;
210
185
  });
211
186
  }
212
- if (itemsOrVariantChanged || changed.has('selected')) {
187
+ if (itemsChanged || changed.has('selected')) {
213
188
  if (this.previousSelectedItem !== this.selectedItem) {
214
- this.previousSelectedItem?.removeAttribute(this.selectedAttribute);
215
- this.selectedItem?.setAttribute(this.selectedAttribute, '');
189
+ this.previousSelectedItem?.removeAttribute('selected');
190
+ this.selectedItem?.setAttribute('selected', '');
216
191
  }
217
192
  if (this.selectedItem !== this.focusedItem) {
218
193
  this.updateFocusableItem(this.selectedItem);
@@ -222,12 +197,15 @@ export class Tabs extends LitElement {
222
197
  }
223
198
  updateFocusableItem(focusableItem) {
224
199
  for (const item of this.items) {
225
- item.focusable = item === focusableItem;
200
+ item.tabIndex = item === focusableItem ? 0 : -1;
226
201
  }
227
202
  }
228
203
  render() {
229
204
  return html `
230
- <slot @slotchange=${this.handleSlotChange} @click=${this.handleItemClick}></slot>
205
+ <div class="tabs">
206
+ <slot @slotchange=${this.handleSlotChange} @click=${this.handleItemClick}></slot>
207
+ </div>
208
+ <md-divider part="divider"></md-divider>
231
209
  `;
232
210
  }
233
211
  async handleItemClick(event) {
@@ -262,36 +240,22 @@ export class Tabs extends LitElement {
262
240
  }
263
241
  // wait for items to render.
264
242
  await this.itemsUpdateComplete();
265
- // TODO(b/293506179): remove vertical logic
266
- const isVertical = false;
267
- const offset = isVertical ? item.offsetTop : item.offsetLeft;
268
- const extent = isVertical ? item.offsetHeight : item.offsetWidth;
269
- const scroll = isVertical ? this.scrollTop : this.scrollLeft;
270
- const hostExtent = isVertical ? this.offsetHeight : this.offsetWidth;
243
+ const offset = item.offsetLeft;
244
+ const extent = item.offsetWidth;
245
+ const scroll = this.scrollLeft;
246
+ const hostExtent = this.offsetWidth;
271
247
  const min = offset - this.scrollMargin;
272
248
  const max = offset + extent - hostExtent + this.scrollMargin;
273
249
  const to = Math.min(min, Math.max(max, scroll));
274
250
  const behavior =
275
251
  // type annotation because `instant` is valid but not included in type.
276
252
  this.focusedItem !== undefined ? 'smooth' : 'instant';
277
- this.scrollTo({
278
- behavior,
279
- [isVertical ? 'left' : 'top']: 0,
280
- [isVertical ? 'top' : 'left']: to
281
- });
253
+ this.scrollTo({ behavior, top: 0, left: to });
282
254
  }
283
255
  }
284
- /** @nocollapse */
285
- Tabs.shadowRootOptions = {
286
- ...LitElement.shadowRootOptions,
287
- delegatesFocus: true
288
- };
289
- __decorate([
290
- property({ reflect: true })
291
- ], Tabs.prototype, "variant", void 0);
292
- __decorate([
293
- property({ type: Boolean })
294
- ], Tabs.prototype, "disabled", void 0);
256
+ (() => {
257
+ setupHostAria(Tabs, { focusable: false });
258
+ })();
295
259
  __decorate([
296
260
  property({ type: Number })
297
261
  ], Tabs.prototype, "selected", void 0);
@@ -299,9 +263,12 @@ __decorate([
299
263
  property({ type: Boolean, attribute: 'select-on-focus' })
300
264
  ], Tabs.prototype, "selectOnFocus", void 0);
301
265
  __decorate([
302
- queryAssignedElements({ selector: 'md-tab', flatten: true })
303
- ], Tabs.prototype, "items", void 0);
266
+ queryAssignedElements({ flatten: true })
267
+ ], Tabs.prototype, "maybeTabItems", void 0);
304
268
  __decorate([
305
269
  state()
306
270
  ], Tabs.prototype, "itemsDirty", void 0);
271
+ function isTab(element) {
272
+ return element instanceof Tab;
273
+ }
307
274
  //# sourceMappingURL=tabs.js.map