astro-abcjs 1.0.0 → 1.1.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.
package/README.md CHANGED
@@ -1,11 +1,51 @@
1
+
1
2
  # astro-abcjs
2
3
 
3
4
  An abcjs component for Astro projects.
4
5
 
5
- ## Credits & Inspiration
6
+ ## Usage
7
+
8
+ ### In .astro files
9
+
10
+ Import the component and use it in your Astro page or component:
11
+
12
+ ```astro
13
+ ---
14
+ import AbcjsPlayer from 'astro-abcjs/AbcjsPlayer.astro';
15
+ ---
16
+
17
+ <AbcjsPlayer
18
+ notation={`X:1\nT:Scale\nM:4/4\nK:C\nC D E F | G A B c |`}
19
+ showControls={true}
20
+ responsive={true}
21
+ abcjsVersion="6.6.0"
22
+ />
23
+ ```
24
+
25
+ ### In MDX files
6
26
 
7
- This component was inspired by the article:
27
+ First, make sure your project supports MDX and components in MDX.
28
+
29
+ Import the component at the top of your MDX file:
30
+
31
+ ```mdx
32
+ import AbcjsPlayer from 'astro-abcjs/AbcjsPlayer.astro';
33
+
34
+ <AbcjsPlayer
35
+ notation={`X:1\nT:Scale\nM:4/4\nK:C\nC D E F | G A B c |`}
36
+ showControls={true}
37
+ responsive={true}
38
+ abcjsVersion="6.6.0"
39
+ />
40
+ ```
41
+
42
+ #### Props
43
+
44
+ - `notation` (string, required): The ABC notation string to render.
45
+ - `showControls` (boolean, default: true): Show audio playback controls.
46
+ - `responsive` (boolean, default: true): Make the notation responsive to container size.
47
+ - `abcjsVersion` (string, optional, default: "6.6.0"): The abcjs version to load from CDN. Override to pin or upgrade/downgrade.
48
+
49
+ ## Credits & Inspiration
8
50
 
