material-plus-ui 1.0.0 → 1.2.0

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 (151) hide show
  1. package/dist/components/animate-appear/MPAnimateAppear.d.ts +56 -0
  2. package/dist/components/animate-appear/MPAnimateAppear.js +1 -0
  3. package/dist/components/animate-appear/index.d.ts +2 -0
  4. package/dist/components/animate-appear/index.js +1 -0
  5. package/dist/components/animate-blink/MPAnimateBlink.d.ts +41 -0
  6. package/dist/components/animate-blink/MPAnimateBlink.js +1 -0
  7. package/dist/components/animate-blink/index.d.ts +2 -0
  8. package/dist/components/animate-blink/index.js +1 -0
  9. package/dist/components/animate-fade/MPAnimateFade.d.ts +38 -0
  10. package/dist/components/animate-fade/MPAnimateFade.js +1 -0
  11. package/dist/components/animate-fade/index.d.ts +2 -0
  12. package/dist/components/animate-fade/index.js +1 -0
  13. package/dist/components/animate-grow/MPAnimateGrow.d.ts +52 -0
  14. package/dist/components/animate-grow/MPAnimateGrow.js +1 -0
  15. package/dist/components/animate-grow/index.d.ts +2 -0
  16. package/dist/components/animate-grow/index.js +1 -0
  17. package/dist/components/animate-headline/MPAnimateHeadline.d.ts +63 -0
  18. package/dist/components/animate-headline/MPAnimateHeadline.js +1 -0
  19. package/dist/components/animate-headline/index.d.ts +2 -0
  20. package/dist/components/animate-headline/index.js +1 -0
  21. package/dist/components/animate-lighting/MPAnimateLighting.d.ts +68 -0
  22. package/dist/components/animate-lighting/MPAnimateLighting.js +1 -0
  23. package/dist/components/animate-lighting/index.d.ts +2 -0
  24. package/dist/components/animate-lighting/index.js +1 -0
  25. package/dist/components/animate-marquee/MPAnimateMarquee.d.ts +66 -0
  26. package/dist/components/animate-marquee/MPAnimateMarquee.js +1 -0
  27. package/dist/components/animate-marquee/index.d.ts +2 -0
  28. package/dist/components/animate-marquee/index.js +1 -0
  29. package/dist/components/animate-rotate/MPAnimateRotate.d.ts +56 -0
  30. package/dist/components/animate-rotate/MPAnimateRotate.js +1 -0
  31. package/dist/components/animate-rotate/index.d.ts +2 -0
  32. package/dist/components/animate-rotate/index.js +1 -0
  33. package/dist/components/animate-slide/MPAnimateSlide.d.ts +53 -0
  34. package/dist/components/animate-slide/MPAnimateSlide.js +1 -0
  35. package/dist/components/animate-slide/index.d.ts +2 -0
  36. package/dist/components/animate-slide/index.js +1 -0
  37. package/dist/components/animate-typing/MPAnimateTyping.d.ts +59 -0
  38. package/dist/components/animate-typing/MPAnimateTyping.js +1 -0
  39. package/dist/components/animate-typing/index.d.ts +2 -0
  40. package/dist/components/animate-typing/index.js +1 -0
  41. package/dist/components/animate-zoom/MPAnimateZoom.d.ts +44 -0
  42. package/dist/components/animate-zoom/MPAnimateZoom.js +1 -0
  43. package/dist/components/animate-zoom/index.d.ts +2 -0
  44. package/dist/components/animate-zoom/index.js +1 -0
  45. package/dist/components/avatar/MPAvatar.d.ts +9 -2
  46. package/dist/components/avatar/MPAvatar.js +1 -1
  47. package/dist/components/badge/MPBadge.js +1 -1
  48. package/dist/components/bottom-navigation/MPBottomNavigation.d.ts +144 -0
  49. package/dist/components/bottom-navigation/MPBottomNavigation.js +1 -0
  50. package/dist/components/bottom-navigation/index.d.ts +2 -0
  51. package/dist/components/bottom-navigation/index.js +1 -0
  52. package/dist/components/breadcrumb/MPBreadcrumb.d.ts +22 -0
  53. package/dist/components/breadcrumb/MPBreadcrumb.js +1 -1
  54. package/dist/components/button/MPButton.d.ts +7 -2
  55. package/dist/components/button/MPButton.js +1 -1
  56. package/dist/components/carousel/MPCarousel.js +1 -1
  57. package/dist/components/checkbox/MPCheckbox.d.ts +2 -2
  58. package/dist/components/checkbox/MPCheckbox.js +1 -1
  59. package/dist/components/chip/MPChip.d.ts +13 -3
  60. package/dist/components/chip/MPChip.js +1 -1
  61. package/dist/components/color-picker/MPColorPicker.d.ts +21 -3
  62. package/dist/components/color-picker/MPColorPicker.js +1 -1
  63. package/dist/components/combobox/MPCombobox.d.ts +38 -10
  64. package/dist/components/combobox/MPCombobox.js +1 -1
  65. package/dist/components/container/MPContainer.d.ts +75 -0
  66. package/dist/components/container/MPContainer.js +1 -0
  67. package/dist/components/container/index.d.ts +2 -0
  68. package/dist/components/container/index.js +1 -0
  69. package/dist/components/date-picker/MPDatePicker.d.ts +3 -0
  70. package/dist/components/date-picker/MPDatePicker.js +1 -1
  71. package/dist/components/date-range-picker/MPDateRangePicker.js +1 -1
  72. package/dist/components/date-time-picker/MPDateTimePicker.js +1 -1
  73. package/dist/components/dialog/MPDialog.d.ts +8 -3
  74. package/dist/components/dialog/MPDialog.js +1 -1
  75. package/dist/components/drawer/MPDrawer.d.ts +33 -9
  76. package/dist/components/drawer/MPDrawer.js +1 -1
  77. package/dist/components/empty/MPEmpty.d.ts +12 -2
  78. package/dist/components/empty/MPEmpty.js +1 -1
  79. package/dist/components/file-picker/MPFilePicker.d.ts +11 -1
  80. package/dist/components/file-picker/MPFilePicker.js +1 -1
  81. package/dist/components/floating-action-button/MPFloatingActionButton.d.ts +126 -0
  82. package/dist/components/floating-action-button/MPFloatingActionButton.js +1 -0
  83. package/dist/components/floating-action-button/index.d.ts +2 -0
  84. package/dist/components/floating-action-button/index.js +1 -0
  85. package/dist/components/grid/MPGrid.d.ts +155 -0
  86. package/dist/components/grid/MPGrid.js +1 -0
  87. package/dist/components/grid/index.d.ts +2 -0
  88. package/dist/components/grid/index.js +1 -0
  89. package/dist/components/highlight/MPHighlight.js +1 -1
  90. package/dist/components/list/MPList.js +1 -1
  91. package/dist/components/menu/MPMenu.d.ts +10 -1
  92. package/dist/components/menu/MPMenu.js +1 -1
  93. package/dist/components/number-field/MPNumberField.d.ts +21 -3
  94. package/dist/components/number-field/MPNumberField.js +1 -1
  95. package/dist/components/pagination/MPPagination.d.ts +106 -0
  96. package/dist/components/pagination/MPPagination.js +1 -0
  97. package/dist/components/pagination/index.d.ts +2 -0
  98. package/dist/components/pagination/index.js +1 -0
  99. package/dist/components/panes/MPPanes.js +1 -1
  100. package/dist/components/pill/MPPill.js +1 -1
  101. package/dist/components/popover/MPPopover.d.ts +8 -3
  102. package/dist/components/popover/MPPopover.js +1 -1
  103. package/dist/components/radio-group/MPRadioGroup.js +1 -1
  104. package/dist/components/rating/MPRating.d.ts +135 -0
  105. package/dist/components/rating/MPRating.js +1 -0
  106. package/dist/components/rating/index.d.ts +2 -0
  107. package/dist/components/rating/index.js +1 -0
  108. package/dist/components/segmented-button/MPSegmentedButton.js +1 -1
  109. package/dist/components/select/MPSelect.d.ts +23 -6
  110. package/dist/components/select/MPSelect.js +1 -1
  111. package/dist/components/skeleton/MPSkeleton.js +1 -1
  112. package/dist/components/slider/MPSlider.js +1 -1
  113. package/dist/components/snackbar/MPSnackbar.d.ts +8 -3
  114. package/dist/components/snackbar/MPSnackbar.js +1 -1
  115. package/dist/components/spoiler/MPSpoiler.js +1 -1
  116. package/dist/components/switch/MPSwitch.d.ts +2 -2
  117. package/dist/components/switch/MPSwitch.js +1 -1
  118. package/dist/components/table/MPTable.d.ts +14 -1
  119. package/dist/components/table/MPTable.js +1 -1
  120. package/dist/components/tabs/MPTabs.d.ts +145 -0
  121. package/dist/components/tabs/MPTabs.js +1 -0
  122. package/dist/components/tabs/index.d.ts +2 -0
  123. package/dist/components/tabs/index.js +1 -0
  124. package/dist/components/text-field/MPTextField.d.ts +37 -7
  125. package/dist/components/text-field/MPTextField.js +1 -1
  126. package/dist/components/text-link/MPTextLink.js +1 -1
  127. package/dist/components/time-picker/MPTimePicker.js +1 -1
  128. package/dist/components/timeline/MPTimeline.js +1 -1
  129. package/dist/constants/icons.d.ts +13 -0
  130. package/dist/constants/icons.js +1 -1
  131. package/dist/index.d.ts +18 -0
  132. package/dist/index.js +1 -1
  133. package/dist/internal/Calendar.js +1 -1
  134. package/dist/internal/FieldOutline.d.ts +75 -4
  135. package/dist/internal/FieldOutline.js +1 -1
  136. package/dist/internal/Picker.d.ts +52 -9
  137. package/dist/internal/Picker.js +1 -1
  138. package/dist/internal/animate.d.ts +179 -0
  139. package/dist/internal/animate.js +1 -0
  140. package/dist/internal/date.d.ts +2 -2
  141. package/dist/internal/date.js +1 -1
  142. package/dist/internal/i18n.d.ts +110 -0
  143. package/dist/internal/i18n.js +1 -1
  144. package/dist/internal/inert.d.ts +11 -0
  145. package/dist/internal/inert.js +1 -0
  146. package/dist/internal/surface.d.ts +42 -12
  147. package/dist/internal/surface.js +1 -1
  148. package/dist/styles.css +1 -1
  149. package/dist/tailwind.css +640 -4
  150. package/dist/types.d.ts +155 -0
  151. package/package.json +10 -10
