@bug-on/md3-react 2.0.3 → 3.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 (308) hide show
  1. package/.turbo/turbo-build.log +33 -0
  2. package/CHANGELOG.md +55 -0
  3. package/dist/index.css.d.ts +2 -0
  4. package/dist/index.d.mts +6127 -0
  5. package/dist/index.d.ts +6127 -71
  6. package/dist/index.js +1653 -614
  7. package/dist/index.js.map +1 -1
  8. package/dist/index.mjs +1566 -547
  9. package/dist/index.mjs.map +1 -1
  10. package/dist/material-symbols-cdn.css.d.ts +2 -0
  11. package/dist/material-symbols-self-hosted.css.d.ts +2 -0
  12. package/dist/typography.css.d.ts +2 -0
  13. package/package.json +22 -19
  14. package/scripts/copy-assets.js +82 -0
  15. package/src/assets/fonts/GoogleSansFlex-VariableFont.woff2 +0 -0
  16. package/src/assets/fonts/MaterialSymbolsOutlined-VariableFont_FILL,GRAD,opsz,wght.ttf +0 -0
  17. package/src/assets/fonts/MaterialSymbolsRounded-VariableFont_FILL,GRAD,opsz,wght.ttf +0 -0
  18. package/src/assets/fonts/MaterialSymbolsSharp-VariableFont_FILL,GRAD,opsz,wght.ttf +0 -0
  19. package/src/assets/loading-indicator.svg +19 -0
  20. package/src/assets/material-symbols-cdn.css +65 -0
  21. package/src/assets/material-symbols-self-hosted.css +90 -0
  22. package/src/css.d.ts +20 -0
  23. package/src/hooks/useClickOutside.ts +37 -0
  24. package/src/hooks/useMediaQuery.ts +28 -0
  25. package/src/hooks/useRipple.ts +88 -0
  26. package/src/index.css +23 -0
  27. package/src/index.ts +349 -0
  28. package/src/lib/material-symbols-preconnect.tsx +82 -0
  29. package/src/lib/theme-utils.ts +180 -0
  30. package/src/lib/utils.ts +6 -0
  31. package/src/test/button.test.tsx +59 -0
  32. package/src/test/icon.test.tsx +91 -0
  33. package/src/test/loading-indicator.test.tsx +128 -0
  34. package/src/test/progress-indicator.test.tsx +306 -0
  35. package/src/test/setup.ts +80 -0
  36. package/src/test/typography.test.tsx +206 -0
  37. package/src/types/index.ts +7 -0
  38. package/src/types/md3.ts +31 -0
  39. package/src/ui/Text.tsx +60 -0
  40. package/src/ui/__snapshots__/divider.test.tsx.snap +63 -0
  41. package/src/ui/app-bar/app-bar-column.tsx +99 -0
  42. package/src/ui/app-bar/app-bar-item-button.tsx +71 -0
  43. package/src/ui/app-bar/app-bar-items.test.tsx +89 -0
  44. package/src/ui/app-bar/app-bar-overflow-indicator.tsx +108 -0
  45. package/src/ui/app-bar/app-bar-row.tsx +104 -0
  46. package/src/ui/app-bar/app-bar.test.tsx +87 -0
  47. package/src/ui/app-bar/app-bar.tokens.ts +223 -0
  48. package/src/ui/app-bar/app-bar.types.ts +441 -0
  49. package/src/ui/app-bar/bottom-app-bar.test.tsx +42 -0
  50. package/src/ui/app-bar/bottom-app-bar.tsx +84 -0
  51. package/src/ui/app-bar/docked-toolbar.test.tsx +34 -0
  52. package/src/ui/app-bar/docked-toolbar.tsx +54 -0
  53. package/src/ui/app-bar/flexible-app-bar.test.tsx +75 -0
  54. package/src/ui/app-bar/hooks/use-app-bar-scroll.ts +110 -0
  55. package/src/ui/app-bar/hooks/use-flexible-app-bar.ts +123 -0
  56. package/{dist/ui/app-bar/index.d.ts → src/ui/app-bar/index.ts} +35 -2
  57. package/src/ui/app-bar/large-flexible-app-bar.tsx +165 -0
  58. package/src/ui/app-bar/medium-flexible-app-bar.tsx +167 -0
  59. package/src/ui/app-bar/search-app-bar.test.tsx +49 -0
  60. package/src/ui/app-bar/search-app-bar.tsx +176 -0
  61. package/src/ui/app-bar/search-view.tsx +227 -0
  62. package/src/ui/app-bar/small-app-bar.test.tsx +48 -0
  63. package/src/ui/app-bar/small-app-bar.tsx +203 -0
  64. package/src/ui/badge.test.tsx +345 -0
  65. package/src/ui/badge.tsx +282 -0
  66. package/src/ui/button-group.test.tsx +71 -0
  67. package/src/ui/button-group.tsx +350 -0
  68. package/src/ui/button.test.tsx +297 -0
  69. package/src/ui/button.tsx +669 -0
  70. package/src/ui/card.test.tsx +187 -0
  71. package/src/ui/card.tsx +259 -0
  72. package/src/ui/checkbox.test.tsx +423 -0
  73. package/src/ui/checkbox.tsx +525 -0
  74. package/src/ui/chip.test.tsx +292 -0
  75. package/src/ui/chip.tsx +548 -0
  76. package/src/ui/code-block.tsx +219 -0
  77. package/src/ui/dialog.test.tsx +300 -0
  78. package/src/ui/dialog.tsx +384 -0
  79. package/src/ui/divider.test.tsx +314 -0
  80. package/src/ui/divider.tsx +412 -0
  81. package/src/ui/drawer.tsx +240 -0
  82. package/src/ui/fab-menu.test.tsx +494 -0
  83. package/src/ui/fab-menu.tsx +739 -0
  84. package/src/ui/fab.test.tsx +232 -0
  85. package/src/ui/fab.tsx +505 -0
  86. package/src/ui/icon-button.test.tsx +515 -0
  87. package/src/ui/icon-button.tsx +525 -0
  88. package/src/ui/icon.test.tsx +197 -0
  89. package/src/ui/icon.tsx +179 -0
  90. package/src/ui/loading-indicator.test.tsx +73 -0
  91. package/src/ui/loading-indicator.tsx +312 -0
  92. package/src/ui/menu/context-menu.tsx +275 -0
  93. package/src/ui/menu/index.ts +77 -0
  94. package/src/ui/menu/menu-animations.ts +102 -0
  95. package/src/ui/menu/menu-context.tsx +99 -0
  96. package/src/ui/menu/menu-divider.tsx +47 -0
  97. package/src/ui/menu/menu-group.tsx +200 -0
  98. package/src/ui/menu/menu-item.tsx +294 -0
  99. package/src/ui/menu/menu-tokens.ts +208 -0
  100. package/src/ui/menu/menu-types.ts +313 -0
  101. package/src/ui/menu/menu.test.tsx +624 -0
  102. package/src/ui/menu/menu.tsx +289 -0
  103. package/src/ui/menu/sub-menu.tsx +223 -0
  104. package/src/ui/menu/vertical-menu.tsx +382 -0
  105. package/src/ui/navigation-rail.test.tsx +404 -0
  106. package/src/ui/navigation-rail.tsx +604 -0
  107. package/src/ui/progress-indicator/circular.tsx +248 -0
  108. package/src/ui/progress-indicator/hooks.ts +51 -0
  109. package/{dist/ui/progress-indicator/index.d.ts → src/ui/progress-indicator/index.tsx} +20 -2
  110. package/src/ui/progress-indicator/linear-flat.tsx +83 -0
  111. package/src/ui/progress-indicator/linear-wavy.tsx +243 -0
  112. package/src/ui/progress-indicator/linear.tsx +143 -0
  113. package/src/ui/progress-indicator/types.ts +158 -0
  114. package/src/ui/progress-indicator/utils.ts +73 -0
  115. package/src/ui/radio-button.test.tsx +407 -0
  116. package/src/ui/radio-button.tsx +551 -0
  117. package/src/ui/ripple.test.tsx +72 -0
  118. package/src/ui/ripple.tsx +234 -0
  119. package/src/ui/scroll-area.test.tsx +58 -0
  120. package/src/ui/scroll-area.tsx +139 -0
  121. package/src/ui/search/animated-placeholder.tsx +145 -0
  122. package/src/ui/search/hooks/use-search-keyboard.test.ts +202 -0
  123. package/src/ui/search/hooks/use-search-keyboard.ts +104 -0
  124. package/src/ui/search/hooks/use-search-view-focus.test.ts +96 -0
  125. package/src/ui/search/hooks/use-search-view-focus.ts +24 -0
  126. package/src/ui/search/index.ts +44 -0
  127. package/src/ui/search/search-bar.tsx +220 -0
  128. package/src/ui/search/search-context.tsx +42 -0
  129. package/src/ui/search/search-view-docked.tsx +194 -0
  130. package/src/ui/search/search-view-fullscreen.tsx +247 -0
  131. package/src/ui/search/search.test.tsx +233 -0
  132. package/src/ui/search/search.tokens.ts +134 -0
  133. package/src/ui/search/search.tsx +131 -0
  134. package/src/ui/search/search.types.ts +154 -0
  135. package/src/ui/search/trailing-action.tsx +49 -0
  136. package/src/ui/shared/constants.ts +122 -0
  137. package/{dist/ui/shared/touch-target.d.ts → src/ui/shared/touch-target.tsx} +13 -1
  138. package/src/ui/slider/hooks/useSliderMath.ts +195 -0
  139. package/{dist/ui/slider/index.d.ts → src/ui/slider/index.ts} +12 -1
  140. package/src/ui/slider/range-slider.tsx +561 -0
  141. package/src/ui/slider/slider-thumb.tsx +379 -0
  142. package/src/ui/slider/slider-track.tsx +912 -0
  143. package/src/ui/slider/slider.tokens.ts +189 -0
  144. package/src/ui/slider/slider.tsx +259 -0
  145. package/src/ui/slider/slider.types.ts +288 -0
  146. package/src/ui/snackbar/index.ts +20 -0
  147. package/src/ui/snackbar/snackbar.test.tsx +338 -0
  148. package/src/ui/snackbar/snackbar.tsx +476 -0
  149. package/{dist/ui/switch/index.d.ts → src/ui/switch/index.ts} +1 -0
  150. package/src/ui/switch/switch.stories.tsx +309 -0
  151. package/src/ui/switch/switch.test.tsx +243 -0
  152. package/src/ui/switch/switch.tokens.ts +89 -0
  153. package/src/ui/switch/switch.tsx +504 -0
  154. package/src/ui/switch/switch.types.ts +62 -0
  155. package/{dist/ui/tabs/index.d.ts → src/ui/tabs/index.ts} +8 -1
  156. package/src/ui/tabs/tab.tsx +407 -0
  157. package/src/ui/tabs/tabs-content.tsx +89 -0
  158. package/src/ui/tabs/tabs-list.tsx +146 -0
  159. package/src/ui/tabs/tabs.test.tsx +290 -0
  160. package/src/ui/tabs/tabs.tokens.ts +121 -0
  161. package/src/ui/tabs/tabs.tsx +229 -0
  162. package/src/ui/tabs/tabs.types.ts +185 -0
  163. package/{dist/ui/text-field/index.d.ts → src/ui/text-field/index.ts} +8 -1
  164. package/src/ui/text-field/subcomponents/active-indicator.tsx +67 -0
  165. package/src/ui/text-field/subcomponents/floating-label.tsx +161 -0
  166. package/src/ui/text-field/subcomponents/leading-icon.tsx +46 -0
  167. package/src/ui/text-field/subcomponents/outline-container.tsx +170 -0
  168. package/src/ui/text-field/subcomponents/prefix-suffix.tsx +59 -0
  169. package/src/ui/text-field/subcomponents/supporting-text.tsx +145 -0
  170. package/src/ui/text-field/subcomponents/trailing-icon.tsx +199 -0
  171. package/src/ui/text-field/text-field.test.tsx +454 -0
  172. package/src/ui/text-field/text-field.tokens.ts +104 -0
  173. package/src/ui/text-field/text-field.tsx +548 -0
  174. package/src/ui/text-field/text-field.types.ts +180 -0
  175. package/src/ui/theme-provider/index.tsx +190 -0
  176. package/src/ui/toc.test.tsx +108 -0
  177. package/src/ui/toc.tsx +172 -0
  178. package/src/ui/tooltip/plain-tooltip.tsx +63 -0
  179. package/src/ui/tooltip/rich-tooltip.tsx +94 -0
  180. package/src/ui/tooltip/tooltip-box.tsx +266 -0
  181. package/src/ui/tooltip/tooltip-caret-shape.tsx +68 -0
  182. package/src/ui/tooltip/tooltip.tokens.ts +26 -0
  183. package/src/ui/tooltip/tooltip.types.ts +70 -0
  184. package/src/ui/tooltip/use-tooltip-position.ts +208 -0
  185. package/src/ui/tooltip/use-tooltip-state.ts +41 -0
  186. package/src/ui/typography/__tests__/typography.test.tsx +170 -0
  187. package/{dist/ui/typography/index.d.ts → src/ui/typography/index.ts} +21 -3
  188. package/src/ui/typography/type-scale-tokens.ts +205 -0
  189. package/src/ui/typography/typography-key-tokens.ts +43 -0
  190. package/src/ui/typography/typography-tokens.ts +360 -0
  191. package/src/ui/typography/typography.css +22 -0
  192. package/src/ui/typography/typography.tsx +559 -0
  193. package/test-render.tsx +4 -0
  194. package/test-shadow.html +26 -0
  195. package/test_output.txt +164 -0
  196. package/test_output_v2.txt +5 -0
  197. package/tsconfig.build.json +10 -0
  198. package/tsconfig.json +18 -0
  199. package/tsup.config.ts +20 -0
  200. package/vitest.config.ts +11 -0
  201. package/dist/hooks/useClickOutside.d.ts +0 -8
  202. package/dist/hooks/useMediaQuery.d.ts +0 -11
  203. package/dist/hooks/useRipple.d.ts +0 -26
  204. package/dist/lib/material-symbols-preconnect.d.ts +0 -42
  205. package/dist/lib/theme-utils.d.ts +0 -63
  206. package/dist/lib/utils.d.ts +0 -2
  207. package/dist/types/index.d.ts +0 -1
  208. package/dist/types/md3.d.ts +0 -14
  209. package/dist/ui/app-bar/app-bar-column.d.ts +0 -28
  210. package/dist/ui/app-bar/app-bar-item-button.d.ts +0 -16
  211. package/dist/ui/app-bar/app-bar-overflow-indicator.d.ts +0 -18
  212. package/dist/ui/app-bar/app-bar-row.d.ts +0 -36
  213. package/dist/ui/app-bar/app-bar.tokens.d.ts +0 -184
  214. package/dist/ui/app-bar/app-bar.types.d.ts +0 -392
  215. package/dist/ui/app-bar/bottom-app-bar.d.ts +0 -31
  216. package/dist/ui/app-bar/docked-toolbar.d.ts +0 -25
  217. package/dist/ui/app-bar/hooks/use-app-bar-scroll.d.ts +0 -42
  218. package/dist/ui/app-bar/hooks/use-flexible-app-bar.d.ts +0 -37
  219. package/dist/ui/app-bar/large-flexible-app-bar.d.ts +0 -26
  220. package/dist/ui/app-bar/medium-flexible-app-bar.d.ts +0 -28
  221. package/dist/ui/app-bar/search-app-bar.d.ts +0 -43
  222. package/dist/ui/app-bar/search-view.d.ts +0 -54
  223. package/dist/ui/app-bar/small-app-bar.d.ts +0 -37
  224. package/dist/ui/badge.d.ts +0 -125
  225. package/dist/ui/button-group.d.ts +0 -59
  226. package/dist/ui/button.d.ts +0 -148
  227. package/dist/ui/card.d.ts +0 -62
  228. package/dist/ui/checkbox.d.ts +0 -82
  229. package/dist/ui/chip.d.ts +0 -110
  230. package/dist/ui/code-block.d.ts +0 -14
  231. package/dist/ui/dialog.d.ts +0 -111
  232. package/dist/ui/divider.d.ts +0 -164
  233. package/dist/ui/drawer.d.ts +0 -39
  234. package/dist/ui/dropdown.d.ts +0 -29
  235. package/dist/ui/fab-menu.d.ts +0 -204
  236. package/dist/ui/fab.d.ts +0 -162
  237. package/dist/ui/icon-button.d.ts +0 -131
  238. package/dist/ui/icon.d.ts +0 -88
  239. package/dist/ui/loading-indicator.d.ts +0 -42
  240. package/dist/ui/navigation-rail.d.ts +0 -29
  241. package/dist/ui/progress-indicator/circular.d.ts +0 -3
  242. package/dist/ui/progress-indicator/hooks.d.ts +0 -3
  243. package/dist/ui/progress-indicator/linear-flat.d.ts +0 -10
  244. package/dist/ui/progress-indicator/linear-wavy.d.ts +0 -18
  245. package/dist/ui/progress-indicator/linear.d.ts +0 -3
  246. package/dist/ui/progress-indicator/types.d.ts +0 -151
  247. package/dist/ui/progress-indicator/utils.d.ts +0 -3
  248. package/dist/ui/radio-button.d.ts +0 -106
  249. package/dist/ui/ripple.d.ts +0 -126
  250. package/dist/ui/scroll-area.d.ts +0 -27
  251. package/dist/ui/search/animated-placeholder.d.ts +0 -54
  252. package/dist/ui/search/hooks/use-search-keyboard.d.ts +0 -32
  253. package/dist/ui/search/hooks/use-search-view-focus.d.ts +0 -6
  254. package/dist/ui/search/index.d.ts +0 -27
  255. package/dist/ui/search/search-bar.d.ts +0 -32
  256. package/dist/ui/search/search-context.d.ts +0 -24
  257. package/dist/ui/search/search-view-docked.d.ts +0 -25
  258. package/dist/ui/search/search-view-fullscreen.d.ts +0 -36
  259. package/dist/ui/search/search.d.ts +0 -50
  260. package/dist/ui/search/search.tokens.d.ts +0 -112
  261. package/dist/ui/search/search.types.d.ts +0 -131
  262. package/dist/ui/search/trailing-action.d.ts +0 -9
  263. package/dist/ui/shared/constants.d.ts +0 -86
  264. package/dist/ui/slider/hooks/useSliderMath.d.ts +0 -101
  265. package/dist/ui/slider/range-slider.d.ts +0 -47
  266. package/dist/ui/slider/slider-thumb.d.ts +0 -33
  267. package/dist/ui/slider/slider-track.d.ts +0 -25
  268. package/dist/ui/slider/slider.d.ts +0 -60
  269. package/dist/ui/slider/slider.tokens.d.ts +0 -151
  270. package/dist/ui/slider/slider.types.d.ts +0 -259
  271. package/dist/ui/snackbar/index.d.ts +0 -6
  272. package/dist/ui/snackbar/snackbar.d.ts +0 -197
  273. package/dist/ui/switch/switch.d.ts +0 -30
  274. package/dist/ui/switch/switch.stories.d.ts +0 -48
  275. package/dist/ui/switch/switch.tokens.d.ts +0 -67
  276. package/dist/ui/switch/switch.types.d.ts +0 -59
  277. package/dist/ui/tabs/tab.d.ts +0 -43
  278. package/dist/ui/tabs/tabs-content.d.ts +0 -36
  279. package/dist/ui/tabs/tabs-list.d.ts +0 -40
  280. package/dist/ui/tabs/tabs.d.ts +0 -60
  281. package/dist/ui/tabs/tabs.tokens.d.ts +0 -94
  282. package/dist/ui/tabs/tabs.types.d.ts +0 -172
  283. package/dist/ui/text-field/subcomponents/active-indicator.d.ts +0 -24
  284. package/dist/ui/text-field/subcomponents/floating-label.d.ts +0 -43
  285. package/dist/ui/text-field/subcomponents/leading-icon.d.ts +0 -23
  286. package/dist/ui/text-field/subcomponents/outline-container.d.ts +0 -42
  287. package/dist/ui/text-field/subcomponents/prefix-suffix.d.ts +0 -24
  288. package/dist/ui/text-field/subcomponents/supporting-text.d.ts +0 -37
  289. package/dist/ui/text-field/subcomponents/trailing-icon.d.ts +0 -41
  290. package/dist/ui/text-field/text-field.d.ts +0 -49
  291. package/dist/ui/text-field/text-field.tokens.d.ts +0 -76
  292. package/dist/ui/text-field/text-field.types.d.ts +0 -126
  293. package/dist/ui/theme-provider/index.d.ts +0 -48
  294. package/dist/ui/toc.d.ts +0 -80
  295. package/dist/ui/tooltip/plain-tooltip.d.ts +0 -2
  296. package/dist/ui/tooltip/rich-tooltip.d.ts +0 -2
  297. package/dist/ui/tooltip/tooltip-box.d.ts +0 -2
  298. package/dist/ui/tooltip/tooltip-caret-shape.d.ts +0 -9
  299. package/dist/ui/tooltip/tooltip.tokens.d.ts +0 -26
  300. package/dist/ui/tooltip/tooltip.types.d.ts +0 -56
  301. package/dist/ui/tooltip/use-tooltip-position.d.ts +0 -8
  302. package/dist/ui/tooltip/use-tooltip-state.d.ts +0 -2
  303. package/dist/ui/typography/type-scale-tokens.d.ts +0 -162
  304. package/dist/ui/typography/typography-key-tokens.d.ts +0 -40
  305. package/dist/ui/typography/typography-tokens.d.ts +0 -220
  306. package/dist/ui/typography/typography.d.ts +0 -265
  307. /package/{dist/hooks/index.d.ts → src/hooks/index.ts} +0 -0
  308. /package/{dist/ui/tooltip/index.d.ts → src/ui/tooltip/index.ts} +0 -0
