@bug-on/m3-expressive 1.0.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 (98) hide show
  1. package/CHANGELOG.md +110 -0
  2. package/README.md +110 -0
  3. package/dist/assets/fonts/GoogleSansFlex-VariableFont.woff2 +0 -0
  4. package/dist/assets/fonts/MaterialSymbolsOutlined-VariableFont_FILL,GRAD,opsz,wght.ttf +0 -0
  5. package/dist/assets/fonts/MaterialSymbolsRounded-VariableFont_FILL,GRAD,opsz,wght.ttf +0 -0
  6. package/dist/assets/fonts/MaterialSymbolsSharp-VariableFont_FILL,GRAD,opsz,wght.ttf +0 -0
  7. package/dist/assets/loading-indicator.svg +19 -0
  8. package/dist/assets/material-symbols-cdn.css +65 -0
  9. package/dist/assets/material-symbols-self-hosted.css +94 -0
  10. package/dist/buttons.d.mts +180 -0
  11. package/dist/buttons.d.ts +180 -0
  12. package/dist/buttons.js +4282 -0
  13. package/dist/buttons.js.map +1 -0
  14. package/dist/buttons.mjs +4227 -0
  15. package/dist/buttons.mjs.map +1 -0
  16. package/dist/core.d.mts +422 -0
  17. package/dist/core.d.ts +422 -0
  18. package/dist/core.js +2581 -0
  19. package/dist/core.js.map +1 -0
  20. package/dist/core.mjs +2547 -0
  21. package/dist/core.mjs.map +1 -0
  22. package/dist/feedback.d.mts +600 -0
  23. package/dist/feedback.d.ts +600 -0
  24. package/dist/feedback.js +2357 -0
  25. package/dist/feedback.js.map +1 -0
  26. package/dist/feedback.mjs +2321 -0
  27. package/dist/feedback.mjs.map +1 -0
  28. package/dist/forms.d.mts +40 -0
  29. package/dist/forms.d.ts +40 -0
  30. package/dist/forms.js +4263 -0
  31. package/dist/forms.js.map +1 -0
  32. package/dist/forms.mjs +4228 -0
  33. package/dist/forms.mjs.map +1 -0
  34. package/dist/icon-button-D-gs0gfj.d.mts +136 -0
  35. package/dist/icon-button-D-gs0gfj.d.ts +136 -0
  36. package/dist/index.css +309 -0
  37. package/dist/index.css.d.ts +2 -0
  38. package/dist/index.d.mts +24 -0
  39. package/dist/index.d.ts +24 -0
  40. package/dist/index.js +23972 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/index.mjs +23668 -0
  43. package/dist/index.mjs.map +1 -0
  44. package/dist/layout.d.mts +610 -0
  45. package/dist/layout.d.ts +610 -0
  46. package/dist/layout.js +5091 -0
  47. package/dist/layout.js.map +1 -0
  48. package/dist/layout.mjs +5042 -0
  49. package/dist/layout.mjs.map +1 -0
  50. package/dist/material-symbols-cdn.css +65 -0
  51. package/dist/material-symbols-cdn.css.d.ts +2 -0
  52. package/dist/material-symbols-self-hosted.css +94 -0
  53. package/dist/material-symbols-self-hosted.css.d.ts +2 -0
  54. package/dist/md3-DFhj-NZj.d.mts +17 -0
  55. package/dist/md3-DFhj-NZj.d.ts +17 -0
  56. package/dist/navigation.d.mts +2766 -0
  57. package/dist/navigation.d.ts +2766 -0
  58. package/dist/navigation.js +6684 -0
  59. package/dist/navigation.js.map +1 -0
  60. package/dist/navigation.mjs +6573 -0
  61. package/dist/navigation.mjs.map +1 -0
  62. package/dist/overlays.d.mts +161 -0
  63. package/dist/overlays.d.ts +161 -0
  64. package/dist/overlays.js +3298 -0
  65. package/dist/overlays.js.map +1 -0
  66. package/dist/overlays.mjs +3244 -0
  67. package/dist/overlays.mjs.map +1 -0
  68. package/dist/pickers.d.mts +1074 -0
  69. package/dist/pickers.d.ts +1074 -0
  70. package/dist/pickers.js +4240 -0
  71. package/dist/pickers.js.map +1 -0
  72. package/dist/pickers.mjs +4200 -0
  73. package/dist/pickers.mjs.map +1 -0
  74. package/dist/plugin.d.mts +1 -0
  75. package/dist/plugin.d.ts +1 -0
  76. package/dist/plugin.js +13 -0
  77. package/dist/plugin.js.map +1 -0
  78. package/dist/plugin.mjs +3 -0
  79. package/dist/plugin.mjs.map +1 -0
  80. package/dist/scroll-area-CVS6HyLl.d.mts +33 -0
  81. package/dist/scroll-area-CVS6HyLl.d.ts +33 -0
  82. package/dist/shapes.d.mts +1119 -0
  83. package/dist/shapes.d.ts +1119 -0
  84. package/dist/shapes.js +2941 -0
  85. package/dist/shapes.js.map +1 -0
  86. package/dist/shapes.mjs +2889 -0
  87. package/dist/shapes.mjs.map +1 -0
  88. package/dist/side-sheet-modal-BY6VCC8p.d.mts +553 -0
  89. package/dist/side-sheet-modal-CglP6KYA.d.ts +553 -0
  90. package/dist/split-button-trailing-uncheckable-C5CLCIKP.d.ts +731 -0
  91. package/dist/split-button-trailing-uncheckable-MXj_kyNt.d.mts +731 -0
  92. package/dist/text-field-eAIpz9z1.d.mts +1038 -0
  93. package/dist/text-field-eAIpz9z1.d.ts +1038 -0
  94. package/dist/typography-339RV6v7.d.mts +486 -0
  95. package/dist/typography-339RV6v7.d.ts +486 -0
  96. package/dist/typography.css +22 -0
  97. package/dist/typography.css.d.ts +2 -0
  98. package/package.json +207 -0