9
- **Building a Reusable Music Component in Astro using ABCjs**
10
- by [Pavlin Gunov](https://www.pavlinbg.com/)
11
- <https://www.pavlinbg.com/posts/building-a-reusable-music-component-in-astro-using-abcjs>
51
+ This component was inspired by the article [Building a Reusable Music Component in Astro using ABCjs](https://www.pavlinbg.com/posts/building-a-reusable-music-component-in-astro-using-abcjs) by [Pavlin Gunov](https://www.pavlinbg.com/).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "astro-abcjs",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "An Astro component to embed abcjs in content",
5
5
  "keywords": [
6
6
  "astro",
@@ -7,9 +7,15 @@ interface Props {
7
7
  notation: string;
8
8
  showControls?: boolean;
9
9
  responsive?: boolean;
10
+ abcjsVersion?: string;
10
11
  }
11
12
 
12
- const { notation, showControls = true, responsive = true } = Astro.props;
13
+ const {
14
+ notation,
15
+ showControls = true,
16
+ responsive = true,
17
+ abcjsVersion = "6.6.0",
18
+ } = Astro.props;
13
19
  ---
14
20
 
15
21
  <div
@@ -17,58 +23,67 @@ const { notation, showControls = true, responsive = true } = Astro.props;
17
23
  data-notation={notation}
18
24
  data-responsive={responsive}
19
25
  >
20
- <div id="paper" class="abcjs-paper"></div>
21
- {showControls && <div id="audio" class="abcjs-audio" />}
26
+ <div class="abcjs-paper"></div>
27
+ {showControls && <div class="abcjs-audio" />}
22
28
  </div>
23
29
 
24
- <script>
30
+ <script define:vars={{ abcjsVersion }}>
25
31
  if (typeof window !== "undefined") {
26
- import("abcjs").then((abcjs) => {
27
- function initializeAbcjs() {
28
- const containers = document.querySelectorAll(".abcjs-container");
29
- containers.forEach((container) => {
30
- if (container.dataset.abcjsInitialized === "true") return;
31
- const notation = container.getAttribute("data-notation");
32
- if (!notation) return;
33
- const isResponsive =
34
- container.getAttribute("data-responsive") === "true";
35
- const paperDiv = container.querySelector("#paper");
36
- const audioDiv = container.querySelector("#audio");
37
- // Render music notation
38
- const visualObj = abcjs.default.renderAbc(paperDiv, notation, {
39
- responsive: isResponsive ? "resize" : undefined,
40
- add_classes: true,
41
- paddingleft: 0,
42
- paddingright: 0,
43
- paddingbottom: 10,
44
- paddingtop: 10,
32
+ // Load abcjs browser build from CDN if not already loaded
33
+ if (!window.ABCJS) {
34
+ const script = document.createElement("script");
35
+ script.src = `https://cdn.jsdelivr.net/npm/abcjs@${abcjsVersion}/dist/abcjs-basic.js`;
36
+ script.onload = initializeAbcjs;
37
+ document.head.appendChild(script);
38
+ } else {
39
+ initializeAbcjs();
40
+ }
41
+
42
+ function initializeAbcjs() {
43
+ const abcjs = window.ABCJS;
44
+ if (!abcjs) return;
45
+ const containers = document.querySelectorAll(".abcjs-container");
46
+ containers.forEach((container) => {
47
+ if (container.dataset.abcjsInitialized === "true") return;
48
+ const notation = container.getAttribute("data-notation");
49
+ if (!notation) return;
50
+ const isResponsive =
51
+ container.getAttribute("data-responsive") === "true";
52
+ const paperDiv = container.querySelector(".abcjs-paper");
53
+ const audioDiv = container.querySelector(".abcjs-audio");
54
+ // Render music notation
55
+ const visualObj = abcjs.renderAbc(paperDiv, notation, {
56
+ responsive: isResponsive ? "resize" : undefined,
57
+ add_classes: true,
58
+ paddingleft: 0,
59
+ paddingright: 0,
60
+ paddingbottom: 10,
61
+ paddingtop: 10,
62
+ });
63
+ // Audio playback controls
64
+ if (audioDiv && abcjs.synth) {
65
+ const synthControl = new abcjs.synth.SynthController();
66
+ synthControl.load(audioDiv, null, {
67
+ displayLoop: true,
68
+ displayRestart: true,
69
+ displayPlay: true,
70
+ displayProgress: true,
71
+ displayWarp: true,
45
72
  });
46
- // Audio playback controls
47
- if (audioDiv) {
48
- const synthControl = new abcjs.default.synth.SynthController();
49
- synthControl.load(audioDiv, null, {
50
- displayLoop: true,
51
- displayRestart: true,
52
- displayPlay: true,
53
- displayProgress: true,
54
- displayWarp: true,
73
+ const createSynth = new abcjs.synth.CreateSynth();
74
+ createSynth
75
+ .init({ visualObj: visualObj[0] })
76
+ .then(() => {
77
+ synthControl.setTune(visualObj[0], false);
78
+ })
79
+ .catch((error) => {
80
+ console.warn("Audio synthesis initialization failed:", error);
55
81
  });
56
- const createSynth = new abcjs.default.synth.CreateSynth();
57
- createSynth
58
- .init({ visualObj: visualObj[0] })
59
- .then(() => {
60
- synthControl.setTune(visualObj[0], false);
61
- })
62
- .catch((error) => {
63
- console.warn("Audio synthesis initialization failed:", error);
64
- });
65
- }
66
- container.dataset.abcjsInitialized = "true";
67
- });
68
- }
69
- initializeAbcjs();
70
- document.addEventListener("astro:page-load", initializeAbcjs);
71
- });
82
+ }
83
+ container.dataset.abcjsInitialized = "true";
84
+ });
85
+ }
86
+ document.addEventListener("astro:page-load", initializeAbcjs);
72
87
  }
73
88
  </script>
74
89