package/dist/tailwind.css CHANGED
@@ -955,14 +955,55 @@
955
955
  --mp-sys-elevation-level2: 0 1px 2px 0 rgb(0 0 0 / 0.3), 0 2px 6px 2px rgb(0 0 0 / 0.15);
956
956
  --mp-sys-elevation-level3: 0 1px 3px 0 rgb(0 0 0 / 0.3), 0 4px 8px 3px rgb(0 0 0 / 0.15);
957
957
 
958
- /* Motion. MD3's `short4`, which is what a text field's label and outline
959
- transition on. Worth knowing if these controls sit beside another
960
- library's: 250ms is a common default elsewhere, and a field from here
961
- will settle slightly sooner unless this is set to match. */
958
+ /*
959
+ * Motion.
960
+ *
961
+ * Seven of MD3's sixteen duration tokens and six of its seven easing curves
962
+ * — the ones something in the library actually reads, on the rule every
963
+ * other token here follows. `short4` is what a text field's label and
964
+ * outline transition on; most of the rest arrived with the `MPAnimate*`
965
+ * components, which take these as their defaults rather than numbers of
966
+ * their own.
967
+ *
968
+ * `short2` is the shortest of them and has one reader: an `MPSlider`'s
969
+ * handle catching up with a value the keyboard moved. A control the reader
970
+ * is holding an arrow key on has to arrive before the next press, and 200ms
971
+ * is longer than a key repeats.
972
+ *
973
+ * Worth knowing if these controls sit beside another library's: 250ms is a
974
+ * common default elsewhere, and a field from here will settle slightly
975
+ * sooner unless `short4` is set to match.
976
+ */
977
+ --mp-sys-motion-duration-short2: 100ms;
962
978
  --mp-sys-motion-duration-short4: 200ms;