@@ -0,0 +1,4282 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var reactSlot = require('@radix-ui/react-slot');
5
+ var react = require('motion/react');
6
+ var React11 = require('react');
7
+ var clsx = require('clsx');
8
+ var tailwindMerge = require('tailwind-merge');
9
+ var jsxRuntime = require('react/jsx-runtime');
10
+ var m3Tokens = require('@bug-on/m3-tokens');
11
+ var classVarianceAuthority = require('class-variance-authority');
12
+
13
+ function _interopNamespace(e) {
14
+ if (e && e.__esModule) return e;
15
+ var n = Object.create(null);
16
+ if (e) {
17
+ Object.keys(e).forEach(function (k) {
18
+ if (k !== 'default') {
19
+ var d = Object.getOwnPropertyDescriptor(e, k);
20
+ Object.defineProperty(n, k, d.get ? d : {
21
+ enumerable: true,
22
+ get: function () { return e[k]; }
23
+ });
24
+ }
25
+ });
26
+ }
27
+ n.default = e;
28
+ return Object.freeze(n);
29
+ }
30
+
31
+ var React11__namespace = /*#__PURE__*/_interopNamespace(React11);
32
+
33
+ var __defProp = Object.defineProperty;
34
+ var __defProps = Object.defineProperties;
35
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
36
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
37
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
38
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
39
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
40
+ var __spreadValues = (a, b) => {
41
+ for (var prop in b || (b = {}))
42
+ if (__hasOwnProp.call(b, prop))
43
+ __defNormalProp(a, prop, b[prop]);
44
+ if (__getOwnPropSymbols)
45
+ for (var prop of __getOwnPropSymbols(b)) {
46
+ if (__propIsEnum.call(b, prop))
47
+ __defNormalProp(a, prop, b[prop]);
48
+ }
49
+ return a;
50
+ };
51
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
52
+ var __objRest = (source, exclude) => {
53
+ var target = {};
54
+ for (var prop in source)
55
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
56
+ target[prop] = source[prop];
57
+ if (source != null && __getOwnPropSymbols)
58
+ for (var prop of __getOwnPropSymbols(source)) {
59
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
60
+ target[prop] = source[prop];
61
+ }
62
+ return target;
63
+ };
64
+ function cn(...inputs) {
65
+ return tailwindMerge.twMerge(clsx.clsx(inputs));
66
+ }
67
+ var SHAPE_KEY_TIMES = "0; 0.14; 0.14; 0.29; 0.29; 0.43; 0.43; 0.57; 0.57; 0.71; 0.71; 0.86; 0.86; 1";
68
+ var SHAPE_KEY_SPLINES = [
69
+ "0.5 0.2 0 0.8",
70
+ "0.5 0.2 0 0.8",
71
+ "0.5 0.2 0 0.8",
72
+ "0.5 0.2 0 0.8",
73
+ "0.5 0.2 0 0.8",
74
+ "0.5 0.2 0 0.8",
75
+ "0.5 0.2 0 0.8",
76
+ "0.5 0.2 0 0.8",
77
+ "0.5 0.2 0 0.8",
78
+ "0.5 0.2 0 0.8",
79
+ "0.5 0.2 0 0.8",
80
+ "0.5 0.2 0 0.8",
81
+ "0.5 0.2 0 0.8"
82
+ ].join("; ");
83
+ var SHAPE_VALUES = [
84
+ "M20.9 10.4 21.4 9.5 21.9 8.7 22.5 7.8 23.2 7.2 24.2 7 25.1 7.4 25.7 8.1 26.2 9 26.8 9.8 27.3 10.6 28.1 11.2 29 11.3 30 11 30.9 10.6 31.8 10.3 32.8 9.9 33.7 10 34.5 10.6 34.9 11.5 34.8 12.5 34.8 13.5 34.7 14.5 34.7 15.5 35.2 16.3 36 16.8 37 17.1 37.9 17.3 38.9 17.5 39.8 17.9 40.4 18.7 40.5 19.7 40 20.5 39.4 21.3 38.7 22 38.1 22.8 37.6 23.7 37.7 24.6 38.3 25.5 38.9 26.2 39.6 27 40.2 27.7 40.5 28.7 40.3 29.6 39.5 30.3 38.6 30.6 37.6 30.8 36.7 31 35.7 31.3 35 31.9 34.6 32.8 34.7 33.8 34.8 34.8 34.9 35.8 34.8 36.8 34.3 37.6 33.4 38.1 32.4 38 31.5 37.6 30.6 37.2 29.7 36.9 28.7 36.6 27.8 36.9 27.1 37.6 26.6 38.5 26.1 39.3 25.5 40.2 24.8 40.8 23.8 41 22.9 40.6 22.3 39.9 21.8 39 21.2 38.2 20.7 37.4 19.9 36.8 19 36.7 18 37 17.1 37.4 16.2 37.7 15.2 38.1 14.3 38 13.5 37.4 13.1 36.5 13.2 35.5 13.2 34.5 13.3 33.5 13.3 32.5 12.8 31.7 12 31.2 11 31 10.1 30.7 9.1 30.5 8.2 30.1 7.6 29.3 7.5 28.3 8 27.5 8.7 26.7 9.3 26 9.9 25.2 10.4 24.3 10.3 23.4 9.7 22.5 9.1 21.8 8.4 21 7.8 20.3 7.5 19.3 7.7 18.4 8.5 17.7 9.4 17.4 10.4 17.2 11.3 17 12.3 16.7 13 16.1 13.4 15.2 13.3 14.2 13.2 13.2 13.1 12.2 13.2 11.2 13.7 10.4 14.6 9.9 15.6 10 16.5 10.4 17.4 10.8 18.3 11.1 19.3 11.4 20.2 11.1Z",
85
+ "M20.3 8.6 21.1 8 22 7.6 23 7.3 23 7.3 24 7.2 25 7.3 25.9 7.5 26.8 8 27.6 8.6 28.4 9.1 28.4 9.1 29.3 9.6 30.3 9.8 31.3 9.9 32.3 10 33.3 10.2 34.2 10.6 34.2 10.6 35 11.2 35.7 11.9 36.3 12.7 36.7 13.6 36.9 14.6 37.2 15.5 37.2 15.5 37.6 16.5 38.2 17.3 38.9 18 39.6 18.7 40.2 19.5 40.6 20.4 40.6 20.4 40.9 21.3 41 22.3 40.9 23.3 40.6 24.3 40.2 25.2 39.8 26.1 39.8 26.1 39.5 27 39.4 28 39.5 29 39.6 30 39.5 31 39.3 32 39.3 32 38.9 32.9 38.3 33.7 37.6 34.4 36.8 35 35.9 35.4 35 35.8 35 35.8 34.1 36.3 33.4 37 32.9 37.9 32.3 38.7 31.6 39.4 30.8 40 30.8 40 29.9 40.4 28.9 40.7 27.9 40.8 27 40.7 26 40.4 25 40.1 25 40.1 24 40 23 40.1 22.1 40.4 21.1 40.7 20.1 40.8 19.1 40.7 19.1 40.7 18.2 40.5 17.3 40 16.4 39.5 15.7 38.8 15.2 37.9 14.6 37.1 14.6 37.1 13.9 36.4 13.1 35.8 12.2 35.4 11.3 35 10.5 34.4 9.7 33.8 9.7 33.8 9.1 32.9 8.7 32 8.5 31.1 8.4 30.1 8.5 29.1 8.6 28.1 8.6 28.1 8.5 27.1 8.3 26.1 7.8 25.2 7.4 24.3 7.1 23.4 7 22.4 7 22.4 7.1 21.4 7.3 20.4 7.8 19.5 8.3 18.7 9.1 18 9.8 17.3 9.8 17.3 10.4 16.5 10.8 15.6 11 14.6 11.3 13.7 11.7 12.8 12.2 11.9 12.2 11.9 12.9 11.2 13.8 10.7 14.7 10.2 15.6 10 16.6 9.9 17.6 9.8 17.6 9.8 18.6 9.6 19.5 9.2Z",
86
+ "M18.6 9.6 19.5 9.2 20.3 8.6 21.1 8 22 7.6 23 7.3 24 7.2 25 7.3 25.9 7.5 26.8 8 27.6 8.6 28.4 9.1 29.3 9.6 30.3 9.8 31.3 9.9 32.3 10 33.3 10.2 34.2 10.6 35 11.2 35.7 11.9 36.3 12.7 36.7 13.6 36.9 14.6 37.2 15.5 37.6 16.4 38.2 17.3 38.9 18 39.6 18.7 40.2 19.5 40.6 20.4 40.9 21.3 41 22.3 40.9 23.3 40.6 24.3 40.2 25.2 39.8 26.1 39.5 27 39.4 28 39.5 29 39.6 30 39.5 31 39.3 32 38.9 32.9 38.3 33.7 37.6 34.4 36.8 35 35.9 35.4 35 35.8 34.1 36.3 33.4 37 32.9 37.9 32.3 38.7 31.6 39.4 30.8 40 29.9 40.4 28.9 40.7 27.9 40.8 27 40.7 26 40.4 25 40.1 24 40 23 40.1 22.1 40.4 21.1 40.7 20.1 40.8 19.1 40.7 18.2 40.5 17.3 40 16.4 39.5 15.7 38.8 15.2 37.9 14.6 37.1 13.9 36.4 13.1 35.8 12.2 35.4 11.3 35 10.5 34.4 9.7 33.8 9.1 32.9 8.7 32 8.5 31.1 8.4 30.1 8.5 29.1 8.6 28.1 8.5 27.1 8.3 26.1 7.8 25.2 7.4 24.3 7.1 23.4 7 22.4 7.1 21.4 7.3 20.4 7.8 19.5 8.3 18.7 9.1 18 9.8 17.3 10.4 16.5 10.8 15.6 11 14.6 11.3 13.7 11.7 12.8 12.2 11.9 12.9 11.2 13.8 10.7 14.7 10.2 15.6 10 16.6 9.9 17.6 9.8Z",
87
+ "M18.6 9.9 19.5 9.4 20.3 8.8 21.1 8.2 22 7.8 23 7.6 23.9 7.5 24.9 7.6 25.9 7.8 26.8 8.2 27.6 8.7 28.5 9.3 29.3 9.9 30.1 10.5 30.9 11 31.7 11.6 32.5 12.2 33.3 12.8 33.7 13.1 34.1 13.3 34.9 13.9 35.7 14.5 36.6 15 37.4 15.6 38.2 16.2 39 16.8 39.7 17.5 40.2 18.3 40.7 19.2 40.9 20.1 41 21.1 40.9 22.1 40.7 23.1 40.3 24 40 24.9 39.7 25.9 39.4 26.8 39 27.8 38.7 28.7 38.4 29.6 38.1 30.6 37.8 31.5 37.5 32.5 37.2 33.4 36.9 34.4 36.6 35.3 36.2 36.2 35.7 37.1 35 37.8 34.3 38.4 33.4 38.9 32.5 39.3 31.5 39.5 30.5 39.5 30 39.5 29.5 39.5 28.5 39.5 27.5 39.5 26.5 39.5 25.5 39.4 24.5 39.4 23.6 39.4 22.6 39.4 21.6 39.5 20.6 39.5 19.6 39.5 18.6 39.5 17.6 39.5 16.6 39.5 15.6 39.3 14.7 39 13.8 38.5 13.1 37.9 12.4 37.2 11.9 36.3 11.5 35.4 11.2 34.5 10.9 33.5 10.6 32.6 10.3 31.6 10 30.7 9.7 29.7 9.3 28.8 9 27.9 8.7 26.9 8.4 26 8 25 7.7 24.1 7.4 23.2 7.1 22.2 7.1 21.7 7 21.2 7.1 20.2 7.3 19.3 7.7 18.4 8.3 17.5 8.9 16.8 9.7 16.2 10.5 15.6 11.4 15.1 12.2 14.5 13 14 13.8 13.4 14.6 12.8 15.4 12.3 16.2 11.7 17 11.1 17.8 10.5Z",
88
+ "M15.4 12.3 16.2 11.7 17 11.1 17.8 10.5 18.6 9.9 19.5 9.4 20.3 8.8 21.1 8.3 22 7.8 23 7.6 23.9 7.5 24.9 7.6 25.9 7.8 26.8 8.2 27.6 8.7 28.5 9.3 29.3 9.9 30.1 10.5 30.9 11 31.7 11.6 32.5 12.2 33.3 12.8 34.1 13.3 34.9 13.9 35.7 14.5 36.6 15 37.4 15.6 38.2 16.2 39 16.8 39.7 17.5 40.2 18.3 40.7 19.2 40.9 20.1 41 21.1 40.9 22.1 40.7 23.1 40.3 24 40 24.9 39.7 25.9 39.4 26.8 39 27.8 38.7 28.7 38.4 29.6 38.1 30.6 37.8 31.5 37.5 32.5 37.2 33.4 36.9 34.4 36.6 35.3 36.2 36.2 35.7 37.1 35 37.8 34.3 38.4 33.4 38.9 32.5 39.3 31.5 39.4 30.5 39.5 29.5 39.5 28.5 39.5 27.5 39.5 26.5 39.5 25.5 39.4 24.5 39.4 23.6 39.4 22.6 39.4 21.6 39.5 20.6 39.5 19.6 39.5 18.6 39.5 17.6 39.5 16.6 39.5 15.6 39.3 14.7 39 13.8 38.5 13.1 37.9 12.4 37.2 11.9 36.3 11.5 35.4 11.2 34.5 10.9 33.5 10.6 32.6 10.3 31.6 10 30.7 9.7 29.7 9.3 28.8 9 27.9 8.7 26.9 8.4 26 8 25 7.7 24.1 7.4 23.2 7.1 22.2 7 21.2 7.1 20.2 7.3 19.3 7.7 18.4 8.3 17.5 8.9 16.8 9.7 16.2 10.5 15.6 11.4 15.1 12.2 14.5 13 14 13.8 13.4 14.6 12.8Z",
89
+ "M17 12.8 17.7 12.1 18.5 11.5 19.3 10.9 20.1 10.5 20.2 10.4 21.1 10 22 9.7 23 9.4 24 9.2 25 9 26 9 27 9 27.6 9.1 28 9.1 28.9 9.3 29.9 9.6 30.9 9.9 31.8 10.3 32.6 10.8 33.5 11.3 34.3 11.9 34.6 12.2 35 12.6 35.7 13.3 36.4 14.1 36.9 14.9 37.4 15.8 37.9 16.6 38.3 17.6 38.6 18.5 38.6 18.7 38.8 19.5 38.9 20.5 39 21.5 39 22.5 38.9 23.5 38.7 24.5 38.5 25.4 38.2 26.3 38.2 26.4 37.8 27.3 37.4 28.2 36.8 29.1 36.2 29.9 35.6 30.6 34.9 31.3 34.2 32 33.8 32.5 33.5 32.8 32.8 33.5 32.1 34.2 31.4 34.9 30.7 35.6 29.9 36.2 29.1 36.8 28.2 37.3 27.9 37.5 27.4 37.8 26.4 38.2 25.5 38.5 24.5 38.7 23.5 38.9 22.5 39 21.5 39 20.5 38.9 20.4 38.9 19.5 38.8 18.6 38.6 17.6 38.3 16.7 37.9 15.8 37.5 14.9 37 14.1 36.4 13.4 35.8 13.3 35.8 12.6 35.1 12 34.3 11.3 33.5 10.8 32.7 10.3 31.8 9.9 30.9 9.6 30 9.4 29.3 9.3 29 9.1 28 9 27 9 26 9 25 9.2 24 9.4 23 9.6 22.1 9.8 21.7 10 21.1 10.4 20.2 10.9 19.4 11.4 18.5 12.1 17.8 12.7 17 13.4 16.3 14.2 15.6 14.2 15.5 14.9 14.9 15.6 14.2 16.3 13.5Z",
90
+ "M33.5 11.3 34.3 11.9 35 12.6 35.3 12.8 35.7 13.3 36.4 14.1 36.9 14.9 37.4 15.8 37.9 16.6 38.3 17.6 38.3 17.7 38.6 18.5 38.8 19.5 38.9 20.5 39 21.5 39 22.5 38.9 23.5 38.9 23.5 38.7 24.5 38.5 25.4 38.2 26.4 37.8 27.3 37.4 28.2 36.9 28.9 36.8 29.1 36.2 29.9 35.6 30.6 34.9 31.3 34.2 32 33.5 32.8 33.1 33.2 32.8 33.5 32.1 34.2 31.4 34.9 30.7 35.6 29.9 36.2 29.1 36.8 28.7 37 28.2 37.3 27.4 37.8 26.4 38.2 25.5 38.5 24.5 38.7 23.5 38.9 23.3 38.9 22.5 39 21.5 39 20.5 38.9 19.5 38.8 18.6 38.6 17.6 38.3 17.6 38.3 16.7 37.9 15.8 37.5 14.9 37 14.1 36.4 13.3 35.8 12.7 35.2 12.6 35.1 12 34.3 11.3 33.5 10.8 32.7 10.3 31.8 9.9 30.9 9.7 30.3 9.6 29.9 9.3 29 9.1 28 9 27 9 26 9 25 9.1 24.5 9.2 24 9.4 23 9.6 22.1 10 21.1 10.4 20.2 10.9 19.4 11.1 19.1 11.5 18.5 12.1 17.7 12.7 17 13.5 16.3 14.2 15.6 14.9 14.9 14.9 14.8 15.6 14.2 16.3 13.5 17 12.8 17.7 12.1 18.5 11.5 19.3 11 19.3 10.9 20.2 10.4 21.1 10 22 9.7 23 9.4 24 9.2 24.7 9.1 25 9 26 9 27 9 28 9.1 28.9 9.3 29.9 9.6 30.4 9.7 30.9 9.9 31.8 10.3 32.6 10.8Z",
91
+ "M33.2 11.1 34.2 11.2 35.1 11.4 36 11.9 36.6 12.7 36.8 13.7 36.9 14.7 36.9 15.7 37 16.7 37.1 17.7 37.3 18.6 37.9 19.4 38.5 20.2 39.2 20.9 39.8 21.7 40.5 22.4 40.9 23.3 41 24.3 40.7 25.2 40.1 26 39.4 26.8 38.8 27.5 38.1 28.3 37.5 29.1 37.1 30 37 31 37 31.9 36.9 32.9 36.8 33.9 36.7 34.9 36.2 35.8 35.5 36.4 34.5 36.8 33.6 36.8 32.6 36.9 31.6 37 30.6 37.1 29.6 37.2 28.8 37.7 28 38.4 27.3 39 26.5 39.7 25.8 40.3 24.9 40.8 23.9 41 23 40.8 22.1 40.2 21.4 39.6 20.6 38.9 19.9 38.3 19.1 37.6 18.3 37.2 17.3 37 16.3 37 15.3 36.9 14.3 36.8 13.3 36.7 12.4 36.4 11.7 35.7 11.3 34.8 11.2 33.8 11.1 32.8 11 31.8 11 30.8 10.9 29.9 10.4 29 9.8 28.2 9.1 27.5 8.5 26.7 7.8 26 7.3 25.1 7 24.2 7.1 23.2 7.6 22.3 8.2 21.6 8.9 20.8 9.5 20.1 10.2 19.3 10.7 18.5 10.9 17.5 11 16.6 11.1 15.6 11.1 14.6 11.2 13.6 11.5 12.6 12.1 11.9 13 11.4 13.9 11.2 14.9 11.1 15.9 11 16.9 11 17.9 10.9 18.8 10.6 19.6 10 20.4 9.3 21.1 8.6 21.9 8 22.6 7.4 23.6 7 24.6 7.1 25.5 7.5 26.2 8.1 27 8.7 27.7 9.4 28.5 10 29.3 10.6 30.2 10.9 31.2 11 32.2 11.1Z",
92
+ "M27.7 9.4 28.5 10 29.3 10.6 30.2 10.9 31.2 11 32.2 11.1 33.2 11.1 34.2 11.2 35.1 11.4 36 11.9 36.6 12.7 36.8 13.7 36.9 14.7 36.9 15.7 37 16.7 37.1 17.7 37.3 18.6 37.9 19.4 38.5 20.2 39.2 20.9 39.8 21.7 40.5 22.4 40.9 23.3 41 24.3 40.7 25.2 40.1 26 39.4 26.8 38.8 27.5 38.1 28.3 37.5 29.1 37.1 30 37 31 37 31.9 36.9 32.9 36.8 33.9 36.7 34.9 36.2 35.8 35.5 36.4 34.5 36.8 33.6 36.9 32.6 36.9 31.6 37 30.6 37.1 29.6 37.2 28.8 37.7 28 38.4 27.3 39 26.5 39.7 25.8 40.3 24.9 40.8 23.9 41 23 40.8 22.1 40.2 21.4 39.6 20.6 38.9 19.9 38.3 19.1 37.6 18.3 37.2 17.3 37 16.3 37 15.3 36.9 14.3 36.8 13.3 36.7 12.4 36.4 11.7 35.7 11.3 34.8 11.2 33.8 11.1 32.8 11 31.8 11 30.8 10.9 29.9 10.4 29 9.8 28.2 9.1 27.5 8.5 26.7 7.8 26 7.3 25.1 7 24.2 7.1 23.2 7.6 22.3 8.2 21.6 8.9 20.8 9.5 20.1 10.2 19.3 10.7 18.5 10.9 17.5 11 16.5 11.1 15.6 11.1 14.6 11.2 13.6 11.5 12.6 12.1 11.9 13 11.4 13.9 11.2 14.9 11.1 15.9 11 16.9 11 17.9 10.9 18.8 10.6 19.6 10 20.4 9.3 21.1 8.6 21.9 8 22.6 7.4 23.6 7 24.6 7.1 25.5 7.5 26.2 8.1 27 8.7Z",
93
+ "M27.9 10.6 28.8 10.3 29.8 10.1 30.8 10 31.8 10.1 32.7 10.3 33.7 10.6 34.6 11.1 34.8 11.3 35.4 11.7 36.1 12.4 36.7 13.1 37.2 14 37.6 14.9 37.9 15.9 38 16.9 38 17.9 37.8 18.8 37.5 19.8 37.1 20.7 36.8 21.6 36.5 22.6 36.4 23.6 36.4 24.4 36.4 24.6 36.5 25.5 36.8 26.5 37.2 27.4 37.6 28.3 37.8 29.3 38 30.3 38 31.3 37.8 32.3 37.6 33.2 37.2 34.1 36.6 35 36 35.7 35.3 36.4 34.4 37 34.1 37.2 33.6 37.4 32.6 37.8 31.6 37.9 30.6 38 29.7 37.9 28.7 37.7 27.8 37.3 26.8 36.9 25.9 36.6 24.9 36.4 23.9 36.4 22.9 36.4 22 36.6 21 37 20.1 37.4 20.1 37.4 19.2 37.7 18.2 37.9 17.2 38 16.2 37.9 15.3 37.7 14.3 37.4 13.4 36.9 12.6 36.3 11.9 35.6 11.3 34.9 10.8 34 10.4 33.1 10.1 32.1 10 31.1 10 30.6 10 30.1 10.2 29.2 10.5 28.2 10.9 27.3 11.2 26.4 11.5 25.4 11.6 24.4 11.6 23.4 11.5 22.5 11.2 21.5 10.8 20.6 10.4 19.7 10.2 18.7 10 17.7 10 16.7 10 16.6 10.2 15.7 10.4 14.8 10.8 13.9 11.4 13 12 12.3 12.7 11.6 13.6 11 14.4 10.6 15.4 10.2 16.4 10.1 17.4 10 18.3 10.1 19.3 10.3 20.2 10.7 20.9 11 21.2 11.1 22.1 11.4 23.1 11.6 24.1 11.6 25.1 11.6 26 11.4 27 11Z",
94
+ "M36 35.7 35.3 36.4 34.4 37 33.6 37.4 32.6 37.8 31.6 37.9 30.6 38 29.7 37.9 28.7 37.7 27.8 37.3 26.8 36.9 25.9 36.6 24.9 36.4 23.9 36.4 22.9 36.4 22 36.6 21 37 20.1 37.4 19.2 37.7 18.2 37.9 17.2 38 16.2 37.9 15.3 37.7 14.3 37.4 13.4 36.9 12.6 36.3 11.9 35.6 11.3 34.9 10.8 34 10.4 33.1 10.1 32.1 10 31.1 10 30.2 10.2 29.2 10.5 28.2 10.9 27.3 11.2 26.4 11.5 25.4 11.6 24.4 11.6 23.4 11.5 22.5 11.2 21.5 10.8 20.6 10.4 19.7 10.2 18.7 10 17.7 10 16.7 10.2 15.7 10.4 14.8 10.8 13.9 11.4 13 12 12.3 12.7 11.6 13.6 11 14.4 10.6 15.4 10.2 16.4 10.1 17.4 10 18.3 10.1 19.3 10.3 20.2 10.7 21.2 11.1 22.1 11.4 23.1 11.6 24.1 11.6 25.1 11.6 26 11.4 27 11 27.9 10.6 28.8 10.3 29.8 10.1 30.8 10 31.8 10.1 32.7 10.3 33.7 10.6 34.6 11.1 35.4 11.7 36.1 12.4 36.7 13.1 37.2 14 37.6 14.9 37.9 15.9 38 16.9 38 17.8 37.8 18.8 37.5 19.8 37.1 20.7 36.8 21.6 36.5 22.6 36.4 23.6 36.4 24.6 36.5 25.5 36.8 26.5 37.2 27.4 37.6 28.3 37.8 29.3 38 30.3 38 31.3 37.8 32.3 37.6 33.2 37.2 34.1 36.6 35Z",
95
+ "M32.1 32.1 31.4 32.8 30.7 33.5 29.9 34.1 29.1 34.7 28.3 35.3 27.6 35.8 27.5 35.8 26.6 36.4 25.8 36.8 24.9 37.3 24 37.7 23.1 38 22.1 38.3 21.2 38.6 20.2 38.8 19.2 38.9 18.2 39 17.2 39 16.6 38.9 16.3 38.9 15.3 38.7 14.3 38.4 13.4 38 12.5 37.5 11.7 36.9 11.1 36.3 10.5 35.5 10 34.6 9.6 33.7 9.3 32.7 9.1 31.7 9.1 31.4 9 30.8 9 29.8 9.1 28.8 9.2 27.8 9.4 26.8 9.7 25.9 10 24.9 10.3 24 10.7 23.1 11.2 22.2 11.6 21.4 12.2 20.5 12.2 20.4 12.7 19.7 13.3 18.9 13.9 18.1 14.5 17.3 15.2 16.6 15.9 15.9 16.6 15.2 17.3 14.5 18.1 13.9 18.9 13.3 19.7 12.7 20.4 12.2 20.5 12.2 21.4 11.6 22.2 11.2 23.1 10.7 24 10.3 24.9 10 25.9 9.7 26.8 9.4 27.8 9.2 28.8 9.1 29.8 9 30.8 9 31.4 9.1 31.7 9.1 32.7 9.3 33.7 9.6 34.6 10 35.5 10.5 36.3 11.1 36.9 11.7 37.5 12.5 38 13.4 38.4 14.3 38.7 15.3 38.9 16.3 38.9 16.6 39 17.2 39 18.2 38.9 19.2 38.8 20.2 38.6 21.2 38.3 22.1 38 23.1 37.7 24 37.3 24.9 36.8 25.8 36.4 26.6 35.8 27.5 35.8 27.6 35.3 28.3 34.7 29.1 34.1 29.9 33.5 30.7 32.8 31.4Z",
96
+ "M24.3 10.2 24.9 10 25.9 9.7 26.8 9.4 27.1 9.4 27.8 9.2 28.8 9.1 29.8 9 29.9 9 30.8 9 31.7 9.1 32.7 9.3 32.8 9.3 33.7 9.6 34.6 10 35.5 10.5 35.5 10.5 36.3 11.1 36.9 11.7 37.5 12.5 37.5 12.5 38 13.4 38.4 14.3 38.7 15.2 38.7 15.3 38.9 16.3 39 17.2 39 18.1 39 18.2 38.9 19.2 38.8 20.2 38.6 20.9 38.6 21.2 38.3 22.1 38 23.1 37.8 23.7 37.7 24 37.3 24.9 36.8 25.8 36.5 26.4 36.4 26.6 35.8 27.5 35.3 28.3 35 28.8 34.7 29.1 34.1 29.9 33.5 30.7 33.1 31.1 32.8 31.4 32.1 32.1 31.4 32.8 31.1 33.1 30.7 33.5 29.9 34.1 29.1 34.7 28.8 35 28.3 35.3 27.5 35.8 26.6 36.4 26.4 36.5 25.8 36.8 24.9 37.3 24 37.7 23.7 37.8 23.1 38 22.1 38.3 21.2 38.6 20.9 38.6 20.2 38.8 19.2 38.9 18.2 39 18.1 39 17.2 39 16.3 38.9 15.3 38.7 15.2 38.7 14.3 38.4 13.4 38 12.5 37.5 12.5 37.5 11.7 36.9 11.1 36.3 10.5 35.5 10.5 35.5 10 34.6 9.6 33.7 9.3 32.8 9.3 32.7 9.1 31.7 9 30.8 9 29.9 9 29.8 9.1 28.8 9.2 27.8 9.4 27.1 9.4 26.8 9.7 25.9 10 24.9 10.2 24.3 10.3 24 10.7 23.1 11.2 22.2 11.5 21.6 11.6 21.4 12.2 20.5 12.7 19.7 13 19.2 13.3 18.9 13.9 18.1 14.5 17.3 14.9 16.9 15.2 16.6 15.9 15.9 16.6 15.2 16.9 14.9 17.3 14.5 18.1 13.9 18.9 13.3 19.2 13 19.7 12.7 20.5 12.2 21.4 11.6 21.6 11.5 22.2 11.2 23.1 10.7 24 10.3Z",
97
+ "M22.5 7.8 23.2 7.2 24.2 7 25.1 7.4 25.7 8.1 26.2 9 26.8 9.8 27.3 10.6 28.1 11.2 29 11.3 30 11 30.9 10.6 31.8 10.3 32.8 9.9 33.7 10 34.5 10.6 34.9 11.5 34.8 12.5 34.8 13.5 34.7 14.5 34.7 15.5 35.2 16.3 36 16.8 37 17 37.9 17.3 38.9 17.5 39.8 17.9 40.4 18.7 40.5 19.7 40 20.5 39.3 21.3 38.7 22 38.1 22.8 37.6 23.7 37.7 24.6 38.3 25.4 38.9 26.2 39.6 27 40.2 27.7 40.5 28.6 40.3 29.6 39.5 30.3 38.6 30.6 37.6 30.8 36.7 31 35.7 31.3 35 31.9 34.6 32.8 34.7 33.8 34.8 34.8 34.8 35.8 34.8 36.8 34.3 37.6 33.4 38.1 32.4 38 31.5 37.6 30.6 37.2 29.7 36.9 28.7 36.6 27.8 36.9 27.1 37.6 26.6 38.5 26.1 39.3 25.5 40.2 24.8 40.8 23.8 41 22.9 40.6 22.3 39.9 21.8 39 21.2 38.2 20.7 37.4 19.9 36.8 19 36.7 18 37 17.1 37.4 16.2 37.7 15.2 38.1 14.3 38 13.5 37.4 13.1 36.5 13.2 35.5 13.2 34.5 13.3 33.5 13.3 32.5 12.8 31.7 12 31.2 11 31 10.1 30.7 9.1 30.5 8.2 30.1 7.6 29.3 7.5 28.3 8 27.5 8.7 26.7 9.3 26 9.9 25.2 10.4 24.3 10.3 23.4 9.7 22.6 9.1 21.8 8.4 21 7.8 20.3 7.5 19.4 7.7 18.4 8.5 17.7 9.4 17.4 10.4 17.2 11.3 17 12.3 16.7 13 16.1 13.4 15.2 13.3 14.2 13.2 13.2 13.2 12.2 13.2 11.2 13.7 10.4 14.6 9.9 15.6 10 16.5 10.4 17.4 10.8 18.3 11.1 19.3 11.4 20.2 11.1 20.9 10.4 21.4 9.5 21.9 8.7Z"
98
+ ].join(";");
99
+ var ROTATE_KEY_TIMES = "0; 0.14; 0.29; 0.43; 0.57; 0.71; 0.86; 1";
100
+ var ROTATE_KEY_SPLINES = [
101
+ "0.5 0.2 0 0.8",
102
+ "0.5 0.2 0 0.8",
103
+ "0.5 0.2 0 0.8",
104
+ "0.5 0.2 0 0.8",
105
+ "0.5 0.2 0 0.8",
106
+ "0.5 0.2 0 0.8",
107
+ "0.5 0.2 0 0.8"
108
+ ].join("; ");
109
+ var ROTATE_VALUES = "0 24 24; 154 24 24; 309 24 24; 463 24 24; 617 24 24; 771 24 24; 926 24 24; 1080 24 24";
110
+ var DETERMINATE_CIRCLE = "M24 7 C34.49 7 41 13.51 41 24 C41 34.49 34.49 41 24 41 C13.51 41 7 34.49 7 24 C7 13.51 13.51 7 24 7 Z";
111
+ var DETERMINATE_SOFT_BURST = "M20.9 10.4 21.4 9.5 21.9 8.7 22.5 7.8 23.2 7.2 24.2 7 25.1 7.4 25.7 8.1 26.2 9 26.8 9.8 27.3 10.6 28.1 11.2 29 11.3 30 11 30.9 10.6 31.8 10.3 32.8 9.9 33.7 10 34.5 10.6 34.9 11.5 34.8 12.5 34.8 13.5 34.7 14.5 34.7 15.5 35.2 16.3 36 16.8 37 17.1 37.9 17.3 38.9 17.5 39.8 17.9 40.4 18.7 40.5 19.7 40 20.5 39.4 21.3 38.7 22 38.1 22.8 37.6 23.7 37.7 24.6 38.3 25.5 38.9 26.2 39.6 27 40.2 27.7 40.5 28.7 40.3 29.6 39.5 30.3 38.6 30.6 37.6 30.8 36.7 31 35.7 31.3 35 31.9 34.6 32.8 34.7 33.8 34.8 34.8 34.9 35.8 34.8 36.8 34.3 37.6 33.4 38.1 32.4 38 31.5 37.6 30.6 37.2 29.7 36.9 28.7 36.6 27.8 36.9 27.1 37.6 26.6 38.5 26.1 39.3 25.5 40.2 24.8 40.8 23.8 41 22.9 40.6 22.3 39.9 21.8 39 21.2 38.2 20.7 37.4 19.9 36.8 19 36.7 18 37 17.1 37.4 16.2 37.7 15.2 38.1 14.3 38 13.5 37.4 13.1 36.5 13.2 35.5 13.2 34.5 13.3 33.5 13.3 32.5 12.8 31.7 12 31.2 11 31 10.1 30.7 9.1 30.5 8.2 30.1 7.6 29.3 7.5 28.3 8 27.5 8.7 26.7 9.3 26 9.9 25.2 10.4 24.3 10.3 23.4 9.7 22.5 9.1 21.8 8.4 21 7.8 20.3 7.5 19.3 7.7 18.4 8.5 17.7 9.4 17.4 10.4 17.2 11.3 17 12.3 16.7 13 16.1 13.4 15.2 13.3 14.2 13.2 13.2 13.1 12.2 13.2 11.2 13.7 10.4 14.6 9.9 15.6 10 16.5 10.4 17.4 10.8 18.3 11.1 19.3 11.4 20.2 11.1Z";
112
+ var IndeterminateSvg = React11__namespace.memo(function IndeterminateSvg2({
113
+ size
114
+ }) {
115
+ const [ready, setReady] = React11__namespace.useState(false);
116
+ React11__namespace.useEffect(() => {
117
+ const raf = requestAnimationFrame(() => setReady(true));
118
+ return () => cancelAnimationFrame(raf);
119
+ }, []);
120
+ return /* @__PURE__ */ jsxRuntime.jsx(
121
+ "svg",
122
+ {
123
+ viewBox: "4 4 40 40",
124
+ width: size,
125
+ height: size,
126
+ fill: "currentColor",
127
+ xmlns: "http://www.w3.org/2000/svg",
128
+ "aria-hidden": "true",
129
+ focusable: "false",
130
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: SHAPE_VALUES.split(";")[0], children: ready && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
131
+ /* @__PURE__ */ jsxRuntime.jsx(
132
+ "animate",
133
+ {
134
+ attributeName: "d",
135
+ dur: "5s",
136
+ repeatCount: "indefinite",
137
+ calcMode: "spline",
138
+ keySplines: SHAPE_KEY_SPLINES,
139
+ keyTimes: SHAPE_KEY_TIMES,
140
+ values: SHAPE_VALUES
141
+ }
142
+ ),
143
+ /* @__PURE__ */ jsxRuntime.jsx(
144
+ "animateTransform",
145
+ {
146
+ attributeName: "transform",
147
+ attributeType: "XML",
148
+ type: "rotate",
149
+ dur: "5s",
150
+ repeatCount: "indefinite",
151
+ calcMode: "spline",
152
+ keySplines: ROTATE_KEY_SPLINES,
153
+ keyTimes: ROTATE_KEY_TIMES,
154
+ values: ROTATE_VALUES
155
+ }
156
+ )
157
+ ] }) })
158
+ }
159
+ );
160
+ });
161
+ var DeterminateSvg = React11__namespace.memo(function DeterminateSvg2({
162
+ size,
163
+ progress
164
+ }) {
165
+ const p = Math.min(1, Math.max(0, progress));
166
+ const rotation = -180 * p;
167
+ const pathD = p < 0.5 ? DETERMINATE_CIRCLE : DETERMINATE_SOFT_BURST;
168
+ return /* @__PURE__ */ jsxRuntime.jsx(
169
+ "svg",
170
+ {
171
+ viewBox: "4 4 40 40",
172
+ width: size,
173
+ height: size,
174
+ fill: "currentColor",
175
+ xmlns: "http://www.w3.org/2000/svg",
176
+ "aria-hidden": "true",
177
+ focusable: "false",
178
+ style: {
179
+ transform: `rotate(${rotation}deg)`,
180
+ transition: "transform 0.3s ease"
181
+ },
182
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: pathD, style: { transition: "d 0.3s ease" } })
183
+ }
184
+ );
185
+ });
186
+ var LoadingIndicator = React11__namespace.forwardRef(
187
+ (_a, ref) => {
188
+ var _b = _a, {
189
+ variant = "uncontained",
190
+ size = 48,
191
+ progress,
192
+ color,
193
+ className,
194
+ "aria-label": ariaLabel,
195
+ style
196
+ } = _b, restProps = __objRest(_b, [
197
+ "variant",
198
+ "size",
199
+ "progress",
200
+ "color",
201
+ "className",
202
+ "aria-label",
203
+ "style"
204
+ ]);
205
+ const isContained = variant === "contained";
206
+ const isDeterminate = progress !== void 0;
207
+ const clampedSize = Math.min(240, Math.max(24, size));
208
+ const scaleFactor = clampedSize / 48;
209
+ const containerSize = isContained ? 38 * scaleFactor : void 0;
210
+ const indicatorSize = isContained ? 24 * scaleFactor : clampedSize;
211
+ const activeColor = isContained ? color != null ? color : "var(--md-sys-color-indicator-contained-active)" : color != null ? color : "var(--md-sys-color-indicator-active)";
212
+ const ariaNow = isDeterminate ? Math.round(Math.min(1, Math.max(0, progress)) * 100) : void 0;
213
+ return /* @__PURE__ */ jsxRuntime.jsx(
214
+ "div",
215
+ __spreadProps(__spreadValues({
216
+ ref,
217
+ role: "progressbar",
218
+ "aria-label": ariaLabel,
219
+ "aria-valuemin": 0,
220
+ "aria-valuemax": 100,
221
+ "aria-valuenow": ariaNow,
222
+ className: cn(
223
+ "inline-flex items-center justify-center shrink-0",
224
+ className
225
+ ),
226
+ style: __spreadValues({
227
+ width: clampedSize,
228
+ height: clampedSize,
229
+ color: activeColor
230
+ }, style)
231
+ }, restProps), {
232
+ children: isContained ? /* @__PURE__ */ jsxRuntime.jsx(
233
+ "div",
234
+ {
235
+ className: "flex items-center justify-center rounded-full",
236
+ style: {
237
+ width: containerSize,
238
+ height: containerSize,
239
+ backgroundColor: "var(--md-sys-color-indicator-contained-container)"
240
+ },
241
+ children: isDeterminate ? /* @__PURE__ */ jsxRuntime.jsx(DeterminateSvg, { size: indicatorSize, progress }) : /* @__PURE__ */ jsxRuntime.jsx(IndeterminateSvg, { size: indicatorSize })
242
+ }
243
+ ) : isDeterminate ? /* @__PURE__ */ jsxRuntime.jsx(DeterminateSvg, { size: indicatorSize, progress }) : /* @__PURE__ */ jsxRuntime.jsx(IndeterminateSvg, { size: indicatorSize })
244
+ })
245
+ );
246
+ }
247
+ );
248
+ LoadingIndicator.displayName = "LoadingIndicator";
249
+
250
+ // src/ui/progress-indicator/utils.ts
251
+ function easeInOutCubic(x) {
252
+ return x < 0.5 ? 4 * x * x * x : 1 - (-2 * x + 2) ** 3 / 2;
253
+ }
254
+ function generateWavyCircularPath(center, radius, amplitude, wavelength) {
255
+ const circumference = 2 * Math.PI * radius;
256
+ const numWaves = Math.max(
257
+ 3,
258
+ Math.round(circumference / Math.max(1, wavelength))
259
+ );
260
+ const steps = numWaves * 4;
261
+ const dt = 2 * Math.PI / steps;
262
+ const rAt = (t) => radius + amplitude * Math.sin(numWaves * t);
263
+ const drAt = (t) => amplitude * numWaves * Math.cos(numWaves * t);
264
+ const xAt = (t) => center + rAt(t) * Math.cos(t);
265
+ const yAt = (t) => center + rAt(t) * Math.sin(t);
266
+ const dxAt = (t) => drAt(t) * Math.cos(t) - rAt(t) * Math.sin(t);
267
+ const dyAt = (t) => drAt(t) * Math.sin(t) + rAt(t) * Math.cos(t);
268
+ let d = "";
269
+ const tStart = 0;
270
+ for (let i = 0; i < steps; i++) {
271
+ const t0 = tStart + i * dt;
272
+ const t1 = tStart + (i + 1) * dt;
273
+ const scale = dt / 3;
274
+ const cp1x = xAt(t0) + scale * dxAt(t0);
275
+ const cp1y = yAt(t0) + scale * dyAt(t0);
276
+ const cp2x = xAt(t1) - scale * dxAt(t1);
277
+ const cp2y = yAt(t1) - scale * dyAt(t1);
278
+ if (i === 0) d += `M ${xAt(t0).toFixed(2)} ${yAt(t0).toFixed(2)}`;
279
+ d += ` C ${cp1x.toFixed(2)} ${cp1y.toFixed(2)}, ${cp2x.toFixed(2)} ${cp2y.toFixed(2)}, ${xAt(t1).toFixed(2)} ${yAt(t1).toFixed(2)}`;
280
+ }
281
+ d += " Z";
282
+ return d;
283
+ }
284
+ function getSinePath(startX, endX, phase, wl, amp) {
285
+ if (startX >= endX) return "";
286
+ let d = "";
287
+ const step = amp === 0 ? Math.max(10, endX - startX) : 1;
288
+ const yStart = Math.sin((startX + phase) / wl * 2 * Math.PI) * amp;
289
+ d += `M ${startX.toFixed(2)} ${yStart.toFixed(2)}`;
290
+ let nextX = Math.ceil(startX / step) * step;
291
+ if (nextX === startX) nextX += step;
292
+ while (nextX < endX) {
293
+ const y = Math.sin((nextX + phase) / wl * 2 * Math.PI) * amp;
294
+ d += ` L ${nextX.toFixed(2)} ${y.toFixed(2)}`;
295
+ nextX += step;
296
+ }
297
+ const yEnd = Math.sin((endX + phase) / wl * 2 * Math.PI) * amp;
298
+ d += ` L ${endX.toFixed(2)} ${yEnd.toFixed(2)}`;
299
+ return d;
300
+ }
301
+ var CircularProgress = React11__namespace.forwardRef(
302
+ (_a, ref) => {
303
+ var _b = _a, {
304
+ value,
305
+ size = 48,
306
+ trackHeight = 4,
307
+ shape = "flat",
308
+ amplitude,
309
+ wavelength,
310
+ gapSize = 4,
311
+ crawlerSpeed = 1,
312
+ color,
313
+ trackColor,
314
+ className,
315
+ "aria-label": ariaLabel
316
+ } = _b, restProps = __objRest(_b, [
317
+ "value",
318
+ "size",
319
+ "trackHeight",
320
+ "shape",
321
+ "amplitude",
322
+ "wavelength",
323
+ "gapSize",
324
+ "crawlerSpeed",
325
+ "color",
326
+ "trackColor",
327
+ "className",
328
+ "aria-label"
329
+ ]);
330
+ const isDeterminate = value !== void 0;
331
+ const clampedValue = isDeterminate ? Math.min(100, Math.max(0, value)) : 0;
332
+ const radius = (size - trackHeight) / 2;
333
+ const center = size / 2;
334
+ const activeColor = color || "var(--md-sys-color-indicator-active)";
335
+ const bgTrackColor = trackColor || "var(--md-sys-color-indicator-track)";
336
+ const isWavy = shape === "wavy";
337
+ const BASELINE_SIZE = 48;
338
+ const scaleFactor = size / BASELINE_SIZE;
339
+ const effectiveAmplitude = React11__namespace.useMemo(
340
+ () => amplitude != null ? amplitude : 1.6 * scaleFactor,
341
+ [amplitude, scaleFactor]
342
+ );
343
+ const effectiveWavelength = React11__namespace.useMemo(
344
+ () => wavelength != null ? wavelength : 15 * scaleFactor,
345
+ [wavelength, scaleFactor]
346
+ );
347
+ const wavyActivePath = React11__namespace.useMemo(
348
+ () => isWavy ? generateWavyCircularPath(
349
+ center,
350
+ radius,
351
+ effectiveAmplitude,
352
+ effectiveWavelength
353
+ ) : null,
354
+ [isWavy, center, radius, effectiveAmplitude, effectiveWavelength]
355
+ );
356
+ const circumference = React11__namespace.useMemo(() => 2 * Math.PI * radius, [radius]);
357
+ const gapForTrack = React11__namespace.useMemo(
358
+ () => (gapSize + trackHeight) / circumference,
359
+ [gapSize, trackHeight, circumference]
360
+ );
361
+ const activeAngularFraction = isDeterminate ? clampedValue / 100 : 0;
362
+ const trackOffset = isDeterminate ? activeAngularFraction + gapForTrack : 0;
363
+ const trackLength = isDeterminate ? Math.max(1e-3, 1 - activeAngularFraction - 2 * gapForTrack) : 1;
364
+ const ActiveCircleElem = react.m.circle;
365
+ const ActivePathElem = react.m.path;
366
+ return /* @__PURE__ */ jsxRuntime.jsx(
367
+ "div",
368
+ __spreadProps(__spreadValues({
369
+ ref,
370
+ role: "progressbar",
371
+ "aria-label": ariaLabel,
372
+ "aria-valuenow": isDeterminate ? clampedValue : void 0,
373
+ "aria-valuemin": 0,
374
+ "aria-valuemax": 100,
375
+ className: cn(
376
+ "relative inline-flex items-center justify-center shrink-0",
377
+ className
378
+ ),
379
+ style: { width: size, height: size }
380
+ }, restProps), {
381
+ children: /* @__PURE__ */ jsxRuntime.jsxs(react.LazyMotion, { features: react.domMax, strict: true, children: [
382
+ /* @__PURE__ */ jsxRuntime.jsxs(
383
+ "svg",
384
+ {
385
+ width: size,
386
+ height: size,
387
+ viewBox: `0 0 ${size} ${size}`,
388
+ "aria-hidden": "true",
389
+ style: { transform: "rotate(-90deg)", overflow: "visible" },
390
+ children: [
391
+ isDeterminate ? /* @__PURE__ */ jsxRuntime.jsx(
392
+ react.m.circle,
393
+ {
394
+ cx: center,
395
+ cy: center,
396
+ r: radius,
397
+ fill: "none",
398
+ stroke: bgTrackColor,
399
+ strokeWidth: trackHeight,
400
+ initial: { pathLength: trackLength, pathOffset: trackOffset },
401
+ animate: { pathLength: trackLength, pathOffset: trackOffset },
402
+ transition: { duration: 0.4, ease: [0.2, 0, 0, 1] },
403
+ strokeLinecap: "round"
404
+ }
405
+ ) : null,
406
+ isDeterminate && (isWavy ? /* @__PURE__ */ jsxRuntime.jsx(
407
+ ActivePathElem,
408
+ {
409
+ d: wavyActivePath != null ? wavyActivePath : "",
410
+ fill: "none",
411
+ stroke: activeColor,
412
+ strokeWidth: trackHeight,
413
+ strokeLinecap: "round",
414
+ initial: { pathLength: 0 },
415
+ animate: { pathLength: clampedValue / 100 },
416
+ transition: {
417
+ duration: 0.4,
418
+ ease: [0.2, 0, 0, 1]
419
+ }
420
+ }
421
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
422
+ ActiveCircleElem,
423
+ {
424
+ cx: center,
425
+ cy: center,
426
+ r: radius,
427
+ fill: "none",
428
+ stroke: activeColor,
429
+ strokeWidth: trackHeight,
430
+ strokeLinecap: "round",
431
+ initial: { pathLength: 0 },
432
+ animate: { pathLength: clampedValue / 100 },
433
+ transition: {
434
+ duration: 0.4,
435
+ ease: [0.2, 0, 0, 1]
436
+ }
437
+ }
438
+ ))
439
+ ]
440
+ }
441
+ ),
442
+ !isDeterminate && /* @__PURE__ */ jsxRuntime.jsxs(
443
+ react.m.svg,
444
+ {
445
+ width: size,
446
+ height: size,
447
+ viewBox: `0 0 ${size} ${size}`,
448
+ "aria-hidden": "true",
449
+ style: {
450
+ position: "absolute",
451
+ inset: 0,
452
+ overflow: "visible",
453
+ rotate: "-90deg",
454
+ transformOrigin: "center"
455
+ },
456
+ animate: { rotate: ["-90deg", "270deg"] },
457
+ transition: {
458
+ rotate: {
459
+ duration: 2 / Math.max(0.1, crawlerSpeed),
460
+ repeat: Number.POSITIVE_INFINITY,
461
+ ease: "linear"
462
+ }
463
+ },
464
+ children: [
465
+ /* @__PURE__ */ jsxRuntime.jsx(
466
+ react.m.circle,
467
+ {
468
+ cx: center,
469
+ cy: center,
470
+ r: radius,
471
+ fill: "none",
472
+ stroke: bgTrackColor,
473
+ strokeWidth: trackHeight,
474
+ strokeLinecap: "round",
475
+ style: { originX: "50%", originY: "50%" },
476
+ animate: {
477
+ pathLength: [
478
+ Math.max(1e-3, 1 - 0.1 - 2 * gapForTrack),
479
+ Math.max(1e-3, 1 - 0.75 - 2 * gapForTrack),
480
+ Math.max(1e-3, 1 - 0.1 - 2 * gapForTrack)
481
+ ],
482
+ rotate: [
483
+ `${(0.1 + gapForTrack) * 360}deg`,
484
+ `${(1 + gapForTrack) * 360}deg`,
485
+ `${(1.1 + gapForTrack) * 360}deg`
486
+ ]
487
+ },
488
+ transition: {
489
+ duration: 2 / Math.max(0.1, crawlerSpeed),
490
+ repeat: Number.POSITIVE_INFINITY,
491
+ ease: [0.4, 0, 0.2, 1]
492
+ }
493
+ }
494
+ ),
495
+ isWavy ? /* @__PURE__ */ jsxRuntime.jsx(
496
+ ActivePathElem,
497
+ {
498
+ d: wavyActivePath != null ? wavyActivePath : "",
499
+ fill: "none",
500
+ stroke: activeColor,
501
+ strokeWidth: trackHeight,
502
+ strokeLinecap: "round",
503
+ style: { originX: "50%", originY: "50%" },
504
+ animate: {
505
+ pathLength: [0.1, 0.75, 0.1],
506
+ rotate: ["0deg", "90deg", "360deg"]
507
+ },
508
+ transition: {
509
+ duration: 2 / Math.max(0.1, crawlerSpeed),
510
+ repeat: Number.POSITIVE_INFINITY,
511
+ ease: [0.4, 0, 0.2, 1]
512
+ }
513
+ }
514
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
515
+ ActiveCircleElem,
516
+ {
517
+ cx: center,
518
+ cy: center,
519
+ r: radius,
520
+ fill: "none",
521
+ stroke: activeColor,
522
+ strokeWidth: trackHeight,
523
+ strokeLinecap: "round",
524
+ style: { originX: "50%", originY: "50%" },
525
+ animate: {
526
+ pathLength: [0.1, 0.75, 0.1],
527
+ rotate: ["0deg", "90deg", "360deg"]
528
+ },
529
+ transition: {
530
+ duration: 2 / Math.max(0.1, crawlerSpeed),
531
+ repeat: Number.POSITIVE_INFINITY,
532
+ ease: [0.4, 0, 0.2, 1]
533
+ }
534
+ }
535
+ )
536
+ ]
537
+ }
538
+ )
539
+ ] })
540
+ })
541
+ );
542
+ }
543
+ );
544
+ CircularProgress.displayName = "CircularProgress";
545
+ function useContainerWidth() {
546
+ const [width, setWidth] = React11__namespace.useState(0);
547
+ const observerRef = React11__namespace.useRef(null);
548
+ const ref = React11__namespace.useCallback((node) => {
549
+ if (observerRef.current) {
550
+ observerRef.current.disconnect();
551
+ observerRef.current = null;
552
+ }
553
+ if (node) {
554
+ const obs = new ResizeObserver((entries) => {
555
+ const contentRect = entries[0].contentRect;
556
+ setWidth(contentRect.width);
557
+ });
558
+ obs.observe(node);
559
+ observerRef.current = obs;
560
+ }
561
+ }, []);
562
+ React11__namespace.useEffect(() => {
563
+ return () => {
564
+ if (observerRef.current) {
565
+ observerRef.current.disconnect();
566
+ }
567
+ };
568
+ }, []);
569
+ return [ref, width];
570
+ }
571
+ function useMergedRef(...refs) {
572
+ return React11__namespace.useCallback(
573
+ (node) => {
574
+ for (const ref of refs) {
575
+ if (typeof ref === "function") {
576
+ ref(node);
577
+ } else if (ref && typeof ref === "object") {
578
+ ref.current = node;
579
+ }
580
+ }
581
+ },
582
+ // eslint-disable-next-line react-hooks/exhaustive-deps
583
+ [refs]
584
+ );
585
+ }
586
+ var FlatLinearTrack = React11__namespace.memo(function FlatLinearTrack2({
587
+ trackHeight,
588
+ activeColor,
589
+ trackColor,
590
+ value,
591
+ isRtl,
592
+ gapSize,
593
+ crawlerSpeed
594
+ }) {
595
+ const isDeterminate = value !== void 0;
596
+ const radius = trackHeight / 2;
597
+ const minActiveWidth = trackHeight;
598
+ return /* @__PURE__ */ jsxRuntime.jsx(
599
+ "div",
600
+ {
601
+ className: "relative w-full overflow-hidden",
602
+ style: { height: trackHeight, borderRadius: radius },
603
+ children: isDeterminate ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
604
+ /* @__PURE__ */ jsxRuntime.jsx(
605
+ react.m.div,
606
+ {
607
+ className: "absolute inset-y-0",
608
+ style: {
609
+ backgroundColor: trackColor,
610
+ borderRadius: radius,
611
+ width: "100%"
612
+ },
613
+ initial: {
614
+ [isRtl ? "right" : "left"]: `calc(max(${minActiveWidth}px, 0%) + ${gapSize}px)`
615
+ },
616
+ animate: {
617
+ [isRtl ? "right" : "left"]: `calc(max(${minActiveWidth}px, ${value}%) + ${gapSize}px)`
618
+ },
619
+ transition: { duration: 0.4, ease: [0.2, 0, 0, 1] }
620
+ }
621
+ ),
622
+ /* @__PURE__ */ jsxRuntime.jsx(
623
+ react.m.div,
624
+ {
625
+ className: "absolute inset-y-0",
626
+ style: __spreadValues({
627
+ backgroundColor: activeColor,
628
+ borderRadius: radius,
629
+ minWidth: minActiveWidth
630
+ }, isRtl ? { right: 0 } : { left: 0 }),
631
+ initial: { width: `${minActiveWidth}px` },
632
+ animate: { width: `${value}%` },
633
+ transition: { duration: 0.4, ease: [0.2, 0, 0, 1] }
634
+ }
635
+ )
636
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
637
+ /* @__PURE__ */ jsxRuntime.jsx(
638
+ "div",
639
+ {
640
+ className: "absolute inset-0",
641
+ style: { backgroundColor: trackColor, borderRadius: radius }
642
+ }
643
+ ),
644
+ /* @__PURE__ */ jsxRuntime.jsx(
645
+ react.m.div,
646
+ {
647
+ className: "absolute inset-y-0",
648
+ style: { backgroundColor: activeColor, borderRadius: radius },
649
+ initial: { left: "-40%", width: "40%" },
650
+ animate: { left: ["-40%", "100%"], width: ["40%", "20%", "40%"] },
651
+ transition: {
652
+ duration: 2 / Math.max(0.1, crawlerSpeed),
653
+ repeat: Number.POSITIVE_INFINITY,
654
+ ease: "easeInOut"
655
+ }
656
+ }
657
+ )
658
+ ] })
659
+ }
660
+ );
661
+ });
662
+ var WavyLinearTrack = React11__namespace.memo(function WavyLinearTrack2({
663
+ trackHeight,
664
+ svgHeight,
665
+ amplitude,
666
+ wavelength,
667
+ indeterminateWavelength,
668
+ activeColor,
669
+ trackColor,
670
+ value,
671
+ isRtl,
672
+ gapSize,
673
+ waveSpeed,
674
+ crawlerSpeed,
675
+ determinateAnimation,
676
+ indeterminateAnimation,
677
+ trackShape
678
+ }) {
679
+ const isDeterminate = typeof value === "number";
680
+ const clampedValue = isDeterminate ? Math.max(0, Math.min(100, value)) : 100;
681
+ const titleId = React11__namespace.useId();
682
+ const [containerRef, width] = useContainerWidth();
683
+ const activePathRef = React11__namespace.useRef(null);
684
+ const trackPathRef = React11__namespace.useRef(null);
685
+ const amplitudeMV = react.useMotionValue(amplitude);
686
+ const fractionMV = react.useMotionValue(isDeterminate ? clampedValue / 100 : 1);
687
+ React11__namespace.useEffect(() => {
688
+ if (isDeterminate) {
689
+ const fraction = clampedValue / 100;
690
+ let targetAmp = amplitude;
691
+ if (determinateAnimation === "md3") {
692
+ targetAmp = fraction <= 0.1 || fraction >= 0.95 ? 0 : amplitude;
693
+ }
694
+ react.animate(amplitudeMV, targetAmp, {
695
+ type: "spring",
696
+ bounce: 0,
697
+ duration: 0.5
698
+ });
699
+ react.animate(fractionMV, fraction, { duration: 0.4, ease: [0.2, 0, 0, 1] });
700
+ }
701
+ }, [
702
+ clampedValue,
703
+ isDeterminate,
704
+ amplitude,
705
+ amplitudeMV,
706
+ fractionMV,
707
+ determinateAnimation
708
+ ]);
709
+ const activeWavelength = Math.max(
710
+ 1,
711
+ isDeterminate ? wavelength : indeterminateWavelength
712
+ );
713
+ const trackAmp = trackShape === "wavy" ? amplitude : 0;
714
+ react.useAnimationFrame((time) => {
715
+ if (width === 0) return;
716
+ const currentAmp = amplitudeMV.get();
717
+ const phase = time / 1e3 * waveSpeed * activeWavelength;
718
+ const capWidth = trackHeight / 2;
719
+ let activePathD = "";
720
+ let trackD = "";
721
+ const totalGap = gapSize + trackHeight;
722
+ if (isDeterminate) {
723
+ const fraction = fractionMV.get();
724
+ const barHead = fraction * width;
725
+ const adjHead = Math.max(capWidth, Math.min(width - capWidth, barHead));
726
+ const adjTail = capWidth;
727
+ if (fraction > 0 && adjHead - adjTail > 0.1) {
728
+ activePathD = getSinePath(
729
+ adjTail,
730
+ adjHead,
731
+ phase,
732
+ activeWavelength,
733
+ currentAmp
734
+ );
735
+ } else if (fraction === 0) {
736
+ activePathD = `M ${capWidth} 0 L ${capWidth + 0.01} 0`;
737
+ }
738
+ const trackStart = adjHead + totalGap;
739
+ if (trackStart < width - capWidth) {
740
+ trackD = getSinePath(
741
+ trackStart,
742
+ width - capWidth,
743
+ phase,
744
+ activeWavelength,
745
+ trackAmp
746
+ );
747
+ }
748
+ } else {
749
+ const safeCrawlerSpeed = Math.max(0.1, crawlerSpeed);
750
+ const activeLines = [];
751
+ if (indeterminateAnimation === "continuous") {
752
+ const cycle = 2e3 / safeCrawlerSpeed;
753
+ const fraction = time % cycle / cycle;
754
+ activeLines.push({
755
+ tail: easeInOutCubic(Math.max(0, fraction * 1.5 - 0.5)),
756
+ head: easeInOutCubic(Math.min(1, fraction * 1.5))
757
+ });
758
+ } else {
759
+ const cycle = 1750 / safeCrawlerSpeed;
760
+ const t = time % cycle * safeCrawlerSpeed;
761
+ const l1H = easeInOutCubic(Math.max(0, Math.min(1, t / 1e3)));
762
+ const l1T = easeInOutCubic(Math.max(0, Math.min(1, (t - 250) / 1e3)));
763
+ const l2H = easeInOutCubic(Math.max(0, Math.min(1, (t - 650) / 850)));
764
+ const l2T = easeInOutCubic(Math.max(0, Math.min(1, (t - 900) / 850)));
765
+ activeLines.push({ tail: l1T, head: l1H });
766
+ activeLines.push({ tail: l2T, head: l2H });
767
+ }
768
+ const segments = activeLines.map((line) => {
769
+ const barTail = line.tail * width;
770
+ const barHead = line.head * width;
771
+ const adjTail = Math.max(
772
+ capWidth,
773
+ Math.min(width - capWidth, barTail)
774
+ );
775
+ const adjHead = Math.max(
776
+ capWidth,
777
+ Math.min(width - capWidth, barHead)
778
+ );
779
+ return { adjTail, adjHead };
780
+ }).filter((seg) => seg.adjHead - seg.adjTail > 0.1);
781
+ activePathD = segments.map(
782
+ (seg) => getSinePath(
783
+ seg.adjTail,
784
+ seg.adjHead,
785
+ phase,
786
+ activeWavelength,
787
+ currentAmp
788
+ )
789
+ ).join(" ");
790
+ let currentTrackX = capWidth;
791
+ for (const seg of segments) {
792
+ const trackEnd = seg.adjTail - totalGap;
793
+ if (trackEnd > currentTrackX) {
794
+ trackD += `${getSinePath(currentTrackX, trackEnd, phase, activeWavelength, trackAmp)} `;
795
+ }
796
+ currentTrackX = Math.max(currentTrackX, seg.adjHead + totalGap);
797
+ }
798
+ if (currentTrackX < width - capWidth) {
799
+ trackD += getSinePath(
800
+ currentTrackX,
801
+ width - capWidth,
802
+ phase,
803
+ activeWavelength,
804
+ trackAmp
805
+ );
806
+ }
807
+ }
808
+ if (activePathRef.current)
809
+ activePathRef.current.setAttribute("d", activePathD);
810
+ if (trackPathRef.current)
811
+ trackPathRef.current.setAttribute("d", trackD.trim());
812
+ });
813
+ return /* @__PURE__ */ jsxRuntime.jsx(
814
+ "div",
815
+ {
816
+ ref: containerRef,
817
+ className: "relative w-full overflow-hidden",
818
+ style: { height: svgHeight },
819
+ children: width > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
820
+ "svg",
821
+ {
822
+ className: "absolute inset-0 w-full h-full",
823
+ style: {
824
+ overflow: "visible",
825
+ transform: isRtl ? "scaleX(-1)" : void 0
826
+ },
827
+ "aria-labelledby": titleId,
828
+ children: [
829
+ /* @__PURE__ */ jsxRuntime.jsx("title", { id: titleId, children: isDeterminate ? `Progress: ${clampedValue}%` : "Indeterminate loading progress" }),
830
+ /* @__PURE__ */ jsxRuntime.jsxs("g", { transform: `translate(0, ${svgHeight / 2})`, children: [
831
+ /* @__PURE__ */ jsxRuntime.jsx(
832
+ "path",
833
+ {
834
+ ref: trackPathRef,
835
+ fill: "none",
836
+ stroke: trackColor,
837
+ strokeWidth: trackHeight,
838
+ strokeLinecap: "round"
839
+ }
840
+ ),
841
+ /* @__PURE__ */ jsxRuntime.jsx(
842
+ "path",
843
+ {
844
+ ref: activePathRef,
845
+ fill: "none",
846
+ stroke: activeColor,
847
+ strokeWidth: trackHeight,
848
+ strokeLinecap: "round"
849
+ }
850
+ )
851
+ ] })
852
+ ]
853
+ }
854
+ )
855
+ }
856
+ );
857
+ });
858
+ var LinearProgress = React11__namespace.forwardRef(
859
+ (_a, ref) => {
860
+ var _b = _a, {
861
+ value,
862
+ shape = "flat",
863
+ trackShape,
864
+ trackHeight = 4,
865
+ amplitude,
866
+ wavelength = 40,
867
+ indeterminateWavelength = 20,
868
+ waveSpeed = 1,
869
+ crawlerSpeed = 1,
870
+ determinateAnimation = "md3",
871
+ indeterminateAnimation = "continuous",
872
+ gapSize = 4,
873
+ showStopIndicator = "auto",
874
+ color,
875
+ trackColor,
876
+ className,
877
+ "aria-label": ariaLabel
878
+ } = _b, restProps = __objRest(_b, [
879
+ "value",
880
+ "shape",
881
+ "trackShape",
882
+ "trackHeight",
883
+ "amplitude",
884
+ "wavelength",
885
+ "indeterminateWavelength",
886
+ "waveSpeed",
887
+ "crawlerSpeed",
888
+ "determinateAnimation",
889
+ "indeterminateAnimation",
890
+ "gapSize",
891
+ "showStopIndicator",
892
+ "color",
893
+ "trackColor",
894
+ "className",
895
+ "aria-label"
896
+ ]);
897
+ const isDeterminate = value !== void 0;
898
+ const clampedValue = isDeterminate ? Math.min(100, Math.max(0, value)) : 0;
899
+ const containerRef = React11__namespace.useRef(null);
900
+ const mergedRef = useMergedRef(ref, containerRef);
901
+ const [isRtl, setIsRtl] = React11__namespace.useState(false);
902
+ React11__namespace.useEffect(() => {
903
+ if (containerRef.current) {
904
+ const dir = getComputedStyle(containerRef.current).direction;
905
+ setIsRtl(dir === "rtl");
906
+ }
907
+ }, []);
908
+ const isWavy = shape === "wavy";
909
+ const resolvedTrackShape = trackShape != null ? trackShape : shape;
910
+ const effectiveAmplitude = React11__namespace.useMemo(() => amplitude != null ? amplitude : 3, [amplitude]);
911
+ const svgHeight = React11__namespace.useMemo(
912
+ () => isWavy ? trackHeight + effectiveAmplitude * 2 : trackHeight,
913
+ [isWavy, trackHeight, effectiveAmplitude]
914
+ );
915
+ const shouldShowStop = React11__namespace.useMemo(
916
+ () => isDeterminate && resolvedTrackShape === "flat" && (showStopIndicator === true || showStopIndicator === "auto" && isDeterminate),
917
+ [isDeterminate, resolvedTrackShape, showStopIndicator]
918
+ );
919
+ const stopSize = React11__namespace.useMemo(
920
+ () => Math.max(2, trackHeight > 4 ? 4 : trackHeight / 2),
921
+ [trackHeight]
922
+ );
923
+ const stopOffset = (trackHeight - stopSize) / 2;
924
+ const activeColor = color || "var(--md-sys-color-indicator-active)";
925
+ const bgTrackColor = trackColor || "var(--md-sys-color-indicator-track)";
926
+ return /* @__PURE__ */ jsxRuntime.jsx(react.LazyMotion, { features: react.domMax, strict: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
927
+ "div",
928
+ __spreadProps(__spreadValues({
929
+ ref: mergedRef,
930
+ role: "progressbar",
931
+ "aria-label": ariaLabel,
932
+ "aria-valuenow": isDeterminate ? clampedValue : void 0,
933
+ "aria-valuemin": 0,
934
+ "aria-valuemax": 100,
935
+ className: cn(
936
+ "relative flex w-full flex-col justify-center",
937
+ className
938
+ ),
939
+ style: { height: svgHeight }
940
+ }, restProps), {
941
+ children: [
942
+ isWavy ? /* @__PURE__ */ jsxRuntime.jsx(
943
+ WavyLinearTrack,
944
+ {
945
+ trackHeight,
946
+ svgHeight,
947
+ amplitude: effectiveAmplitude,
948
+ wavelength,
949
+ indeterminateWavelength,
950
+ activeColor,
951
+ trackColor: bgTrackColor,
952
+ value: isDeterminate ? clampedValue : void 0,
953
+ isRtl,
954
+ gapSize,
955
+ waveSpeed,
956
+ crawlerSpeed,
957
+ determinateAnimation,
958
+ indeterminateAnimation,
959
+ trackShape: resolvedTrackShape
960
+ }
961
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
962
+ FlatLinearTrack,
963
+ {
964
+ trackHeight,
965
+ activeColor,
966
+ trackColor: bgTrackColor,
967
+ value: isDeterminate ? clampedValue : void 0,
968
+ isRtl,
969
+ gapSize,
970
+ crawlerSpeed
971
+ }
972
+ ),
973
+ shouldShowStop && /* @__PURE__ */ jsxRuntime.jsx(
974
+ "div",
975
+ {
976
+ "aria-hidden": "true",
977
+ className: "absolute rounded-full",
978
+ style: __spreadValues({
979
+ width: stopSize,
980
+ height: stopSize,
981
+ backgroundColor: "var(--md-sys-color-indicator-stop)",
982
+ top: svgHeight / 2 - stopSize / 2
983
+ }, isRtl ? { left: stopOffset } : { right: stopOffset })
984
+ }
985
+ )
986
+ ]
987
+ })
988
+ ) });
989
+ }
990
+ );
991
+ LinearProgress.displayName = "LinearProgress";
992
+ var ProgressIndicator = React11__namespace.forwardRef((props, ref) => {
993
+ if (props.variant === "circular") {
994
+ return /* @__PURE__ */ jsxRuntime.jsx(CircularProgress, __spreadValues({ ref }, props));
995
+ }
996
+ return /* @__PURE__ */ jsxRuntime.jsx(LinearProgress, __spreadValues({ ref }, props));
997
+ });
998
+ ProgressIndicator.displayName = "ProgressIndicator";
999
+ var RippleItem = React11__namespace.memo(function RippleItem2({
1000
+ ripple,
1001
+ onDone
1002
+ }) {
1003
+ return /* @__PURE__ */ jsxRuntime.jsx(
1004
+ react.m.span,
1005
+ {
1006
+ "aria-hidden": "true",
1007
+ style: {
1008
+ position: "absolute",
1009
+ left: ripple.x - ripple.size / 2,
1010
+ top: ripple.y - ripple.size / 2,
1011
+ width: ripple.size,
1012
+ height: ripple.size,
1013
+ borderRadius: "50%",
1014
+ backgroundColor: "currentColor",
1015
+ pointerEvents: "none",
1016
+ transformOrigin: "center"
1017
+ },
1018
+ initial: { scale: 0, opacity: 0.12 },
1019
+ animate: { scale: 1, opacity: 0 },
1020
+ exit: { opacity: 0 },
1021
+ transition: {
1022
+ scale: { duration: 0.5, ease: [0.2, 0, 0, 1] },
1023
+ opacity: { duration: 0.4, ease: "easeOut", delay: 0.1 }
1024
+ },
1025
+ onAnimationComplete: () => onDone(ripple.id)
1026
+ },
1027
+ ripple.id
1028
+ );
1029
+ });
1030
+ function Ripple({
1031
+ ripples,
1032
+ onRippleDone,
1033
+ disabled = false,
1034
+ respectSystemMotion = true
1035
+ }) {
1036
+ const prefersReduced = react.useReducedMotion();
1037
+ if (disabled) return null;
1038
+ if (respectSystemMotion && prefersReduced) return null;
1039
+ return /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { children: ripples.map((r) => /* @__PURE__ */ jsxRuntime.jsx(RippleItem, { ripple: r, onDone: onRippleDone }, r.id)) });
1040
+ }
1041
+ function useRippleState(options = {}) {
1042
+ const { disabled = false } = options;
1043
+ const [ripples, setRipples] = React11__namespace.useState([]);
1044
+ const onPointerDown = React11__namespace.useCallback(
1045
+ (e) => {
1046
+ if (disabled) return;
1047
+ const rect = e.currentTarget.getBoundingClientRect();
1048
+ const x = e.clientX - rect.left;
1049
+ const y = e.clientY - rect.top;
1050
+ const rippleSize = Math.hypot(rect.width, rect.height) * 2;
1051
+ setRipples((prev) => [
1052
+ ...prev,
1053
+ { id: Date.now(), x, y, size: rippleSize }
1054
+ ]);
1055
+ },
1056
+ [disabled]
1057
+ );
1058
+ const removeRipple = React11__namespace.useCallback((id) => {
1059
+ setRipples((prev) => prev.filter((r) => r.id !== id));
1060
+ }, []);
1061
+ return { ripples, onPointerDown, removeRipple };
1062
+ }
1063
+
1064
+ // src/ui/shared/motion-tokens.ts
1065
+ var FAST_SPATIAL_SPRING = {
1066
+ type: "spring",
1067
+ stiffness: 800,
1068
+ damping: 33.94
1069
+ };
1070
+ var FAST_EFFECTS_SPRING = {
1071
+ type: "spring",
1072
+ stiffness: 3800,
1073
+ damping: 123.29
1074
+ };
1075
+ var DEFAULT_EFFECTS_SPRING = {
1076
+ type: "spring",
1077
+ stiffness: 1600,
1078
+ damping: 80
1079
+ };
1080
+
1081
+ // src/ui/shared/constants.ts
1082
+ var SPRING_TRANSITION_FAST = FAST_EFFECTS_SPRING;
1083
+ var SPRING_TRANSITION = DEFAULT_EFFECTS_SPRING;
1084
+ var ICON_SPAN_VARIANTS = {
1085
+ initial: { scale: 0.01 },
1086
+ animate: { scale: 1 },
1087
+ exit: { scale: 0.01 }
1088
+ };
1089
+ function TouchTarget() {
1090
+ return /* @__PURE__ */ jsxRuntime.jsx(
1091
+ "span",
1092
+ {
1093
+ "aria-hidden": "true",
1094
+ className: "absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 min-w-12 min-h-12 cursor-pointer pointer-events-none"
1095
+ }
1096
+ );
1097
+ }
1098
+ var BUTTON_SHAPE_MORPH_SPRING = FAST_SPATIAL_SPRING;
1099
+ var BUTTON_RADIUS_SPRING = FAST_EFFECTS_SPRING;
1100
+ var BUTTON_SIZE_TOKENS = {
1101
+ xs: {
1102
+ height: "2rem",
1103
+ // 32dp
1104
+ leadingSpace: "1rem",
1105
+ // 16dp
1106
+ trailingSpace: "1rem",
1107
+ // 16dp
1108
+ iconSize: "1.25rem",
1109
+ // 20dp
1110
+ iconLabelSpace: "0.5rem",
1111
+ // 8dp
1112
+ outlineWidth: 1,
1113
+ // 1dp
1114
+ squareShapeRadius: m3Tokens.cornerRadius.medium,
1115
+ // 12dp
1116
+ pressedShapeRadius: m3Tokens.cornerRadius.small,
1117
+ // 8dp
1118
+ roundShapeRadius: 16
1119
+ },
1120
+ sm: {
1121
+ height: "2.5rem",
1122
+ // 40dp
1123
+ leadingSpace: "1rem",
1124
+ // 16dp
1125
+ trailingSpace: "1rem",
1126
+ // 16dp
1127
+ iconSize: "1.25rem",
1128
+ // 20dp
1129
+ iconLabelSpace: "0.5rem",
1130
+ // 8dp
1131
+ outlineWidth: 1,
1132
+ // 1dp
1133
+ squareShapeRadius: m3Tokens.cornerRadius.medium,
1134
+ // 12dp
1135
+ pressedShapeRadius: m3Tokens.cornerRadius.small,
1136
+ // 8dp
1137
+ roundShapeRadius: 20
1138
+ },
1139
+ md: {
1140
+ height: "3.5rem",
1141
+ // 56dp
1142
+ leadingSpace: "1.5rem",
1143
+ // 24dp
1144
+ trailingSpace: "1.5rem",
1145
+ // 24dp
1146
+ iconSize: "1.5rem",
1147
+ // 24dp
1148
+ iconLabelSpace: "0.5rem",
1149
+ // 8dp
1150
+ outlineWidth: 1,
1151
+ // 1dp
1152
+ squareShapeRadius: m3Tokens.cornerRadius.large,
1153
+ // 16dp
1154
+ pressedShapeRadius: m3Tokens.cornerRadius.medium,
1155
+ // 12dp
1156
+ roundShapeRadius: 28
1157
+ },
1158
+ lg: {
1159
+ height: "6rem",
1160
+ // 96dp
1161
+ leadingSpace: "3rem",
1162
+ // 48dp
1163
+ trailingSpace: "3rem",
1164
+ // 48dp
1165
+ iconSize: "2rem",
1166
+ // 32dp
1167
+ iconLabelSpace: "0.75rem",
1168
+ // 12dp
1169
+ outlineWidth: 2,
1170
+ // 2dp
1171
+ squareShapeRadius: m3Tokens.cornerRadius.extraLarge,
1172
+ // 28dp
1173
+ pressedShapeRadius: m3Tokens.cornerRadius.large,
1174
+ // 16dp
1175
+ roundShapeRadius: 48
1176
+ },
1177
+ xl: {
1178
+ height: "8.5rem",
1179
+ // 136dp
1180
+ leadingSpace: "4rem",
1181
+ // 64dp
1182
+ trailingSpace: "4rem",
1183
+ // 64dp
1184
+ iconSize: "2.5rem",
1185
+ // 40dp
1186
+ iconLabelSpace: "1rem",
1187
+ // 16dp
1188
+ outlineWidth: 3,
1189
+ // 3dp
1190
+ squareShapeRadius: m3Tokens.cornerRadius.extraLarge,
1191
+ // 28dp
1192
+ pressedShapeRadius: m3Tokens.cornerRadius.large,
1193
+ // 16dp
1194
+ roundShapeRadius: 68
1195
+ }
1196
+ };
1197
+ var BUTTON_TYPOGRAPHY_TOKENS = {
1198
+ xs: "text-sm font-medium tracking-wide",
1199
+ // labelLarge
1200
+ sm: "text-sm font-medium tracking-wide",
1201
+ // labelLarge
1202
+ md: "text-base font-medium",
1203
+ // titleMedium
1204
+ lg: "text-xl font-normal",
1205
+ // headlineSmall
1206
+ xl: "text-[2rem] font-normal leading-none"
1207
+ // headlineLarge
1208
+ };
1209
+ var BUTTON_COLOR_TOKENS = {
1210
+ elevated: {
1211
+ default: "bg-m3-surface-container-low text-m3-primary shadow-md",
1212
+ selected: "bg-m3-primary text-m3-on-primary shadow-md",
1213
+ unselected: "bg-m3-surface-container-low text-m3-primary shadow-md"
1214
+ },
1215
+ filled: {
1216
+ default: "bg-m3-primary text-m3-on-primary",
1217
+ selected: "bg-m3-primary text-m3-on-primary",
1218
+ unselected: "bg-m3-surface-container text-m3-on-surface-variant"
1219
+ },
1220
+ tonal: {
1221
+ default: "bg-m3-secondary-container text-m3-on-secondary-container",
1222
+ selected: "bg-m3-secondary text-m3-on-secondary",
1223
+ unselected: "bg-m3-secondary-container text-m3-on-secondary-container"
1224
+ },
1225
+ outlined: {
1226
+ default: "bg-transparent text-m3-on-surface-variant border-m3-outline-variant",
1227
+ selected: "bg-m3-inverse-surface text-m3-inverse-on-surface border-transparent",
1228
+ unselected: "bg-transparent text-m3-on-surface-variant border-m3-outline-variant"
1229
+ },
1230
+ text: {
1231
+ default: "bg-transparent text-m3-primary",
1232
+ selected: "bg-transparent text-m3-primary",
1233
+ unselected: "bg-transparent text-m3-primary"
1234
+ }
1235
+ };
1236
+ var MOTION_PROP_KEYS = [
1237
+ "animate",
1238
+ "exit",
1239
+ "initial",
1240
+ "transition",
1241
+ "variants",
1242
+ "whileHover",
1243
+ "whileTap",
1244
+ "whileFocus",
1245
+ "whileDrag",
1246
+ "whileInView",
1247
+ "onAnimationStart",
1248
+ "onAnimationComplete",
1249
+ "onUpdate",
1250
+ "onDragStart",
1251
+ "onDragEnd",
1252
+ "onDrag",
1253
+ "onDirectionLock",
1254
+ "onDragTransitionEnd",
1255
+ "layout",
1256
+ "layoutId",
1257
+ "onLayoutAnimationComplete"
1258
+ ];
1259
+ function springAnimate(value, to) {
1260
+ return react.animate(value, to, __spreadProps(__spreadValues({}, BUTTON_RADIUS_SPRING), { type: "spring" }));
1261
+ }
1262
+ function AnimatedIconSlot({
1263
+ iconSize,
1264
+ children,
1265
+ ariaHidden,
1266
+ transition
1267
+ }) {
1268
+ return /* @__PURE__ */ jsxRuntime.jsx(
1269
+ react.m.span,
1270
+ {
1271
+ layout: "position",
1272
+ initial: { width: 0, opacity: 0, scale: 0.5 },
1273
+ animate: { width: iconSize, opacity: 1, scale: 1 },
1274
+ exit: { width: 0, opacity: 0, scale: 0.5 },
1275
+ transition,
1276
+ "aria-hidden": ariaHidden ? "true" : void 0,
1277
+ style: { height: iconSize },
1278
+ className: cn(
1279
+ "flex items-center justify-center shrink-0 [&>svg]:w-full [&>svg]:h-full overflow-hidden"
1280
+ ),
1281
+ children
1282
+ }
1283
+ );
1284
+ }
1285
+ var ButtonComponent = React11__namespace.forwardRef(
1286
+ (_a, ref) => {
1287
+ var _b = _a, {
1288
+ className,
1289
+ style,
1290
+ variant = "default",
1291
+ colorStyle = "filled",
1292
+ selectedColorStyle: _selectedColorStyle,
1293
+ size: size = "sm",
1294
+ shape = "round",
1295
+ selected,
1296
+ icon,
1297
+ iconPosition = "leading",
1298
+ loading = false,
1299
+ loadingVariant = "loading-indicator",
1300
+ asChild = false,
1301
+ outlineWidth,
1302
+ children,
1303
+ onClick,
1304
+ onKeyDown,
1305
+ "aria-label": ariaLabelProp,
1306
+ transition: customTransition
1307
+ } = _b, restProps = __objRest(_b, [
1308
+ "className",
1309
+ "style",
1310
+ "variant",
1311
+ "colorStyle",
1312
+ "selectedColorStyle",
1313
+ // Deprecated — destructured to strip from restProps
1314
+ "size",
1315
+ "shape",
1316
+ "selected",
1317
+ "icon",
1318
+ "iconPosition",
1319
+ "loading",
1320
+ "loadingVariant",
1321
+ "asChild",
1322
+ "outlineWidth",
1323
+ "children",
1324
+ "onClick",
1325
+ "onKeyDown",
1326
+ "aria-label",
1327
+ "transition"
1328
+ ]);
1329
+ var _a2, _b2;
1330
+ const isToggle = variant === "toggle";
1331
+ const isSelected = isToggle ? !!selected : false;
1332
+ const effectiveShape = isSelected ? shape === "round" ? "square" : "round" : shape;
1333
+ const sizeTokens = (_a2 = BUTTON_SIZE_TOKENS[size]) != null ? _a2 : BUTTON_SIZE_TOKENS.sm;
1334
+ const animateRadius = effectiveShape === "round" ? sizeTokens.roundShapeRadius : sizeTokens.squareShapeRadius;
1335
+ const pressedRadius = sizeTokens.pressedShapeRadius;
1336
+ const colorState = isToggle ? isSelected ? "selected" : "unselected" : "default";
1337
+ const colorClass = BUTTON_COLOR_TOKENS[colorStyle][colorState];
1338
+ const typographyClass = (_b2 = BUTTON_TYPOGRAPHY_TOKENS[size]) != null ? _b2 : BUTTON_TYPOGRAPHY_TOKENS.sm;
1339
+ const mergedStyle = __spreadValues({
1340
+ height: sizeTokens.height,
1341
+ paddingInlineStart: sizeTokens.leadingSpace,
1342
+ paddingInlineEnd: sizeTokens.trailingSpace,
1343
+ gap: sizeTokens.iconLabelSpace,
1344
+ borderWidth: outlineWidth != null ? outlineWidth : colorStyle === "outlined" ? sizeTokens.outlineWidth : 0,
1345
+ borderStyle: colorStyle === "outlined" ? "solid" : void 0
1346
+ }, style);
1347
+ const labelText = React11__namespace.useMemo(() => {
1348
+ if (asChild) {
1349
+ const child = React11__namespace.Children.only(children);
1350
+ return child.props.children;
1351
+ }
1352
+ return children;
1353
+ }, [children, asChild]);
1354
+ const computedAriaLabel = ariaLabelProp || (typeof children === "string" ? children : void 0);
1355
+ const needsTouchTarget = size === "xs" || size === "sm";
1356
+ const motionRadius = react.useMotionValue(animateRadius);
1357
+ const asChildRef = React11__namespace.useRef(null);
1358
+ const mergedRef = React11__namespace.useCallback(
1359
+ (node) => {
1360
+ asChildRef.current = node;
1361
+ if (typeof ref === "function") ref(node);
1362
+ else if (ref)
1363
+ ref.current = node;
1364
+ },
1365
+ [ref]
1366
+ );
1367
+ React11__namespace.useEffect(() => {
1368
+ if (!asChild) return;
1369
+ return motionRadius.on("change", (v) => {
1370
+ if (asChildRef.current)
1371
+ asChildRef.current.style.borderRadius = `${v}px`;
1372
+ });
1373
+ }, [motionRadius, asChild]);
1374
+ React11__namespace.useEffect(() => {
1375
+ if (!asChild) return;
1376
+ const controls = springAnimate(motionRadius, animateRadius);
1377
+ return () => controls.stop();
1378
+ }, [animateRadius, motionRadius, asChild]);
1379
+ const { ripples, onPointerDown, removeRipple } = useRippleState({
1380
+ disabled: loading
1381
+ });
1382
+ const handleClick = React11__namespace.useCallback(
1383
+ (e) => {
1384
+ if (loading) return e.preventDefault();
1385
+ onClick == null ? void 0 : onClick(e);
1386
+ },
1387
+ [loading, onClick]
1388
+ );
1389
+ const handleKeyDown = React11__namespace.useCallback(
1390
+ (e) => {
1391
+ if (loading) return;
1392
+ if (onClick && (e.key === "Enter" || e.key === " ")) {
1393
+ e.preventDefault();
1394
+ e.currentTarget.click();
1395
+ }
1396
+ onKeyDown == null ? void 0 : onKeyDown(e);
1397
+ },
1398
+ [loading, onClick, onKeyDown]
1399
+ );
1400
+ const buttonClassName = cn(
1401
+ "relative w-fit shrink-0 inline-flex flex-row items-center justify-center",
1402
+ "whitespace-nowrap select-none cursor-pointer",
1403
+ "transition-[background-color,color,border-color,box-shadow,opacity,filter] duration-200",
1404
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-m3-primary focus-visible:ring-offset-2",
1405
+ "disabled:pointer-events-none disabled:opacity-[0.38] disabled:shadow-none",
1406
+ colorClass,
1407
+ "overflow-hidden",
1408
+ typographyClass,
1409
+ loading && "pointer-events-none opacity-75 cursor-not-allowed",
1410
+ className
1411
+ );
1412
+ const sharedTransition = customTransition != null ? customTransition : {
1413
+ borderRadius: BUTTON_RADIUS_SPRING,
1414
+ layout: BUTTON_SHAPE_MORPH_SPRING,
1415
+ default: SPRING_TRANSITION
1416
+ };
1417
+ const innerContent = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1418
+ needsTouchTarget && /* @__PURE__ */ jsxRuntime.jsx(TouchTarget, {}),
1419
+ /* @__PURE__ */ jsxRuntime.jsx(Ripple, { ripples, onRippleDone: removeRipple }),
1420
+ /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { initial: false, mode: "popLayout", children: (loading || icon && iconPosition === "leading") && /* @__PURE__ */ jsxRuntime.jsx(
1421
+ AnimatedIconSlot,
1422
+ {
1423
+ iconSize: sizeTokens.iconSize,
1424
+ ariaHidden: !loading,
1425
+ transition: sharedTransition,
1426
+ children: loading ? loadingVariant === "loading-indicator" ? /* @__PURE__ */ jsxRuntime.jsx(
1427
+ LoadingIndicator,
1428
+ {
1429
+ size: parseFloat(sizeTokens.iconSize) * 16,
1430
+ color: "currentColor",
1431
+ "aria-label": "Loading"
1432
+ }
1433
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
1434
+ ProgressIndicator,
1435
+ {
1436
+ variant: "circular",
1437
+ size: parseFloat(sizeTokens.iconSize) * 16,
1438
+ color: "currentColor",
1439
+ trackColor: "transparent",
1440
+ "aria-label": "Loading"
1441
+ }
1442
+ ) : icon
1443
+ }
1444
+ ) }),
1445
+ labelText && /* @__PURE__ */ jsxRuntime.jsx(
1446
+ react.m.span,
1447
+ {
1448
+ layout: "position",
1449
+ className: "inline-flex items-center h-full gap-[inherit]",
1450
+ transition: sharedTransition,
1451
+ children: labelText
1452
+ }
1453
+ ),
1454
+ /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { initial: false, mode: "popLayout", children: icon && iconPosition === "trailing" && /* @__PURE__ */ jsxRuntime.jsx(
1455
+ AnimatedIconSlot,
1456
+ {
1457
+ iconSize: sizeTokens.iconSize,
1458
+ ariaHidden: true,
1459
+ transition: sharedTransition,
1460
+ children: icon
1461
+ }
1462
+ ) })
1463
+ ] });
1464
+ const handleAsChildPointerDown = React11__namespace.useCallback(
1465
+ (e) => {
1466
+ springAnimate(motionRadius, pressedRadius);
1467
+ onPointerDown == null ? void 0 : onPointerDown(e);
1468
+ },
1469
+ [motionRadius, pressedRadius, onPointerDown]
1470
+ );
1471
+ const handleAsChildPointerUp = React11__namespace.useCallback(() => {
1472
+ springAnimate(motionRadius, animateRadius);
1473
+ }, [motionRadius, animateRadius]);
1474
+ const handlePointerDown = React11__namespace.useCallback(
1475
+ (e) => {
1476
+ onPointerDown(e);
1477
+ },
1478
+ [onPointerDown]
1479
+ );
1480
+ if (asChild) {
1481
+ const strippedProps = __spreadValues({}, restProps);
1482
+ for (const key of MOTION_PROP_KEYS) delete strippedProps[key];
1483
+ const htmlProps = strippedProps;
1484
+ const child = React11__namespace.Children.only(children);
1485
+ return /* @__PURE__ */ jsxRuntime.jsx(react.LazyMotion, { features: react.domMax, strict: true, children: /* @__PURE__ */ jsxRuntime.jsx(
1486
+ reactSlot.Slot,
1487
+ __spreadProps(__spreadValues({
1488
+ ref: mergedRef,
1489
+ "aria-label": computedAriaLabel,
1490
+ onClick: handleClick,
1491
+ onPointerDown: handleAsChildPointerDown,
1492
+ onPointerUp: handleAsChildPointerUp,
1493
+ onPointerLeave: handleAsChildPointerUp,
1494
+ onPointerCancel: handleAsChildPointerUp,
1495
+ onKeyDown: handleKeyDown,
1496
+ style: __spreadProps(__spreadValues({}, mergedStyle), {
1497
+ borderRadius: `${animateRadius}px`
1498
+ }),
1499
+ className: buttonClassName
1500
+ }, htmlProps), {
1501
+ children: React11__namespace.cloneElement(child, { children: innerContent })
1502
+ })
1503
+ ) });
1504
+ }
1505
+ return /* @__PURE__ */ jsxRuntime.jsx(react.LazyMotion, { features: react.domMax, strict: true, children: /* @__PURE__ */ jsxRuntime.jsx(
1506
+ react.m.button,
1507
+ __spreadProps(__spreadValues({
1508
+ ref,
1509
+ layout: true,
1510
+ type: "button",
1511
+ "aria-pressed": isToggle ? isSelected : void 0,
1512
+ "aria-label": computedAriaLabel,
1513
+ "aria-busy": loading ? true : void 0,
1514
+ "aria-disabled": loading ? true : restProps.disabled,
1515
+ onClick: handleClick,
1516
+ onPointerDown: handlePointerDown,
1517
+ onKeyDown: handleKeyDown,
1518
+ style: mergedStyle,
1519
+ animate: { borderRadius: animateRadius },
1520
+ whileTap: { borderRadius: pressedRadius },
1521
+ transition: sharedTransition,
1522
+ className: buttonClassName
1523
+ }, restProps), {
1524
+ children: innerContent
1525
+ })
1526
+ ) });
1527
+ }
1528
+ );
1529
+ ButtonComponent.displayName = "Button";
1530
+ var Button = React11__namespace.memo(ButtonComponent);
1531
+ var VARIANT_FONT = {
1532
+ outlined: "'Material Symbols Outlined'",
1533
+ rounded: "'Material Symbols Rounded'",
1534
+ sharp: "'Material Symbols Sharp'"
1535
+ };
1536
+ var IconComponent = React11__namespace.forwardRef(
1537
+ (_a, ref) => {
1538
+ var _b = _a, {
1539
+ name,
1540
+ variant = "outlined",
1541
+ fill = 0,
1542
+ weight = 400,
1543
+ grade = 0,
1544
+ opticalSize = 24,
1545
+ size,
1546
+ animateFill = false,
1547
+ className,
1548
+ style
1549
+ } = _b, restProps = __objRest(_b, [
1550
+ "name",
1551
+ "variant",
1552
+ "fill",
1553
+ "weight",
1554
+ "grade",
1555
+ "opticalSize",
1556
+ "size",
1557
+ "animateFill",
1558
+ "className",
1559
+ "style"
1560
+ ]);
1561
+ const fontVariationSettings = `'FILL' ${fill}, 'wght' ${weight}, 'GRAD' ${grade}, 'opsz' ${opticalSize}`;
1562
+ const computedStyle = __spreadValues({
1563
+ fontFamily: VARIANT_FONT[variant],
1564
+ fontSize: size === "inherit" ? "inherit" : size != null ? `${size}px` : `${opticalSize}px`,
1565
+ fontVariationSettings
1566
+ }, style);
1567
+ if (animateFill) {
1568
+ return /* @__PURE__ */ jsxRuntime.jsx(react.LazyMotion, { features: react.domMax, strict: true, children: /* @__PURE__ */ jsxRuntime.jsx(
1569
+ react.m.span,
1570
+ __spreadProps(__spreadValues({
1571
+ ref,
1572
+ className: cn(
1573
+ "md-icon inline-flex items-center justify-center shrink-0 select-none",
1574
+ className
1575
+ ),
1576
+ "aria-hidden": "true",
1577
+ animate: { fontVariationSettings },
1578
+ transition: SPRING_TRANSITION_FAST,
1579
+ style: computedStyle
1580
+ }, restProps), {
1581
+ children: name
1582
+ })
1583
+ ) });
1584
+ }
1585
+ return /* @__PURE__ */ jsxRuntime.jsx(
1586
+ "span",
1587
+ __spreadProps(__spreadValues({
1588
+ ref,
1589
+ className: cn(
1590
+ "md-icon inline-flex items-center justify-center shrink-0 select-none",
1591
+ className
1592
+ ),
1593
+ "aria-hidden": "true",
1594
+ style: computedStyle
1595
+ }, restProps), {
1596
+ children: name
1597
+ })
1598
+ );
1599
+ }
1600
+ );
1601
+ IconComponent.displayName = "Icon";
1602
+ var Icon = React11__namespace.memo(IconComponent);
1603
+ var BUTTON_GROUP_TOKENS = {
1604
+ standard: {
1605
+ betweenSpace: 12,
1606
+ // 12dp / 0.75rem / gap-3
1607
+ containerHeight: 40
1608
+ // 40dp / 2.5rem
1609
+ },
1610
+ connected: {
1611
+ betweenSpace: 2,
1612
+ // 2dp / 0.125rem / gap-0.5
1613
+ containerHeight: 40,
1614
+ // 40dp / 2.5rem
1615
+ containerShape: m3Tokens.cornerRadius.full,
1616
+ // 9999px
1617
+ innerCorner: m3Tokens.cornerRadius.small,
1618
+ // 8dp
1619
+ pressedInnerCorner: m3Tokens.cornerRadius.extraSmall,
1620
+ // 4dp
1621
+ selectedCornerPercent: 50
1622
+ // 50% -> full pill
1623
+ }
1624
+ };
1625
+
1626
+ // src/ui/buttons/button-group/button-group-defaults.ts
1627
+ var PILL_RADIUS_MAP = {
1628
+ xs: 16,
1629
+ sm: 20,
1630
+ md: 28,
1631
+ lg: 48,
1632
+ xl: 68
1633
+ };
1634
+ var PRESSED_RADIUS_MAP = {
1635
+ xs: 8,
1636
+ sm: 10,
1637
+ md: 16,
1638
+ lg: 28,
1639
+ xl: 40
1640
+ };
1641
+ var PILL_CORNERS = {
1642
+ tl: 9999,
1643
+ tr: 9999,
1644
+ br: 9999,
1645
+ bl: 9999
1646
+ };
1647
+ function buildConnectedShapes(size, defaultCorners, pressedCorners) {
1648
+ const outer = PILL_RADIUS_MAP[size];
1649
+ const inner = BUTTON_GROUP_TOKENS.connected.innerCorner;
1650
+ const pressedInner = BUTTON_GROUP_TOKENS.connected.pressedInnerCorner;
1651
+ return {
1652
+ default: defaultCorners(outer, inner),
1653
+ pressed: pressedCorners(outer, pressedInner),
1654
+ checked: __spreadValues({}, PILL_CORNERS)
1655
+ };
1656
+ }
1657
+ var ButtonGroupDefaults = {
1658
+ expandedRatio: 0.15,
1659
+ connectedLeadingButtonShapes: (size) => buildConnectedShapes(
1660
+ size,
1661
+ (o, i) => ({ tl: o, tr: i, br: i, bl: o }),
1662
+ (o, pi) => ({ tl: o, tr: pi, br: pi, bl: o })
1663
+ ),
1664
+ connectedMiddleButtonShapes: (size) => buildConnectedShapes(
1665
+ size,
1666
+ (_o, i) => ({ tl: i, tr: i, br: i, bl: i }),
1667
+ (_o, pi) => ({ tl: pi, tr: pi, br: pi, bl: pi })
1668
+ ),
1669
+ connectedTrailingButtonShapes: (size) => buildConnectedShapes(
1670
+ size,
1671
+ (o, i) => ({ tl: i, tr: o, br: o, bl: i }),
1672
+ (o, pi) => ({ tl: pi, tr: o, br: o, bl: pi })
1673
+ ),
1674
+ /** For orientation="vertical". */
1675
+ connectedTopButtonShapes: (size) => buildConnectedShapes(
1676
+ size,
1677
+ (o, i) => ({ tl: o, tr: o, br: i, bl: i }),
1678
+ (o, pi) => ({ tl: o, tr: o, br: pi, bl: pi })
1679
+ ),
1680
+ connectedBottomButtonShapes: (size) => buildConnectedShapes(
1681
+ size,
1682
+ (o, i) => ({ tl: i, tr: i, br: o, bl: o }),
1683
+ (o, pi) => ({ tl: pi, tr: pi, br: o, bl: o })
1684
+ )
1685
+ };
1686
+ var PILL_BORDER_RADIUS = 9999;
1687
+ var MIN_FLEX_GROW = 0.01;
1688
+ var PADDING_EXPAND_MULTIPLIER = 4;
1689
+ var CHECK_ICON_SIZE = 24;
1690
+ var CHECK_ICON = /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "check", size: CHECK_ICON_SIZE, weight: 700 });
1691
+ var CHECK_ICON_GAP_MAP = {
1692
+ xs: 6,
1693
+ sm: 8,
1694
+ md: 8,
1695
+ lg: 12,
1696
+ xl: 12
1697
+ };
1698
+ var CHECK_ICON_MOTION = {
1699
+ type: "spring",
1700
+ stiffness: 420,
1701
+ damping: 34,
1702
+ mass: 0.75
1703
+ };
1704
+ var WIDTH_MORPH_SPRING = {
1705
+ type: "spring",
1706
+ stiffness: 360,
1707
+ damping: 38,
1708
+ mass: 0.85
1709
+ };
1710
+ var NAVBAR_EXPRESSIVE_SPRING = {
1711
+ type: "spring",
1712
+ stiffness: 430,
1713
+ damping: 38,
1714
+ mass: 0.8
1715
+ };
1716
+ var AnimatedCheckLabel = React11__namespace.memo(function AnimatedCheckLabel2({
1717
+ selected,
1718
+ size,
1719
+ children
1720
+ }) {
1721
+ var _a;
1722
+ const gap = (_a = CHECK_ICON_GAP_MAP[size]) != null ? _a : CHECK_ICON_GAP_MAP.sm;
1723
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1724
+ react.m.span,
1725
+ {
1726
+ layout: true,
1727
+ className: "inline-flex min-w-0 items-center justify-center whitespace-nowrap align-middle",
1728
+ children: [
1729
+ /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { initial: false, children: selected && /* @__PURE__ */ jsxRuntime.jsx(
1730
+ react.m.span,
1731
+ {
1732
+ "aria-hidden": "true",
1733
+ initial: { width: 0, opacity: 0, marginRight: 0, x: -4 },
1734
+ animate: {
1735
+ width: CHECK_ICON_SIZE,
1736
+ opacity: 1,
1737
+ marginRight: gap,
1738
+ x: 0
1739
+ },
1740
+ exit: { width: 0, opacity: 0, marginRight: 0, x: -4 },
1741
+ transition: CHECK_ICON_MOTION,
1742
+ className: "inline-flex shrink-0 items-center justify-center overflow-hidden",
1743
+ style: { willChange: "width, opacity, transform, margin-right" },
1744
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex h-6 w-6 items-center justify-center", children: CHECK_ICON })
1745
+ },
1746
+ "selected-check"
1747
+ ) }),
1748
+ /* @__PURE__ */ jsxRuntime.jsx(react.m.span, { layout: "position", className: "min-w-0 truncate", children })
1749
+ ]
1750
+ }
1751
+ );
1752
+ });
1753
+ var AnimatedNavbarLabel = React11__namespace.memo(function AnimatedNavbarLabel2({
1754
+ show,
1755
+ children
1756
+ }) {
1757
+ return /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { initial: false, mode: "popLayout", children: show && /* @__PURE__ */ jsxRuntime.jsx(
1758
+ react.m.span,
1759
+ {
1760
+ initial: { width: 0, opacity: 0, scale: 0.8 },
1761
+ animate: { width: "auto", opacity: 1, scale: 1 },
1762
+ exit: { width: 0, opacity: 0, scale: 0.8 },
1763
+ transition: NAVBAR_EXPRESSIVE_SPRING,
1764
+ className: "overflow-hidden whitespace-nowrap text-sm font-semibold tracking-[0.01em] ml-1.5",
1765
+ children
1766
+ },
1767
+ "navbar-label"
1768
+ ) });
1769
+ });
1770
+ function resolveConnectedShapes(variant, orientation, isFirst, isLast, itemSize) {
1771
+ const defaults = ButtonGroupDefaults.connectedLeadingButtonShapes(itemSize);
1772
+ if (variant !== "connected") return defaults;
1773
+ if (orientation === "horizontal") {
1774
+ if (isFirst && !isLast)
1775
+ return ButtonGroupDefaults.connectedLeadingButtonShapes(itemSize);
1776
+ if (!isFirst && isLast)
1777
+ return ButtonGroupDefaults.connectedTrailingButtonShapes(itemSize);
1778
+ if (!isFirst && !isLast)
1779
+ return ButtonGroupDefaults.connectedMiddleButtonShapes(itemSize);
1780
+ } else {
1781
+ if (isFirst && !isLast)
1782
+ return ButtonGroupDefaults.connectedTopButtonShapes(itemSize);
1783
+ if (!isFirst && isLast)
1784
+ return ButtonGroupDefaults.connectedBottomButtonShapes(itemSize);
1785
+ if (!isFirst && !isLast)
1786
+ return ButtonGroupDefaults.connectedMiddleButtonShapes(itemSize);
1787
+ }
1788
+ return defaults;
1789
+ }
1790
+ function resolveIconAndLabel(element, isSelected, itemSize, variant, showCheck, iconBehavior, labelBehavior) {
1791
+ let icon = element.props.icon;
1792
+ let label = element.props.children;
1793
+ const animateCheckInLabel = showCheck && iconBehavior !== "none" && iconBehavior !== "selected" && label !== void 0;
1794
+ if (iconBehavior === "none" || animateCheckInLabel) {
1795
+ icon = void 0;
1796
+ } else if (iconBehavior === "selected") {
1797
+ icon = isSelected ? element.props.icon : void 0;
1798
+ }
1799
+ if (labelBehavior === "none") {
1800
+ label = void 0;
1801
+ } else if (labelBehavior === "selected") {
1802
+ label = isSelected ? element.props.children : void 0;
1803
+ }
1804
+ if (animateCheckInLabel && label !== void 0) {
1805
+ label = /* @__PURE__ */ jsxRuntime.jsx(AnimatedCheckLabel, { selected: isSelected, size: itemSize, children: label });
1806
+ } else if (variant === "navbar" && label !== void 0) {
1807
+ const showLabel = !labelBehavior || labelBehavior === "all" || labelBehavior === "selected" && isSelected;
1808
+ label = /* @__PURE__ */ jsxRuntime.jsx(AnimatedNavbarLabel, { show: showLabel, children: label });
1809
+ }
1810
+ return { icon, label };
1811
+ }
1812
+ function resolveFlexTargets(variant, orientation, isSelected, isPressed, hasSelected, count, fullWidth, activeMorphing, morphingWidth, expandedRatio, basePx) {
1813
+ const increment = expandedRatio * PADDING_EXPAND_MULTIPLIER;
1814
+ if (activeMorphing) {
1815
+ const isFlexLayout = fullWidth || variant === "connected" && orientation === "horizontal";
1816
+ if (isFlexLayout) {
1817
+ if (isSelected) return { flexGrow: 1 + expandedRatio };
1818
+ if (hasSelected && count > 1)
1819
+ return {
1820
+ flexGrow: Math.max(MIN_FLEX_GROW, 1 - expandedRatio / (count - 1))
1821
+ };
1822
+ return { flexGrow: 1 };
1823
+ }
1824
+ if (isSelected)
1825
+ return { paddingInline: `calc(${basePx} + ${increment}rem)` };
1826
+ if (hasSelected && count > 1) {
1827
+ const decrement = increment / (count - 1);
1828
+ return { paddingInline: `calc(${basePx} - ${decrement}rem)` };
1829
+ }
1830
+ return { paddingInline: basePx };
1831
+ }
1832
+ if (morphingWidth && variant === "standard") {
1833
+ if (fullWidth) return { flexGrow: isPressed ? 1 + expandedRatio : 1 };
1834
+ return {
1835
+ paddingInline: isPressed ? `calc(${basePx} + ${increment}rem)` : basePx
1836
+ };
1837
+ }
1838
+ return {};
1839
+ }
1840
+ function buildMotionProps(variant, isSelected, isPressed, itemSize, shapes, flex, existingAnimate, existingWhileTap) {
1841
+ var _a, _b;
1842
+ const props = { animate: __spreadValues({}, existingAnimate) };
1843
+ if (variant !== "navbar") {
1844
+ if (flex.flexGrow !== void 0) {
1845
+ props.animate.flexGrow = flex.flexGrow;
1846
+ }
1847
+ if (flex.paddingInline !== void 0) {
1848
+ props.animate.paddingInline = flex.paddingInline;
1849
+ }
1850
+ }
1851
+ if (variant === "standard") {
1852
+ const pressedRadius = (_a = PRESSED_RADIUS_MAP[itemSize]) != null ? _a : PRESSED_RADIUS_MAP.sm;
1853
+ const itemSizeTokens = (_b = BUTTON_SIZE_TOKENS[itemSize]) != null ? _b : BUTTON_SIZE_TOKENS.sm;
1854
+ const isSquish = isSelected || isPressed;
1855
+ props.animate.borderRadius = isSquish ? pressedRadius : itemSizeTokens.roundShapeRadius;
1856
+ props.whileTap = __spreadValues({
1857
+ scale: 0.98
1858
+ }, existingWhileTap);
1859
+ props.transition = {
1860
+ borderRadius: BUTTON_RADIUS_SPRING,
1861
+ flexGrow: WIDTH_MORPH_SPRING,
1862
+ paddingInline: WIDTH_MORPH_SPRING,
1863
+ layout: WIDTH_MORPH_SPRING,
1864
+ default: BUTTON_SHAPE_MORPH_SPRING
1865
+ };
1866
+ props.layout = true;
1867
+ }
1868
+ if (variant === "connected") {
1869
+ const { tl, tr, br, bl } = isSelected ? {
1870
+ tl: PILL_BORDER_RADIUS,
1871
+ tr: PILL_BORDER_RADIUS,
1872
+ br: PILL_BORDER_RADIUS,
1873
+ bl: PILL_BORDER_RADIUS
1874
+ } : shapes.default;
1875
+ props.animate = __spreadProps(__spreadValues({}, props.animate), {
1876
+ borderRadius: void 0,
1877
+ borderTopLeftRadius: tl,
1878
+ borderTopRightRadius: tr,
1879
+ borderBottomRightRadius: br,
1880
+ borderBottomLeftRadius: bl
1881
+ });
1882
+ props.whileTap = __spreadValues({
1883
+ borderRadius: void 0,
1884
+ borderTopLeftRadius: shapes.pressed.tl,
1885
+ borderTopRightRadius: shapes.pressed.tr,
1886
+ borderBottomRightRadius: shapes.pressed.br,
1887
+ borderBottomLeftRadius: shapes.pressed.bl
1888
+ }, existingWhileTap);
1889
+ props.transition = __spreadProps(__spreadValues({}, BUTTON_SHAPE_MORPH_SPRING), {
1890
+ flexGrow: WIDTH_MORPH_SPRING,
1891
+ paddingInline: WIDTH_MORPH_SPRING,
1892
+ borderTopLeftRadius: BUTTON_RADIUS_SPRING,
1893
+ borderTopRightRadius: BUTTON_RADIUS_SPRING,
1894
+ borderBottomRightRadius: BUTTON_RADIUS_SPRING,
1895
+ borderBottomLeftRadius: BUTTON_RADIUS_SPRING,
1896
+ layout: WIDTH_MORPH_SPRING
1897
+ });
1898
+ props.layout = true;
1899
+ }
1900
+ if (variant === "navbar") {
1901
+ props.layout = true;
1902
+ props.transition = {
1903
+ layout: WIDTH_MORPH_SPRING,
1904
+ default: BUTTON_SHAPE_MORPH_SPRING
1905
+ };
1906
+ }
1907
+ return props;
1908
+ }
1909
+ var ButtonGroupComponent = React11__namespace.forwardRef(
1910
+ (_a, ref) => {
1911
+ var _b = _a, {
1912
+ className,
1913
+ variant = "standard",
1914
+ orientation = "horizontal",
1915
+ fullWidth = false,
1916
+ size,
1917
+ morphingWidth = true,
1918
+ activeMorphing = false,
1919
+ itemClassName,
1920
+ expandedRatio = ButtonGroupDefaults.expandedRatio,
1921
+ showCheck = false,
1922
+ children,
1923
+ iconBehavior,
1924
+ labelBehavior,
1925
+ style
1926
+ } = _b, props = __objRest(_b, [
1927
+ "className",
1928
+ "variant",
1929
+ "orientation",
1930
+ "fullWidth",
1931
+ "size",
1932
+ "morphingWidth",
1933
+ "activeMorphing",
1934
+ "itemClassName",
1935
+ "expandedRatio",
1936
+ "showCheck",
1937
+ "children",
1938
+ "iconBehavior",
1939
+ "labelBehavior",
1940
+ "style"
1941
+ ]);
1942
+ const [pressedIndex, setPressedIndex] = React11__namespace.useState(null);
1943
+ const [lockedGroupSize, setLockedGroupSize] = React11__namespace.useState(
1944
+ null
1945
+ );
1946
+ const layoutIdGroup = React11__namespace.useId();
1947
+ const rootRef = React11__namespace.useRef(null);
1948
+ const setRootRef = React11__namespace.useCallback(
1949
+ (node) => {
1950
+ rootRef.current = node;
1951
+ if (typeof ref === "function") {
1952
+ ref(node);
1953
+ } else if (ref) {
1954
+ ref.current = node;
1955
+ }
1956
+ },
1957
+ [ref]
1958
+ );
1959
+ const childrenArray = React11__namespace.useMemo(
1960
+ () => React11__namespace.Children.toArray(children).filter(React11__namespace.isValidElement),
1961
+ [children]
1962
+ );
1963
+ const count = childrenArray.length;
1964
+ const groupSizeSignature = React11__namespace.useMemo(
1965
+ () => `${childrenArray.map((child, index) => {
1966
+ var _a2, _b2, _c, _d, _e;
1967
+ const element = child;
1968
+ const label = typeof element.props.children === "string" || typeof element.props.children === "number" ? element.props.children : (_a2 = element.key) != null ? _a2 : index;
1969
+ return [
1970
+ (_b2 = element.key) != null ? _b2 : index,
1971
+ (_d = (_c = element.props.size) != null ? _c : size) != null ? _d : "",
1972
+ label,
1973
+ Boolean(element.props.icon),
1974
+ (_e = element.props.className) != null ? _e : ""
1975
+ ].join(":");
1976
+ }).join("|")}|${variant}|${orientation}|${showCheck}`,
1977
+ [childrenArray, orientation, showCheck, size, variant]
1978
+ );
1979
+ const groupSizeSignatureRef = React11__namespace.useRef(groupSizeSignature);
1980
+ React11__namespace.useLayoutEffect(() => {
1981
+ if (groupSizeSignatureRef.current !== groupSizeSignature) {
1982
+ groupSizeSignatureRef.current = groupSizeSignature;
1983
+ setLockedGroupSize(null);
1984
+ }
1985
+ }, [groupSizeSignature]);
1986
+ const hasExplicitGroupSize = orientation === "horizontal" ? (style == null ? void 0 : style.width) !== void 0 || (style == null ? void 0 : style.inlineSize) !== void 0 : (style == null ? void 0 : style.height) !== void 0 || (style == null ? void 0 : style.blockSize) !== void 0;
1987
+ const shouldLockGroupSize = activeMorphing && !fullWidth && !hasExplicitGroupSize && count > 1;
1988
+ React11__namespace.useLayoutEffect(() => {
1989
+ if (!shouldLockGroupSize) {
1990
+ if (lockedGroupSize !== null) setLockedGroupSize(null);
1991
+ return;
1992
+ }
1993
+ if (lockedGroupSize !== null) return;
1994
+ const node = rootRef.current;
1995
+ if (!node) return;
1996
+ const rect = node.getBoundingClientRect();
1997
+ const nextSize = orientation === "horizontal" ? rect.width : rect.height;
1998
+ if (nextSize > 0) {
1999
+ setLockedGroupSize(Math.ceil(nextSize * 100) / 100);
2000
+ }
2001
+ }, [lockedGroupSize, orientation, shouldLockGroupSize]);
2002
+ const groupStyle = React11__namespace.useMemo(() => {
2003
+ const nextStyle = __spreadValues({}, style);
2004
+ if (shouldLockGroupSize && lockedGroupSize !== null) {
2005
+ if (orientation === "horizontal") {
2006
+ nextStyle.inlineSize = `${lockedGroupSize}px`;
2007
+ } else {
2008
+ nextStyle.blockSize = `${lockedGroupSize}px`;
2009
+ }
2010
+ }
2011
+ return nextStyle;
2012
+ }, [lockedGroupSize, orientation, shouldLockGroupSize, style]);
2013
+ const hasSelected = React11__namespace.useMemo(
2014
+ () => childrenArray.some(
2015
+ (child) => child.props.selected
2016
+ ),
2017
+ [childrenArray]
2018
+ );
2019
+ const handlePointerLeaveAndUp = React11__namespace.useCallback(() => {
2020
+ setPressedIndex(null);
2021
+ }, []);
2022
+ return /* @__PURE__ */ jsxRuntime.jsx(
2023
+ "fieldset",
2024
+ __spreadProps(__spreadValues({
2025
+ ref: setRootRef,
2026
+ className: cn(
2027
+ "inline-flex p-0 m-0 border-none max-w-full [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
2028
+ orientation === "vertical" ? "flex-col items-stretch overflow-y-auto overflow-x-hidden" : "flex-row overflow-x-auto overflow-y-hidden",
2029
+ variant === "standard" ? "gap-3" : variant === "navbar" ? "gap-1.5 h-full" : "gap-0.5",
2030
+ fullWidth && "w-full",
2031
+ fullWidth && orientation === "vertical" && "h-full",
2032
+ className
2033
+ ),
2034
+ style: groupStyle,
2035
+ onPointerLeave: handlePointerLeaveAndUp,
2036
+ onPointerUp: handlePointerLeaveAndUp
2037
+ }, props), {
2038
+ children: childrenArray.map((child, index) => {
2039
+ var _a2, _b2, _c;
2040
+ const element = child;
2041
+ const isSelected = element.props.selected === true;
2042
+ const isFirst = index === 0;
2043
+ const isLast = index === count - 1;
2044
+ const itemSize = size || element.props.size || "sm";
2045
+ const basePx = ((_a2 = BUTTON_SIZE_TOKENS[itemSize]) == null ? void 0 : _a2.leadingSpace) || "1rem";
2046
+ const isPressed = pressedIndex === index;
2047
+ const { icon: explicitIcon, label: explicitLabel } = resolveIconAndLabel(
2048
+ element,
2049
+ isSelected,
2050
+ itemSize,
2051
+ variant,
2052
+ showCheck,
2053
+ iconBehavior,
2054
+ labelBehavior
2055
+ );
2056
+ const shapes = resolveConnectedShapes(
2057
+ variant,
2058
+ orientation,
2059
+ isFirst,
2060
+ isLast,
2061
+ itemSize
2062
+ );
2063
+ const flex = resolveFlexTargets(
2064
+ variant,
2065
+ orientation,
2066
+ isSelected,
2067
+ isPressed,
2068
+ hasSelected,
2069
+ count,
2070
+ fullWidth,
2071
+ activeMorphing,
2072
+ morphingWidth,
2073
+ expandedRatio,
2074
+ basePx
2075
+ );
2076
+ const dynamicStyle = __spreadValues({}, element.props.style);
2077
+ if (variant !== "navbar" && flex.flexGrow !== void 0 && fullWidth) {
2078
+ dynamicStyle.flexBasis = 0;
2079
+ dynamicStyle.flexShrink = 1;
2080
+ dynamicStyle.minWidth = 0;
2081
+ }
2082
+ const existingAnimate = typeof element.props.animate === "object" && !Array.isArray(element.props.animate) ? element.props.animate : {};
2083
+ const existingWhileTap = typeof element.props.whileTap === "object" && !Array.isArray(element.props.whileTap) ? element.props.whileTap : {};
2084
+ const motionProps = buildMotionProps(
2085
+ variant,
2086
+ isSelected,
2087
+ isPressed,
2088
+ itemSize,
2089
+ shapes,
2090
+ flex,
2091
+ existingAnimate,
2092
+ existingWhileTap
2093
+ );
2094
+ const connectedClasses = variant === "connected" && isSelected ? "z-20" : "";
2095
+ const navbarFlexStyle = flex.flexGrow !== void 0 ? {
2096
+ flexBasis: fullWidth && labelBehavior !== "selected" ? 0 : "auto",
2097
+ flexShrink: fullWidth ? 1 : 0,
2098
+ flexGrow: flex.flexGrow,
2099
+ minWidth: labelBehavior !== "selected" ? 0 : "fit-content"
2100
+ } : {};
2101
+ const clonedElement = React11__namespace.cloneElement(element, __spreadValues(__spreadProps(__spreadValues(__spreadValues(__spreadValues({
2102
+ key: (_b2 = element.key) != null ? _b2 : index,
2103
+ tabIndex: isFirst ? 0 : -1,
2104
+ size: size || element.props.size,
2105
+ icon: explicitIcon,
2106
+ children: explicitLabel
2107
+ }, variant === "connected" && {
2108
+ colorStyle: element.props.colorStyle || "tonal",
2109
+ selectedColorStyle: element.props.selectedColorStyle || "filled"
2110
+ }), variant === "navbar" && {
2111
+ colorStyle: "text",
2112
+ selectedColorStyle: "text",
2113
+ className: cn(
2114
+ element.props.className,
2115
+ "w-full! h-full! px-3! min-w-0! relative z-20 flex items-center justify-center",
2116
+ isSelected ? "text-m3-on-secondary-container! hover:bg-transparent! active:bg-transparent!" : "text-m3-on-surface-variant! hover:bg-transparent! active:bg-transparent!",
2117
+ itemClassName
2118
+ )
2119
+ }), variant !== "navbar" && {
2120
+ className: cn(
2121
+ element.props.className,
2122
+ connectedClasses,
2123
+ "focus-visible:z-10 hover:z-10 relative min-w-0",
2124
+ orientation === "vertical" && "w-full",
2125
+ itemClassName
2126
+ )
2127
+ }), {
2128
+ style: variant === "navbar" ? __spreadProps(__spreadValues({}, dynamicStyle), { minWidth: 0 }) : dynamicStyle,
2129
+ onPointerDown: (e) => {
2130
+ setPressedIndex(index);
2131
+ if (element.props.onPointerDown) element.props.onPointerDown(e);
2132
+ }
2133
+ }), motionProps));
2134
+ if (variant === "navbar") {
2135
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2136
+ react.m.div,
2137
+ {
2138
+ layout: true,
2139
+ whileTap: { scale: 0.96 },
2140
+ transition: NAVBAR_EXPRESSIVE_SPRING,
2141
+ className: "group relative h-full flex items-center justify-center min-w-0",
2142
+ style: navbarFlexStyle,
2143
+ children: [
2144
+ /* @__PURE__ */ jsxRuntime.jsxs(
2145
+ "div",
2146
+ {
2147
+ className: "absolute inset-x-1 inset-y-0 m-auto flex items-center justify-center pointer-events-none",
2148
+ style: { zIndex: 1 },
2149
+ children: [
2150
+ /* @__PURE__ */ jsxRuntime.jsx(
2151
+ "div",
2152
+ {
2153
+ className: "w-full h-[40px] bg-m3-on-surface-variant/8 opacity-0 group-hover:opacity-100 transition-opacity duration-200",
2154
+ style: { borderRadius: PILL_BORDER_RADIUS }
2155
+ }
2156
+ ),
2157
+ /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { children: isSelected && /* @__PURE__ */ jsxRuntime.jsx(
2158
+ react.m.div,
2159
+ {
2160
+ layoutId: `navbar-active-indicator-${layoutIdGroup}`,
2161
+ className: "absolute inset-0 m-auto w-full h-[40px] bg-m3-secondary-container",
2162
+ style: { borderRadius: PILL_BORDER_RADIUS },
2163
+ transition: NAVBAR_EXPRESSIVE_SPRING
2164
+ }
2165
+ ) })
2166
+ ]
2167
+ }
2168
+ ),
2169
+ clonedElement
2170
+ ]
2171
+ },
2172
+ (_c = element.key) != null ? _c : index
2173
+ );
2174
+ }
2175
+ return clonedElement;
2176
+ })
2177
+ })
2178
+ );
2179
+ }
2180
+ );
2181
+ ButtonGroupComponent.displayName = "ButtonGroup";
2182
+ var ButtonGroup = React11__namespace.memo(ButtonGroupComponent);
2183
+ var SIZE_HEIGHT = {
2184
+ sm: "h-14",
2185
+ md: "h-20",
2186
+ lg: "h-24"
2187
+ };
2188
+ var SIZE_WIDTH_COLLAPSED = {
2189
+ sm: "w-14",
2190
+ md: "w-20",
2191
+ lg: "w-24"
2192
+ };
2193
+ var SIZE_PADDING = {
2194
+ sm: "px-4",
2195
+ md: "px-[26px]",
2196
+ lg: "px-7"
2197
+ };
2198
+ var SIZE_GAP = {
2199
+ sm: "gap-2",
2200
+ md: "gap-3",
2201
+ lg: "gap-4"
2202
+ };
2203
+ var SIZE_ICON = {
2204
+ sm: { cls: "size-6", px: 24 },
2205
+ md: { cls: "size-7", px: 28 },
2206
+ lg: { cls: "size-9", px: 36 }
2207
+ };
2208
+ var SIZE_TEXT = {
2209
+ sm: "text-base font-medium",
2210
+ md: "text-lg font-medium",
2211
+ lg: "text-xl font-normal"
2212
+ };
2213
+ var MORPH_RADIUS = {
2214
+ sm: { default: 16, pressed: 10 },
2215
+ md: { default: 20, pressed: 14 },
2216
+ lg: { default: 28, pressed: 18 }
2217
+ };
2218
+ var COLOR_CLASSES = {
2219
+ primary: {
2220
+ bg: "bg-m3-primary-container",
2221
+ text: "text-m3-on-primary-container"
2222
+ },
2223
+ secondary: {
2224
+ bg: "bg-m3-secondary-container",
2225
+ text: "text-m3-on-secondary-container"
2226
+ },
2227
+ tertiary: {
2228
+ bg: "bg-m3-tertiary-container",
2229
+ text: "text-m3-on-tertiary-container"
2230
+ },
2231
+ surface: {
2232
+ bg: "bg-m3-surface-container-high",
2233
+ text: "text-m3-on-surface"
2234
+ }
2235
+ };
2236
+ function useScrollCollapse(enabled, scrollThreshold, onCollapsedChange) {
2237
+ const [collapsed, setCollapsed] = React11__namespace.useState(false);
2238
+ const lastScrollY = React11__namespace.useRef(0);
2239
+ React11__namespace.useEffect(() => {
2240
+ if (!enabled || typeof window === "undefined") return;
2241
+ lastScrollY.current = window.scrollY;
2242
+ const handleScroll = () => {
2243
+ const currentScrollY = window.scrollY;
2244
+ const diff = currentScrollY - lastScrollY.current;
2245
+ if (Math.abs(diff) < scrollThreshold) return;
2246
+ if (diff > 0 && !collapsed) {
2247
+ setCollapsed(true);
2248
+ onCollapsedChange == null ? void 0 : onCollapsedChange(true);
2249
+ } else if (diff < 0 && collapsed) {
2250
+ setCollapsed(false);
2251
+ onCollapsedChange == null ? void 0 : onCollapsedChange(false);
2252
+ }
2253
+ lastScrollY.current = currentScrollY;
2254
+ };
2255
+ window.addEventListener("scroll", handleScroll, { passive: true });
2256
+ return () => {
2257
+ window.removeEventListener("scroll", handleScroll);
2258
+ };
2259
+ }, [enabled, scrollThreshold, collapsed, onCollapsedChange]);
2260
+ return collapsed;
2261
+ }
2262
+ var ExtendedFABComponent = React11__namespace.forwardRef(
2263
+ (_a, ref) => {
2264
+ var _b = _a, {
2265
+ className,
2266
+ style,
2267
+ label,
2268
+ icon,
2269
+ size = "sm",
2270
+ colorStyle = "primary",
2271
+ lowered = false,
2272
+ loading = false,
2273
+ loadingVariant = "loading-indicator",
2274
+ visible = true,
2275
+ collapseOnScroll = false,
2276
+ scrollThreshold = 50,
2277
+ collapsed,
2278
+ onCollapsedChange,
2279
+ onClick,
2280
+ onKeyDown,
2281
+ layoutId,
2282
+ "aria-label": ariaLabel
2283
+ } = _b, restProps = __objRest(_b, [
2284
+ "className",
2285
+ "style",
2286
+ "label",
2287
+ "icon",
2288
+ "size",
2289
+ "colorStyle",
2290
+ "lowered",
2291
+ "loading",
2292
+ "loadingVariant",
2293
+ "visible",
2294
+ "collapseOnScroll",
2295
+ "scrollThreshold",
2296
+ "collapsed",
2297
+ "onCollapsedChange",
2298
+ "onClick",
2299
+ "onKeyDown",
2300
+ "layoutId",
2301
+ "aria-label"
2302
+ ]);
2303
+ var _a2, _b2, _c, _d;
2304
+ const localRef = React11__namespace.useRef(null);
2305
+ React11__namespace.useImperativeHandle(ref, () => localRef.current);
2306
+ const [dir, setDir] = React11__namespace.useState("ltr");
2307
+ React11__namespace.useEffect(() => {
2308
+ var _a3;
2309
+ if (!localRef.current) return;
2310
+ const closestDir = (_a3 = localRef.current.closest("[dir]")) == null ? void 0 : _a3.getAttribute("dir");
2311
+ if (closestDir === "rtl" || closestDir === "ltr") {
2312
+ setDir(closestDir);
2313
+ }
2314
+ }, []);
2315
+ const internalCollapsed = useScrollCollapse(
2316
+ collapseOnScroll,
2317
+ scrollThreshold,
2318
+ onCollapsedChange
2319
+ );
2320
+ const isCollapsed = collapsed !== void 0 ? collapsed : internalCollapsed;
2321
+ const hasIcon = !!icon || loading;
2322
+ const colors = (_a2 = COLOR_CLASSES[colorStyle]) != null ? _a2 : COLOR_CLASSES.primary;
2323
+ const radiusConfig = (_b2 = MORPH_RADIUS[size]) != null ? _b2 : MORPH_RADIUS.sm;
2324
+ const sizeIcon = (_c = SIZE_ICON[size]) != null ? _c : SIZE_ICON.sm;
2325
+ const { ripples, onPointerDown, removeRipple } = useRippleState({
2326
+ disabled: loading
2327
+ });
2328
+ const handleClick = React11__namespace.useCallback(
2329
+ (e) => {
2330
+ if (loading) {
2331
+ e.preventDefault();
2332
+ return;
2333
+ }
2334
+ onClick == null ? void 0 : onClick(e);
2335
+ },
2336
+ [loading, onClick]
2337
+ );
2338
+ const handleKeyDown = React11__namespace.useCallback(
2339
+ (e) => {
2340
+ if (loading) return;
2341
+ if ((e.key === "Enter" || e.key === " ") && onClick) {
2342
+ e.preventDefault();
2343
+ e.currentTarget.click();
2344
+ }
2345
+ onKeyDown == null ? void 0 : onKeyDown(e);
2346
+ },
2347
+ [loading, onClick, onKeyDown]
2348
+ );
2349
+ return /* @__PURE__ */ jsxRuntime.jsx(react.LazyMotion, { features: react.domMax, strict: true, children: /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { children: visible && !(isCollapsed && !hasIcon) && /* @__PURE__ */ jsxRuntime.jsxs(
2350
+ react.m.button,
2351
+ __spreadProps(__spreadValues({
2352
+ ref: localRef,
2353
+ type: "button",
2354
+ layout: true,
2355
+ layoutId,
2356
+ "aria-label": ariaLabel || label,
2357
+ "aria-busy": loading || void 0,
2358
+ "aria-disabled": loading || restProps.disabled,
2359
+ onClick: handleClick,
2360
+ onPointerDown,
2361
+ onKeyDown: handleKeyDown,
2362
+ style,
2363
+ initial: {
2364
+ scale: 0.6,
2365
+ opacity: 0,
2366
+ borderRadius: radiusConfig.default
2367
+ },
2368
+ animate: {
2369
+ scale: 1,
2370
+ opacity: 1,
2371
+ borderRadius: radiusConfig.default
2372
+ },
2373
+ exit: { scale: 0.6, opacity: 0 },
2374
+ whileTap: { borderRadius: radiusConfig.pressed },
2375
+ transition: {
2376
+ borderRadius: { type: "spring", stiffness: 500, damping: 30 },
2377
+ scale: SPRING_TRANSITION,
2378
+ opacity: { duration: 0.2, ease: "linear" },
2379
+ layout: SPRING_TRANSITION
2380
+ },
2381
+ className: cn(
2382
+ "relative shrink-0 inline-flex items-center select-none cursor-pointer overflow-hidden",
2383
+ "transition-[box-shadow,filter] duration-200",
2384
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-m3-primary focus-visible:ring-offset-2",
2385
+ "disabled:pointer-events-none disabled:opacity-[0.38] disabled:shadow-none",
2386
+ colors.bg,
2387
+ colors.text,
2388
+ lowered ? "shadow-sm" : "shadow-md",
2389
+ (_d = SIZE_HEIGHT[size]) != null ? _d : "h-14",
2390
+ SIZE_TEXT[size],
2391
+ isCollapsed ? cn("px-0 justify-center", SIZE_WIDTH_COLLAPSED[size]) : cn(
2392
+ hasIcon ? "justify-start" : "justify-center",
2393
+ SIZE_PADDING[size],
2394
+ hasIcon && SIZE_GAP[size]
2395
+ ),
2396
+ dir === "rtl" || restProps.dir === "rtl" ? "flex-row-reverse" : "flex-row",
2397
+ loading && "pointer-events-none opacity-75 cursor-not-allowed",
2398
+ className
2399
+ )
2400
+ }, restProps), {
2401
+ children: [
2402
+ /* @__PURE__ */ jsxRuntime.jsx(Ripple, { ripples, onRippleDone: removeRipple }),
2403
+ hasIcon && /* @__PURE__ */ jsxRuntime.jsx(
2404
+ react.m.span,
2405
+ {
2406
+ layout: "position",
2407
+ className: cn(
2408
+ "flex items-center justify-center shrink-0",
2409
+ sizeIcon.cls
2410
+ ),
2411
+ children: /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { mode: "wait", initial: false, children: loading ? /* @__PURE__ */ jsxRuntime.jsx(
2412
+ react.m.span,
2413
+ __spreadProps(__spreadValues({}, ICON_SPAN_VARIANTS), {
2414
+ transition: SPRING_TRANSITION,
2415
+ className: "flex items-center justify-center shrink-0 w-full h-full",
2416
+ children: loadingVariant === "loading-indicator" ? /* @__PURE__ */ jsxRuntime.jsx(
2417
+ LoadingIndicator,
2418
+ {
2419
+ size: sizeIcon.px,
2420
+ color: "currentColor",
2421
+ "aria-label": "Loading"
2422
+ }
2423
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
2424
+ ProgressIndicator,
2425
+ {
2426
+ variant: "circular",
2427
+ size: sizeIcon.px,
2428
+ color: "currentColor",
2429
+ trackColor: "transparent",
2430
+ "aria-label": "Loading"
2431
+ }
2432
+ )
2433
+ }),
2434
+ "loading"
2435
+ ) : icon && /* @__PURE__ */ jsxRuntime.jsx(
2436
+ react.m.span,
2437
+ __spreadProps(__spreadValues({}, ICON_SPAN_VARIANTS), {
2438
+ transition: SPRING_TRANSITION,
2439
+ "aria-hidden": "true",
2440
+ className: "flex items-center justify-center shrink-0 w-full h-full [&>svg]:w-full [&>svg]:h-full",
2441
+ children: icon
2442
+ }),
2443
+ "icon"
2444
+ ) })
2445
+ }
2446
+ ),
2447
+ /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { initial: false, children: !isCollapsed && /* @__PURE__ */ jsxRuntime.jsx(
2448
+ react.m.span,
2449
+ {
2450
+ layout: "position",
2451
+ initial: { opacity: 0, width: 0 },
2452
+ animate: { opacity: 1, width: "auto" },
2453
+ exit: { opacity: 0, width: 0 },
2454
+ transition: {
2455
+ opacity: { duration: 0.15, ease: "linear" },
2456
+ width: SPRING_TRANSITION
2457
+ },
2458
+ className: "overflow-hidden whitespace-nowrap",
2459
+ children: label
2460
+ },
2461
+ "label"
2462
+ ) })
2463
+ ]
2464
+ })
2465
+ ) }) });
2466
+ }
2467
+ );
2468
+ ExtendedFABComponent.displayName = "ExtendedFAB";
2469
+ var ExtendedFAB = React11__namespace.memo(ExtendedFABComponent);
2470
+ var SIZE_STYLES = {
2471
+ sm: "h-10 w-10",
2472
+ md: "h-14 w-14",
2473
+ lg: "h-24 w-24",
2474
+ xl: "h-[8.5rem] w-[8.5rem]"
2475
+ };
2476
+ var SIZE_ICON2 = {
2477
+ sm: { cls: "size-6", px: 24 },
2478
+ md: { cls: "size-6", px: 24 },
2479
+ lg: { cls: "size-8", px: 32 },
2480
+ xl: { cls: "size-10", px: 40 }
2481
+ };
2482
+ var SIZE_TEXT_CLASS = {
2483
+ sm: "text-sm font-medium",
2484
+ md: "text-base font-medium",
2485
+ lg: "text-xl font-semibold",
2486
+ xl: "text-2xl font-semibold"
2487
+ };
2488
+ var MORPH_RADIUS2 = {
2489
+ sm: { default: 12, pressed: 8, extended: 12, extended_pressed: 8 },
2490
+ md: { default: 16, pressed: 10, extended: 16, extended_pressed: 10 },
2491
+ lg: { default: 28, pressed: 20, extended: 28, extended_pressed: 20 },
2492
+ xl: { default: 40, pressed: 28, extended: 40, extended_pressed: 28 }
2493
+ };
2494
+ var COLOR_CLASSES2 = {
2495
+ primary: {
2496
+ bg: "bg-m3-primary-container",
2497
+ text: "text-m3-on-primary-container",
2498
+ shadow: "shadow-md"
2499
+ },
2500
+ secondary: {
2501
+ bg: "bg-m3-secondary-container",
2502
+ text: "text-m3-on-secondary-container",
2503
+ shadow: "shadow-md"
2504
+ },
2505
+ tertiary: {
2506
+ bg: "bg-m3-tertiary-container",
2507
+ text: "text-m3-on-tertiary-container",
2508
+ shadow: "shadow-md"
2509
+ },
2510
+ surface: {
2511
+ bg: "bg-m3-surface-container-high",
2512
+ text: "text-m3-primary",
2513
+ shadow: "shadow-md"
2514
+ }
2515
+ };
2516
+ var POSITION_CLASS = {
2517
+ "bottom-right": "bottom-4 right-4 sm:bottom-6 sm:right-6",
2518
+ "bottom-left": "bottom-4 left-4 sm:bottom-6 sm:left-6",
2519
+ "top-right": "top-4 right-4 sm:top-6 sm:right-6",
2520
+ "top-left": "top-4 left-4 sm:top-6 sm:left-6"
2521
+ };
2522
+ function FABPosition({
2523
+ position = "bottom-right",
2524
+ children,
2525
+ className
2526
+ }) {
2527
+ var _a;
2528
+ return /* @__PURE__ */ jsxRuntime.jsx(
2529
+ "div",
2530
+ {
2531
+ className: cn(
2532
+ "absolute z-10",
2533
+ (_a = POSITION_CLASS[position]) != null ? _a : POSITION_CLASS["bottom-right"],
2534
+ className
2535
+ ),
2536
+ children
2537
+ }
2538
+ );
2539
+ }
2540
+ var FABComponent = React11__namespace.forwardRef(
2541
+ (_a, ref) => {
2542
+ var _b = _a, {
2543
+ className,
2544
+ style,
2545
+ icon,
2546
+ size = "md",
2547
+ colorStyle = "primary",
2548
+ extended = false,
2549
+ children,
2550
+ lowered = false,
2551
+ loading = false,
2552
+ loadingVariant = "loading-indicator",
2553
+ visible = true,
2554
+ onClick,
2555
+ onKeyDown,
2556
+ "aria-label": ariaLabel
2557
+ } = _b, restProps = __objRest(_b, [
2558
+ "className",
2559
+ "style",
2560
+ "icon",
2561
+ "size",
2562
+ "colorStyle",
2563
+ "extended",
2564
+ "children",
2565
+ "lowered",
2566
+ "loading",
2567
+ "loadingVariant",
2568
+ "visible",
2569
+ "onClick",
2570
+ "onKeyDown",
2571
+ "aria-label"
2572
+ ]);
2573
+ var _a2, _b2, _c, _d;
2574
+ const colors = (_a2 = COLOR_CLASSES2[colorStyle]) != null ? _a2 : COLOR_CLASSES2.primary;
2575
+ const radiusConfig = (_b2 = MORPH_RADIUS2[size]) != null ? _b2 : MORPH_RADIUS2.md;
2576
+ const animateRadius = extended ? radiusConfig.extended : radiusConfig.default;
2577
+ const pressedRadius = extended ? radiusConfig.extended_pressed : radiusConfig.pressed;
2578
+ const sizeIcon = (_c = SIZE_ICON2[size]) != null ? _c : SIZE_ICON2.md;
2579
+ const iconClass = sizeIcon.cls;
2580
+ const iconPx = sizeIcon.px;
2581
+ const needsTouchTarget = size === "sm";
2582
+ const { ripples, onPointerDown, removeRipple } = useRippleState({
2583
+ disabled: loading
2584
+ });
2585
+ const handleClick = React11__namespace.useCallback(
2586
+ (e) => {
2587
+ if (loading) {
2588
+ e.preventDefault();
2589
+ return;
2590
+ }
2591
+ onClick == null ? void 0 : onClick(e);
2592
+ },
2593
+ [loading, onClick]
2594
+ );
2595
+ const handleKeyDown = React11__namespace.useCallback(
2596
+ (e) => {
2597
+ if (loading) return;
2598
+ if ((e.key === "Enter" || e.key === " ") && onClick) {
2599
+ e.preventDefault();
2600
+ e.currentTarget.click();
2601
+ }
2602
+ onKeyDown == null ? void 0 : onKeyDown(e);
2603
+ },
2604
+ [loading, onClick, onKeyDown]
2605
+ );
2606
+ return /* @__PURE__ */ jsxRuntime.jsx(react.LazyMotion, { features: react.domMax, strict: true, children: /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { children: visible && /* @__PURE__ */ jsxRuntime.jsxs(
2607
+ react.m.button,
2608
+ __spreadProps(__spreadValues({
2609
+ ref,
2610
+ type: "button",
2611
+ "aria-label": ariaLabel || (typeof children === "string" ? children : void 0),
2612
+ "aria-busy": loading || void 0,
2613
+ "aria-disabled": loading || restProps.disabled,
2614
+ onClick: handleClick,
2615
+ onPointerDown,
2616
+ onKeyDown: handleKeyDown,
2617
+ style,
2618
+ initial: { scale: 0.5, opacity: 0, borderRadius: animateRadius },
2619
+ animate: { scale: 1, opacity: 1, borderRadius: animateRadius },
2620
+ exit: { scale: 0.5, opacity: 0 },
2621
+ whileTap: { borderRadius: pressedRadius },
2622
+ transition: {
2623
+ borderRadius: SPRING_TRANSITION_FAST,
2624
+ scale: SPRING_TRANSITION,
2625
+ opacity: { duration: 0.25, ease: "easeOut" }
2626
+ },
2627
+ className: cn(
2628
+ "relative shrink-0 inline-flex items-center justify-center",
2629
+ "select-none cursor-pointer overflow-hidden",
2630
+ "transition-[box-shadow,opacity,filter] duration-200",
2631
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-m3-primary focus-visible:ring-offset-2",
2632
+ "disabled:pointer-events-none disabled:opacity-[0.38] disabled:shadow-none",
2633
+ colors.bg,
2634
+ colors.text,
2635
+ lowered ? "shadow-sm" : colors.shadow,
2636
+ (_d = SIZE_STYLES[size]) != null ? _d : "h-14 w-14",
2637
+ extended && "w-auto px-6",
2638
+ SIZE_TEXT_CLASS[size],
2639
+ loading && "pointer-events-none opacity-75 cursor-not-allowed",
2640
+ className
2641
+ )
2642
+ }, restProps), {
2643
+ children: [
2644
+ needsTouchTarget && /* @__PURE__ */ jsxRuntime.jsx(TouchTarget, {}),
2645
+ /* @__PURE__ */ jsxRuntime.jsx(Ripple, { ripples, onRippleDone: removeRipple }),
2646
+ /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { mode: "wait", initial: false, children: loading ? /* @__PURE__ */ jsxRuntime.jsx(
2647
+ react.m.span,
2648
+ __spreadProps(__spreadValues({}, ICON_SPAN_VARIANTS), {
2649
+ transition: SPRING_TRANSITION,
2650
+ className: cn(
2651
+ "flex items-center justify-center shrink-0",
2652
+ iconClass
2653
+ ),
2654
+ children: loadingVariant === "loading-indicator" ? /* @__PURE__ */ jsxRuntime.jsx(
2655
+ LoadingIndicator,
2656
+ {
2657
+ size: iconPx,
2658
+ color: "currentColor",
2659
+ "aria-label": "Loading"
2660
+ }
2661
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
2662
+ ProgressIndicator,
2663
+ {
2664
+ variant: "circular",
2665
+ size: iconPx,
2666
+ color: "currentColor",
2667
+ trackColor: "transparent",
2668
+ "aria-label": "Loading"
2669
+ }
2670
+ )
2671
+ }),
2672
+ "loading"
2673
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
2674
+ react.m.span,
2675
+ __spreadProps(__spreadValues({}, ICON_SPAN_VARIANTS), {
2676
+ transition: SPRING_TRANSITION,
2677
+ "aria-hidden": "true",
2678
+ className: cn(
2679
+ "flex items-center justify-center shrink-0 [&>svg]:w-full [&>svg]:h-full",
2680
+ iconClass
2681
+ ),
2682
+ children: icon
2683
+ }),
2684
+ "icon"
2685
+ ) }),
2686
+ /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { initial: false, children: extended && children && /* @__PURE__ */ jsxRuntime.jsx(
2687
+ react.m.span,
2688
+ {
2689
+ initial: { width: 0, opacity: 0 },
2690
+ animate: { width: "auto", opacity: 1 },
2691
+ exit: { width: 0, opacity: 0 },
2692
+ transition: SPRING_TRANSITION,
2693
+ className: "overflow-hidden whitespace-nowrap ml-3",
2694
+ children
2695
+ },
2696
+ "label"
2697
+ ) })
2698
+ ]
2699
+ })
2700
+ ) }) });
2701
+ }
2702
+ );
2703
+ FABComponent.displayName = "FAB";
2704
+ var FAB = React11__namespace.memo(FABComponent);
2705
+ var SPRING_NORMAL = { stiffness: 700, damping: 40 };
2706
+ var SPRING_REDUCED = { stiffness: 1e4, damping: 100 };
2707
+ var FOCUS_DELAY_MS = 50;
2708
+ var TOGGLE_FAB_COLORS = {
2709
+ primary: {
2710
+ containerBg: "bg-m3-primary-container",
2711
+ containerText: "text-m3-on-primary-container",
2712
+ checkedBg: "bg-m3-primary",
2713
+ checkedText: "text-m3-on-primary"
2714
+ },
2715
+ secondary: {
2716
+ containerBg: "bg-m3-secondary-container",
2717
+ containerText: "text-m3-on-secondary-container",
2718
+ checkedBg: "bg-m3-secondary",
2719
+ checkedText: "text-m3-on-secondary"
2720
+ },
2721
+ tertiary: {
2722
+ containerBg: "bg-m3-tertiary-container",
2723
+ containerText: "text-m3-on-tertiary-container",
2724
+ checkedBg: "bg-m3-tertiary",
2725
+ checkedText: "text-m3-on-tertiary"
2726
+ }
2727
+ };
2728
+ var TOGGLE_FAB_SIZES = {
2729
+ baseline: { sizeClass: "h-14 w-14", initialRadius: 16, finalRadius: 28 },
2730
+ medium: { sizeClass: "h-20 w-20", initialRadius: 20, finalRadius: 40 },
2731
+ large: { sizeClass: "h-24 w-24", initialRadius: 28, finalRadius: 48 }
2732
+ };
2733
+ var MENU_ITEM_STYLES = {
2734
+ padding: "ps-4 pe-6",
2735
+ gap: "gap-3",
2736
+ size: "h-14 min-w-14",
2737
+ cornerRadius: 999
2738
+ };
2739
+ var MENU_ITEM_COLORS = {
2740
+ primary: {
2741
+ bg: "bg-m3-primary-container",
2742
+ text: "text-m3-on-primary-container"
2743
+ },
2744
+ secondary: {
2745
+ bg: "bg-m3-secondary-container",
2746
+ text: "text-m3-on-secondary-container"
2747
+ },
2748
+ tertiary: {
2749
+ bg: "bg-m3-tertiary-container",
2750
+ text: "text-m3-on-tertiary-container"
2751
+ }
2752
+ };
2753
+ var ALIGNMENT_CONTAINER_CLASSES = {
2754
+ end: "items-end bottom-4 right-4 sm:bottom-6 sm:right-6",
2755
+ start: "items-start bottom-4 left-4 sm:bottom-6 sm:left-6",
2756
+ center: "items-center bottom-4 left-1/2 -translate-x-1/2 sm:bottom-6"
2757
+ };
2758
+ var ALIGNMENT_ITEMS_CLASSES = {
2759
+ end: "items-end",
2760
+ start: "items-start",
2761
+ center: "items-center"
2762
+ };
2763
+ var ALIGNMENT_TRANSFORM_ORIGIN = {
2764
+ end: "right",
2765
+ start: "left",
2766
+ center: "bottom"
2767
+ };
2768
+ var ITEM_SPRING = { type: "spring", stiffness: 700, damping: 25 };
2769
+ var MENU_CONTAINER_VARIANTS = {
2770
+ open: { transition: { staggerChildren: 0.033, staggerDirection: 1 } },
2771
+ closed: { transition: { staggerChildren: 0.02, staggerDirection: -1 } }
2772
+ };
2773
+ var MENU_ITEM_VARIANTS = {
2774
+ open: { scaleX: 1, opacity: 1, transition: ITEM_SPRING },
2775
+ closed: { scaleX: 0, opacity: 0, transition: ITEM_SPRING }
2776
+ };
2777
+ function AddIcon() {
2778
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2779
+ "svg",
2780
+ {
2781
+ "aria-hidden": "true",
2782
+ viewBox: "0 0 24 24",
2783
+ fill: "currentColor",
2784
+ width: "24",
2785
+ height: "24",
2786
+ children: [
2787
+ /* @__PURE__ */ jsxRuntime.jsx("title", { children: "Add" }),
2788
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z" })
2789
+ ]
2790
+ }
2791
+ );
2792
+ }
2793
+ function CloseIcon() {
2794
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2795
+ "svg",
2796
+ {
2797
+ "aria-hidden": "true",
2798
+ viewBox: "0 0 24 24",
2799
+ fill: "currentColor",
2800
+ width: "24",
2801
+ height: "24",
2802
+ children: [
2803
+ /* @__PURE__ */ jsxRuntime.jsx("title", { children: "Close" }),
2804
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" })
2805
+ ]
2806
+ }
2807
+ );
2808
+ }
2809
+ function defaultFabIcon(progress) {
2810
+ return progress > 0.5 ? /* @__PURE__ */ jsxRuntime.jsx(CloseIcon, {}) : /* @__PURE__ */ jsxRuntime.jsx(AddIcon, {});
2811
+ }
2812
+ var ToggleFABComponent = React11__namespace.forwardRef(
2813
+ ({
2814
+ expanded,
2815
+ onToggle,
2816
+ icon,
2817
+ colorVariant = "primary",
2818
+ fabSize = "baseline",
2819
+ className,
2820
+ id,
2821
+ "aria-label": ariaLabel,
2822
+ "aria-controls": ariaControls
2823
+ }, ref) => {
2824
+ var _a, _b;
2825
+ const prefersReduced = react.useReducedMotion();
2826
+ const colors = (_a = TOGGLE_FAB_COLORS[colorVariant]) != null ? _a : TOGGLE_FAB_COLORS.primary;
2827
+ const sizeTokens = (_b = TOGGLE_FAB_SIZES[fabSize]) != null ? _b : TOGGLE_FAB_SIZES.baseline;
2828
+ const springConfig = prefersReduced ? SPRING_REDUCED : SPRING_NORMAL;
2829
+ const checkedProgress = react.useSpring(expanded ? 1 : 0, springConfig);
2830
+ React11__namespace.useEffect(() => {
2831
+ checkedProgress.set(expanded ? 1 : 0);
2832
+ }, [expanded, checkedProgress]);
2833
+ const borderRadius = react.useTransform(
2834
+ checkedProgress,
2835
+ [0, 1],
2836
+ [`${sizeTokens.initialRadius}px`, `${sizeTokens.finalRadius}px`]
2837
+ );
2838
+ const [iconProgress, setIconProgress] = React11__namespace.useState(expanded ? 1 : 0);
2839
+ React11__namespace.useEffect(() => {
2840
+ return checkedProgress.on("change", setIconProgress);
2841
+ }, [checkedProgress]);
2842
+ const { ripples, onPointerDown, removeRipple } = useRippleState();
2843
+ const handleClick = React11__namespace.useCallback(() => {
2844
+ onToggle(!expanded);
2845
+ }, [expanded, onToggle]);
2846
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2847
+ react.m.button,
2848
+ {
2849
+ ref,
2850
+ id,
2851
+ type: "button",
2852
+ "aria-expanded": expanded,
2853
+ "aria-haspopup": "menu",
2854
+ "aria-label": ariaLabel != null ? ariaLabel : expanded ? "Close menu" : "Open menu",
2855
+ "aria-controls": ariaControls,
2856
+ "data-expanded": expanded ? "true" : "false",
2857
+ onClick: handleClick,
2858
+ onPointerDown,
2859
+ style: { borderRadius },
2860
+ animate: {
2861
+ boxShadow: expanded ? "0 4px 8px 3px rgba(0,0,0,0.15), 0 1px 3px rgba(0,0,0,0.3)" : "0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24)"
2862
+ },
2863
+ whileTap: { scale: 0.95, transition: SPRING_TRANSITION_FAST },
2864
+ transition: { boxShadow: SPRING_TRANSITION },
2865
+ className: cn(
2866
+ "relative shrink-0 inline-flex items-center justify-center",
2867
+ "select-none cursor-pointer overflow-hidden",
2868
+ "transition-colors duration-200",
2869
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-m3-primary focus-visible:ring-offset-2",
2870
+ sizeTokens.sizeClass,
2871
+ expanded ? colors.checkedBg : colors.containerBg,
2872
+ expanded ? colors.checkedText : colors.containerText,
2873
+ className
2874
+ ),
2875
+ children: [
2876
+ /* @__PURE__ */ jsxRuntime.jsx(TouchTarget, {}),
2877
+ /* @__PURE__ */ jsxRuntime.jsx(Ripple, { ripples, onRippleDone: removeRipple }),
2878
+ /* @__PURE__ */ jsxRuntime.jsx(
2879
+ "span",
2880
+ {
2881
+ "aria-hidden": "true",
2882
+ className: "relative z-10 flex items-center justify-center size-6 pointer-events-none",
2883
+ children: icon(iconProgress)
2884
+ }
2885
+ )
2886
+ ]
2887
+ }
2888
+ );
2889
+ }
2890
+ );
2891
+ ToggleFABComponent.displayName = "ToggleFAB";
2892
+ var ToggleFAB = React11__namespace.memo(ToggleFABComponent);
2893
+ function FABMenuItem({
2894
+ icon,
2895
+ label,
2896
+ onClick,
2897
+ disabled = false,
2898
+ colorVariant = "primary",
2899
+ className,
2900
+ tabIndex = 0
2901
+ }) {
2902
+ var _a;
2903
+ const colors = (_a = MENU_ITEM_COLORS[colorVariant]) != null ? _a : MENU_ITEM_COLORS.primary;
2904
+ const { ripples, onPointerDown, removeRipple } = useRippleState({ disabled });
2905
+ const handleClick = React11__namespace.useCallback(
2906
+ (e) => {
2907
+ if (disabled) {
2908
+ e.preventDefault();
2909
+ return;
2910
+ }
2911
+ onClick();
2912
+ },
2913
+ [disabled, onClick]
2914
+ );
2915
+ const handleKeyDown = React11__namespace.useCallback(
2916
+ (e) => {
2917
+ if (disabled) return;
2918
+ if (e.key === "Enter" || e.key === " ") {
2919
+ e.preventDefault();
2920
+ onClick();
2921
+ }
2922
+ },
2923
+ [disabled, onClick]
2924
+ );
2925
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2926
+ react.m.div,
2927
+ {
2928
+ role: "menuitem",
2929
+ tabIndex,
2930
+ "aria-disabled": disabled ? "true" : void 0,
2931
+ "data-disabled": disabled ? "true" : void 0,
2932
+ onClick: handleClick,
2933
+ onPointerDown,
2934
+ onKeyDown: handleKeyDown,
2935
+ variants: MENU_ITEM_VARIANTS,
2936
+ style: {
2937
+ transformOrigin: "right",
2938
+ borderRadius: `${MENU_ITEM_STYLES.cornerRadius}px`
2939
+ },
2940
+ className: cn(
2941
+ "relative inline-flex flex-row items-center",
2942
+ "select-none cursor-pointer overflow-hidden",
2943
+ "whitespace-nowrap",
2944
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-m3-primary focus-visible:ring-offset-1",
2945
+ MENU_ITEM_STYLES.size,
2946
+ MENU_ITEM_STYLES.gap,
2947
+ label ? MENU_ITEM_STYLES.padding : "px-4",
2948
+ !label && "justify-center",
2949
+ colors.bg,
2950
+ colors.text,
2951
+ disabled && "opacity-[0.38] pointer-events-none",
2952
+ className
2953
+ ),
2954
+ children: [
2955
+ /* @__PURE__ */ jsxRuntime.jsx(TouchTarget, {}),
2956
+ /* @__PURE__ */ jsxRuntime.jsx(Ripple, { ripples, onRippleDone: removeRipple }),
2957
+ /* @__PURE__ */ jsxRuntime.jsx(
2958
+ "span",
2959
+ {
2960
+ "aria-hidden": "true",
2961
+ className: "relative z-10 flex items-center justify-center size-6 shrink-0 [&>svg]:w-full [&>svg]:h-full pointer-events-none",
2962
+ children: icon
2963
+ }
2964
+ ),
2965
+ label && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "relative z-10 text-base font-medium leading-none pointer-events-none", children: label })
2966
+ ]
2967
+ }
2968
+ );
2969
+ }
2970
+ function FABMenu({
2971
+ expanded,
2972
+ onToggle,
2973
+ items,
2974
+ colorVariant = "primary",
2975
+ fabSize = "baseline",
2976
+ alignment = "end",
2977
+ className,
2978
+ closeOnBackdropClick = true,
2979
+ focusLast = true,
2980
+ "aria-label": ariaLabel
2981
+ }) {
2982
+ const fabId = React11__namespace.useId();
2983
+ const menuId = React11__namespace.useId();
2984
+ const toggleRef = React11__namespace.useRef(null);
2985
+ const itemRefs = React11__namespace.useRef([]);
2986
+ const [focusedIndex, setFocusedIndex] = React11__namespace.useState(-1);
2987
+ const reversedItems = React11__namespace.useMemo(() => [...items].reverse(), [items]);
2988
+ const focusItem = React11__namespace.useCallback((index) => {
2989
+ var _a;
2990
+ const clampedIndex = Math.max(
2991
+ 0,
2992
+ Math.min(index, itemRefs.current.length - 1)
2993
+ );
2994
+ setFocusedIndex(clampedIndex);
2995
+ (_a = itemRefs.current[clampedIndex]) == null ? void 0 : _a.focus();
2996
+ }, []);
2997
+ const wasExpandedRef = React11__namespace.useRef(false);
2998
+ React11__namespace.useEffect(() => {
2999
+ var _a;
3000
+ if (expanded) {
3001
+ wasExpandedRef.current = true;
3002
+ const timer = setTimeout(() => {
3003
+ focusItem(focusLast ? items.length - 1 : 0);
3004
+ }, FOCUS_DELAY_MS);
3005
+ return () => clearTimeout(timer);
3006
+ }
3007
+ if (wasExpandedRef.current) {
3008
+ (_a = toggleRef.current) == null ? void 0 : _a.focus();
3009
+ }
3010
+ wasExpandedRef.current = false;
3011
+ setFocusedIndex(-1);
3012
+ }, [expanded, focusLast, items.length, focusItem]);
3013
+ const handleMenuKeyDown = React11__namespace.useCallback(
3014
+ (e) => {
3015
+ if (!expanded) return;
3016
+ const lastIndex = items.length - 1;
3017
+ switch (e.key) {
3018
+ case "Escape":
3019
+ e.preventDefault();
3020
+ onToggle(false);
3021
+ break;
3022
+ case "ArrowUp": {
3023
+ e.preventDefault();
3024
+ focusItem(focusedIndex <= 0 ? lastIndex : focusedIndex - 1);
3025
+ break;
3026
+ }
3027
+ case "ArrowDown": {
3028
+ e.preventDefault();
3029
+ focusItem(focusedIndex >= lastIndex ? 0 : focusedIndex + 1);
3030
+ break;
3031
+ }
3032
+ case "Tab": {
3033
+ e.preventDefault();
3034
+ if (e.shiftKey) {
3035
+ focusItem(focusedIndex <= 0 ? lastIndex : focusedIndex - 1);
3036
+ } else {
3037
+ focusItem(focusedIndex >= lastIndex ? 0 : focusedIndex + 1);
3038
+ }
3039
+ break;
3040
+ }
3041
+ }
3042
+ },
3043
+ [expanded, focusedIndex, items.length, focusItem, onToggle]
3044
+ );
3045
+ return /* @__PURE__ */ jsxRuntime.jsxs(react.LazyMotion, { features: react.domMax, strict: true, children: [
3046
+ expanded && closeOnBackdropClick && /* @__PURE__ */ jsxRuntime.jsx(
3047
+ "div",
3048
+ {
3049
+ "aria-hidden": "true",
3050
+ className: "fixed inset-0 z-40",
3051
+ onClick: () => onToggle(false)
3052
+ }
3053
+ ),
3054
+ /* @__PURE__ */ jsxRuntime.jsxs(
3055
+ "div",
3056
+ {
3057
+ role: "group",
3058
+ "aria-label": ariaLabel != null ? ariaLabel : "Actions menu",
3059
+ className: cn(
3060
+ "fixed z-50 flex flex-col gap-2",
3061
+ ALIGNMENT_CONTAINER_CLASSES[alignment],
3062
+ "*:shrink-0",
3063
+ className
3064
+ ),
3065
+ onKeyDown: handleMenuKeyDown,
3066
+ children: [
3067
+ /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { children: expanded && /* @__PURE__ */ jsxRuntime.jsx(
3068
+ react.m.div,
3069
+ {
3070
+ id: menuId,
3071
+ role: "menu",
3072
+ "aria-labelledby": fabId,
3073
+ "aria-orientation": "vertical",
3074
+ variants: MENU_CONTAINER_VARIANTS,
3075
+ initial: "closed",
3076
+ animate: "open",
3077
+ exit: "closed",
3078
+ className: cn(
3079
+ "flex flex-col-reverse gap-2",
3080
+ ALIGNMENT_ITEMS_CLASSES[alignment]
3081
+ ),
3082
+ children: reversedItems.map((item, reversedIndex) => {
3083
+ var _a;
3084
+ const originalIndex = items.length - 1 - reversedIndex;
3085
+ return /* @__PURE__ */ jsxRuntime.jsx(
3086
+ react.m.div,
3087
+ {
3088
+ variants: MENU_ITEM_VARIANTS,
3089
+ style: {
3090
+ transformOrigin: (_a = ALIGNMENT_TRANSFORM_ORIGIN[alignment]) != null ? _a : "right"
3091
+ },
3092
+ ref: (el) => {
3093
+ itemRefs.current[originalIndex] = el;
3094
+ },
3095
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3096
+ FABMenuItem,
3097
+ {
3098
+ icon: item.icon,
3099
+ label: item.label,
3100
+ onClick: () => {
3101
+ if (!item.disabled) {
3102
+ item.onClick();
3103
+ onToggle(false);
3104
+ }
3105
+ },
3106
+ disabled: item.disabled,
3107
+ colorVariant,
3108
+ className: item.className,
3109
+ tabIndex: expanded ? 0 : -1
3110
+ }
3111
+ )
3112
+ },
3113
+ item.id
3114
+ );
3115
+ })
3116
+ }
3117
+ ) }),
3118
+ /* @__PURE__ */ jsxRuntime.jsx(
3119
+ ToggleFAB,
3120
+ {
3121
+ ref: toggleRef,
3122
+ id: fabId,
3123
+ expanded,
3124
+ onToggle,
3125
+ colorVariant,
3126
+ fabSize,
3127
+ "aria-label": ariaLabel != null ? ariaLabel : expanded ? "Close actions menu" : "Open actions menu",
3128
+ "aria-controls": menuId,
3129
+ icon: defaultFabIcon
3130
+ }
3131
+ )
3132
+ ]
3133
+ }
3134
+ )
3135
+ ] });
3136
+ }
3137
+ var SIZE_STYLES2 = {
3138
+ xs: "h-8 w-8",
3139
+ sm: "h-10 w-10",
3140
+ md: "h-14 w-14",
3141
+ lg: "h-24 w-24",
3142
+ xl: "h-[8.5rem] w-[8.5rem]"
3143
+ };
3144
+ var SIZE_ICON3 = {
3145
+ xs: { cls: "size-5", px: 20 },
3146
+ sm: { cls: "size-6", px: 24 },
3147
+ md: { cls: "size-6", px: 24 },
3148
+ lg: { cls: "size-8", px: 32 },
3149
+ xl: { cls: "size-10", px: 40 }
3150
+ };
3151
+ var RADIUS_MAP = {
3152
+ xs: {
3153
+ round: 16,
3154
+ square: 12,
3155
+ pressed: 8,
3156
+ selectedRound: 12,
3157
+ selectedSquare: 16
3158
+ },
3159
+ sm: {
3160
+ round: 20,
3161
+ square: 12,
3162
+ pressed: 8,
3163
+ selectedRound: 12,
3164
+ selectedSquare: 20
3165
+ },
3166
+ md: {
3167
+ round: 28,
3168
+ square: 16,
3169
+ pressed: 12,
3170
+ selectedRound: 16,
3171
+ selectedSquare: 28
3172
+ },
3173
+ lg: {
3174
+ round: 48,
3175
+ square: 28,
3176
+ pressed: 16,
3177
+ selectedRound: 28,
3178
+ selectedSquare: 48
3179
+ },
3180
+ xl: {
3181
+ round: 68,
3182
+ square: 28,
3183
+ pressed: 16,
3184
+ selectedRound: 28,
3185
+ selectedSquare: 68
3186
+ }
3187
+ };
3188
+ var SIZE_OUTLINE_WIDTH = {
3189
+ xs: "border",
3190
+ sm: "border",
3191
+ md: "border",
3192
+ lg: "border-2",
3193
+ xl: "border-[3px]"
3194
+ };
3195
+ var colorStyles = {
3196
+ standard: {
3197
+ default: "text-m3-on-surface-variant hover:bg-m3-on-surface-variant/8 active:bg-m3-on-surface-variant/12",
3198
+ selected: "text-m3-primary hover:bg-m3-primary/8 active:bg-m3-primary/12"
3199
+ },
3200
+ filled: {
3201
+ default: "bg-m3-surface-container text-m3-on-surface-variant hover:bg-m3-on-surface-variant/8 active:bg-m3-on-surface-variant/12",
3202
+ selected: "bg-m3-primary text-m3-on-primary hover:brightness-95 active:brightness-90"
3203
+ },
3204
+ tonal: {
3205
+ default: "bg-m3-secondary-container text-m3-on-secondary-container hover:bg-m3-on-secondary-container/8 active:bg-m3-on-secondary-container/12",
3206
+ selected: "bg-m3-secondary text-m3-on-secondary hover:brightness-95 active:brightness-90"
3207
+ },
3208
+ outlined: {
3209
+ default: "border-m3-outline-variant text-m3-on-surface-variant hover:bg-m3-on-surface-variant/8 active:bg-m3-on-surface-variant/12",
3210
+ selected: "bg-m3-inverse-surface text-m3-inverse-on-surface border-transparent hover:brightness-95 active:brightness-90"
3211
+ }
3212
+ };
3213
+ var baseIconButtonClasses = [
3214
+ "relative shrink-0 inline-flex items-center justify-center",
3215
+ "select-none cursor-pointer",
3216
+ "transition-[background-color,color,border-color,box-shadow,opacity,filter] duration-200",
3217
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-m3-primary focus-visible:ring-offset-2",
3218
+ "disabled:pointer-events-none disabled:opacity-[0.38]"
3219
+ ];
3220
+ function resolveAnimateRadius(radiusConfig, shape, isToggle, isSelected) {
3221
+ if (isToggle && isSelected) {
3222
+ return shape === "round" ? radiusConfig.selectedRound : radiusConfig.selectedSquare;
3223
+ }
3224
+ return shape === "round" ? radiusConfig.round : radiusConfig.square;
3225
+ }
3226
+ function resolveDisabledBgClass(colorStyle) {
3227
+ if (colorStyle === "filled" || colorStyle === "tonal") {
3228
+ return "disabled:bg-m3-on-surface/12 disabled:text-m3-on-surface/[0.38]";
3229
+ }
3230
+ if (colorStyle === "outlined") {
3231
+ return "disabled:text-m3-on-surface/[0.38] disabled:border-m3-on-surface/[0.12]";
3232
+ }
3233
+ return "disabled:text-m3-on-surface/[0.38]";
3234
+ }
3235
+ var IconButtonComponent = React11__namespace.forwardRef(
3236
+ (_a, ref) => {
3237
+ var _b = _a, {
3238
+ className,
3239
+ style,
3240
+ variant = "default",
3241
+ colorStyle = "standard",
3242
+ size = "sm",
3243
+ shape = "round",
3244
+ selected,
3245
+ loading = false,
3246
+ loadingVariant = "loading-indicator",
3247
+ iconSize,
3248
+ children,
3249
+ onClick,
3250
+ onKeyDown,
3251
+ "aria-label": ariaLabel
3252
+ } = _b, restProps = __objRest(_b, [
3253
+ "className",
3254
+ "style",
3255
+ "variant",
3256
+ "colorStyle",
3257
+ "size",
3258
+ "shape",
3259
+ "selected",
3260
+ "loading",
3261
+ "loadingVariant",
3262
+ "iconSize",
3263
+ "children",
3264
+ "onClick",
3265
+ "onKeyDown",
3266
+ "aria-label"
3267
+ ]);
3268
+ var _a2, _b2;
3269
+ const isToggle = variant === "toggle";
3270
+ const isSelected = isToggle && !!selected;
3271
+ const resolvedColorClass = React11__namespace.useMemo(
3272
+ () => isSelected ? colorStyles[colorStyle].selected : colorStyles[colorStyle].default,
3273
+ [isSelected, colorStyle]
3274
+ );
3275
+ const outlineWidthClass = React11__namespace.useMemo(
3276
+ () => {
3277
+ var _a3;
3278
+ return colorStyle === "outlined" && !isSelected ? (_a3 = SIZE_OUTLINE_WIDTH[size]) != null ? _a3 : "border" : "";
3279
+ },
3280
+ [colorStyle, isSelected, size]
3281
+ );
3282
+ const disabledBgClass = React11__namespace.useMemo(
3283
+ () => resolveDisabledBgClass(colorStyle),
3284
+ [colorStyle]
3285
+ );
3286
+ const radiusConfig = (_a2 = RADIUS_MAP[size]) != null ? _a2 : RADIUS_MAP.sm;
3287
+ const animateRadius = resolveAnimateRadius(
3288
+ radiusConfig,
3289
+ shape,
3290
+ isToggle,
3291
+ isSelected
3292
+ );
3293
+ const pressedRadius = radiusConfig.pressed;
3294
+ const sizeIcon = (_b2 = SIZE_ICON3[size]) != null ? _b2 : SIZE_ICON3.sm;
3295
+ const iconClass = sizeIcon.cls;
3296
+ const defaultIconPx = sizeIcon.px;
3297
+ const iconPx = iconSize != null ? iconSize : defaultIconPx;
3298
+ const isCustomSize = iconSize != null && iconSize !== "inherit";
3299
+ const needsTouchTarget = size === "xs" || size === "sm";
3300
+ const { ripples, onPointerDown, removeRipple } = useRippleState({
3301
+ disabled: loading
3302
+ });
3303
+ const handleClick = React11__namespace.useCallback(
3304
+ (e) => {
3305
+ if (loading) {
3306
+ e.preventDefault();
3307
+ return;
3308
+ }
3309
+ onClick == null ? void 0 : onClick(e);
3310
+ },
3311
+ [loading, onClick]
3312
+ );
3313
+ const handleKeyDown = React11__namespace.useCallback(
3314
+ (e) => {
3315
+ if (loading) return;
3316
+ if ((e.key === "Enter" || e.key === " ") && onClick) {
3317
+ e.preventDefault();
3318
+ e.currentTarget.click();
3319
+ }
3320
+ onKeyDown == null ? void 0 : onKeyDown(e);
3321
+ },
3322
+ [loading, onClick, onKeyDown]
3323
+ );
3324
+ return /* @__PURE__ */ jsxRuntime.jsx(react.LazyMotion, { features: react.domMax, strict: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
3325
+ react.m.button,
3326
+ __spreadProps(__spreadValues({
3327
+ ref,
3328
+ type: "button",
3329
+ "aria-pressed": isToggle ? isSelected : void 0,
3330
+ "aria-label": ariaLabel,
3331
+ "aria-busy": loading || void 0,
3332
+ "aria-disabled": loading || restProps.disabled,
3333
+ onClick: handleClick,
3334
+ onPointerDown,
3335
+ onKeyDown: handleKeyDown,
3336
+ style,
3337
+ animate: { borderRadius: animateRadius },
3338
+ whileTap: { borderRadius: pressedRadius },
3339
+ transition: { borderRadius: SPRING_TRANSITION_FAST },
3340
+ className: cn(
3341
+ baseIconButtonClasses,
3342
+ resolvedColorClass,
3343
+ outlineWidthClass,
3344
+ disabledBgClass,
3345
+ "overflow-hidden",
3346
+ SIZE_STYLES2[size],
3347
+ loading && "pointer-events-none opacity-75 cursor-not-allowed",
3348
+ className
3349
+ )
3350
+ }, restProps), {
3351
+ children: [
3352
+ needsTouchTarget && /* @__PURE__ */ jsxRuntime.jsx(TouchTarget, {}),
3353
+ /* @__PURE__ */ jsxRuntime.jsx(Ripple, { ripples, onRippleDone: removeRipple }),
3354
+ /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { mode: "wait", initial: false, children: loading ? /* @__PURE__ */ jsxRuntime.jsx(
3355
+ react.m.span,
3356
+ __spreadProps(__spreadValues({}, ICON_SPAN_VARIANTS), {
3357
+ transition: SPRING_TRANSITION,
3358
+ className: cn(
3359
+ "flex items-center justify-center shrink-0",
3360
+ iconSize != null ? void 0 : iconClass
3361
+ ),
3362
+ style: isCustomSize ? { width: `${iconSize}px`, height: `${iconSize}px` } : void 0,
3363
+ children: loadingVariant === "loading-indicator" ? /* @__PURE__ */ jsxRuntime.jsx(
3364
+ LoadingIndicator,
3365
+ {
3366
+ size: typeof iconPx === "number" ? iconPx : defaultIconPx,
3367
+ color: "currentColor",
3368
+ "aria-label": "Loading"
3369
+ }
3370
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
3371
+ ProgressIndicator,
3372
+ {
3373
+ variant: "circular",
3374
+ size: typeof iconPx === "number" ? iconPx : defaultIconPx,
3375
+ color: "currentColor",
3376
+ trackColor: "transparent",
3377
+ "aria-label": "Loading"
3378
+ }
3379
+ )
3380
+ }),
3381
+ "loading"
3382
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
3383
+ react.m.span,
3384
+ __spreadProps(__spreadValues({}, ICON_SPAN_VARIANTS), {
3385
+ transition: SPRING_TRANSITION,
3386
+ "aria-hidden": "true",
3387
+ className: cn(
3388
+ "flex items-center justify-center shrink-0 [&_svg]:w-full [&_svg]:h-full [&_.md-icon]:text-[length:inherit]!",
3389
+ iconSize != null ? void 0 : iconClass
3390
+ ),
3391
+ style: {
3392
+ fontSize: typeof iconPx === "number" ? `${iconPx}px` : iconPx,
3393
+ width: isCustomSize ? `${iconSize}px` : void 0,
3394
+ height: isCustomSize ? `${iconSize}px` : void 0
3395
+ },
3396
+ children
3397
+ }),
3398
+ "content"
3399
+ ) })
3400
+ ]
3401
+ })
3402
+ ) });
3403
+ }
3404
+ );
3405
+ IconButtonComponent.displayName = "IconButton";
3406
+ var IconButton = React11__namespace.memo(IconButtonComponent);
3407
+ var SplitButtonContext = React11__namespace.createContext(null);
3408
+ function useSplitButtonContext() {
3409
+ return React11__namespace.useContext(SplitButtonContext);
3410
+ }
3411
+ var SplitButtonLayoutComponent = React11__namespace.forwardRef(
3412
+ (_a, ref) => {
3413
+ var _b = _a, {
3414
+ leadingButton,
3415
+ trailingButton,
3416
+ className,
3417
+ spacing = 2,
3418
+ variant: layoutVariant,
3419
+ size: layoutSize
3420
+ } = _b, restProps = __objRest(_b, [
3421
+ "leadingButton",
3422
+ "trailingButton",
3423
+ "className",
3424
+ "spacing",
3425
+ "variant",
3426
+ "size"
3427
+ ]);
3428
+ const leadingProps = React11__namespace.isValidElement(leadingButton) ? leadingButton.props : {};
3429
+ const size = layoutSize || leadingProps.size;
3430
+ const variant = layoutVariant || leadingProps.variant;
3431
+ const contextValue = React11__namespace.useMemo(
3432
+ () => ({
3433
+ size,
3434
+ variant
3435
+ }),
3436
+ [size, variant]
3437
+ );
3438
+ return /* @__PURE__ */ jsxRuntime.jsx(SplitButtonContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsxs(
3439
+ "div",
3440
+ __spreadProps(__spreadValues({
3441
+ ref,
3442
+ className: cn(
3443
+ "inline-flex flex-row items-stretch justify-center w-fit shrink-0 relative",
3444
+ className
3445
+ ),
3446
+ style: { gap: `${spacing}px` }
3447
+ }, restProps), {
3448
+ children: [
3449
+ leadingButton,
3450
+ trailingButton
3451
+ ]
3452
+ })
3453
+ ) });
3454
+ }
3455
+ );
3456
+ SplitButtonLayoutComponent.displayName = "SplitButtonLayout";
3457
+ var SplitButtonLayout = React11__namespace.memo(SplitButtonLayoutComponent);
3458
+ var StateLayer = React11__namespace.forwardRef(
3459
+ (_a, ref) => {
3460
+ var _b = _a, { className, hovered, focused, pressed } = _b, props = __objRest(_b, ["className", "hovered", "focused", "pressed"]);
3461
+ let opacity = 0;
3462
+ if (pressed) {
3463
+ opacity = 0.12;
3464
+ } else if (focused) {
3465
+ opacity = 0.1;
3466
+ } else if (hovered) {
3467
+ opacity = 0.08;
3468
+ }
3469
+ return /* @__PURE__ */ jsxRuntime.jsx(react.LazyMotion, { features: react.domMax, strict: true, children: /* @__PURE__ */ jsxRuntime.jsx(
3470
+ react.m.div,
3471
+ __spreadValues({
3472
+ ref,
3473
+ className: cn(
3474
+ "absolute inset-0 bg-current pointer-events-none rounded-[inherit]",
3475
+ className
3476
+ ),
3477
+ initial: false,
3478
+ animate: { opacity },
3479
+ transition: { duration: 0.2 },
3480
+ "aria-hidden": "true"
3481
+ }, props)
3482
+ ) });
3483
+ }
3484
+ );
3485
+ StateLayer.displayName = "StateLayer";
3486
+ var SPLIT_BUTTON_CHEVRON_SPRING = {
3487
+ type: "spring",
3488
+ stiffness: 200,
3489
+ damping: 20,
3490
+ mass: 1
3491
+ };
3492
+ var SPLIT_BUTTON_RADIUS_SPRING = FAST_EFFECTS_SPRING;
3493
+ var SPLIT_BUTTON_TOKENS = {
3494
+ xs: {
3495
+ containerHeight: 32,
3496
+ // XSmallTokens: ContainerHeight = 32.0.dp
3497
+ betweenSpace: 2,
3498
+ // XSmallTokens: BetweenSpace = 2.0.dp
3499
+ innerCorner: {
3500
+ default: m3Tokens.cornerRadius.extraSmall,
3501
+ // 4dp
3502
+ hovered: m3Tokens.cornerRadius.small,
3503
+ // 8dp
3504
+ pressed: m3Tokens.cornerRadius.small
3505
+ // 8dp
3506
+ },
3507
+ outerCornerPercent: 50,
3508
+ // XSmallTokens: OuterCornerCornerSizePercent = 50.0f → full pill
3509
+ leadingPadding: {
3510
+ start: 12,
3511
+ // XSmallTokens: LeadingButtonLeadingSpace = 12.0.dp
3512
+ end: 10
3513
+ // XSmallTokens: LeadingButtonTrailingSpace = 10.0.dp
3514
+ },
3515
+ trailingPadding: {
3516
+ start: 13,
3517
+ // XSmallTokens: TrailingButtonLeadingSpace = 13.0.dp
3518
+ end: 13
3519
+ // XSmallTokens: TrailingButtonTrailingSpace = 13.0.dp
3520
+ },
3521
+ trailingIconSize: 22,
3522
+ // XSmallTokens: TrailingIconSize = 22.0.dp
3523
+ opticalCenterOffset: -1
3524
+ // Spec: XS = -1dp from center
3525
+ },
3526
+ sm: {
3527
+ containerHeight: 40,
3528
+ // SmallTokens: ContainerHeight = 40.0.dp
3529
+ betweenSpace: 2,
3530
+ // SmallTokens: BetweenSpace = 2.0.dp
3531
+ innerCorner: {
3532
+ default: m3Tokens.cornerRadius.extraSmall,
3533
+ // 4dp
3534
+ hovered: m3Tokens.cornerRadius.medium,
3535
+ // 12dp
3536
+ pressed: m3Tokens.cornerRadius.medium
3537
+ // 12dp
3538
+ },
3539
+ outerCornerPercent: 50,
3540
+ leadingPadding: {
3541
+ start: 16,
3542
+ // SmallTokens: LeadingButtonLeadingSpace = 16.0.dp
3543
+ end: 12
3544
+ // SmallTokens: LeadingButtonTrailingSpace = 12.0.dp
3545
+ },
3546
+ trailingPadding: {
3547
+ start: 13,
3548
+ // SmallTokens: TrailingButtonLeadingSpace = 13.0.dp
3549
+ end: 13
3550
+ // SmallTokens: TrailingButtonTrailingSpace = 13.0.dp
3551
+ },
3552
+ trailingIconSize: 22,
3553
+ // SmallTokens: TrailingIconSize = 22.0.dp
3554
+ opticalCenterOffset: -1
3555
+ // Spec: S = -1dp from center
3556
+ },
3557
+ md: {
3558
+ containerHeight: 56,
3559
+ // MediumTokens: ContainerHeight = 56.0.dp
3560
+ betweenSpace: 2,
3561
+ // MediumTokens: BetweenSpace = 2.0.dp
3562
+ innerCorner: {
3563
+ default: m3Tokens.cornerRadius.extraSmall,
3564
+ // 4dp
3565
+ hovered: m3Tokens.cornerRadius.medium,
3566
+ // 12dp
3567
+ pressed: m3Tokens.cornerRadius.medium
3568
+ // 12dp
3569
+ },
3570
+ outerCornerPercent: 50,
3571
+ leadingPadding: {
3572
+ start: 24,
3573
+ // MediumTokens: LeadingButtonLeadingSpace = 24.0.dp
3574
+ end: 24
3575
+ // MediumTokens: LeadingButtonTrailingSpace = 24.0.dp
3576
+ },
3577
+ trailingPadding: {
3578
+ start: 15,
3579
+ // MediumTokens: TrailingButtonLeadingSpace = 15.0.dp
3580
+ end: 15
3581
+ // MediumTokens: TrailingButtonTrailingSpace = 15.0.dp
3582
+ },
3583
+ trailingIconSize: 26,
3584
+ // MediumTokens: TrailingIconSize = 26.0.dp
3585
+ opticalCenterOffset: -2
3586
+ // Spec: M = -2dp from center
3587
+ },
3588
+ lg: {
3589
+ containerHeight: 96,
3590
+ // LargeTokens: ContainerHeight = 96.0.dp
3591
+ betweenSpace: 2,
3592
+ // LargeTokens: BetweenSpace = 2.0.dp
3593
+ innerCorner: {
3594
+ default: m3Tokens.cornerRadius.small,
3595
+ // 8dp
3596
+ hovered: 28,
3597
+ // LargeTokens: InnerHoveredCornerCornerSize = CornerValueLargeIncreased (28dp)
3598
+ pressed: 28
3599
+ // LargeTokens: InnerPressedCornerCornerSize = CornerValueLargeIncreased (28dp)
3600
+ },
3601
+ outerCornerPercent: 50,
3602
+ leadingPadding: {
3603
+ start: 48,
3604
+ // LargeTokens: LeadingButtonLeadingSpace = 48.0.dp
3605
+ end: 48
3606
+ // LargeTokens: LeadingButtonTrailingSpace = 48.0.dp
3607
+ },
3608
+ trailingPadding: {
3609
+ start: 29,
3610
+ // LargeTokens: TrailingButtonLeadingSpace = 29.0.dp
3611
+ end: 29
3612
+ // LargeTokens: TrailingButtonTrailingSpace = 29.0.dp
3613
+ },
3614
+ trailingIconSize: 38,
3615
+ // LargeTokens: TrailingIconSize = 38.0.dp
3616
+ opticalCenterOffset: -3
3617
+ // Spec: L = -3dp from center
3618
+ },
3619
+ xl: {
3620
+ containerHeight: 136,
3621
+ // XLargeTokens: ContainerHeight = 136.0.dp
3622
+ betweenSpace: 2,
3623
+ // XLargeTokens: BetweenSpace = 2.0.dp
3624
+ innerCorner: {
3625
+ default: m3Tokens.cornerRadius.medium,
3626
+ // 12dp
3627
+ hovered: 28,
3628
+ // XLargeTokens: InnerHoveredCornerCornerSize = CornerValueLargeIncreased (28dp)
3629
+ pressed: 28
3630
+ // XLargeTokens: InnerPressedCornerCornerSize = CornerValueLargeIncreased (28dp)
3631
+ },
3632
+ outerCornerPercent: 50,
3633
+ leadingPadding: {
3634
+ start: 64,
3635
+ // XLargeTokens: LeadingButtonLeadingSpace = 64.0.dp
3636
+ end: 64
3637
+ // XLargeTokens: LeadingButtonTrailingSpace = 64.0.dp
3638
+ },
3639
+ trailingPadding: {
3640
+ start: 43,
3641
+ // XLargeTokens: TrailingButtonLeadingSpace = 43.0.dp
3642
+ end: 43
3643
+ // XLargeTokens: TrailingButtonTrailingSpace = 43.0.dp
3644
+ },
3645
+ trailingIconSize: 50,
3646
+ // XLargeTokens: TrailingIconSize = 50.0.dp
3647
+ opticalCenterOffset: -6
3648
+ // Spec: XL = -6dp from center
3649
+ }
3650
+ };
3651
+ var LEADING_ICON_SIZE_FOR_SIZE = {
3652
+ xs: 18,
3653
+ sm: 20,
3654
+ md: 24,
3655
+ lg: 32,
3656
+ xl: 40
3657
+ };
3658
+ var splitButtonSizeVariants = {
3659
+ xs: "min-h-[32px]",
3660
+ sm: "min-h-[40px]",
3661
+ md: "min-h-[56px]",
3662
+ lg: "min-h-[96px]",
3663
+ xl: "min-h-[136px]"
3664
+ };
3665
+ var splitButtonVariants = classVarianceAuthority.cva(
3666
+ "group relative w-fit shrink-0 inline-flex flex-row items-center justify-center whitespace-nowrap select-none cursor-pointer transition-[background-color,color,border-color,box-shadow,opacity,filter] duration-200 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-m3-primary z-10 overflow-hidden",
3667
+ {
3668
+ variants: {
3669
+ variant: {
3670
+ filled: "bg-m3-primary text-m3-on-primary",
3671
+ tonal: "bg-m3-secondary-container text-m3-on-secondary-container",
3672
+ elevated: "bg-m3-surface-container-low text-m3-primary shadow-md hover:shadow-lg",
3673
+ outlined: "bg-transparent text-m3-primary border border-m3-outline"
3674
+ },
3675
+ size: splitButtonSizeVariants,
3676
+ disabled: {
3677
+ true: "pointer-events-none",
3678
+ false: ""
3679
+ }
3680
+ },
3681
+ compoundVariants: [
3682
+ {
3683
+ variant: "filled",
3684
+ disabled: true,
3685
+ className: "bg-m3-on-surface/10 text-m3-on-surface/[0.38]"
3686
+ },
3687
+ {
3688
+ variant: "tonal",
3689
+ disabled: true,
3690
+ className: "bg-m3-on-surface/10 text-m3-on-surface/[0.38]"
3691
+ },
3692
+ {
3693
+ variant: "elevated",
3694
+ disabled: true,
3695
+ className: "bg-m3-on-surface/10 text-m3-on-surface/[0.38] shadow-none"
3696
+ },
3697
+ {
3698
+ variant: "outlined",
3699
+ disabled: true,
3700
+ className: "text-m3-on-surface/[0.38] border-m3-on-surface/[0.12]"
3701
+ }
3702
+ ],
3703
+ defaultVariants: {
3704
+ variant: "filled",
3705
+ size: "sm",
3706
+ disabled: false
3707
+ }
3708
+ }
3709
+ );
3710
+ var SplitButtonLeadingComponent = React11__namespace.forwardRef(
3711
+ (_a, ref) => {
3712
+ var _b = _a, {
3713
+ className,
3714
+ style,
3715
+ variant = "filled",
3716
+ size = "sm",
3717
+ icon,
3718
+ children,
3719
+ disabled,
3720
+ onClick,
3721
+ onPointerDown,
3722
+ onPointerUp,
3723
+ onPointerLeave,
3724
+ onPointerCancel,
3725
+ onFocus,
3726
+ onBlur
3727
+ } = _b, restProps = __objRest(_b, [
3728
+ "className",
3729
+ "style",
3730
+ "variant",
3731
+ "size",
3732
+ "icon",
3733
+ "children",
3734
+ "disabled",
3735
+ "onClick",
3736
+ "onPointerDown",
3737
+ "onPointerUp",
3738
+ "onPointerLeave",
3739
+ "onPointerCancel",
3740
+ "onFocus",
3741
+ "onBlur"
3742
+ ]);
3743
+ var _a2, _b2, _c;
3744
+ const context = useSplitButtonContext();
3745
+ const actualSize = (_a2 = context == null ? void 0 : context.size) != null ? _a2 : size;
3746
+ const actualVariant = (_b2 = context == null ? void 0 : context.variant) != null ? _b2 : variant;
3747
+ const [isHovered, setIsHovered] = React11__namespace.useState(false);
3748
+ const [isFocused, setIsFocused] = React11__namespace.useState(false);
3749
+ const [isPressed, setIsPressed] = React11__namespace.useState(false);
3750
+ const tokens = SPLIT_BUTTON_TOKENS[actualSize];
3751
+ const typographyClass = (_c = BUTTON_TYPOGRAPHY_TOKENS[actualSize]) != null ? _c : BUTTON_TYPOGRAPHY_TOKENS.sm;
3752
+ const needsTouchTarget = actualSize === "xs" || actualSize === "sm";
3753
+ const {
3754
+ ripples,
3755
+ onPointerDown: onRipplePointerDown,
3756
+ removeRipple
3757
+ } = useRippleState({ disabled });
3758
+ const innerCornerRadius = isPressed || isFocused ? tokens.innerCorner.pressed : isHovered ? tokens.innerCorner.hovered : tokens.innerCorner.default;
3759
+ const outerRadius = tokens.containerHeight * tokens.outerCornerPercent / 100;
3760
+ const borderRadius = `${outerRadius}px ${innerCornerRadius}px ${innerCornerRadius}px ${outerRadius}px`;
3761
+ const handleClick = React11__namespace.useCallback(
3762
+ (e) => {
3763
+ if (disabled) {
3764
+ e.preventDefault();
3765
+ return;
3766
+ }
3767
+ onClick == null ? void 0 : onClick(e);
3768
+ },
3769
+ [disabled, onClick]
3770
+ );
3771
+ const handlePointerDown = React11__namespace.useCallback(
3772
+ (e) => {
3773
+ onRipplePointerDown(e);
3774
+ setIsPressed(true);
3775
+ onPointerDown == null ? void 0 : onPointerDown(e);
3776
+ },
3777
+ [onRipplePointerDown, onPointerDown]
3778
+ );
3779
+ const handlePointerUp = React11__namespace.useCallback(
3780
+ (e) => {
3781
+ setIsPressed(false);
3782
+ onPointerUp == null ? void 0 : onPointerUp(e);
3783
+ },
3784
+ [onPointerUp]
3785
+ );
3786
+ const handlePointerEnter = React11__namespace.useCallback(() => {
3787
+ if (!disabled) {
3788
+ setIsHovered(true);
3789
+ }
3790
+ }, [disabled]);
3791
+ const handlePointerLeave = React11__namespace.useCallback(
3792
+ (e) => {
3793
+ setIsHovered(false);
3794
+ setIsPressed(false);
3795
+ onPointerLeave == null ? void 0 : onPointerLeave(e);
3796
+ },
3797
+ [onPointerLeave]
3798
+ );
3799
+ const handlePointerCancel = React11__namespace.useCallback(
3800
+ (e) => {
3801
+ setIsPressed(false);
3802
+ onPointerCancel == null ? void 0 : onPointerCancel(e);
3803
+ },
3804
+ [onPointerCancel]
3805
+ );
3806
+ const handleFocus = React11__namespace.useCallback(
3807
+ (e) => {
3808
+ if (!disabled) setIsFocused(true);
3809
+ onFocus == null ? void 0 : onFocus(e);
3810
+ },
3811
+ [disabled, onFocus]
3812
+ );
3813
+ const handleBlur = React11__namespace.useCallback(
3814
+ (e) => {
3815
+ setIsFocused(false);
3816
+ onBlur == null ? void 0 : onBlur(e);
3817
+ },
3818
+ [onBlur]
3819
+ );
3820
+ const leadingIconSize = LEADING_ICON_SIZE_FOR_SIZE[actualSize];
3821
+ return /* @__PURE__ */ jsxRuntime.jsx(react.LazyMotion, { features: react.domMax, strict: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
3822
+ react.m.button,
3823
+ __spreadProps(__spreadValues({
3824
+ ref,
3825
+ type: "button",
3826
+ "aria-disabled": disabled,
3827
+ disabled,
3828
+ onClick: handleClick,
3829
+ onPointerDown: handlePointerDown,
3830
+ onPointerUp: handlePointerUp,
3831
+ onPointerEnter: handlePointerEnter,
3832
+ onPointerLeave: handlePointerLeave,
3833
+ onPointerCancel: handlePointerCancel,
3834
+ onFocus: handleFocus,
3835
+ onBlur: handleBlur,
3836
+ animate: { borderRadius },
3837
+ transition: SPLIT_BUTTON_RADIUS_SPRING,
3838
+ style: __spreadValues({
3839
+ paddingInlineStart: tokens.leadingPadding.start,
3840
+ paddingInlineEnd: tokens.leadingPadding.end,
3841
+ gap: "8px"
3842
+ }, style),
3843
+ className: cn(
3844
+ splitButtonVariants({
3845
+ variant: actualVariant,
3846
+ size: actualSize,
3847
+ disabled
3848
+ }),
3849
+ typographyClass,
3850
+ className
3851
+ )
3852
+ }, restProps), {
3853
+ children: [
3854
+ needsTouchTarget && /* @__PURE__ */ jsxRuntime.jsx(TouchTarget, {}),
3855
+ /* @__PURE__ */ jsxRuntime.jsx(
3856
+ StateLayer,
3857
+ {
3858
+ hovered: isHovered,
3859
+ focused: isFocused,
3860
+ pressed: isPressed
3861
+ }
3862
+ ),
3863
+ /* @__PURE__ */ jsxRuntime.jsx(Ripple, { ripples, onRippleDone: removeRipple }),
3864
+ icon && /* @__PURE__ */ jsxRuntime.jsx(
3865
+ "span",
3866
+ {
3867
+ className: "flex items-center justify-center shrink-0 [&>svg]:w-full [&>svg]:h-full overflow-hidden [&_.md-icon]:text-[length:inherit]!",
3868
+ style: {
3869
+ fontSize: leadingIconSize,
3870
+ width: leadingIconSize,
3871
+ height: leadingIconSize
3872
+ },
3873
+ children: icon
3874
+ }
3875
+ ),
3876
+ children && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex items-center h-full gap-[inherit]", children })
3877
+ ]
3878
+ })
3879
+ ) });
3880
+ }
3881
+ );
3882
+ SplitButtonLeadingComponent.displayName = "SplitButtonLeading";
3883
+ var SplitButtonLeading = React11__namespace.memo(SplitButtonLeadingComponent);
3884
+ var FilledSplitButtonLeading = React11__namespace.forwardRef((props, ref) => /* @__PURE__ */ jsxRuntime.jsx(SplitButtonLeading, __spreadValues({ ref, variant: "filled" }, props)));
3885
+ FilledSplitButtonLeading.displayName = "FilledSplitButtonLeading";
3886
+ var TonalSplitButtonLeading = React11__namespace.forwardRef((props, ref) => /* @__PURE__ */ jsxRuntime.jsx(SplitButtonLeading, __spreadValues({ ref, variant: "tonal" }, props)));
3887
+ TonalSplitButtonLeading.displayName = "TonalSplitButtonLeading";
3888
+ var ElevatedSplitButtonLeading = React11__namespace.forwardRef((props, ref) => /* @__PURE__ */ jsxRuntime.jsx(SplitButtonLeading, __spreadValues({ ref, variant: "elevated" }, props)));
3889
+ ElevatedSplitButtonLeading.displayName = "ElevatedSplitButtonLeading";
3890
+ var OutlinedSplitButtonLeading = React11__namespace.forwardRef((props, ref) => /* @__PURE__ */ jsxRuntime.jsx(SplitButtonLeading, __spreadValues({ ref, variant: "outlined" }, props)));
3891
+ OutlinedSplitButtonLeading.displayName = "OutlinedSplitButtonLeading";
3892
+ var SplitButtonTrailingComponent = React11__namespace.forwardRef(
3893
+ (_a, ref) => {
3894
+ var _b = _a, {
3895
+ className,
3896
+ style,
3897
+ variant = "filled",
3898
+ size = "sm",
3899
+ checked,
3900
+ onCheckedChange,
3901
+ icon,
3902
+ disabled,
3903
+ onPointerDown,
3904
+ onPointerUp,
3905
+ onPointerLeave,
3906
+ onPointerCancel,
3907
+ onFocus,
3908
+ onBlur,
3909
+ "aria-label": ariaLabel
3910
+ } = _b, restProps = __objRest(_b, [
3911
+ "className",
3912
+ "style",
3913
+ "variant",
3914
+ "size",
3915
+ "checked",
3916
+ "onCheckedChange",
3917
+ "icon",
3918
+ "disabled",
3919
+ "onPointerDown",
3920
+ "onPointerUp",
3921
+ "onPointerLeave",
3922
+ "onPointerCancel",
3923
+ "onFocus",
3924
+ "onBlur",
3925
+ "aria-label"
3926
+ ]);
3927
+ var _a2, _b2;
3928
+ const context = useSplitButtonContext();
3929
+ const actualSize = (_a2 = context == null ? void 0 : context.size) != null ? _a2 : size;
3930
+ const actualVariant = (_b2 = context == null ? void 0 : context.variant) != null ? _b2 : variant;
3931
+ const [isHovered, setIsHovered] = React11__namespace.useState(false);
3932
+ const [isFocused, setIsFocused] = React11__namespace.useState(false);
3933
+ const [isPressed, setIsPressed] = React11__namespace.useState(false);
3934
+ const tokens = SPLIT_BUTTON_TOKENS[actualSize];
3935
+ const prefersReducedMotion = react.useReducedMotion();
3936
+ const needsTouchTarget = actualSize === "xs" || actualSize === "sm";
3937
+ const {
3938
+ ripples,
3939
+ onPointerDown: onRipplePointerDown,
3940
+ removeRipple
3941
+ } = useRippleState({ disabled });
3942
+ const innerCornerRadius = isPressed || isFocused ? tokens.innerCorner.pressed : isHovered ? tokens.innerCorner.hovered : tokens.innerCorner.default;
3943
+ const outerRadius = tokens.containerHeight * tokens.outerCornerPercent / 100;
3944
+ const borderRadius = checked ? `${outerRadius}px ${outerRadius}px ${outerRadius}px ${outerRadius}px` : `${innerCornerRadius}px ${outerRadius}px ${outerRadius}px ${innerCornerRadius}px`;
3945
+ const handleToggle = React11__namespace.useCallback(() => {
3946
+ if (!disabled) {
3947
+ onCheckedChange(!checked);
3948
+ }
3949
+ }, [disabled, checked, onCheckedChange]);
3950
+ const handlePointerDown = React11__namespace.useCallback(
3951
+ (e) => {
3952
+ onRipplePointerDown(e);
3953
+ setIsPressed(true);
3954
+ onPointerDown == null ? void 0 : onPointerDown(e);
3955
+ },
3956
+ [onRipplePointerDown, onPointerDown]
3957
+ );
3958
+ const handlePointerUp = React11__namespace.useCallback(
3959
+ (e) => {
3960
+ setIsPressed(false);
3961
+ onPointerUp == null ? void 0 : onPointerUp(e);
3962
+ },
3963
+ [onPointerUp]
3964
+ );
3965
+ const handlePointerEnter = React11__namespace.useCallback(() => {
3966
+ if (!disabled) {
3967
+ setIsHovered(true);
3968
+ }
3969
+ }, [disabled]);
3970
+ const handlePointerLeave = React11__namespace.useCallback(
3971
+ (e) => {
3972
+ setIsHovered(false);
3973
+ setIsPressed(false);
3974
+ onPointerLeave == null ? void 0 : onPointerLeave(e);
3975
+ },
3976
+ [onPointerLeave]
3977
+ );
3978
+ const handlePointerCancel = React11__namespace.useCallback(
3979
+ (e) => {
3980
+ setIsPressed(false);
3981
+ onPointerCancel == null ? void 0 : onPointerCancel(e);
3982
+ },
3983
+ [onPointerCancel]
3984
+ );
3985
+ const handleFocus = React11__namespace.useCallback(
3986
+ (e) => {
3987
+ if (!disabled) setIsFocused(true);
3988
+ onFocus == null ? void 0 : onFocus(e);
3989
+ },
3990
+ [disabled, onFocus]
3991
+ );
3992
+ const handleBlur = React11__namespace.useCallback(
3993
+ (e) => {
3994
+ setIsFocused(false);
3995
+ onBlur == null ? void 0 : onBlur(e);
3996
+ },
3997
+ [onBlur]
3998
+ );
3999
+ return /* @__PURE__ */ jsxRuntime.jsx(react.LazyMotion, { features: react.domMax, strict: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
4000
+ react.m.button,
4001
+ __spreadProps(__spreadValues({
4002
+ ref,
4003
+ type: "button",
4004
+ "aria-pressed": checked,
4005
+ "aria-expanded": checked,
4006
+ "aria-label": ariaLabel,
4007
+ disabled,
4008
+ onClick: handleToggle,
4009
+ onPointerDown: handlePointerDown,
4010
+ onPointerUp: handlePointerUp,
4011
+ onPointerEnter: handlePointerEnter,
4012
+ onPointerLeave: handlePointerLeave,
4013
+ onPointerCancel: handlePointerCancel,
4014
+ onFocus: handleFocus,
4015
+ onBlur: handleBlur,
4016
+ animate: { borderRadius },
4017
+ transition: SPLIT_BUTTON_RADIUS_SPRING,
4018
+ style: __spreadValues({
4019
+ paddingInlineStart: tokens.trailingPadding.start,
4020
+ paddingInlineEnd: tokens.trailingPadding.end
4021
+ }, style),
4022
+ className: cn(
4023
+ splitButtonVariants({
4024
+ variant: actualVariant,
4025
+ size: actualSize,
4026
+ disabled
4027
+ }),
4028
+ className
4029
+ )
4030
+ }, restProps), {
4031
+ children: [
4032
+ needsTouchTarget && /* @__PURE__ */ jsxRuntime.jsx(TouchTarget, {}),
4033
+ /* @__PURE__ */ jsxRuntime.jsx(
4034
+ StateLayer,
4035
+ {
4036
+ hovered: isHovered,
4037
+ focused: isFocused,
4038
+ pressed: isPressed
4039
+ }
4040
+ ),
4041
+ /* @__PURE__ */ jsxRuntime.jsx(Ripple, { ripples, onRippleDone: removeRipple }),
4042
+ /* @__PURE__ */ jsxRuntime.jsx(
4043
+ react.m.div,
4044
+ {
4045
+ animate: {
4046
+ rotate: checked ? 180 : 0,
4047
+ x: checked ? 0 : tokens.opticalCenterOffset
4048
+ },
4049
+ transition: prefersReducedMotion ? { duration: 0 } : SPLIT_BUTTON_CHEVRON_SPRING,
4050
+ className: "flex items-center justify-center shrink-0",
4051
+ children: icon != null ? icon : /* @__PURE__ */ jsxRuntime.jsx(
4052
+ Icon,
4053
+ {
4054
+ name: "arrow_drop_down",
4055
+ size: tokens.trailingIconSize,
4056
+ opticalSize: 24
4057
+ }
4058
+ )
4059
+ }
4060
+ )
4061
+ ]
4062
+ })
4063
+ ) });
4064
+ }
4065
+ );
4066
+ SplitButtonTrailingComponent.displayName = "SplitButtonTrailing";
4067
+ var SplitButtonTrailing = React11__namespace.memo(SplitButtonTrailingComponent);
4068
+ var FilledSplitButtonTrailing = React11__namespace.forwardRef((props, ref) => /* @__PURE__ */ jsxRuntime.jsx(SplitButtonTrailing, __spreadValues({ ref, variant: "filled" }, props)));
4069
+ FilledSplitButtonTrailing.displayName = "FilledSplitButtonTrailing";
4070
+ var TonalSplitButtonTrailing = React11__namespace.forwardRef((props, ref) => /* @__PURE__ */ jsxRuntime.jsx(SplitButtonTrailing, __spreadValues({ ref, variant: "tonal" }, props)));
4071
+ TonalSplitButtonTrailing.displayName = "TonalSplitButtonTrailing";
4072
+ var ElevatedSplitButtonTrailing = React11__namespace.forwardRef((props, ref) => /* @__PURE__ */ jsxRuntime.jsx(SplitButtonTrailing, __spreadValues({ ref, variant: "elevated" }, props)));
4073
+ ElevatedSplitButtonTrailing.displayName = "ElevatedSplitButtonTrailing";
4074
+ var OutlinedSplitButtonTrailing = React11__namespace.forwardRef((props, ref) => /* @__PURE__ */ jsxRuntime.jsx(SplitButtonTrailing, __spreadValues({ ref, variant: "outlined" }, props)));
4075
+ OutlinedSplitButtonTrailing.displayName = "OutlinedSplitButtonTrailing";
4076
+ var SplitButtonTrailingUncheckableComponent = React11__namespace.forwardRef(
4077
+ (_a, ref) => {
4078
+ var _b = _a, {
4079
+ className,
4080
+ style,
4081
+ variant = "filled",
4082
+ size = "sm",
4083
+ icon,
4084
+ disabled,
4085
+ onClick,
4086
+ onPointerDown,
4087
+ onPointerUp,
4088
+ onPointerLeave,
4089
+ onPointerCancel,
4090
+ onFocus,
4091
+ onBlur,
4092
+ "aria-label": ariaLabel
4093
+ } = _b, restProps = __objRest(_b, [
4094
+ "className",
4095
+ "style",
4096
+ "variant",
4097
+ "size",
4098
+ "icon",
4099
+ "disabled",
4100
+ "onClick",
4101
+ "onPointerDown",
4102
+ "onPointerUp",
4103
+ "onPointerLeave",
4104
+ "onPointerCancel",
4105
+ "onFocus",
4106
+ "onBlur",
4107
+ "aria-label"
4108
+ ]);
4109
+ var _a2, _b2;
4110
+ const context = useSplitButtonContext();
4111
+ const actualSize = (_a2 = context == null ? void 0 : context.size) != null ? _a2 : size;
4112
+ const actualVariant = (_b2 = context == null ? void 0 : context.variant) != null ? _b2 : variant;
4113
+ const [isHovered, setIsHovered] = React11__namespace.useState(false);
4114
+ const [isFocused, setIsFocused] = React11__namespace.useState(false);
4115
+ const [isPressed, setIsPressed] = React11__namespace.useState(false);
4116
+ const tokens = SPLIT_BUTTON_TOKENS[actualSize];
4117
+ const needsTouchTarget = actualSize === "xs" || actualSize === "sm";
4118
+ const {
4119
+ ripples,
4120
+ onPointerDown: onRipplePointerDown,
4121
+ removeRipple
4122
+ } = useRippleState({ disabled });
4123
+ const innerCornerRadius = isPressed || isFocused ? tokens.innerCorner.pressed : isHovered ? tokens.innerCorner.hovered : tokens.innerCorner.default;
4124
+ const outerRadius = tokens.containerHeight * tokens.outerCornerPercent / 100;
4125
+ const borderRadius = `${innerCornerRadius}px ${outerRadius}px ${outerRadius}px ${innerCornerRadius}px`;
4126
+ const handlePointerDown = React11__namespace.useCallback(
4127
+ (e) => {
4128
+ onRipplePointerDown(e);
4129
+ setIsPressed(true);
4130
+ onPointerDown == null ? void 0 : onPointerDown(e);
4131
+ },
4132
+ [onRipplePointerDown, onPointerDown]
4133
+ );
4134
+ const handlePointerUp = React11__namespace.useCallback(
4135
+ (e) => {
4136
+ setIsPressed(false);
4137
+ onPointerUp == null ? void 0 : onPointerUp(e);
4138
+ },
4139
+ [onPointerUp]
4140
+ );
4141
+ const handlePointerEnter = React11__namespace.useCallback(() => {
4142
+ if (!disabled) {
4143
+ setIsHovered(true);
4144
+ }
4145
+ }, [disabled]);
4146
+ const handlePointerLeave = React11__namespace.useCallback(
4147
+ (e) => {
4148
+ setIsHovered(false);
4149
+ setIsPressed(false);
4150
+ onPointerLeave == null ? void 0 : onPointerLeave(e);
4151
+ },
4152
+ [onPointerLeave]
4153
+ );
4154
+ const handlePointerCancel = React11__namespace.useCallback(
4155
+ (e) => {
4156
+ setIsPressed(false);
4157
+ onPointerCancel == null ? void 0 : onPointerCancel(e);
4158
+ },
4159
+ [onPointerCancel]
4160
+ );
4161
+ const handleFocus = React11__namespace.useCallback(
4162
+ (e) => {
4163
+ if (!disabled) setIsFocused(true);
4164
+ onFocus == null ? void 0 : onFocus(e);
4165
+ },
4166
+ [disabled, onFocus]
4167
+ );
4168
+ const handleBlur = React11__namespace.useCallback(
4169
+ (e) => {
4170
+ setIsFocused(false);
4171
+ onBlur == null ? void 0 : onBlur(e);
4172
+ },
4173
+ [onBlur]
4174
+ );
4175
+ return /* @__PURE__ */ jsxRuntime.jsx(react.LazyMotion, { features: react.domMax, strict: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
4176
+ react.m.button,
4177
+ __spreadProps(__spreadValues({
4178
+ ref,
4179
+ type: "button",
4180
+ "aria-label": ariaLabel,
4181
+ disabled,
4182
+ onClick,
4183
+ onPointerDown: handlePointerDown,
4184
+ onPointerUp: handlePointerUp,
4185
+ onPointerEnter: handlePointerEnter,
4186
+ onPointerLeave: handlePointerLeave,
4187
+ onPointerCancel: handlePointerCancel,
4188
+ onFocus: handleFocus,
4189
+ onBlur: handleBlur,
4190
+ animate: { borderRadius },
4191
+ transition: SPLIT_BUTTON_RADIUS_SPRING,
4192
+ style: __spreadValues({
4193
+ paddingInlineStart: tokens.trailingPadding.start,
4194
+ paddingInlineEnd: tokens.trailingPadding.end
4195
+ }, style),
4196
+ className: cn(
4197
+ splitButtonVariants({
4198
+ variant: actualVariant,
4199
+ size: actualSize,
4200
+ disabled
4201
+ }),
4202
+ className
4203
+ )
4204
+ }, restProps), {
4205
+ children: [
4206
+ needsTouchTarget && /* @__PURE__ */ jsxRuntime.jsx(TouchTarget, {}),
4207
+ /* @__PURE__ */ jsxRuntime.jsx(
4208
+ StateLayer,
4209
+ {
4210
+ hovered: isHovered,
4211
+ focused: isFocused,
4212
+ pressed: isPressed
4213
+ }
4214
+ ),
4215
+ /* @__PURE__ */ jsxRuntime.jsx(Ripple, { ripples, onRippleDone: removeRipple }),
4216
+ /* @__PURE__ */ jsxRuntime.jsx(
4217
+ react.m.div,
4218
+ {
4219
+ animate: { x: tokens.opticalCenterOffset },
4220
+ transition: SPLIT_BUTTON_RADIUS_SPRING,
4221
+ className: "flex items-center justify-center shrink-0 [&>svg]:w-full [&>svg]:h-full",
4222
+ style: {
4223
+ width: tokens.trailingIconSize,
4224
+ height: tokens.trailingIconSize
4225
+ },
4226
+ children: icon
4227
+ }
4228
+ )
4229
+ ]
4230
+ })
4231
+ ) });
4232
+ }
4233
+ );
4234
+ SplitButtonTrailingUncheckableComponent.displayName = "SplitButtonTrailingUncheckable";
4235
+ var SplitButtonTrailingUncheckable = React11__namespace.memo(
4236
+ SplitButtonTrailingUncheckableComponent
4237
+ );
4238
+ var FilledSplitButtonTrailingUncheckable = React11__namespace.forwardRef((props, ref) => /* @__PURE__ */ jsxRuntime.jsx(SplitButtonTrailingUncheckable, __spreadValues({ ref, variant: "filled" }, props)));
4239
+ FilledSplitButtonTrailingUncheckable.displayName = "FilledSplitButtonTrailingUncheckable";
4240
+ var TonalSplitButtonTrailingUncheckable = React11__namespace.forwardRef((props, ref) => /* @__PURE__ */ jsxRuntime.jsx(SplitButtonTrailingUncheckable, __spreadValues({ ref, variant: "tonal" }, props)));
4241
+ TonalSplitButtonTrailingUncheckable.displayName = "TonalSplitButtonTrailingUncheckable";
4242
+ var ElevatedSplitButtonTrailingUncheckable = React11__namespace.forwardRef((props, ref) => /* @__PURE__ */ jsxRuntime.jsx(SplitButtonTrailingUncheckable, __spreadValues({ ref, variant: "elevated" }, props)));
4243
+ ElevatedSplitButtonTrailingUncheckable.displayName = "ElevatedSplitButtonTrailingUncheckable";
4244
+ var OutlinedSplitButtonTrailingUncheckable = React11__namespace.forwardRef((props, ref) => /* @__PURE__ */ jsxRuntime.jsx(SplitButtonTrailingUncheckable, __spreadValues({ ref, variant: "outlined" }, props)));
4245
+ OutlinedSplitButtonTrailingUncheckable.displayName = "OutlinedSplitButtonTrailingUncheckable";
4246
+
4247
+ exports.BUTTON_COLOR_TOKENS = BUTTON_COLOR_TOKENS;
4248
+ exports.BUTTON_GROUP_TOKENS = BUTTON_GROUP_TOKENS;
4249
+ exports.BUTTON_SIZE_TOKENS = BUTTON_SIZE_TOKENS;
4250
+ exports.Button = Button;
4251
+ exports.ButtonGroup = ButtonGroup;
4252
+ exports.ButtonGroupDefaults = ButtonGroupDefaults;
4253
+ exports.ElevatedSplitButtonLeading = ElevatedSplitButtonLeading;
4254
+ exports.ElevatedSplitButtonTrailing = ElevatedSplitButtonTrailing;
4255
+ exports.ElevatedSplitButtonTrailingUncheckable = ElevatedSplitButtonTrailingUncheckable;
4256
+ exports.ExtendedFAB = ExtendedFAB;
4257
+ exports.FAB = FAB;
4258
+ exports.FABMenu = FABMenu;
4259
+ exports.FABMenuItem = FABMenuItem;
4260
+ exports.FABPosition = FABPosition;
4261
+ exports.FilledSplitButtonLeading = FilledSplitButtonLeading;
4262
+ exports.FilledSplitButtonTrailing = FilledSplitButtonTrailing;
4263
+ exports.FilledSplitButtonTrailingUncheckable = FilledSplitButtonTrailingUncheckable;
4264
+ exports.IconButton = IconButton;
4265
+ exports.LEADING_ICON_SIZE_FOR_SIZE = LEADING_ICON_SIZE_FOR_SIZE;
4266
+ exports.OutlinedSplitButtonLeading = OutlinedSplitButtonLeading;
4267
+ exports.OutlinedSplitButtonTrailing = OutlinedSplitButtonTrailing;
4268
+ exports.OutlinedSplitButtonTrailingUncheckable = OutlinedSplitButtonTrailingUncheckable;
4269
+ exports.SPLIT_BUTTON_CHEVRON_SPRING = SPLIT_BUTTON_CHEVRON_SPRING;
4270
+ exports.SPLIT_BUTTON_RADIUS_SPRING = SPLIT_BUTTON_RADIUS_SPRING;
4271
+ exports.SPLIT_BUTTON_TOKENS = SPLIT_BUTTON_TOKENS;
4272
+ exports.SplitButtonLayout = SplitButtonLayout;
4273
+ exports.SplitButtonLeading = SplitButtonLeading;
4274
+ exports.SplitButtonTrailing = SplitButtonTrailing;
4275
+ exports.SplitButtonTrailingUncheckable = SplitButtonTrailingUncheckable;
4276
+ exports.ToggleFAB = ToggleFAB;
4277
+ exports.TonalSplitButtonLeading = TonalSplitButtonLeading;
4278
+ exports.TonalSplitButtonTrailing = TonalSplitButtonTrailing;
4279
+ exports.TonalSplitButtonTrailingUncheckable = TonalSplitButtonTrailingUncheckable;
4280
+ exports.splitButtonVariants = splitButtonVariants;
4281
+ //# sourceMappingURL=buttons.js.map
4282
+ //# sourceMappingURL=buttons.js.map