@neo-ui-kit/react 0.0.0-stage → 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 (270) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +203 -2
  3. package/dist/artwork/icons.json.d.ts +2 -0
  4. package/dist/artwork/illustrations.json.d.ts +2 -0
  5. package/dist/chunks/chunk-347P6ZE4.js +104 -0
  6. package/dist/chunks/chunk-BJSFN52W.js +417 -0
  7. package/dist/chunks/chunk-FCOU3ODR.js +63 -0
  8. package/dist/chunks/chunk-JZ4GDTH5.js +87 -0
  9. package/dist/chunks/chunk-UGDRXR7P.js +3362 -0
  10. package/dist/chunks/chunk-VK6GHRLV.js +335 -0
  11. package/dist/chunks/chunk-YKCUOZ7V.js +777 -0
  12. package/dist/components/artwork/DatabaseArt/DatabaseArt.d.ts +6 -0
  13. package/dist/components/artwork/DatabaseArt/styles.css +58 -0
  14. package/dist/components/artwork/Landscape/Landscape.d.ts +7 -0
  15. package/dist/components/artwork/Landscape/styles.css +79 -0
  16. package/dist/components/artwork/NeonWaves/NeonWaves.d.ts +15 -0
  17. package/dist/components/artwork/NeonWaves/styles.css +48 -0
  18. package/dist/components/artwork/Planet/Planet.d.ts +4 -0
  19. package/dist/components/artwork/Planet/styles.css +52 -0
  20. package/dist/components/artwork/QuantumField/QuantumField.d.ts +42 -0
  21. package/dist/components/artwork/QuantumField/QuantumFieldExperience.d.ts +22 -0
  22. package/dist/components/artwork/QuantumField/UPSTREAM-LICENSE.txt +21 -0
  23. package/dist/components/artwork/QuantumField/audio.d.ts +15 -0
  24. package/dist/components/artwork/QuantumField/renderer.d.ts +24 -0
  25. package/dist/components/artwork/QuantumField/styles.css +77 -0
  26. package/dist/components/artwork/ServerArt/ServerArt.d.ts +8 -0
  27. package/dist/components/artwork/ServerArt/styles.css +43 -0
  28. package/dist/components/artwork/Spectrum/Spectrum.d.ts +7 -0
  29. package/dist/components/artwork/Spectrum/styles.css +35 -0
  30. package/dist/components/artwork/layers.d.ts +15 -0
  31. package/dist/components/artwork/useArtwork.d.ts +8 -0
  32. package/dist/components/controls/Autocomplete/Autocomplete.d.ts +2 -0
  33. package/dist/components/controls/Autocomplete/styles.css +1 -0
  34. package/dist/components/controls/Button/Button.d.ts +2 -0
  35. package/dist/components/controls/Button/styles.css +1 -0
  36. package/dist/components/controls/Checkbox/Checkbox.d.ts +2 -0
  37. package/dist/components/controls/Checkbox/styles.css +70 -0
  38. package/dist/components/controls/Chip/Chip.d.ts +21 -0
  39. package/dist/components/controls/Chip/styles.css +74 -0
  40. package/dist/components/controls/ChipField.d.ts +25 -0
  41. package/dist/components/controls/ColorPicker/ColorPicker.d.ts +16 -0
  42. package/dist/components/controls/ColorPicker/color.d.ts +9 -0
  43. package/dist/components/controls/ColorPicker/styles.css +103 -0
  44. package/dist/components/controls/DatePicker/DatePicker.d.ts +19 -0
  45. package/dist/components/controls/DatePicker/styles.css +69 -0
  46. package/dist/components/controls/FilePicker/FilePicker.d.ts +2 -0
  47. package/dist/components/controls/FilePicker/styles.css +149 -0
  48. package/dist/components/controls/IconButton/IconButton.d.ts +2 -0
  49. package/dist/components/controls/IconButton/styles.css +4 -0
  50. package/dist/components/controls/InputBase/InputBase.d.ts +21 -0
  51. package/dist/components/controls/InputBase/styles.css +379 -0
  52. package/dist/components/controls/Link/Link.d.ts +11 -0
  53. package/dist/components/controls/Link/styles.css +50 -0
  54. package/dist/components/controls/NumberField/NumberField.d.ts +2 -0
  55. package/dist/components/controls/NumberField/styles.css +1 -0
  56. package/dist/components/controls/PeoplePicker/PeoplePicker.d.ts +37 -0
  57. package/dist/components/controls/PeoplePicker/styles.css +7 -0
  58. package/dist/components/controls/SegmentedControl/SegmentedControl.d.ts +2 -0
  59. package/dist/components/controls/SegmentedControl/styles.css +9 -0
  60. package/dist/components/controls/Select/Select.d.ts +8 -0
  61. package/dist/components/controls/Select/styles.css +142 -0
  62. package/dist/components/controls/Slider/Slider.d.ts +3 -0
  63. package/dist/components/controls/Slider/styles.css +138 -0
  64. package/dist/components/controls/SplitButton/SplitButton.d.ts +2 -0
  65. package/dist/components/controls/SplitButton/styles.css +169 -0
  66. package/dist/components/controls/Switch/Switch.d.ts +2 -0
  67. package/dist/components/controls/Switch/styles.css +54 -0
  68. package/dist/components/controls/Tab/Tab.d.ts +2 -0
  69. package/dist/components/controls/Tab/styles.css +111 -0
  70. package/dist/components/controls/Tabs/Tabs.d.ts +2 -0
  71. package/dist/components/controls/Tabs/styles.css +239 -0
  72. package/dist/components/controls/TagInput/TagInput.d.ts +24 -0
  73. package/dist/components/controls/TagInput/styles.css +24 -0
  74. package/dist/components/controls/TextArea/TextArea.d.ts +2 -0
  75. package/dist/components/controls/TextArea/styles.css +15 -0
  76. package/dist/components/controls/TextField/TextField.d.ts +2 -0
  77. package/dist/components/controls/ThemePicker/ThemePicker.d.ts +24 -0
  78. package/dist/components/controls/ThemePicker/styles.css +128 -0
  79. package/dist/components/controls/ToggleButton/ToggleButton.d.ts +2 -0
  80. package/dist/components/controls/ToggleButton/styles.css +49 -0
  81. package/dist/components/controls/internal.d.ts +62 -0
  82. package/dist/components/controls/shared.css +694 -0
  83. package/dist/components/controls/shared.d.ts +204 -0
  84. package/dist/components/editor/PianoRoll/PianoRoll.d.ts +65 -0
  85. package/dist/components/editor/PianoRoll/styles.css +186 -0
  86. package/dist/components/editor/shared.css +1 -0
  87. package/dist/components/effects/AnimatedBorder/AnimatedBorder.d.ts +9 -0
  88. package/dist/components/effects/AnimatedBorder/styles.css +7 -0
  89. package/dist/components/effects/Beacon/Beacon.d.ts +9 -0
  90. package/dist/components/effects/Beacon/styles.css +38 -0
  91. package/dist/components/effects/Equalizer/Equalizer.d.ts +14 -0
  92. package/dist/components/effects/Equalizer/styles.css +38 -0
  93. package/dist/components/effects/GlowText/GlowText.d.ts +9 -0
  94. package/dist/components/effects/GlowText/styles.css +56 -0
  95. package/dist/components/effects/ImageShine/ImageShine.d.ts +13 -0
  96. package/dist/components/effects/ImageShine/styles.css +66 -0
  97. package/dist/components/effects/Marquee/Marquee.d.ts +9 -0
  98. package/dist/components/effects/Marquee/styles.css +46 -0
  99. package/dist/components/effects/MelodixText/MelodixText.d.ts +15 -0
  100. package/dist/components/effects/MelodixText/styles.css +28 -0
  101. package/dist/components/effects/Reveal/Reveal.d.ts +13 -0
  102. package/dist/components/effects/Reveal/styles.css +25 -0
  103. package/dist/components/effects/Shimmer/Shimmer.d.ts +10 -0
  104. package/dist/components/effects/Shimmer/styles.css +48 -0
  105. package/dist/components/effects/Sparkles/Sparkles.d.ts +9 -0
  106. package/dist/components/effects/Sparkles/styles.css +28 -0
  107. package/dist/components/effects/Spotlight/Spotlight.d.ts +11 -0
  108. package/dist/components/effects/Spotlight/styles.css +45 -0
  109. package/dist/components/effects/Tilt/Tilt.d.ts +11 -0
  110. package/dist/components/effects/Tilt/styles.css +67 -0
  111. package/dist/components/feedback/Badge/Badge.d.ts +3 -0
  112. package/dist/components/feedback/Badge/styles.css +91 -0
  113. package/dist/components/feedback/CollapsibleSection/CollapsibleSection.d.ts +2 -0
  114. package/dist/components/feedback/CollapsibleSection/styles.css +76 -0
  115. package/dist/components/feedback/DataTable/DataTable.d.ts +16 -0
  116. package/dist/components/feedback/DataTable/styles.css +522 -0
  117. package/dist/components/feedback/Dialog/Dialog.d.ts +2 -0
  118. package/dist/components/feedback/Dialog/styles.css +82 -0
  119. package/dist/components/feedback/EmptyState/EmptyState.d.ts +2 -0
  120. package/dist/components/feedback/EmptyState/styles.css +80 -0
  121. package/dist/components/feedback/KeyValueList/KeyValueList.d.ts +2 -0
  122. package/dist/components/feedback/KeyValueList/styles.css +51 -0
  123. package/dist/components/feedback/Menu/Menu.d.ts +2 -0
  124. package/dist/components/feedback/Menu/styles.css +123 -0
  125. package/dist/components/feedback/MenuItem/MenuItem.d.ts +2 -0
  126. package/dist/components/feedback/MenuItem/styles.css +71 -0
  127. package/dist/components/feedback/MessageBar/MessageBar.d.ts +2 -0
  128. package/dist/components/feedback/MessageBar/styles.css +116 -0
  129. package/dist/components/feedback/Popover/Popover.d.ts +2 -0
  130. package/dist/components/feedback/Popover/styles.css +44 -0
  131. package/dist/components/feedback/ProgressBar/ProgressBar.d.ts +2 -0
  132. package/dist/components/feedback/ProgressBar/styles.css +76 -0
  133. package/dist/components/feedback/SignalBars/SignalBars.d.ts +11 -0
  134. package/dist/components/feedback/SignalBars/styles.css +31 -0
  135. package/dist/components/feedback/StatusIndicator/StatusIndicator.d.ts +2 -0
  136. package/dist/components/feedback/StatusIndicator/styles.css +88 -0
  137. package/dist/components/feedback/Steps/Steps.d.ts +2 -0
  138. package/dist/components/feedback/Steps/styles.css +152 -0
  139. package/dist/components/feedback/Toast/Toast.d.ts +2 -0
  140. package/dist/components/feedback/Toast/styles.css +89 -0
  141. package/dist/components/feedback/Tooltip/Tooltip.d.ts +15 -0
  142. package/dist/components/feedback/Tooltip/styles.css +38 -0
  143. package/dist/components/feedback/shared.css +22 -0
  144. package/dist/components/feedback/shared.d.ts +231 -0
  145. package/dist/components/forms/Form/Form.d.ts +35 -0
  146. package/dist/components/forms/Form/styles.css +1 -0
  147. package/dist/components/forms/FormFields/FormFields.d.ts +20 -0
  148. package/dist/components/forms/FormFields/styles.css +72 -0
  149. package/dist/components/foundation/Loader/Loader.d.ts +30 -0
  150. package/dist/components/foundation/LoaderGenerator/LoaderGenerator.d.ts +38 -0
  151. package/dist/components/foundation/LoaderGenerator/styles.css +104 -0
  152. package/dist/components/foundation/ThemeEditor/ThemeEditor.d.ts +15 -0
  153. package/dist/components/foundation/ThemeEditor/styles.css +97 -0
  154. package/dist/components/foundation/ThemeEditor/themeConfig.d.ts +47 -0
  155. package/dist/components/foundation/ThemeProvider/ThemeProvider.d.ts +32 -0
  156. package/dist/components/foundation/ThemeProvider/styles.css +59 -0
  157. package/dist/components/foundation/Typography/Typography.d.ts +17 -0
  158. package/dist/components/foundation/Typography/styles.css +115 -0
  159. package/dist/components/layout/Avatar/Avatar.d.ts +2 -0
  160. package/dist/components/layout/Avatar/HostSeal.d.ts +5 -0
  161. package/dist/components/layout/Avatar/styles.css +166 -0
  162. package/dist/components/layout/BrandMark/BrandMark.d.ts +2 -0
  163. package/dist/components/layout/BrandMark/styles.css +39 -0
  164. package/dist/components/layout/ButtonGroup/ButtonGroup.d.ts +12 -0
  165. package/dist/components/layout/ButtonGroup/styles.css +36 -0
  166. package/dist/components/layout/Card/Card.d.ts +14 -0
  167. package/dist/components/layout/Card/styles.css +37 -0
  168. package/dist/components/layout/DialogActions/DialogActions.d.ts +12 -0
  169. package/dist/components/layout/DialogActions/styles.css +31 -0
  170. package/dist/components/layout/DialogBody/DialogBody.d.ts +12 -0
  171. package/dist/components/layout/DialogBody/styles.css +28 -0
  172. package/dist/components/layout/Divider/Divider.d.ts +2 -0
  173. package/dist/components/layout/Divider/styles.css +58 -0
  174. package/dist/components/layout/FloatingPanel/FloatingPanel.d.ts +15 -0
  175. package/dist/components/layout/FloatingPanel/styles.css +47 -0
  176. package/dist/components/layout/FloatingPanel/useFloatingPanel.d.ts +54 -0
  177. package/dist/components/layout/Grid/Grid.d.ts +24 -0
  178. package/dist/components/layout/Grid/styles.css +90 -0
  179. package/dist/components/layout/Header/Header.d.ts +2 -0
  180. package/dist/components/layout/Header/styles.css +42 -0
  181. package/dist/components/layout/Icon/Icon.d.ts +4 -0
  182. package/dist/components/layout/Icon/styles.css +62 -0
  183. package/dist/components/layout/Illustration/Illustration.d.ts +2 -0
  184. package/dist/components/layout/Illustration/styles.css +104 -0
  185. package/dist/components/layout/ScrollArea/ScrollArea.d.ts +2 -0
  186. package/dist/components/layout/ScrollArea/styles.css +61 -0
  187. package/dist/components/layout/Stack/Stack.d.ts +21 -0
  188. package/dist/components/layout/Stack/styles.css +53 -0
  189. package/dist/components/layout/StatTile/StatTile.d.ts +20 -0
  190. package/dist/components/layout/StatTile/styles.css +90 -0
  191. package/dist/components/layout/TabPanel/TabPanel.d.ts +2 -0
  192. package/dist/components/layout/TabPanel/styles.css +16 -0
  193. package/dist/components/layout/Text/Text.d.ts +2 -0
  194. package/dist/components/layout/Text/styles.css +29 -0
  195. package/dist/components/layout/Toolbar/Toolbar.d.ts +12 -0
  196. package/dist/components/layout/Toolbar/styles.css +7 -0
  197. package/dist/components/layout/shared.css +79 -0
  198. package/dist/components/layout/shared.d.ts +64 -0
  199. package/dist/components/media/AudioPlayer/AudioPlayer.d.ts +2 -0
  200. package/dist/components/media/AudioPlayer/styles.css +86 -0
  201. package/dist/components/media/KaraokeLyrics/KaraokeLyrics.d.ts +25 -0
  202. package/dist/components/media/KaraokeLyrics/styles.css +56 -0
  203. package/dist/components/media/LevelMeter/LevelMeter.d.ts +7 -0
  204. package/dist/components/media/LevelMeter/styles.css +30 -0
  205. package/dist/components/media/MediaCard/MediaCard.d.ts +24 -0
  206. package/dist/components/media/MediaCard/styles.css +108 -0
  207. package/dist/components/media/MelodyRoll/MelodyRoll.d.ts +48 -0
  208. package/dist/components/media/MelodyRoll/styles.css +196 -0
  209. package/dist/components/media/PianoKeyboard/PianoKeyboard.d.ts +24 -0
  210. package/dist/components/media/PianoKeyboard/styles.css +83 -0
  211. package/dist/components/media/RotaryKnob/RotaryKnob.d.ts +3 -0
  212. package/dist/components/media/RotaryKnob/styles.css +319 -0
  213. package/dist/components/media/Sparkline/Sparkline.d.ts +2 -0
  214. package/dist/components/media/Sparkline/styles.css +70 -0
  215. package/dist/components/media/WaveDecoration/WaveDecoration.d.ts +2 -0
  216. package/dist/components/media/WaveDecoration/styles.css +2 -0
  217. package/dist/components/media/Waveform/Waveform.d.ts +9 -0
  218. package/dist/components/media/Waveform/styles.css +375 -0
  219. package/dist/components/media/Waveform/useWaveformPeaks.d.ts +11 -0
  220. package/dist/components/media/shared.css +7 -0
  221. package/dist/components/media/shared.d.ts +80 -0
  222. package/dist/components/navigation/Router/Router.d.ts +32 -0
  223. package/dist/components/navigation/Router/styles.css +1 -0
  224. package/dist/components.css +102 -0
  225. package/dist/core/artwork.d.ts +17 -0
  226. package/dist/core/base.d.ts +65 -0
  227. package/dist/core/environment.d.ts +5 -0
  228. package/dist/core/i18n.d.ts +34 -0
  229. package/dist/core/messages.d.ts +1 -0
  230. package/dist/core/motion/hooks.d.ts +17 -0
  231. package/dist/core/motion-engine.d.ts +13 -0
  232. package/dist/core/noise.d.ts +20 -0
  233. package/dist/core/providers/context.d.ts +4 -0
  234. package/dist/core/responsive.d.ts +13 -0
  235. package/dist/core.d.ts +8 -0
  236. package/dist/core.js +56 -0
  237. package/dist/editor.d.ts +2 -0
  238. package/dist/editor.js +8 -0
  239. package/dist/fonts/melodix/Melodix-100.woff2 +0 -0
  240. package/dist/fonts/melodix/Melodix-200.woff2 +0 -0
  241. package/dist/fonts/melodix/Melodix-300.woff2 +0 -0
  242. package/dist/fonts/melodix/Melodix-400.woff2 +0 -0
  243. package/dist/fonts/melodix/Melodix-500.woff2 +0 -0
  244. package/dist/fonts/melodix/Melodix-600.woff2 +0 -0
  245. package/dist/fonts/melodix/Melodix-700.woff2 +0 -0
  246. package/dist/fonts/melodix/Melodix-800.woff2 +0 -0
  247. package/dist/fonts/melodix/Melodix-900.woff2 +0 -0
  248. package/dist/fonts/melodix/MelodixText-100.woff2 +0 -0
  249. package/dist/fonts/melodix/MelodixText-200.woff2 +0 -0
  250. package/dist/fonts/melodix/MelodixText-300.woff2 +0 -0
  251. package/dist/fonts/melodix/MelodixText-400.woff2 +0 -0
  252. package/dist/fonts/melodix/MelodixText-500.woff2 +0 -0
  253. package/dist/fonts/melodix/MelodixText-600.woff2 +0 -0
  254. package/dist/fonts/melodix/MelodixText-700.woff2 +0 -0
  255. package/dist/fonts/melodix/MelodixText-800.woff2 +0 -0
  256. package/dist/fonts/melodix/MelodixText-900.woff2 +0 -0
  257. package/dist/fonts/melodix/OFL-PlayfairDisplay.txt +93 -0
  258. package/dist/fonts/melodix.css +123 -0
  259. package/dist/forms.d.ts +4 -0
  260. package/dist/forms.js +17 -0
  261. package/dist/index.d.ts +163 -0
  262. package/dist/index.js +9683 -0
  263. package/dist/router.d.ts +2 -0
  264. package/dist/router.js +11 -0
  265. package/dist/styles.css +2 -0
  266. package/dist/theme/base.css +221 -0
  267. package/dist/theme/tokens.css +196 -0
  268. package/dist/theme/typography.d.ts +24 -0
  269. package/dist/tokens.css +1 -0
  270. package/package.json +83 -4