979
+ --mp-sys-motion-duration-medium2: 300ms;
980
+ --mp-sys-motion-duration-medium4: 400ms;
981
+ --mp-sys-motion-duration-long2: 500ms;
982
+ --mp-sys-motion-duration-extra-long4: 1000ms;
983
+
963
984
  /* The spec's `standard` curve: quick to leave, slow to arrive. Read by the
964
985
  one thing in the library that actually travels, a switch's thumb. */
965
986
  --mp-sys-motion-easing-standard: cubic-bezier(0.2, 0, 0, 1);
987
+ --mp-sys-motion-easing-standard-decelerate: cubic-bezier(0, 0, 0, 1);
988
+ --mp-sys-motion-easing-standard-accelerate: cubic-bezier(0.3, 0, 1, 1);
989
+ /*
990
+ * The emphasized set, which is what MD3 asks a *transition* to use — a
991
+ * standard curve is for a control changing state, an emphasized one for
992
+ * something arriving on or leaving the screen.
993
+ *
994
+ * `emphasized` itself is two curves joined in the middle in the
995
+ * specification, and CSS has no single value that is both. This is the
996
+ * one-curve stand-in MD3's own web implementation publishes. Where the
997
+ * halves genuinely matter — a line rising as another leaves — the two below
998
+ * are the halves, and they are what the components reach for.
999
+ */
1000
+ --mp-sys-motion-easing-emphasized: cubic-bezier(0.2, 0, 0, 1);
1001
+ --mp-sys-motion-easing-emphasized-decelerate: cubic-bezier(0.05, 0.7, 0.1, 1);
1002
+ --mp-sys-motion-easing-emphasized-accelerate: cubic-bezier(0.3, 0, 0.8, 0.15);
1003
+ /* CSS's own `linear` is a keyword rather than a curve, and a token that
1004
+ cannot be interpolated with the other six is a token that breaks the one
1005
+ place they are swapped. The identity bezier is the same line. */
1006
+ --mp-sys-motion-easing-linear: cubic-bezier(0, 0, 1, 1);
966
1007
  }
967
1008
 