@@ -1,36 +0,0 @@
1
- /**
2
- * @file search-view-fullscreen.tsx
3
- * MD3 Expressive SearchView — FullScreen variant.
4
- *
5
- * Renders a full-screen overlay via React Portal.
6
- * Using Portal avoids z-index stacking context issues and ensures
7
- * the overlay always covers the entire viewport correctly.
8
- *
9
- * Animation (Option B — MD3 morphing):
10
- * - Shares `layoutId` with SearchBar. After SearchBar exits via its own
11
- * AnimatePresence (mode="popLayout"), this view claims the layoutId and
12
- * Framer Motion morphs the pill shape → full-screen rect (CornerFull → CornerNone).
13
- * - mode="popLayout" on this AnimatePresence enables SearchBar to re-enter
14
- * after this view exits.
15
- * - Focus: double-rAF pattern syncs focus with layout animation frame.
16
- *
17
- * Header height: 72dp per SearchViewTokens.FullScreenHeaderContainerHeight.
18
- * ESC key closes the view (handled by useSearchKeyboard).
19
- */
20
- import * as React from "react";
21
- import type { SearchInternalProps, SearchProps } from "./search.types";
22
- type SearchViewFullScreenProps = Pick<SearchProps, "query" | "onQueryChange" | "onSearch" | "active" | "onActiveChange" | "leadingIcon" | "trailingIcon" | "placeholder" | "textAlign" | "styleType" | "children" | "viewClassName" | "aria-label"> & SearchInternalProps & {
23
- onKeyDown: (e: React.KeyboardEvent) => void;
24
- activeIndex: number;
25
- };
26
- /**
27
- * SearchView FullScreen — full-screen overlay via React Portal.
28
- *
29
- * The `layoutId` shared with SearchBar enables Framer Motion to animate
30
- * the shape morphing from the pill (rounded-full) to a full-screen rect.
31
- *
32
- * Contained style: no divider, background preserved.
33
- * Divided style: HorizontalDivider between header and results.
34
- */
35
- export declare function SearchViewFullScreen({ query, onQueryChange, onSearch, active, onActiveChange, leadingIcon, trailingIcon, placeholder, textAlign, styleType, children, viewClassName, "aria-label": ariaLabel, searchId, listboxId, onKeyDown, activeIndex, }: SearchViewFullScreenProps): React.ReactPortal | null;
36
- export {};
@@ -1,50 +0,0 @@
1
- /**
2
- * @file search.tsx
3
- * MD3 Expressive Search — Orchestrator component.
4
- *
5
- * Composes SearchBar (collapsed) + SearchView (expanded) into a single
6
- * developer-facing API. Routes to the correct SearchView variant based on props.
7
- *
8
- * Developer usage:
9
- * ```tsx
10
- * const [query, setQuery] = useState("");
11
- * const [active, setActive] = useState(false);
12
- *
13
- * <Search
14
- * query={query}
15
- * onQueryChange={setQuery}
16
- * onSearch={(q) => doSearch(q)}
17
- * active={active}
18
- * onActiveChange={setActive}
19
- * variant="docked"
20
- * styleType="contained"
21
- * >
22
- * {results.map((r) => (
23
- * <div key={r.id} id={`${YOUR_LISTBOX_ID}-option-0`} role="option">
24
- * {r.label}
25
- * </div>
26
- * ))}
27
- * </Search>
28
- * ```
29
- */
30
- import type { SearchProps } from "./search.types";
31
- import { useSearch } from "./search-context";
32
- /**
33
- * MD3 Expressive Search — Orchestrator component.
34
- *
35
- * Renders a SearchBar (collapsed pill) and the appropriate SearchView
36
- * (docked popup or fullscreen overlay) based on `variant`.
37
- *
38
- * The component is fully controlled:
39
- * - `active` / `onActiveChange` manage open/close state.
40
- * - `query` / `onQueryChange` manage input value.
41
- *
42
- * Shared `searchId` (React.useId) links SearchBar and SearchView via
43
- * Framer Motion `layoutId` for seamless animated transitions.
44
- */
45
- declare function SearchComponent({ query, onQueryChange, onSearch, active, onActiveChange, variant, styleType, hasGap, leadingIcon, trailingIcon, placeholder, textAlign, children, id, "aria-label": ariaLabel, className, viewClassName, }: SearchProps): import("react/jsx-runtime").JSX.Element;
46
- /** MD3 Expressive Search component with `Search.useSearch` context accessor. */
47
- export declare const Search: typeof SearchComponent & {
48
- useSearch: typeof useSearch;
49
- };
50
- export {};
@@ -1,112 +0,0 @@
1
- /**
2
- * @file search.tokens.ts
3
- * MD3 Expressive Search — Design tokens ported from:
4
- * - SearchBarTokens.kt (v0_210)
5
- * - SearchViewTokens.kt (v0_210)
6
- *
7
- * All dimensional values are in px (1dp = 1px on web).
8
- * Colors reference CSS custom properties — do NOT hardcode hex.
9
- * @see docs/m3/search/SearchBarTokens.kt
10
- * @see docs/m3/search/SearchViewTokens.kt
11
- */
12
- /**
13
- * Height and shape tokens for Search variants.
14
- * Maps directly from MD3 Kotlin token files.
15
- */
16
- export declare const SearchTokens: {
17
- readonly heights: {
18
- /** SearchBarTokens.ContainerHeight = 56dp */
19
- readonly bar: 56;
20
- /** SearchViewTokens.DockedHeaderContainerHeight = 56dp */
21
- readonly dockedHeader: 56;
22
- /** SearchViewTokens.FullScreenHeaderContainerHeight = 72dp */
23
- readonly fullScreenHeader: 72;
24
- };
25
- /** SearchBarTokens.AvatarSize = 30dp */
26
- readonly avatarSize: 30;
27
- /** Standard icon size for leading/trailing icons. */
28
- readonly iconSize: 20;
29
- /** Touch target for interactive icons per MD3 a11y spec. */
30
- readonly iconTouchTarget: 48;
31
- /** Gap between SearchBar and results list when hasGap=true. */
32
- readonly dropdownGap: 2;
33
- };
34
- /**
35
- * CSS custom property references for Search colors.
36
- * Maps to --md-sys-color-* tokens in the MD3 theme system.
37
- *
38
- * SearchBarTokens.kt:
39
- * - ContainerColor → SurfaceContainerHigh
40
- * - LeadingIconColor → OnSurface
41
- * - TrailingIconColor → OnSurfaceVariant
42
- * - InputTextColor → OnSurface
43
- * - SupportingTextColor → OnSurfaceVariant (placeholder)
44
- *
45
- * SearchViewTokens.kt:
46
- * - ContainerColor → SurfaceContainerHigh
47
- * - DividerColor → Outline
48
- */
49
- export declare const SEARCH_COLORS: {
50
- /** SearchBarTokens.ContainerColor → surface-container-high */
51
- readonly container: "var(--md-sys-color-surface-container-high)";
52
- /** SearchBarTokens.LeadingIconColor → on-surface */
53
- readonly leadingIcon: "var(--md-sys-color-on-surface)";
54
- /** SearchBarTokens.TrailingIconColor → on-surface-variant */
55
- readonly trailingIcon: "var(--md-sys-color-on-surface-variant)";
56
- /** SearchBarTokens.InputTextColor → on-surface */
57
- readonly inputText: "var(--md-sys-color-on-surface)";
58
- /** SearchBarTokens.SupportingTextColor → on-surface-variant (placeholder) */
59
- readonly supportingText: "var(--md-sys-color-on-surface-variant)";
60
- /** SearchViewTokens.DividerColor → outline */
61
- readonly divider: "var(--md-sys-color-outline)";
62
- /** Focus indicator → secondary */
63
- readonly focusIndicator: "var(--md-sys-color-secondary)";
64
- };
65
- /**
66
- * SearchBarTokens.InputTextFont = BodyLarge (16sp / 24sp line-height).
67
- * SearchBarTokens.SupportingTextFont = BodyLarge.
68
- */
69
- export declare const SEARCH_TYPOGRAPHY: {
70
- /** BodyLarge — used for input text and placeholder. */
71
- readonly bodyLarge: "text-[16px] leading-6 font-normal tracking-[0.5px]";
72
- };
73
- /**
74
- * Spring animation for SearchBar width expand (inactive → active).
75
- * Matches MD3 FastSpatial motion scheme.
76
- */
77
- export declare const SEARCH_BAR_EXPAND_SPRING: {
78
- type: "spring";
79
- stiffness: number;
80
- damping: number;
81
- mass: number;
82
- };
83
- /**
84
- * Spring animation for Docked SearchView dropdown reveal (slide + fade).
85
- * Offset Y: -8px on enter, opacity 0→1.
86
- */
87
- export declare const SEARCH_DOCKED_REVEAL_SPRING: {
88
- type: "spring";
89
- stiffness: number;
90
- damping: number;
91
- mass: number;
92
- };
93
- /**
94
- * Spring animation for FullScreen SearchView shape morphing.
95
- * Lower stiffness + mass gives a smoother pill→fullscreen morph.
96
- */
97
- export declare const SEARCH_FULLSCREEN_SPRING: {
98
- type: "spring";
99
- stiffness: number;
100
- damping: number;
101
- mass: number;
102
- };
103
- /**
104
- * Exit transition for SearchBar when mode="popLayout" is used.
105
- * Fast fade-out so SearchView can claim the layoutId quickly.
106
- */
107
- export declare const SEARCH_BAR_EXIT_SPRING: {
108
- type: "spring";
109
- stiffness: number;
110
- damping: number;
111
- mass: number;
112
- };
@@ -1,131 +0,0 @@
1
- /**
2
- * @file search.types.ts
3
- * MD3 Expressive Search — TypeScript prop definitions.
4
- * Spec: https://m3.material.io/components/search/overview
5
- * Reference: docs/m3/search/SearchBar.kt (MD3 Expressive)
6
- */
7
- import type * as React from "react";
8
- /**
9
- * Display variant for the expanded SearchView.
10
- *
11
- * - `docked`: Popup dropdown below the SearchBar. For medium/large screens.
12
- * - `fullscreen`: Full-screen dialog overlay. For compact/mobile screens.
13
- */
14
- export type SearchVariant = "docked" | "fullscreen";
15
- /**
16
- * Visual style type for the SearchView.
17
- *
18
- * - `contained`: No divider between the input area and results.
19
- * The container background is preserved continuously (recommended).
20
- * - `divided`: A HorizontalDivider separates the input area from results.
21
- */
22
- export type SearchStyleType = "contained" | "divided";
23
- /**
24
- * Internal props shared between SearchBar and SearchView sub-components.
25
- * Not part of the public API.
26
- * @internal
27
- */
28
- export interface SearchInternalProps {
29
- /** Unique ID generated by useId(), used as Framer Motion layoutId. */
30
- searchId: string;
31
- /** Unique ID for the results listbox, used for aria-controls. */
32
- listboxId: string;
33
- }
34
- /**
35
- * Props for the `<Search>` component (orchestrator).
36
- *
37
- * @example
38
- * ```tsx
39
- * const [query, setQuery] = useState("");
40
- * const [active, setActive] = useState(false);
41
- *
42
- * <Search
43
- * query={query}
44
- * onQueryChange={setQuery}
45
- * onSearch={(q) => console.log("search:", q)}
46
- * active={active}
47
- * onActiveChange={setActive}
48
- * variant="docked"
49
- * styleType="contained"
50
- * >
51
- * <SearchResultsList />
52
- * </Search>
53
- * ```
54
- */
55
- export interface SearchProps {
56
- /** Current search query value (controlled). */
57
- query: string;
58
- /** Called when user types in the search input. */
59
- onQueryChange: (query: string) => void;
60
- /** Called when user submits search (Enter key or suggestion click). */
61
- onSearch: (query: string) => void;
62
- /** Whether the SearchView is expanded/open (controlled). */
63
- active: boolean;
64
- /** Called when the Search open/close state should change. */
65
- onActiveChange: (active: boolean) => void;
66
- /**
67
- * Display variant for the expanded state.
68
- * @default "docked"
69
- */
70
- variant?: SearchVariant;
71
- /**
72
- * Visual style for the SearchView container.
73
- * @default "contained"
74
- */
75
- styleType?: SearchStyleType;
76
- /**
77
- * Whether to add a 2dp gap between the input header and the results list.
78
- * Only applies when `variant="docked"`.
79
- * @default false
80
- */
81
- hasGap?: boolean;
82
- /**
83
- * Icon rendered at the leading edge of the search input.
84
- * Defaults to a built-in search icon.
85
- */
86
- leadingIcon?: React.ReactNode;
87
- /**
88
- * Icon or action rendered at the trailing edge of the search input.
89
- * Common examples: mic, camera, QR code.
90
- */
91
- trailingIcon?: React.ReactNode;
92
- /** Placeholder text shown when the input is empty. @default "Search" */
93
- placeholder?: string;
94
- /**
95
- * Align the placeholder text to left, center, or right.
96
- * Typed text will always remain left-aligned.
97
- * @default "left"
98
- */
99
- textAlign?: "left" | "center" | "right";
100
- /**
101
- * Search results or suggestions rendered inside the SearchView.
102
- * Use `role="option"` on each item for accessibility.
103
- */
104
- children?: React.ReactNode;
105
- /**
106
- * Override the auto-generated input element ID.
107
- * Auto-generated via React.useId() if not provided.
108
- */
109
- id?: string;
110
- /**
111
- * Accessible label for the search landmark.
112
- * @default "Search"
113
- */
114
- "aria-label"?: string;
115
- /** Additional CSS classes for the SearchBar root element. */
116
- className?: string;
117
- /** Additional CSS classes for the SearchView container. */
118
- viewClassName?: string;
119
- }
120
- /**
121
- * Return type for `useSearchKeyboard`.
122
- * @internal
123
- */
124
- export interface UseSearchKeyboardReturn {
125
- /** Currently highlighted suggestion index. -1 = none. */
126
- activeIndex: number;
127
- /** KeyDown handler — attach to the search input. */
128
- handleKeyDown: (e: React.KeyboardEvent) => void;
129
- /** Reset activeIndex (e.g., when query changes). */
130
- resetActiveIndex: () => void;
131
- }
@@ -1,9 +0,0 @@
1
- import type * as React from "react";
2
- interface TrailingActionProps {
3
- query: string;
4
- trailingIcon?: React.ReactNode;
5
- onClear: () => void;
6
- }
7
- /** Clear button when query is non-empty, otherwise the trailing icon slot. */
8
- export declare function TrailingAction({ query, trailingIcon, onClear, }: TrailingActionProps): import("react/jsx-runtime").JSX.Element | null;
9
- export {};
@@ -1,86 +0,0 @@
1
- /**
2
- * @file shared/constants.ts
3
- *
4
- * Shared animation constants for MD3 Expressive UI components.
5
- * Centralises spring transition configs and motion variant objects to avoid
6
- * duplication across button, icon-button, FAB, and other interactive components.
7
- *
8
- * @see https://m3.material.io/foundations/animation/overview
9
- */
10
- import type { Target, TargetAndTransition, Transition } from "motion/react";
11
- /**
12
- * Fast critically-damped spring — used for border-radius morphing.
13
- *
14
- * - Duration: 200ms
15
- * - Bounce: 0 (no overshoot → prevents negative radius jitter)
16
- *
17
- * @example
18
- * ```tsx
19
- * <m.button transition={{ borderRadius: SPRING_TRANSITION_FAST }}>...</m.button>
20
- * ```
21
- */
22
- export declare const SPRING_TRANSITION_FAST: Transition;
23
- /**
24
- * Standard critically-damped spring — used for icon/content scale animations.
25
- *
26
- * - Duration: 300ms
27
- * - Bounce: 0 (no overshoot)
28
- *
29
- * @example
30
- * ```tsx
31
- * <m.span transition={SPRING_TRANSITION}>...</m.span>
32
- * ```
33
- */
34
- export declare const SPRING_TRANSITION: Transition;
35
- /**
36
- * Framer Motion variants for animating icon spans in/out.
37
- *
38
- * Scale from near-zero → 1 on enter; back to near-zero on exit.
39
- * The near-zero value (0.01) avoids the SMIL freeze bug on Chromium
40
- * that occurs when an element starts at exactly `scale(0)`.
41
- *
42
- * @example
43
- * ```tsx
44
- * <AnimatePresence mode="wait">
45
- * {loading ? (
46
- * <m.span key="loading" {...ICON_SPAN_VARIANTS} transition={SPRING_TRANSITION}>
47
- * <LoadingIndicator />
48
- * </m.span>
49
- * ) : (
50
- * <m.span key="icon" {...ICON_SPAN_VARIANTS} transition={SPRING_TRANSITION}>
51
- * {icon}
52
- * </m.span>
53
- * )}
54
- * </AnimatePresence>
55
- * ```
56
- */
57
- export declare const ICON_SPAN_VARIANTS: {
58
- initial: Target;
59
- animate: TargetAndTransition;
60
- exit: TargetAndTransition;
61
- };
62
- /**
63
- * MD3 Standard easing curve — used for label float, active indicator expand.
64
- * cubic-bezier(0.2, 0, 0, 1)
65
- *
66
- * @see https://m3.material.io/foundations/animation/easing-and-duration
67
- */
68
- export declare const MD3_STANDARD_EASING: [number, number, number, number];
69
- /**
70
- * Duration for floating label transition: 150ms.
71
- * Used when label moves between inline position ↔ floated position.
72
- */
73
- export declare const MD3_LABEL_FLOAT_DURATION = 0.15;
74
- /**
75
- * Duration for active indicator expand/collapse: 200ms.
76
- * Used for the bottom border (filled) and outline (outlined) on focus.
77
- */
78
- export declare const MD3_INDICATOR_DURATION = 0.2;
79
- /**
80
- * Duration for supporting text / error text appear/disappear: 120ms.
81
- */
82
- export declare const MD3_SUPPORTING_DURATION = 0.12;
83
- /**
84
- * Duration for trailing icon appear/disappear (clear button, password toggle): 100ms.
85
- */
86
- export declare const MD3_ICON_SWAP_DURATION = 0.1;
@@ -1,101 +0,0 @@
1
- /**
2
- * @file useSliderMath.ts
3
- * MD3 Expressive Slider — Math utility hook.
4
- *
5
- * Handles all slider math in one place:
6
- * - value coercion to [min, max]
7
- * - step snapping for discrete mode
8
- * - value ↔ percent conversion
9
- * - keyboard delta calculation
10
- * - tick position generation
11
- *
12
- * Exported as a pure hook for testability and reuse in both Slider and RangeSlider.
13
- */
14
- /**
15
- * Clamps `value` to the closed interval `[min, max]`.
16
- *
17
- * @example coerceValue(150, 0, 100) → 100
18
- */
19
- export declare function coerceValue(value: number, min: number, max: number): number;
20
- /**
21
- * Rounds `value` to the nearest multiple of `step` relative to `min`.
22
- * When `step === 0`, returns `value` unchanged (continuous mode).
23
- *
24
- * @example snapToStep(23, 0, 10) → 20
25
- * @example snapToStep(27, 0, 10) → 30
26
- */
27
- export declare function snapToStep(value: number, min: number, step: number): number;
28
- /**
29
- * Converts a raw value to a 0–1 fraction of the [min, max] range.
30
- * Returns 0 when max === min (degenerate range).
31
- *
32
- * @example valueToPercent(50, 0, 100) → 0.5
33
- */
34
- export declare function valueToPercent(value: number, min: number, max: number): number;
35
- /**
36
- * Converts a 0–1 fraction to a value within [min, max], then snaps to step.
37
- * The result is also coerced to [min, max].
38
- *
39
- * @example percentToValue(0.5, 0, 100, 10) → 50
40
- * @example percentToValue(0.23, 0, 100, 10) → 20
41
- */
42
- export declare function percentToValue(percent: number, min: number, max: number, step: number): number;
43
- /**
44
- * Computes the keyboard increment for a given key.
45
- *
46
- * Key mappings per WAI-ARIA Slider pattern:
47
- * - ArrowRight/Up → +step (or +1% of range if continuous)
48
- * - ArrowLeft/Down → -step (or -1% of range)
49
- * - PageUp → +10% of range (snapped to step)
50
- * - PageDown → -10% of range (snapped to step)
51
- * - Home / End → handled by the caller (jump to min/max)
52
- *
53
- * @returns the signed delta to add to current value, or `null` for Home/End.
54
- */
55
- export declare function getKeyboardDelta(key: string, step: number, min: number, max: number): number | null;
56
- /**
57
- * Generates the list of value positions for tick marks.
58
- * Returns an empty array when `step === 0` (continuous mode).
59
- *
60
- * @example generateTicks(0, 100, 10) → [0, 10, 20, ..., 100]
61
- */
62
- export declare function generateTicks(min: number, max: number, step: number): number[];
63
- export interface UseSliderMathOptions {
64
- min: number;
65
- max: number;
66
- step: number;
67
- }
68
- export interface UseSliderMathReturn {
69
- /** Clamp value to [min, max]. */
70
- coerce: (v: number) => number;
71
- /** Snap value to nearest step (no-op if step=0). */
72
- snap: (v: number) => number;
73
- /** Value → percent [0, 1]. */
74
- toPercent: (v: number) => number;
75
- /** Percent [0, 1] → snapped value. */
76
- fromPercent: (pct: number) => number;
77
- /**
78
- * Signed delta for a keyboard key.
79
- * Returns `null` for Home/End (jump to min/max, handled by caller).
80
- */
81
- getKeyDelta: (key: string) => number | null;
82
- /** Tick positions. Empty array in continuous mode. */
83
- ticks: number[];
84
- }
85
- /**
86
- * Math utility hook for MD3 Slider components.
87
- *
88
- * Memoizes all math functions against `min`, `max`, `step` changes.
89
- * Use this in both `<Slider>` and `<RangeSlider>` to share logic.
90
- *
91
- * @example
92
- * ```ts
93
- * const { coerce, snap, toPercent, fromPercent, getKeyDelta, ticks } =
94
- * useSliderMath({ min: 0, max: 100, step: 10 });
95
- *
96
- * const percent = toPercent(value); // → 0.5 for value=50
97
- * const newValue = fromPercent(dragPercent); // → 50
98
- * const delta = getKeyDelta("ArrowRight"); // → 10
99
- * ```
100
- */
101
- export declare function useSliderMath({ min, max, step, }: UseSliderMathOptions): UseSliderMathReturn;
@@ -1,47 +0,0 @@
1
- /**
2
- * @file range-slider.tsx
3
- * MD3 Expressive RangeSlider — Two-thumb slider with crossover prevention.
4
- *
5
- * Extends the core Slider architecture with:
6
- * - Two SliderThumb instances (start + end)
7
- * - Crossover prevention: start cannot exceed end and vice versa
8
- * - Z-index management: last-dragged thumb always on top
9
- * - Active track spans from startPercent to endPercent
10
- *
11
- * Design decisions:
12
- * - The track renders a custom "range" segment between the two thumbs.
13
- * - Each thumb has independent onValueChange callbacks + crossover clamping.
14
- * - Last-active thumb gets zIndex=2 to appear on top when thumbs are at same position.
15
- *
16
- * @see https://m3.material.io/components/sliders/overview
17
- * @see docs/m3/sliders/Slider.kt#RangeSlider
18
- */
19
- import * as React from "react";
20
- import type { RangeSliderProps } from "./slider.types";
21
- /**
22
- * MD3 Expressive RangeSlider component.
23
- *
24
- * Two-thumb slider where the active track spans between the two thumbs.
25
- * Thumbs cannot cross each other (crossover prevention built in).
26
- *
27
- * @example
28
- * ```tsx
29
- * // Controlled
30
- * <RangeSlider
31
- * value={[20, 80]}
32
- * onValueChange={([start, end]) => setRange([start, end])}
33
- * aria-label="Price range"
34
- * />
35
- *
36
- * // Discrete
37
- * <RangeSlider defaultValue={[0, 100]} step={10} />
38
- *
39
- * // Vertical
40
- * <div className="h-64">
41
- * <RangeSlider defaultValue={[25, 75]} orientation="vertical" />
42
- * </div>
43
- * ```
44
- *
45
- * @see https://m3.material.io/components/sliders/overview
46
- */
47
- export declare const RangeSlider: React.NamedExoticComponent<RangeSliderProps & React.RefAttributes<HTMLDivElement>>;
@@ -1,33 +0,0 @@
1
- /**
2
- * @file slider-thumb.tsx
3
- * MD3 Expressive Slider — Animated pill-shaped thumb (handle).
4
- *
5
- * Design decisions:
6
- * 1. POINTER EVENTS (not Framer Motion drag): We use React pointer events
7
- * + useMotionValue for real-time position tracking without re-render lag.
8
- * Framer Motion's `drag` prop adds momentum/inertia that conflicts with MD3
9
- * precise positioning; direct pointer handling gives us full control.
10
- * 2. SQUEEZE ANIMATION: `whileTap` shrinks width from 4px → 2px via spring.
11
- * 3. INVERTED Y-AXIS: Vertical slider maps bottom=min, top=max by inverting
12
- * the pointer delta direction.
13
- * 4. VALUE INDICATOR: AnimatePresence pill tooltip with teardrop origin point.
14
- * 5. ACCESSIBILITY: role=slider, full ARIA attributes, keyboard nav.
15
- * 6. prefers-reduced-motion: Disables all animations for accessibility.
16
- *
17
- * @see docs/m3/sliders/Slider.kt#SliderDefaults.Thumb
18
- */
19
- import * as React from "react";
20
- import type { SliderThumbProps } from "./slider.types";
21
- /**
22
- * MD3 Expressive Slider Thumb (handle).
23
- *
24
- * - Pill shape: 4px wide × 44px tall by default.
25
- * - Squeezes to 2px wide on press/drag (Framer Motion spring).
26
- * - Floats above track via absolute positioning at `percent` along the track.
27
- * - Handles pointer drag via React PointerEvents + useMotionValue.
28
- * - Full keyboard navigation per WAI-ARIA Slider pattern.
29
- * - Value indicator tooltip with AnimatePresence.
30
- *
31
- * @internal — consumed by `<Slider>` and `<RangeSlider>`
32
- */
33
- export declare const SliderThumb: React.NamedExoticComponent<SliderThumbProps>;
@@ -1,25 +0,0 @@
1
- /**
2
- * @file slider-track.tsx
3
- * MD3 Expressive Slider — Track with asymmetric corner radii, 6px thumb gaps,
4
- * discrete tick marks, and centered-mode support.
5
- *
6
- * Design decisions:
7
- * 1. GAP MATH: The 6px gap between track and thumb is calculated mathematically
8
- * using CSS calc() — NOT using margin/padding which would break layout.
9
- * 2. ASYMMETRIC RADII: Inner corners (facing thumb) = 2px; outer ends = size/2 (pill cap).
10
- * 3. CENTERED MODE: Active segment spans from 50% outward to thumb, not from min.
11
- * 4. TICKS: 4×4px dots positioned absolutely along track center axis.
12
- * Color differs on active vs inactive portions of the track.
13
- * 5. VERTICAL: Uses height/top instead of width/left, with inverted axis
14
- * (bottom=0%, top=100%) per MD3 vertical spec.
15
- *
16
- * @see docs/m3/sliders/Slider.kt#SliderDefaults.Track
17
- */
18
- import * as React from "react";
19
- import type { SliderTrackProps } from "./slider.types";
20
- /**
21
- * MD3 Expressive Slider Track.
22
- */
23
- export declare const SliderTrack: React.NamedExoticComponent<Omit<SliderTrackProps, "step"> & {
24
- ticks?: number[];
25
- }>;