minecraft-inventory 0.1.42 → 0.1.43

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,5 +1,7 @@
1
1
  # minecraft-inventory
2
2
 
3
+ DEMO: https://minecraft-inventory-npm.vercel.app/
4
+
3
5
  A flexible, scalable React library for rendering Minecraft inventory GUIs. Designed for integration into real Minecraft clients (e.g., mineflayer bots, web clients) without using CSS `transform: scale` — all sizing is driven by CSS custom properties.
4
6
 
5
7
  ## Features
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "minecraft-inventory",
3
- "version": "0.1.42",
3
+ "version": "0.1.43",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "release": {
@@ -16,6 +16,17 @@
16
16
  "files": [
17
17
  "src"
18
18
  ],
19
+ "homepage": "https://mcraft.fun",
20
+ "keywords": [
21
+ "minecraft",
22
+ "minecraft-ui",
23
+ "minecraft-inventory",
24
+ "inventory",
25
+ "vanilla",
26
+ "react",
27
+ "typescript",
28
+ "web"
29
+ ],
19
30
  "devDependencies": {
20
31
  "@rsbuild/core": "^1.7.3",
21
32
  "@rsbuild/plugin-react": "^1.4.6",
@@ -1,4 +1,4 @@
1
- import React, { useCallback, useState } from 'react'
1
+ import React, { useCallback, useEffect, useState } from 'react'
2
2
  import { useCloseOnWClick } from '../../hooks/useCloseOnWClick'
3
3
  import { useInventoryContext } from '../../context/InventoryContext'
4
4
  import { useScale } from '../../context/ScaleContext'
@@ -94,7 +94,7 @@ export function InventoryOverlay({
94
94
  noWatermark = false,
95
95
  onOpenSettings,
96
96
  }: InventoryOverlayProps) {
97
- const { heldItem, sendAction, setHeldItem, focusedSlot, setFocusedSlot } = useInventoryContext()
97
+ const { heldItem, sendAction, setHeldItem, focusedSlot, setFocusedSlot, hoveredSlot, getSlot } = useInventoryContext()
98
98
  const { scale } = useScale()
99
99
  const [settingsHovered, setSettingsHovered] = useState(false)
100
100
 
@@ -136,8 +136,30 @@ export function InventoryOverlay({
136
136
  pushRecipeFrame({ item, mode, guides, guideIndex: 0 })
137
137
  }, [jeiOnGetRecipes, jeiOnGetUsages, pushRecipeFrame])
138
138
 
139
+ // R / U while hovering a regular inventory slot (not JEI, not recipe view)
140
+ useEffect(() => {
141
+ if (!jeiOnGetRecipes && !jeiOnGetUsages) return
142
+ const handler = (e: KeyboardEvent) => {
143
+ if (e.code !== 'KeyR' && e.code !== 'KeyU') return
144
+ const target = e.target as Element | null
145
+ const tagName = (target as { tagName?: string })?.tagName ?? ''
146
+ if (tagName === 'INPUT' || tagName === 'TEXTAREA' || tagName === 'SELECT' || (target as { isContentEditable?: boolean })?.isContentEditable) return
147
+ if (recipeNavStack.length > 0) return // RecipeInventoryView handles its own R/U
148
+ if (hoveredSlot === null || hoveredSlot < 0) return // JEI slots handled by JEI.tsx
149
+ const slot = getSlot(hoveredSlot)
150
+ if (!slot?.item) return
151
+ const item = slot.item
152
+ handleRecipePushFrame(
153
+ { type: item.type, name: item.name ?? '', displayName: item.displayName ?? item.name ?? `Item #${item.type}`, count: item.count, metadata: item.metadata },
154
+ e.code === 'KeyR' ? 'recipes' : 'usages',
155
+ )
156
+ }
157
+ window.addEventListener('keydown', handler)
158
+ return () => window.removeEventListener('keydown', handler)
159
+ }, [jeiOnGetRecipes, jeiOnGetUsages, recipeNavStack.length, hoveredSlot, getSlot, handleRecipePushFrame])
160
+
139
161
  // Fires for any click that isn't stopped by an interactive panel (inventory, hotbar, JEI, etc.)
140
- const handleBackdropClick = useCallback((e: React.MouseEvent) => {
162
+ const handleBackdropClick = useCallback((e: React.MouseEvent<HTMLDivElement>) => {
141
163
  // Only handle left (drop all) and right (drop one) mouse buttons
142
164
  if (e.button !== 0 && e.button !== 2) return
143
165
  if (heldItem) {
@@ -316,6 +338,7 @@ export function InventoryOverlay({
316
338
  href="https://www.npmjs.com/package/minecraft-inventory"
317
339
  target="_blank"
318
340
  rel="noopener noreferrer"
341
+ onMouseDown={(e) => e.stopPropagation()}
319
342
  onClick={(e) => e.stopPropagation()}
320
343
  style={{
321
344
  position: 'absolute',
@@ -330,7 +353,7 @@ export function InventoryOverlay({
330
353
  lineHeight: 1,
331
354
  }}
332
355
  >
333
- INV 0.1.42
356
+ INV 0.1.43
334
357
  </a>
335
358
  )}
336
359
 
@@ -167,6 +167,7 @@ export function Notes({
167
167
  </span>
168
168
  <button
169
169
  type="button"
170
+ onMouseDown={(e) => e.stopPropagation()}
170
171
  onClick={(e) => {
171
172
  e.stopPropagation()
172
173
  removeNote(note.id)
@@ -205,6 +206,7 @@ export function Notes({
205
206
  value={draft}
206
207
  rows={2}
207
208
  autoFocus
209
+ onMouseDown={(e) => e.stopPropagation()}
208
210
  onClick={(e) => e.stopPropagation()}
209
211
  onChange={(e) => {
210
212
  setDraft(e.target.value.replace(/[\r\n]/g, ''))
@@ -235,6 +237,7 @@ export function Notes({
235
237
  {showInput && (
236
238
  <button
237
239
  type="button"
240
+ onMouseDown={(e) => e.stopPropagation()}
238
241
  onClick={(e) => {
239
242
  e.stopPropagation()
240
243
  setShowInput(false)
@@ -257,6 +260,7 @@ export function Notes({
257
260
  )}
258
261
  <button
259
262
  type="button"
263
+ onMouseDown={(e) => e.stopPropagation()}
260
264
  onClick={(e) => {
261
265
  e.stopPropagation()
262
266
  handleAddButtonClick()