968
1009
  /*
@@ -1139,6 +1180,165 @@
1139
1180
  --ease-mp-standard: var(--mp-sys-motion-easing-standard);
1140
1181
  }
1141
1182
 
1183
+ /* ---------------------------------------------------------------------------
1184
+ * The layout grid
1185
+ *
1186
+ * A column is `(100% + gutter) * span / columns - gutter`, and the arithmetic
1187
+ * lives here for the reason the keyframes below do: Tailwind finds classes by
1188
+ * scanning source text, and `columns` is a number the caller picks at runtime.
1189
+ * A class name assembled in JavaScript is a class name Tailwind never sees, so
1190
+ * the per-instance numbers arrive as inline `--_mp-*` slots — exactly as a
1191
+ * `color` reaches a background — and the rules that read them are written once,
1192
+ * here.
1193
+ *
1194
+ * `min(span, columns)` is the clamp: `span={99}` fills its row instead of
1195
+ * running off the page, which is what the caller meant.
1196
+ *
1197
+ * Every slot cascades upward — each window size class falls back through the
1198
+ * ones below it — so `span={{ expanded: 6 }}` sets one custom property and not
1199
+ * five. The chains get long at `extra-large`; that is the cost of keeping the
1200
+ * DOM lean, and it is paid once here rather than on every grid item in a
1201
+ * consumer's application.
1202
+ *
1203
+ * The widths are **MD3's window size classes** — 600, 840, 1200 and 1600dp —
1204
+ * and not Tailwind's breakpoints. See `MPWindowClass` in `src/types.ts`.
1205
+ *
1206
+ * Unlayered, like the two animation classes below and for the same reason: a
1207
+ * layered rule loses to every unlayered one, and a consumer's own page styling
1208
+ * is unlayered. A grid whose widths could be cancelled by a stray `div { }` in
1209
+ * an application's stylesheet is not a grid.
1210
+ * ------------------------------------------------------------------------- */
1211
+
1212
+ .mp-grid {
1213
+ --_mp-cols: var(--_mp-cols-compact, 12);
1214
+ --_mp-gap-x: var(--_mp-gap-x-compact, 0px);
1215
+ --_mp-gap-y: var(--_mp-gap-y-compact, 0px);
1216
+ }
1217
+
1218
+ .mp-grid-item {
1219
+ --_mp-span: var(--_mp-span-compact, var(--_mp-cols, 12));
1220
+ --_mp-offset: var(--_mp-offset-compact, 0);
1221
+
1222
+ /* One column plus one gutter. `--_mp-cols` and `--_mp-gap-x` are inherited
1223
+ from the grid, so this re-resolves on its own at every window class. */
1224
+ --_mp-track: calc((100% + var(--_mp-gap-x, 0px)) / var(--_mp-cols, 12));
1225
+
1226
+ /* Inseparable from the width under them: `flex` stops the row resizing the
1227
+ item, `min-width` stops a long unbroken word doing the same, and
1228
+ `box-sizing` is what makes the percentage mean the whole item. */
1229
+ box-sizing: border-box;
1230
+ flex: 0 0 auto;
1231
+ min-width: 0;
1232
+ width: calc(var(--_mp-track) * min(var(--_mp-span), var(--_mp-cols, 12)) - var(--_mp-gap-x, 0px));
1233
+ margin-inline-start: calc(var(--_mp-track) * min(var(--_mp-offset), var(--_mp-cols, 12)));
1234
+ }
1235
+
1236
+ @media (width >= 600px) {
1237
+ .mp-grid {
1238
+ --_mp-cols: var(--_mp-cols-medium, var(--_mp-cols-compact, 12));
1239
+ --_mp-gap-x: var(--_mp-gap-x-medium, var(--_mp-gap-x-compact, 0px));
1240
+ --_mp-gap-y: var(--_mp-gap-y-medium, var(--_mp-gap-y-compact, 0px));
1241
+ }
1242
+
1243
+ .mp-grid-item {
1244
+ --_mp-span: var(--_mp-span-medium, var(--_mp-span-compact, var(--_mp-cols, 12)));
1245
+ --_mp-offset: var(--_mp-offset-medium, var(--_mp-offset-compact, 0));
1246
+ }
1247
+ }
1248
+
1249
+ @media (width >= 840px) {
1250
+ .mp-grid {
1251
+ --_mp-cols: var(--_mp-cols-expanded, var(--_mp-cols-medium, var(--_mp-cols-compact, 12)));
1252
+ --_mp-gap-x: var(--_mp-gap-x-expanded, var(--_mp-gap-x-medium, var(--_mp-gap-x-compact, 0px)));
1253
+ --_mp-gap-y: var(--_mp-gap-y-expanded, var(--_mp-gap-y-medium, var(--_mp-gap-y-compact, 0px)));
1254
+ }
1255
+
1256
+ .mp-grid-item {
1257
+ --_mp-span: var(
1258
+ --_mp-span-expanded,
1259
+ var(--_mp-span-medium, var(--_mp-span-compact, var(--_mp-cols, 12)))
1260
+ );
1261
+ --_mp-offset: var(
1262
+ --_mp-offset-expanded,
1263
+ var(--_mp-offset-medium, var(--_mp-offset-compact, 0))
1264
+ );
1265
+ }
1266
+ }
1267
+
1268
+ @media (width >= 1200px) {
1269
+ .mp-grid {
1270
+ --_mp-cols: var(
1271
+ --_mp-cols-large,
1272
+ var(--_mp-cols-expanded, var(--_mp-cols-medium, var(--_mp-cols-compact, 12)))
1273
+ );
1274
+ --_mp-gap-x: var(
1275
+ --_mp-gap-x-large,
1276
+ var(--_mp-gap-x-expanded, var(--_mp-gap-x-medium, var(--_mp-gap-x-compact, 0px)))
1277
+ );
1278
+ --_mp-gap-y: var(
1279
+ --_mp-gap-y-large,
1280
+ var(--_mp-gap-y-expanded, var(--_mp-gap-y-medium, var(--_mp-gap-y-compact, 0px)))
1281
+ );
1282
+ }
1283
+
1284
+ .mp-grid-item {
1285
+ --_mp-span: var(
1286
+ --_mp-span-large,
1287
+ var(--_mp-span-expanded, var(--_mp-span-medium, var(--_mp-span-compact, var(--_mp-cols, 12))))
1288
+ );
1289
+ --_mp-offset: var(
1290
+ --_mp-offset-large,
1291
+ var(--_mp-offset-expanded, var(--_mp-offset-medium, var(--_mp-offset-compact, 0)))
1292
+ );
1293
+ }
1294
+ }
1295
+
1296
+ @media (width >= 1600px) {
1297
+ .mp-grid {
1298
+ --_mp-cols: var(
1299
+ --_mp-cols-extra-large,
1300
+ var(
1301
+ --_mp-cols-large,
1302
+ var(--_mp-cols-expanded, var(--_mp-cols-medium, var(--_mp-cols-compact, 12)))
1303
+ )
1304
+ );
1305
+ --_mp-gap-x: var(
1306
+ --_mp-gap-x-extra-large,
1307
+ var(
1308
+ --_mp-gap-x-large,
1309
+ var(--_mp-gap-x-expanded, var(--_mp-gap-x-medium, var(--_mp-gap-x-compact, 0px)))
1310
+ )
1311
+ );
1312
+ --_mp-gap-y: var(
1313
+ --_mp-gap-y-extra-large,
1314
+ var(
1315
+ --_mp-gap-y-large,
1316
+ var(--_mp-gap-y-expanded, var(--_mp-gap-y-medium, var(--_mp-gap-y-compact, 0px)))
1317
+ )
1318
+ );
1319
+ }
1320
+
1321
+ .mp-grid-item {
1322
+ --_mp-span: var(
1323
+ --_mp-span-extra-large,
1324
+ var(
1325
+ --_mp-span-large,
1326
+ var(
1327
+ --_mp-span-expanded,
1328
+ var(--_mp-span-medium, var(--_mp-span-compact, var(--_mp-cols, 12)))
1329
+ )
1330
+ )
1331
+ );
1332
+ --_mp-offset: var(
1333
+ --_mp-offset-extra-large,
1334
+ var(
1335
+ --_mp-offset-large,
1336
+ var(--_mp-offset-expanded, var(--_mp-offset-medium, var(--_mp-offset-compact, 0)))
1337
+ )
1338
+ );
1339
+ }
1340
+ }
1341
+
1142
1342
  /* ---------------------------------------------------------------------------
1143
1343
  * Keyframes
1144
1344
  *
@@ -1326,3 +1526,439 @@
1326
1526
  opacity: 0.6;
1327
1527
  }
1328
1528
  }
1529
+
1530
+ /* ---------------------------------------------------------------------------
1531
+ * The calendar's page turn
1532
+ *
1533
+ * A keyframe rather than a transition, for the reason the indicators above are:
1534
+ * what changes when a month is stepped is the *content* of six rows, and there
1535
+ * are no two states for CSS to interpolate between — the weeks that were there
1536
+ * are gone. An animation on the arriving set is the only thing there is to run.
1537
+ *
1538
+ * `internal/Calendar.tsx` supplies the direction as a sign and restarts the
1539
+ * animation by clearing `animation-name` and putting it back, which is the same
1540
+ * move `internal/animate.ts` makes and for the same reason: React cannot rewind
1541
+ * a CSS animation, and a `key` would restart it by unmounting the cell the
1542
+ * reader's focus is standing on.
1543
+ *
1544
+ * The distance is one cell, which is deliberately short. A full grid's width
1545
+ * would be a filmstrip, and the thing being said is only which way the reader
1546
+ * went — a page that comes from the right and settles says that in the first
1547
+ * hundred milliseconds, and the rest of the animation is the numbers arriving
1548
+ * where they can be read.
1549
+ *
1550
+ * Unlayered, like the keyframes above, and switched off for a reader who asked
1551
+ * for less motion. What is left then is the swap the grid did before, which
1552
+ * loses the direction and nothing else.
1553
+ * ------------------------------------------------------------------------- */
1554
+
1555
+ @keyframes mp-calendar-page {
1556
+ from {
1557
+ opacity: 0;
1558
+ translate: calc(var(--_mp-calendar-from, 0) * var(--_mp-cell)) 0;
1559
+ }
1560
+ }
1561
+
1562
+ .mp-calendar__page[data-mp-paged] {
1563
+ animation: mp-calendar-page var(--mp-sys-motion-duration-medium2)
1564
+ var(--mp-sys-motion-easing-emphasized-decelerate);
1565
+ }
1566
+
1567
+ @media (prefers-reduced-motion: reduce) {
1568
+ .mp-calendar__page[data-mp-paged] {
1569
+ animation: none;
1570
+ }
1571
+ }
1572
+
1573
+ /* ---------------------------------------------------------------------------
1574
+ * Animation
1575
+ *
1576
+ * The `MPAnimate*` components. Real CSS for the reason the loading indicators
1577
+ * above are: a keyframe is not a Tailwind variant, so there is nothing to
1578
+ * express one with.
1579
+ *
1580
+ * The whole set is built on one idea. An effect is a single `@keyframes` that
1581
+ * runs from a state written entirely in `--_mp-anim-*` custom properties to the
1582
+ * element's natural one — so `src/internal/animate.ts` never generates CSS, it
1583
+ * only fills slots, and running an effect backwards is `animation-direction:
1584
+ * reverse` rather than a second keyframe. That is what makes `mode="out"` cost
1585
+ * nothing, and it is also what makes it *correct*: CSS mirrors the timing
1586
+ * function along with the keyframes, so an entrance eased on
1587
+ * `emphasized-decelerate` comes back accelerating. MD3 asks for exactly that
1588
+ * pair; the browser supplies the second half of it.
1589
+ *
1590
+ * `fill-mode` is `both` throughout, which is what lets an animation that has
1591
+ * not been triggered yet sit paused on its own first frame. Without it, an
1592
+ * element waiting to be scrolled into view would be fully drawn and then blink
1593
+ * out the moment it arrived.
1594
+ *
1595
+ * This is also where the library's rule against transforms is at its narrowest.
1596
+ * A *control* never moves — that rule is about a button resampling its own
1597
+ * label under the pointer, and it holds without exception. An `MPAnimate*`
1598
+ * moves content the caller asked to have moved, and it moves it with the
1599
+ * independent `translate`, `scale` and `rotate` properties rather than the
1600
+ * `transform` shorthand, so a caller's own transform on the same element
1601
+ * survives.
1602
+ *
1603
+ * Unlayered, like the keyframes above: `@keyframes` takes no part in the
1604
+ * cascade, but the classes do, and a layered class would lose to any unlayered
1605
+ * rule a consumer's own stylesheet happens to have.
1606
+ * ------------------------------------------------------------------------- */
1607
+
1608
+ .mp-anim {
1609
+ animation-duration: var(--_mp-anim-duration, var(--mp-sys-motion-duration-medium4));
1610
+ animation-delay: var(--_mp-anim-delay, 0ms);
1611
+ animation-timing-function: var(
1612
+ --_mp-anim-ease,
1613
+ var(--mp-sys-motion-easing-emphasized-decelerate)
1614
+ );
1615
+ animation-iteration-count: var(--_mp-anim-repeat, 1);
1616
+ animation-direction: var(--_mp-anim-direction, normal);
1617
+ animation-fill-mode: both;
1618
+ animation-play-state: var(--_mp-anim-state, running);
1619
+ }
1620
+
1621
+ @keyframes mp-anim-fade {
1622
+ from {
1623
+ opacity: var(--_mp-anim-opacity, 0);
1624
+ }
1625
+
1626
+ to {
1627
+ opacity: 1;
1628
+ }
1629
+ }
1630
+
1631
+ .mp-anim-fade {
1632
+ animation-name: mp-anim-fade;
1633
+ }
1634
+
1635
+ /* Grow and Zoom share this one: they are the same arithmetic at two strengths,
1636
+ separated by their defaults and by their origin rather than by their maths. */
1637
+ @keyframes mp-anim-scale {
1638
+ from {
1639
+ opacity: var(--_mp-anim-opacity, 0);
1640
+ scale: var(--_mp-anim-scale, 0.8);
1641
+ }
1642
+
1643
+ to {
1644
+ opacity: 1;
1645
+ scale: 1;
1646
+ }
1647
+ }
1648
+
1649
+ .mp-anim-scale {
1650
+ animation-name: mp-anim-scale;
1651
+ }
1652
+
1653
+ @keyframes mp-anim-slide {
1654
+ from {
1655
+ opacity: var(--_mp-anim-opacity, 0);
1656
+ translate: var(--_mp-anim-x, 0px) var(--_mp-anim-y, 0px);
1657
+ }
1658
+
1659
+ to {
1660
+ opacity: 1;
1661
+ translate: 0 0;
1662
+ }
1663
+ }
1664
+
1665
+ .mp-anim-slide {
1666
+ animation-name: mp-anim-slide;
1667
+ }
1668
+
1669
+ /* Two angles rather than one, so the same keyframe covers both the quarter turn
1670
+ something arrives on and the endless one a decorative mark spins through. */
1671
+ @keyframes mp-anim-rotate {
1672
+ from {
1673
+ opacity: var(--_mp-anim-opacity, 0);
1674
+ rotate: var(--_mp-anim-angle, -180deg);
1675
+ }
1676
+
1677
+ to {
1678
+ opacity: 1;
1679
+ rotate: var(--_mp-anim-angle-to, 0deg);
1680
+ }
1681
+ }
1682
+
1683
+ .mp-anim-rotate {
1684
+ animation-name: mp-anim-rotate;
1685
+ }
1686
+
1687
+ /* Symmetric on purpose: a blink that ended anywhere but where it started would
1688
+ leave the element half drawn whenever the count ran out. */
1689
+ @keyframes mp-anim-blink {
1690
+ 0%,
1691
+ 100% {
1692
+ opacity: 1;
1693
+ }
1694
+
1695
+ 50% {
1696
+ opacity: var(--_mp-anim-opacity, 0);
1697
+ }
1698
+ }
1699
+
1700
+ .mp-anim-blink {
1701
+ animation-name: mp-anim-blink;
1702
+ }
1703
+
1704
+ @media (prefers-reduced-motion: reduce) {
1705
+ /*
1706
+ * The Animate components go the other way from the indicators above, and the
1707
+ * difference is what each of them is saying. A spinner that stops is lying
1708
+ * about whether anything is happening; an entrance that does not play has
1709
+ * still delivered its content, which is the only thing it was ever carrying.
1710
+ *
1711
+ * `animation: none` rather than a zero duration, because the shorthand also
1712
+ * clears `fill-mode` — and it is the fill that was holding an untriggered
1713
+ * element on its own first frame at `opacity: 0`. Left in place, respecting a
1714
+ * reader's preference would blank the page.
1715
+ */
1716
+ .mp-anim {
1717
+ animation: none;
1718
+ }
1719
+ }
1720
+
1721
+ /*
1722
+ * Lighting: a light travelling around the outside of something.
1723
+ *
1724
+ * The arc is a conic gradient and what moves is its `from` angle, which is only
1725
+ * animatable because the angle is a registered custom property with a type. The
1726
+ * alternative — rotating the pseudo-element itself — swings its corners out
1727
+ * past the element on every quarter turn.
1728
+ *
1729
+ * `z-index: -1` inside an isolated stacking context puts the glow behind the
1730
+ * content but still inside the component, so it reads as light escaping from
1731
+ * under a sheet rather than as a border drawn around one. Nothing inside is
1732
+ * overlaid and nothing is tinted, which is what lets it go around a card or a
1733
+ * button without touching how either is drawn.
1734
+ */
1735
+ @property --mp-glow-angle {
1736
+ syntax: '<angle>';
1737
+ initial-value: 0deg;
1738
+ inherits: false;
1739
+ }
1740
+
1741
+ @keyframes mp-anim-lighting {
1742
+ to {
1743
+ --mp-glow-angle: 360deg;
1744
+ }
1745
+ }
1746
+
1747
+ .mp-anim-lighting {
1748
+ position: relative;
1749
+ isolation: isolate;
1750
+ }
1751
+
1752
+ .mp-anim-lighting::before {
1753
+ content: '';
1754
+ position: absolute;
1755
+ z-index: -1;
1756
+ inset: calc(-1 * var(--_mp-anim-glow-width, 3px));
1757
+ border-radius: inherit;
1758
+ background: conic-gradient(
1759
+ from var(--mp-glow-angle),
1760
+ transparent 0deg,
1761
+ var(--_mp-anim-glow, var(--_mp-accent)) var(--_mp-anim-glow-arc, 50deg),
1762
+ transparent calc(var(--_mp-anim-glow-arc, 50deg) * 2),
1763
+ transparent 360deg
1764
+ );
1765
+ filter: blur(var(--_mp-anim-glow-blur, 4px));
1766
+ animation-name: mp-anim-lighting;
1767
+ animation-duration: var(--_mp-anim-duration, 3s);
1768
+ animation-delay: var(--_mp-anim-delay, 0ms);
1769
+ /* Linear, and not a token: a loop with no beginning has nothing to
1770
+ decelerate into, and an eased revolution reads as the light hesitating at
1771
+ an arbitrary point on a circle that has no arbitrary points. */
1772
+ animation-timing-function: linear;
1773
+ animation-iteration-count: var(--_mp-anim-repeat, infinite);
1774
+ animation-direction: var(--_mp-anim-direction, normal);
1775
+ animation-fill-mode: both;
1776
+ animation-play-state: var(--_mp-anim-state, running);
1777
+ }
1778
+
1779
+ @media (prefers-reduced-motion: reduce) {
1780
+ /* The arc stops travelling and becomes an even glow. The same trade the
1781
+ skeleton makes: the decoration survives, the motion does not — a light
1782
+ that marked the live row still marks it while holding still. */
1783
+ .mp-anim-lighting::before {
1784
+ background: var(--_mp-anim-glow, var(--_mp-accent));
1785
+ animation: none;
1786
+ }
1787
+ }
1788
+
1789
+ /*
1790
+ * Marquee: two identical copies, both moving by exactly one copy plus the gap.
1791
+ *
1792
+ * Which is the whole trick — when the first copy has travelled its own width,
1793
+ * the second is standing precisely where the first began, so there is no seam
1794
+ * and no frame where the strip is empty. A percentage `translate` resolves
1795
+ * against the element's own box, so neither copy has to be measured for this to
1796
+ * hold; measuring only ever decides how *fast* it goes.
1797
+ */
1798
+ @keyframes mp-anim-marquee-x {
1799
+ from {
1800
+ translate: 0 0;
1801
+ }
1802
+
1803
+ to {
1804
+ translate: calc(-100% - var(--_mp-anim-gap, 0px)) 0;
1805
+ }
1806
+ }
1807
+
1808
+ @keyframes mp-anim-marquee-y {
1809
+ from {
1810
+ translate: 0 0;
1811
+ }
1812
+
1813
+ to {
1814
+ translate: 0 calc(-100% - var(--_mp-anim-gap, 0px));
1815
+ }
1816
+ }
1817
+
1818
+ .mp-marquee {
1819
+ display: flex;
1820
+ overflow: hidden;
1821
+ gap: var(--_mp-anim-gap, 0px);
1822
+ }
1823
+
1824
+ .mp-marquee-vertical {
1825
+ flex-direction: column;
1826
+ }
1827
+
1828
+ .mp-marquee-track {
1829
+ display: flex;
1830
+ flex: 0 0 auto;
1831
+ align-items: center;
1832
+ gap: var(--_mp-anim-gap, 0px);
1833
+ animation-name: mp-anim-marquee-x;
1834
+ animation-duration: var(--_mp-anim-duration, 12s);
1835
+ animation-delay: var(--_mp-anim-delay, 0ms);
1836
+ /* Linear unless a caller insists otherwise. An eased marquee slows at both
1837
+ ends of a loop that has no ends, which reads as the page stuttering. */
1838
+ animation-timing-function: var(--_mp-anim-ease, linear);
1839
+ animation-iteration-count: var(--_mp-anim-repeat, infinite);
1840
+ animation-direction: var(--_mp-anim-direction, normal);
1841
+ animation-fill-mode: both;
1842
+ animation-play-state: var(--_mp-anim-state, running);
1843
+ }
1844
+
1845
+ .mp-marquee-vertical .mp-marquee-track {
1846
+ flex-direction: column;
1847
+ animation-name: mp-anim-marquee-y;
1848
+ }
1849
+
1850
+ .mp-marquee[data-mp-pause-on-hover]:hover .mp-marquee-track {
1851
+ animation-play-state: paused;
1852
+ }
1853
+
1854
+ @media (prefers-reduced-motion: reduce) {
1855
+ /* Stopped, not slowed. A strip of logos that has stopped scrolling is a strip
1856
+ of logos, and the first copy is fully in frame — which is more than the
1857
+ moving version guarantees at any given moment. */
1858
+ .mp-marquee-track {
1859
+ animation: none;
1860
+ }
1861
+ }
1862
+
1863
+ /*
1864
+ * Headline: one line replacing another from below.
1865
+ *
1866
+ * Every item is in the same grid cell, so the box is as tall as the tallest of
1867
+ * them from the first frame and never resizes as the reel turns. The ones not
1868
+ * on screen keep their space with `visibility` rather than `display`, which is
1869
+ * what makes that true.
1870
+ *
1871
+ * The two halves take the two halves of MD3's emphasized curve — the line
1872
+ * arriving decelerates into place, the line leaving accelerates away — which is
1873
+ * the one place in the library where both are written out rather than one being
1874
+ * a reversed run of the other. Here they genuinely are two animations on two
1875
+ * elements at the same moment.
1876
+ */
1877
+ @keyframes mp-anim-headline-in {
1878
+ from {
1879
+ translate: 0 var(--_mp-anim-rise, 100%);
1880
+ opacity: 0;
1881
+ }
1882
+
1883
+ to {
1884
+ translate: 0 0;
1885
+ opacity: 1;
1886
+ }
1887
+ }
1888
+
1889
+ @keyframes mp-anim-headline-out {
1890
+ from {
1891
+ translate: 0 0;
1892
+ opacity: 1;
1893
+ }
1894
+
1895
+ to {
1896
+ translate: 0 calc(-1 * var(--_mp-anim-rise, 100%));
1897
+ opacity: 0;
1898
+ }
1899
+ }
1900
+
1901
+ .mp-headline {
1902
+ display: grid;
1903
+ overflow: hidden;
1904
+ }
1905
+
1906
+ .mp-headline-item {
1907
+ grid-area: 1 / 1;
1908
+ visibility: hidden;
1909
+ animation-duration: var(--_mp-anim-duration, var(--mp-sys-motion-duration-long2));
1910
+ animation-fill-mode: both;
1911
+ }
1912
+
1913
+ .mp-headline-item[data-mp-state='active'] {
1914
+ visibility: visible;
1915
+ animation-name: mp-anim-headline-in;
1916
+ animation-timing-function: var(
1917
+ --_mp-anim-ease,
1918
+ var(--mp-sys-motion-easing-emphasized-decelerate)
1919
+ );
1920
+ }
1921
+
1922
+ .mp-headline-item[data-mp-state='leaving'] {
1923
+ visibility: visible;
1924
+ animation-name: mp-anim-headline-out;
1925
+ animation-timing-function: var(
1926
+ --_mp-anim-ease,
1927
+ var(--mp-sys-motion-easing-emphasized-accelerate)
1928
+ );
1929
+ }
1930
+
1931
+ @media (prefers-reduced-motion: reduce) {
1932
+ /* The reel still turns — it is a set of phrases and stopping on the first
1933
+ would be a different message — but the lines swap rather than travel. */
1934
+ .mp-headline-item {
1935
+ animation: none;
1936
+ }
1937
+ }
1938
+
1939
+ /* The block after a typewriter. `step-end` rather than a fade, because a caret
1940
+ that eases is a caret that looks like it is being rendered slowly. */
1941
+ @keyframes mp-anim-caret {
1942
+ 0%,
1943
+ 45% {
1944
+ opacity: 1;
1945
+ }
1946
+
1947
+ 55%,
1948
+ 100% {
1949
+ opacity: 0;
1950
+ }
1951
+ }
1952
+
1953
+ .mp-typing-caret {
1954
+ display: inline-block;
1955
+ animation: mp-anim-caret 1s step-end infinite;
1956
+ }
1957
+
1958
+ @media (prefers-reduced-motion: reduce) {
1959
+ /* The whole string is already there under this preference — the caret would
1960
+ be a cursor blinking after text nobody is typing. */
1961
+ .mp-typing-caret {
1962
+ animation: none;
1963
+ }
1964
+ }