@@ -0,0 +1,335 @@
1
+ import {
2
+ clamp,
3
+ mark,
4
+ useControllable,
5
+ useTr
6
+ } from "./chunk-BJSFN52W.js";
7
+
8
+ // src/components/media/PianoKeyboard/PianoKeyboard.tsx
9
+ import { memo, useEffect, useRef, useState } from "react";
10
+ import { jsx, jsxs } from "react/jsx-runtime";
11
+ var BLACK = /* @__PURE__ */ new Set([1, 3, 6, 8, 10]);
12
+ var NAMES = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
13
+ var isBlackKey = (midi) => BLACK.has((midi % 12 + 12) % 12);
14
+ var noteName = (midi) => `${NAMES[(midi % 12 + 12) % 12]}${Math.floor(midi / 12) - 1}`;
15
+ var whiteKeys = (min, max) => {
16
+ const rows = max - min + 1;
17
+ const white = Array.from({ length: rows }, (_, i) => max - i).filter((midi) => !isBlackKey(midi));
18
+ const centers = white.map((midi) => max - midi + 0.5);
19
+ return white.map((midi, i) => {
20
+ const center = centers[i] ?? 0;
21
+ const top = i ? (center + (centers[i - 1] ?? 0)) / 2 : 0;
22
+ const bottom = i === white.length - 1 ? rows : (center + (centers[i + 1] ?? rows)) / 2;
23
+ return { midi, top, size: bottom - top };
24
+ });
25
+ };
26
+ var PianoKeyboard = /* @__PURE__ */ memo(function PianoKeyboard2({
27
+ minMidi = 55,
28
+ maxMidi = 79,
29
+ activeMidi,
30
+ hit = false,
31
+ labels = "all",
32
+ onKeyPress,
33
+ label,
34
+ ...p
35
+ }) {
36
+ const tr = useTr();
37
+ const [pressed, setPressed] = useState();
38
+ const release = useRef(void 0);
39
+ useEffect(() => () => clearTimeout(release.current), []);
40
+ const rows = Math.max(1, maxMidi - minMidi + 1);
41
+ const pct = (value) => `${value / rows * 100}%`;
42
+ const named = (midi) => labels === "all" || labels === "octaves" && midi % 12 === 0;
43
+ const press = (midi) => {
44
+ clearTimeout(release.current);
45
+ setPressed(midi);
46
+ onKeyPress?.(midi);
47
+ release.current = setTimeout(() => setPressed(void 0), 220);
48
+ };
49
+ const key = (midi, top, size, black) => {
50
+ const props = {
51
+ className: "ad-piano-key",
52
+ "data-black": black || void 0,
53
+ "data-active": midi === activeMidi || void 0,
54
+ "data-hit": midi === activeMidi && hit || void 0,
55
+ "data-pressed": midi === pressed || void 0,
56
+ style: { top: pct(top), height: pct(size) },
57
+ children: named(midi) ? /* @__PURE__ */ jsx("span", { children: noteName(midi) }) : null
58
+ };
59
+ return onKeyPress ? /* @__PURE__ */ jsx(
60
+ "button",
61
+ {
62
+ type: "button",
63
+ "aria-label": noteName(midi),
64
+ onPointerDown: (event) => {
65
+ if (event.button === 0 && event.isPrimary) press(midi);
66
+ },
67
+ onClick: (event) => {
68
+ if (event.detail === 0) press(midi);
69
+ },
70
+ ...props
71
+ },
72
+ midi
73
+ ) : /* @__PURE__ */ jsx("span", { ...props }, midi);
74
+ };
75
+ const blacks = Array.from({ length: rows }, (_, i) => maxMidi - i).filter(isBlackKey);
76
+ return /* @__PURE__ */ jsxs(
77
+ "div",
78
+ {
79
+ ...mark("PianoKeyboard", p),
80
+ role: onKeyPress ? "group" : "img",
81
+ "aria-label": label ?? tr("\u041A\u043B\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u0430 {from}\u2013{to}", { from: noteName(minMidi), to: noteName(maxMidi) }),
82
+ style: { ...p.style, "--ad-keys": rows },
83
+ children: [
84
+ whiteKeys(minMidi, maxMidi).map(({ midi, top, size }) => key(midi, top, size, false)),
85
+ blacks.map((midi) => key(midi, maxMidi - midi + 0.16, 0.68, true))
86
+ ]
87
+ }
88
+ );
89
+ });
90
+
91
+ // src/components/editor/PianoRoll/PianoRoll.tsx
92
+ import { useEffect as useEffect2, useRef as useRef2 } from "react";
93
+ import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
94
+ var DEMO = [
95
+ { id: "1", start: 0.4, end: 1.1, pitch: 64 },
96
+ { id: "2", start: 1.2, end: 1.6, pitch: 67 },
97
+ { id: "3", start: 1.7, end: 2.6, pitch: 69 },
98
+ { id: "4", start: 2.8, end: 3.4, pitch: 67 },
99
+ { id: "5", start: 3.5, end: 4.4, pitch: 64 },
100
+ { id: "6", start: 4.6, end: 6, pitch: 62 }
101
+ ];
102
+ var DEMO_WORDS = [
103
+ { id: "a", text: "\u041D\u043E\u0447\u044C", start: 0.4, end: 1.1 },
104
+ { id: "b", text: "\u0433\u043E\u0440\u0438\u0442", start: 1.2, end: 2.6 },
105
+ { id: "c", text: "\u043E\u0433\u043D\u044F\u043C\u0438", start: 2.8, end: 6 }
106
+ ];
107
+ var PianoRoll = ({
108
+ notes = DEMO,
109
+ words = notes === DEMO ? DEMO_WORDS : [],
110
+ duration = 8,
111
+ position = 2,
112
+ selected,
113
+ zoom: zoomProp,
114
+ defaultZoom = 1,
115
+ onZoomChange,
116
+ minPitch = 55,
117
+ maxPitch = 79,
118
+ follow = false,
119
+ grid = true,
120
+ nudgeSeconds = 0.05,
121
+ onSelect,
122
+ onSelectArea,
123
+ onSeek,
124
+ onNoteDrag,
125
+ onNoteDragEnd,
126
+ onNudge,
127
+ onKeyPress,
128
+ label,
129
+ ...p
130
+ }) => {
131
+ const tr = useTr();
132
+ const [zoom, setZoom] = useControllable(zoomProp, defaultZoom, onZoomChange);
133
+ const scroller = useRef2(null);
134
+ const world = useRef2(null);
135
+ const drag = useRef2(null);
136
+ const areaBox = useRef2(null);
137
+ const rows = maxPitch - minPitch + 1;
138
+ const length = Math.max(duration, 1);
139
+ const at = (seconds2) => `calc(var(--ad-pps) * ${seconds2})`;
140
+ const row = (pitch) => `calc(100% * ${(maxPitch - pitch) / rows})`;
141
+ const seconds = Array.from({ length: Math.ceil(length) + 1 }, (_, i) => i);
142
+ useEffect2(() => {
143
+ const box = scroller.current;
144
+ const area = world.current;
145
+ if (!follow || !box || !area) return;
146
+ const x = position / length * area.offsetWidth;
147
+ if (x < box.scrollLeft || x > box.scrollLeft + box.clientWidth * 0.8) box.scrollLeft = Math.max(0, x - box.clientWidth * 0.3);
148
+ }, [follow, position, length, zoom]);
149
+ const scale = () => {
150
+ const area = world.current?.getBoundingClientRect();
151
+ return { secondPx: (area?.width ?? 1) / length, rowPx: (area?.height ?? rows) / rows, area };
152
+ };
153
+ const startMove = (event, note) => {
154
+ if (event.button !== 0 || drag.current) return;
155
+ event.stopPropagation();
156
+ const additive = event.ctrlKey || event.metaKey || event.shiftKey;
157
+ const ids = selected?.has(note.id) && !additive ? [...selected] : [note.id];
158
+ onSelect?.(note.id, additive);
159
+ event.currentTarget.setPointerCapture?.(event.pointerId);
160
+ const { secondPx, rowPx } = scale();
161
+ drag.current = { kind: "move", ids, x: event.clientX, y: event.clientY, secondPx, rowPx, pointerId: event.pointerId };
162
+ };
163
+ const startResize = (event, note, edge) => {
164
+ if (event.button !== 0 || drag.current) return;
165
+ event.stopPropagation();
166
+ event.currentTarget.setPointerCapture?.(event.pointerId);
167
+ drag.current = { kind: "resize", id: note.id, edge, x: event.clientX, secondPx: scale().secondPx, pointerId: event.pointerId };
168
+ };
169
+ const startArea = (event) => {
170
+ if (event.button !== 0 || !world.current || drag.current) return;
171
+ event.currentTarget.setPointerCapture?.(event.pointerId);
172
+ drag.current = { kind: "area", x: event.clientX, y: event.clientY, additive: event.ctrlKey || event.metaKey || event.shiftKey, box: world.current.getBoundingClientRect(), pointerId: event.pointerId };
173
+ };
174
+ const move = (event) => {
175
+ const current = drag.current;
176
+ if (!current || current.pointerId !== event.pointerId) return;
177
+ if (current.kind === "move")
178
+ onNoteDrag?.({ kind: "move", ids: current.ids, seconds: (event.clientX - current.x) / current.secondPx, pitch: -Math.round((event.clientY - current.y) / current.rowPx) });
179
+ else if (current.kind === "resize")
180
+ onNoteDrag?.({ kind: "resize", id: current.id, edge: current.edge, seconds: (event.clientX - current.x) / current.secondPx });
181
+ else if (areaBox.current) {
182
+ const left = Math.min(current.x, event.clientX) - current.box.left;
183
+ const top = Math.min(current.y, event.clientY) - current.box.top;
184
+ Object.assign(areaBox.current.style, {
185
+ display: "block",
186
+ left: `${left}px`,
187
+ top: `${top}px`,
188
+ width: `${Math.abs(event.clientX - current.x)}px`,
189
+ height: `${Math.abs(event.clientY - current.y)}px`
190
+ });
191
+ }
192
+ };
193
+ const cancel = () => {
194
+ const current = drag.current;
195
+ drag.current = null;
196
+ if (!current) return;
197
+ if (areaBox.current) areaBox.current.style.display = "none";
198
+ if (current.kind === "area") return;
199
+ onNoteDrag?.(current.kind === "move" ? { kind: "move", ids: current.ids, pitch: 0, seconds: 0 } : { kind: "resize", id: current.id, edge: current.edge, seconds: 0 });
200
+ onNoteDragEnd?.();
201
+ };
202
+ const end = (event) => {
203
+ const current = drag.current;
204
+ if (!current || current.pointerId !== event.pointerId) return;
205
+ if (event.type !== "pointerup") return cancel();
206
+ drag.current = null;
207
+ if (current.kind !== "area") return onNoteDragEnd?.();
208
+ if (areaBox.current) areaBox.current.style.display = "none";
209
+ const { secondPx, rowPx } = scale();
210
+ const x0 = (Math.min(current.x, event.clientX) - current.box.left) / secondPx;
211
+ const x1 = (Math.max(current.x, event.clientX) - current.box.left) / secondPx;
212
+ const top = maxPitch - (Math.max(current.y, event.clientY) - current.box.top) / rowPx;
213
+ const bottom = maxPitch - (Math.min(current.y, event.clientY) - current.box.top) / rowPx;
214
+ if (Math.abs(event.clientX - current.x) < 4 && Math.abs(event.clientY - current.y) < 4) return onSeek?.(clamp(x0, 0, length));
215
+ onSelectArea?.(notes.filter((note) => note.end >= x0 && note.start <= x1 && note.pitch >= top - 1 && note.pitch <= bottom).map((note) => note.id), current.additive);
216
+ };
217
+ const nudge = (event, note) => {
218
+ const steps = {
219
+ ArrowUp: [1, 0],
220
+ ArrowDown: [-1, 0],
221
+ ArrowLeft: [0, -nudgeSeconds],
222
+ ArrowRight: [0, nudgeSeconds]
223
+ };
224
+ const step = steps[event.key];
225
+ if (!step) return;
226
+ event.preventDefault();
227
+ onNudge?.(note.id, step[0], step[1]);
228
+ };
229
+ const wheel = (event) => {
230
+ if (!event.ctrlKey || !event.deltaY) return;
231
+ event.preventDefault();
232
+ setZoom(clamp(zoom * (event.deltaY > 0 ? 1 / 1.15 : 1.15), 0.25, 6));
233
+ };
234
+ return /* @__PURE__ */ jsx2(
235
+ "div",
236
+ {
237
+ ...mark("PianoRoll", p),
238
+ role: "application",
239
+ "aria-label": label ?? tr("\u0420\u0435\u0434\u0430\u043A\u0442\u043E\u0440 \u043C\u0435\u043B\u043E\u0434\u0438\u0438"),
240
+ "data-grid": grid || void 0,
241
+ style: { ...p.style, "--ad-pps": `${4 * zoom}rem`, "--ad-roll-rows": rows },
242
+ children: /* @__PURE__ */ jsxs2("div", { className: "ad-piano-roll-scroll", ref: scroller, onWheel: wheel, children: [
243
+ /* @__PURE__ */ jsx2("div", { className: "ad-piano-roll-corner" }),
244
+ /* @__PURE__ */ jsxs2(
245
+ "div",
246
+ {
247
+ className: "ad-piano-roll-ruler",
248
+ style: { width: at(length) },
249
+ onPointerDown: (event) => {
250
+ const box = event.currentTarget.getBoundingClientRect();
251
+ onSeek?.(clamp((event.clientX - box.left) / box.width * length, 0, length));
252
+ },
253
+ children: [
254
+ seconds.map((second) => /* @__PURE__ */ jsx2("span", { style: { left: at(second) }, "data-major": second % 5 === 0 || void 0, children: second }, second)),
255
+ /* @__PURE__ */ jsx2("i", { className: "ad-piano-roll-head-mark", style: { left: at(position) } })
256
+ ]
257
+ }
258
+ ),
259
+ /* @__PURE__ */ jsx2(PianoKeyboard, { className: "ad-piano-roll-keys", minMidi: minPitch, maxMidi: maxPitch, labels: "octaves", onKeyPress }),
260
+ /* @__PURE__ */ jsxs2(
261
+ "div",
262
+ {
263
+ className: "ad-piano-roll-world",
264
+ ref: world,
265
+ style: { width: at(length) },
266
+ onPointerDown: startArea,
267
+ onPointerMove: move,
268
+ onPointerUp: end,
269
+ onPointerCancel: end,
270
+ onLostPointerCapture: end,
271
+ onKeyDown: (event) => {
272
+ if (event.key === "Escape" && drag.current) {
273
+ event.preventDefault();
274
+ cancel();
275
+ }
276
+ },
277
+ children: [
278
+ Array.from({ length: rows }, (_, i) => maxPitch - i).filter(isBlackKey).map((pitch) => /* @__PURE__ */ jsx2("i", { className: "ad-piano-roll-row", style: { top: row(pitch) } }, pitch)),
279
+ notes.map((note) => /* @__PURE__ */ jsxs2(
280
+ "div",
281
+ {
282
+ className: "ad-piano-roll-note",
283
+ "data-selected": selected?.has(note.id) || void 0,
284
+ "data-now": position >= note.start && position <= note.end || void 0,
285
+ style: { left: at(note.start), width: `max(0.25rem, ${at(note.end - note.start)})`, top: row(note.pitch) },
286
+ children: [
287
+ /* @__PURE__ */ jsx2(
288
+ "button",
289
+ {
290
+ type: "button",
291
+ className: "ad-piano-roll-note-body",
292
+ "aria-label": tr("\u041D\u043E\u0442\u0430 {pitch}", { pitch: note.pitch }),
293
+ "aria-pressed": selected?.has(note.id) ?? false,
294
+ onPointerDown: (event) => startMove(event, note),
295
+ onKeyDown: (event) => nudge(event, note),
296
+ onClick: (event) => {
297
+ if (event.detail === 0) onSelect?.(note.id, event.ctrlKey || event.metaKey || event.shiftKey);
298
+ }
299
+ }
300
+ ),
301
+ /* @__PURE__ */ jsx2("span", { className: "ad-piano-roll-edge", "data-edge": "start", "aria-hidden": "true", onPointerDown: (event) => startResize(event, note, "start") }),
302
+ /* @__PURE__ */ jsx2("span", { className: "ad-piano-roll-edge", "data-edge": "end", "aria-hidden": "true", onPointerDown: (event) => startResize(event, note, "end") })
303
+ ]
304
+ },
305
+ note.id
306
+ )),
307
+ /* @__PURE__ */ jsx2("div", { className: "ad-piano-roll-area", ref: areaBox }),
308
+ /* @__PURE__ */ jsx2("span", { className: "ad-piano-roll-playhead", style: { left: at(position) } })
309
+ ]
310
+ }
311
+ ),
312
+ words.length > 0 && /* @__PURE__ */ jsxs2(Fragment, { children: [
313
+ /* @__PURE__ */ jsx2("div", { className: "ad-piano-roll-corner" }),
314
+ /* @__PURE__ */ jsx2("div", { className: "ad-piano-roll-words", style: { width: at(length) }, children: words.map((word) => /* @__PURE__ */ jsx2(
315
+ "span",
316
+ {
317
+ style: { left: at(word.start), width: at(word.end - word.start) },
318
+ "data-sung": position > word.end || void 0,
319
+ "data-now": position >= word.start && position <= word.end || void 0,
320
+ children: word.text
321
+ },
322
+ word.id
323
+ )) })
324
+ ] })
325
+ ] })
326
+ }
327
+ );
328
+ };
329
+
330
+ export {
331
+ isBlackKey,
332
+ noteName,
333
+ PianoKeyboard,
334
+ PianoRoll
335
+ };