First object collapse is overwritten by pending hover state in React 19 (standalone production repro)
まだ誰も着手していません。
評価
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 初心者へのやさしさ
- 54/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 活発
- 技術スタック
- javascript, playwright, react, vite
調査の方向性
Start with Object.js at the reported hover handling, child rendering, getDerivedStateFromProps, and handleToggleCollapsed locations, then inspect ObjectAttributes.js and the standalone production reproduction. Trace how the fresh namespace and expanded cache interact when a click overlaps pending hover state. Done means the single native click collapses the branch reliably in the React 19 production fixture while the existing behavior remains intact.
索引モデルが issue の本文から書いたものです。
説明
Summary
With @microlink/react-json-view 1.31.43 and React 19.3.1, the first native click to collapse a nested object can leave it expanded when the pointer moves directly from outside the tree onto its toggle. The click is delivered; a props-derived state calculation overwrites the queued collapse before it commits.
This reproduces in an independent production build, using the unmodified published package. Storybook, Vitest, StrictMode, React act, external props changes and application wrappers are not required.
This report has been rewritten after standalone source investigation and verification. In particular, a fresh branch has no expanded-cache entry yet: the overwrite can come from the initial expanded default, not necessarily a previously stored stale value. All current conclusions and reproduction files are below; no earlier comment is needed to interpret the report.
Reproduction steps
- Save the six files in the “Complete standalone project” section below into an empty directory. The package and full lockfile pin the dependencies.
- Use Node >=22.12, Corepack/pnpm 9.15.9, and an installed Google Chrome. Run:
corepack pnpm install --frozen-lockfile
corepack pnpm build
corepack pnpm preview
- In a second terminal in that directory, run:
COUNT=100 URL=http://127.0.0.1:6422 OUTPUT=results-prod.json corepack pnpm test
The reproduction assertion expects the leaf to disappear and therefore exits 1 when the bug occurs. It is not an expected-failure test. Each attempt navigates to a fresh document, positions the pointer on the outside button, waits two frames, then performs exactly one normal native locator.click() on the branch toggle. The runner verifies that it selected the branch row, checks after two animation frames and again 250ms later, records every pass/failure and saves the first failure screenshot. It never clicks a second time, retries the click, patches the dependency or changes component state/cache.
For a manual attempt, open the preview, put the pointer on “Pointer start”, then move directly onto the branch's collapse icon and click promptly. Pausing over the tree before clicking can make the attempt pass, so a manually passing attempt does not refute the timing condition. The automated input is included to make this condition easier to reproduce.
Expected
The branch collapses after the first click; "LEAF" is absent from the DOM.
Actual
The branch remains expanded and "LEAF" remains in the DOM, including after the later 250ms observation. The failing natural production run had no page errors, console warnings/errors or HTTP failures.
Measured results and limits
Each entry is a separate group of fresh document loads. These counts are observations in the recorded environment, not a guarantee of 100% reproduction on every machine, browser or manual input interval.
| Standalone configuration | First-click failures / fresh loads |
|---|---|
| React 19.3.1 production, StrictMode on, no observers | 100/100 |
| Independent reviewer rerun of the same production fixture, no observers | 30/30 |
| React 19.3.1 development, StrictMode on, no observers | 30/30 |
| React 19.3.1 production, StrictMode off, no observers | 30/30 |
| React 19.3.1 development, StrictMode off, no observers | 30/30 |
| React 18.3.1 production, StrictMode on, no observers | 0/30 |
| React 18.3.1 development, StrictMode on, no observers | 0/30 |
| React 19.3.1 development, hover settles for two frames before the single click | 0/30 |
Earlier standalone development batches were 29/30 and 28/30; those passing samples were retained. An optional state-trace batch was 29/30. Instrumentation and input timing affect the frequency, which is why uninstrumented production, traced and controlled-scheduling results are kept separate.
Environment: @microlink/react-json-view 1.31.43, React/ReactDOM 19.3.1 or 18.3.1, Vite 8.3.5, Playwright 1.59.1, Google Chrome 156.0.8078.79, Node 24.15.0, pnpm 9.15.9, macOS 15.8.1, viewport 414 × 896. React 18 and React 19 comparison projects were installed independently. The fixture uses no Ant Design or application component library.
Source-level cause
The following references are pinned to the commit behind the v1.31.43 release, 076754db9d2d8b528ae2bdc10d02452f51c7a84c, and were checked against the published bundle.
- Object hover handling queues parent/child hover updates when the pointer enters the tree.
- Rendering child objects allocates a fresh
namespace.concat(...)array even when the logical path has not changed. - getDerivedStateFromProps compares namespace by reference and calls
getStatewhen that reference changes. - getState reads expanded state from AttributeStore.get. A fresh branch has no expanded-cache entry; for this nonempty object with the default collapsed=false, it falls back to true.
- handleToggleCollapsed queues
expanded:false, but only persists expanded state in the later setState callback, usingthis.state.expandedat that time.
When the parent hover is still pending at the click, the parent render gives the child a new namespace reference. The child's queued toggle has been processed as false, but derived state reads the cached-or-initial value true before the callback has saved false. Derived state overwrites false with true; the callback then saves true.
A read-only trace of the original methods recorded this sequence in all 29 failing traced documents:
root hover enqueue
branch hover enqueue; rootPending=8
branch toggle enqueue expanded=false; rootPending=8; actQueueActive=false
branch derive: before=false; namespaceChanged=true; result=true
branch callback: expanded=true
The sole passing traced document had already committed hover: pending lanes were 0 when toggling, namespace did not change, and the callback saved false. Every observed document received exactly one trusted click.
The installed React DOM 19.3.1 implementation selects pending event lanes using lanes & 42, allowing the click lane 2 and continuous-hover lane 8 to render together in this case. React 18.3.1 selects the synchronous lane first; its comparison traces saved false before the later parent-hover derivation. This explains the observed version difference. It does not establish a React bug; the lost collapse is in this component's derived-state/cache synchronization.
Controls and optional diagnostics
?strict=0disables StrictMode; the independent dev and production runs still reproduce.STRATEGY=settled-hoverhovers over the target and waits two frames before the one click. It passed 30/30 under React 19. This verifies the timing boundary, not a production workaround.- Default runs install neither event observers nor React method wrappers.
?eventsrecords native events;?trace&eventsadditionally observes original state methods. It forwards the original arguments and return values and does not mutate props/state/cache, but can affect timing and therefore has separate results. DIAGNOSTIC=actis a development-only experiment that deliberately holds React's test queue across the native click. It produced 100/100 failures, but changes scheduling and is not included in the natural production count. It is not needed for the production reproduction.- The published upstream bundle was not changed. Existing successful array/update/remount/clipboard observations are separate; this report does not claim that every JSON-tree operation fails.
Complete standalone project
Save each file below using its indicated filename. The default production run does not enable the optional diagnostics. The scripts contain no imports from our repository or absolute local paths.
package.json
{
"name": "d42-json-tree-first-native-click",
"version": "1.0.0",
"private": true,
"type": "module",
"packageManager": "[email protected]",
"engines": { "node": ">=22.12.0" },
"scripts": {
"dev": "vite --host 127.0.0.1 --port 6421 --strictPort",
"build": "vite build",
"preview": "vite preview --host 127.0.0.1 --port 6422 --strictPort",
"test": "node run.mjs"
},
"dependencies": {
"@microlink/react-json-view": "1.31.43",
"react": "19.3.1",
"react-dom": "19.3.1"
},
"devDependencies": {
"playwright": "1.59.1",
"vite": "8.3.5"
}
}
index.html
<!doctype html>
<html lang="en">
<head><meta charset="UTF-8"><link rel="icon" href="data:,"><title>D42 JSON tree reproduction</title></head>
<body><div id="root"></div><script type="module" src="/main.jsx"></script></body>
</html>
main.jsx
import React, { StrictMode, act } from 'react';
import { createRoot } from 'react-dom/client';
import ReactJsonView from '@microlink/react-json-view';
import { installTrace } from './trace.js';
const params = new URLSearchParams(location.search);
const data = { branch: { leaf: 'LEAF' }, list: [{ item: 'ITEM' }] };
// Both observers are opt-in. The default reproduction installs neither.
if (params.has('trace')) window.restoreTrace = installTrace();
window.events = [];
if (params.has('events')) {
for (const type of ['mouseover', 'mouseenter', 'mousemove', 'pointerdown', 'mousedown', 'mouseup', 'click']) {
document.addEventListener(type, event => {
window.events.push({
type,
time: performance.now(),
trusted: event.isTrusted,
target: event.target.getAttribute?.('class'),
});
}, true);
}
}
function Example() {
return <>
<button id="outside" type="button">Pointer start</button>
<div style={{ position: 'relative', overflow: 'auto', marginBottom: 8, padding: 16, borderRadius: 8, background: '#f1f5f9' }}>
<ReactJsonView
style={{ width: '100%', height: '100%' }}
src={data}
name={false}
displayDataTypes={false}
displayArrayKey={false}
displayObjectSize={false}
enableClipboard={false}
/>
</div>
</>;
}
const root = createRoot(document.getElementById('root'));
root.render(params.get('strict') === '0' ? <Example /> : <StrictMode><Example /></StrictMode>);
window.environment = {
react: React.version,
mode: import.meta.env.MODE,
strict: params.get('strict') !== '0',
trace: params.has('trace'),
events: params.has('events'),
};
// Diagnostic only: hold React's test queue across native input. This changes
// scheduling, so its results must never be counted as natural-user evidence.
if (import.meta.env.DEV) {
let batch;
let release;
let previousActEnvironment;
window.beginDiagnosticBatch = () => {
if (batch) throw new Error('Diagnostic batch already active');
previousActEnvironment = globalThis.IS_REACT_ACT_ENVIRONMENT;
globalThis.IS_REACT_ACT_ENVIRONMENT = true;
const gate = new Promise(resolve => { release = resolve; });
batch = (async () => { await act(async () => { await gate; }); })();
};
window.endDiagnosticBatch = async () => {
if (!batch) throw new Error('Diagnostic batch is not active');
try {
release();
await batch;
} finally {
globalThis.IS_REACT_ACT_ENVIRONMENT = previousActEnvironment;
batch = undefined;
release = undefined;
}
};
}
trace.js
import React from 'react';
export function installTrace() {
const originalSetState = React.PureComponent.prototype.setState;
const derives = new Map();
window.stateTrace = [];
const log = entry => window.stateTrace.push({ time: performance.now(), ...entry });
const pendingLanes = instance => {
// Read-only private React data, used only by this optional diagnostic.
let fiber = instance._reactInternals;
if (!fiber) throw new Error('Diagnostic requires a React class fiber');
while (fiber.return) fiber = fiber.return;
return {
rootPending: fiber.stateNode.pendingLanes,
actQueueActive: React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE?.actQueue != null,
};
};
React.PureComponent.prototype.setState = function (update, callback) {
if (!(this.props && 'namespace' in this.props && 'src' in this.props)) {
return originalSetState.call(this, update, callback);
}
const Constructor = this.constructor;
if (!derives.has(Constructor) && Constructor.getDerivedStateFromProps) {
const derive = Constructor.getDerivedStateFromProps;
derives.set(Constructor, derive);
Constructor.getDerivedStateFromProps = function (props, state) {
const result = derive.call(this, props, state);
log({
kind: 'derive', name: props.name, before: state.expanded,
namespaceChanged: props.namespace !== state.prevProps?.namespace,
result: result?.expanded,
});
return result;
};
}
log({
kind: 'enqueue', name: this.props.name, before: this.state.expanded,
update: typeof update === 'object' ? { expanded: update.expanded, hovered: update.hovered } : typeof update,
callback: !!callback, ...pendingLanes(this),
});
// Preserve callback presence and all arguments. Do not touch state, props,
// the update payload, the cache, or any scheduling primitive.
return originalSetState.call(this, update, callback ? function (...args) {
log({ kind: 'callback', name: this.props.name, expanded: this.state.expanded });
return callback.apply(this, args);
} : undefined);
};
return () => {
React.PureComponent.prototype.setState = originalSetState;
for (const [Constructor, derive] of derives) Constructor.getDerivedStateFromProps = derive;
};
}
run.mjs
import { chromium } from 'playwright';
import { mkdir, writeFile } from 'node:fs/promises';
import { dirname } from 'node:path';
const count = Number(process.env.COUNT || 30);
const base = process.env.URL || 'http://127.0.0.1:6421';
const strategy = process.env.STRATEGY || 'locator';
const diagnostic = process.env.DIAGNOSTIC || 'none';
const output = process.env.OUTPUT || 'results.json';
const cpuRate = Number(process.env.CPU_RATE || 1);
if (!Number.isInteger(count) || count < 1) throw new Error('COUNT must be a positive integer');
if (!['locator', 'force', 'fast-mouse', 'mouse', 'settled-hover', 'cdp'].includes(strategy)) throw new Error(`Unknown STRATEGY: ${strategy}`);
if (!['none', 'act'].includes(diagnostic)) throw new Error(`Unknown DIAGNOSTIC: ${diagnostic}`);
if (!Number.isFinite(cpuRate) || cpuRate < 1) throw new Error('CPU_RATE must be >= 1');
await mkdir(dirname(output), { recursive: true });
const browser = await chromium.launch({ channel: process.env.CHANNEL || 'chrome', headless: process.env.HEADED !== '1' });
const context = await browser.newContext({ viewport: { width: 414, height: 896 } });
const page = await context.newPage();
const results = [], errors = [], consoleMessages = [], responseFailures = [];
page.on('pageerror', error => { errors.push(String(error)); console.error(error); });
page.on('response', response => {
if (response.status() >= 400) {
responseFailures.push({ url: response.url(), status: response.status() });
console.error(`[HTTP ${response.status()}] ${response.url()}`);
}
});
page.on('console', message => {
if (message.type() === 'error' || message.type() === 'warning') {
consoleMessages.push({ type: message.type(), text: message.text(), location: message.location() });
console.error(`[browser ${message.type()}] ${message.text()}`);
}
});
const frames = () => page.evaluate(() => new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve))));
if (cpuRate !== 1) {
const cdp = await context.newCDPSession(page);
await cdp.send('Emulation.setCPUThrottlingRate', { rate: cpuRate });
await cdp.detach();
}
try {
// These are independent fresh documents, never retries of a failed click.
for (let attempt = 1; attempt <= count; attempt++) {
await page.mouse.move(400, 850);
await page.goto(base);
await page.locator('.string-value').filter({ hasText: /^"LEAF"$/ }).waitFor();
await page.locator('#outside').hover();
await frames();
if (diagnostic === 'act') await page.evaluate(() => window.beginDiagnosticBatch());
try {
const label = page.locator('.object-key').filter({ hasText: /^"branch"$/ });
const row = page.locator('.object-key-val').filter({ has: label }).last();
const toggle = row.locator('.icon-container').first();
const selectedName = await toggle.evaluate(element => element.closest('.object-key-val').querySelector('.object-key').textContent);
if (selectedName !== '"branch"') throw new Error(`Wrong toggle selected: ${selectedName}`);
if (strategy === 'locator') await toggle.click();
else if (strategy === 'force') await toggle.click({ force: true });
else if (strategy === 'settled-hover') {
await toggle.hover();
await frames();
await toggle.click();
} else {
const box = await toggle.boundingBox();
if (!box) throw new Error('Missing branch toggle box');
const x = box.x + box.width / 2, y = box.y + box.height / 2;
if (strategy === 'fast-mouse') await page.mouse.click(x, y);
else if (strategy === 'mouse') {
await page.mouse.move(x, y);
await page.mouse.down();
await page.mouse.up();
} else {
const cdp = await context.newCDPSession(page);
try {
for (const [type, buttons] of [['mouseMoved', 0], ['mousePressed', 1], ['mouseReleased', 0]]) {
await cdp.send('Input.dispatchMouseEvent', {
type, x, y, button: type === 'mouseMoved' ? 'none' : 'left',
buttons, clickCount: type === 'mouseMoved' ? 0 : 1,
});
}
} finally { await cdp.detach(); }
}
}
} finally {
if (diagnostic === 'act') await page.evaluate(() => window.endDiagnosticBatch());
}
await frames();
const afterFrames = await page.locator('.string-value').filter({ hasText: /^"LEAF"$/ }).count();
// Also observe a later state so a delayed successful commit is not called a failure.
await page.waitForTimeout(250);
const result = await page.evaluate(() => ({
environment: window.environment,
leafPresent: [...document.querySelectorAll('.string-value')].some(element => element.textContent === '"LEAF"'),
events: window.events,
stateTrace: window.stateTrace,
}));
results.push({ attempt, afterFrames, ...result });
if (result.leafPresent && results.filter(item => item.leafPresent).length === 1) {
await page.screenshot({ path: output.replace(/\.json$/, '') + '.first-failure.png' });
}
await page.evaluate(() => { window.restoreTrace?.(); });
}
} finally {
await page.evaluate(() => { window.restoreTrace?.(); }).catch(error => {
errors.push(`Trace cleanup failed: ${error}`);
console.error(error);
});
await writeFile(output, JSON.stringify({
browser: browser.version(), node: process.version, count, base, strategy, diagnostic,
cpuRate, viewport: { width: 414, height: 896 }, errors, consoleMessages, responseFailures, results,
}, null, 2) + '\n');
await browser.close();
}
const failures = results.filter(result => result.leafPresent).length;
console.log(JSON.stringify({ output, failures, attempts: results.length, firstFailed: results[0]?.leafPresent, errors, consoleMessages: consoleMessages.length, responseFailures }));
// A collapse failure is an ordinary failing result. There is no expected-failure
// mode, second click, test retry, relaxed assertion, or patched dependency.
if (failures || errors.length || responseFailures.length || results.length !== count) process.exitCode = 1;
pnpm-lock.yaml
lockfileVersion: '9.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
importers:
.:
dependencies:
'@microlink/react-json-view':
specifier: 1.31.43
version: 1.31.43([email protected]([email protected]))([email protected])
react:
specifier: 19.3.1
version: 19.3.1
react-dom:
specifier: 19.3.1
version: 19.3.1([email protected])
devDependencies:
playwright:
specifier: 1.59.1
version: 1.59.1
vite:
specifier: 8.3.5
version: 8.3.5([email protected])
packages:
'@babel/[email protected]':
resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==}
engines: {node: '>=6.9.0'}
'@microlink/[email protected]':
resolution: {integrity: sha512-zKmzMq1W1dr2ALRbqZkjZlar9Z/J3xsn/c8cQ/gnblSrrOaaYa7FaY9DNElr9LSEckVmY7vljEJ22V46ICZF5w==}
engines: {node: '>=17'}
peerDependencies:
react: '>= 15'
react-dom: '>= 15'
'@oxc-project/[email protected]':
resolution: {integrity: sha512-SeE8JPwW1xs1tHeNycjUtUBdhorRa8o4jlvjwk49R7/Z291i+4DQa7JJIgOm/TaYQZx+QrPQbVJ/9c8dMIZN8Q==}
'@rolldown/[email protected]':
resolution: {integrity: sha512-aLcgK9gIJ3YRvrrtfSBbRa27F5WrpiTaPulnFpsHPxpUHgFlSgnU4854MHwoRGEBhfRJDWCS2WQ7lIjskE9Olw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [android]
'@rolldown/[email protected]':
resolution: {integrity: sha512-xD7DdZCrbThKuxNg7ooQmvp07ys4J/pnSEMTG3/OdOWl6daC67m/Q4fL78sRHMxTH/N4fGUbYhcPM0MF5WFHkg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [android]
'@rolldown/[email protected]':
resolution: {integrity: sha512-m2WuQ6r0B4OTYxyPpNLtXaMRbRDUbG8YQV2Q3KTdSSK8Th6KHCnC8jVCJt8bvYeSB5WivkkNbc85mKadaSdOxA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [darwin]
'@rolldown/[email protected]':
resolution: {integrity: sha512-5RtnsHM36nodM9WbMy+zip0LGS/G+y5wro5RHrpOlr4ac24+1zSi9kiV2MP1myZeZ/ifEHfulQcWjnAXzc2C2A==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [darwin]
'@rolldown/[email protected]':
resolution: {integrity: sha512-g3l09pyFqhu+135JKkbkwiKGQmwU5hUMUPJ4VdBADvuqR8d33L6H578rh8m7rtxbdp+VmX/+nzI7nvhSZlzpUQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [freebsd]
'@rolldown/[email protected]':
resolution: {integrity: sha512-nIe3VugI97nGQtspPxDqA4sXMUpeiocKIP/CqpY/u/vgbT+alX+cVxu1C/oVBPKg4feNTmYovE91v4DgXvXNwQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [linux]
'@rolldown/[email protected]':
resolution: {integrity: sha512-iTBjXx+B5QSvgI89lJfmqh4wTh8NabR1YZIIN3hNx4zSG0EVfVqkOvLulNpG4251pbd6/IAmZ/LefVk1Y4rPhw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@rolldown/[email protected]':
resolution: {integrity: sha512-uN26XOnVR7rqQupG3V9oAG2EGGatWjcJHOeDOHUFCh4TBWmP2tHTFoVN13aYbwfm0aHqJAEmcwhAu6sooIjfqQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
libc: [musl]
'@rolldown/[email protected]':
resolution: {integrity: sha512-9nWkcdd+H+XhaA3fQIwpHnKIrfx/PQ6rO0pivr78Og07tXlUlctBBJoEYLPfhTmCR/QxEVdn6uPjHV5SymPhdw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [ppc64]
os: [linux]
libc: [glibc]
'@rolldown/[email protected]':
resolution: {integrity: sha512-Ggh0ciFjLwIusLSLz7LZYEaGdxOAUJXI+Qu5JCbhPJJHEt8vP+IjRATTJheiJsdzzTYgUiHUiw3X1Ea3ZpMBdA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [s390x]
os: [linux]
libc: [glibc]
'@rolldown/[email protected]':
resolution: {integrity: sha512-FHg60rS6DBePAYZ9X9F67x+JObFdmgn6tupA1C/a3B+CufFmTD4mX+e8M75tCiAO3foR/6xwVBI0KQiI7sn/rw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
libc: [glibc]
'@rolldown/[email protected]':
resolution: {integrity: sha512-/cvV/7v5VGz/moiz0XKRj2dE8DzsKyhIu1KpOvJGPjRywg3yscON889UGvAe8zfiJLHup7VLjBduoGWi3HusWQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
libc: [musl]
'@rolldown/[email protected]':
resolution: {integrity: sha512-MyzC5Hrv/sm+Z7TSGKP/j8001RO2xQm1zOpCNVL4j0cY/VhBZviludA2YFQ7i4lH6ZAXxQm0lcMdBzM+99mE7w==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [openharmony]
'@rolldown/[email protected]':
resolution: {integrity: sha512-+PgYiS+AH5omy6L45ZLxybasauJaj3M8buoT83D+nzPmCayXlxUV9hydhciCKVyIg0B/v0BtXPDE1uGqNwCPpg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [win32]
'@rolldown/[email protected]':
resolution: {integrity: sha512-HFZd2QNQYn1JbIi+Hpd7H+r/lkWxcfIu28nirZ6eCn2LafuvmExMlb/P96Sfx5tf7pPArw39IdhmCF8vmV+NhQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [win32]
'@rolldown/[email protected]':
resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==}
'@types/[email protected]':
resolution: {integrity: sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA==}
[email protected]:
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
engines: {node: '>=7.0.0'}
[email protected]:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
[email protected]:
resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==}
[email protected]:
resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==}
engines: {node: '>=12.5.0'}
[email protected]:
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
[email protected]:
resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
engines: {node: '>=8'}
[email protected]:
resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
engines: {node: '>=12.0.0'}
peerDependencies:
picomatch: ^3 || ^4
peerDependenciesMeta:
picomatch:
optional: true
[email protected]:
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os: [darwin]
[email protected]:
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os: [darwin]
[email protected]:
resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==}
[email protected]:
resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==}
hasBin: true
[email protected]:
resolution: {integrity: sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==}
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [android]
[email protected]:
resolution: {integrity: sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==}
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [darwin]
[email protected]:
resolution: {integrity: sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [darwin]
[email protected]:
resolution: {integrity: sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [freebsd]
[email protected]:
resolution: {integrity: sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==}
engines: {node: '>= 12.0.0'}
cpu: [arm]
os: [linux]
[email protected]:
resolution: {integrity: sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==}
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [linux]
libc: [glibc]
[email protected]:
resolution: {integrity: sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==}
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [linux]
libc: [musl]
[email protected]:
resolution: {integrity: sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [linux]
libc: [glibc]
[email protected]:
resolution: {integrity: sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [linux]
libc: [musl]
[email protected]:
resolution: {integrity: sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==}
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [win32]
[email protected]:
resolution: {integrity: sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [win32]
[email protected]:
resolution: {integrity: sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==}
engines: {node: '>= 12.0.0'}
[email protected]:
resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==}
[email protected]:
resolution: {integrity: sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true
[email protected]:
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
[email protected]:
resolution: {integrity: sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==}
engines: {node: '>=12'}
[email protected]:
resolution: {integrity: sha512-HBV/RJg81z5BiiZ9yPzIiClYV/QMsDCKUyogwH9p3MCP6IYjUFu/MActgYAvK0oWyV9NlwM3GLBjADyWgydVyg==}
engines: {node: '>=18'}
hasBin: true
[email protected]:
resolution: {integrity: sha512-C8oWjPR3F81yljW9o5OxcWzfh6avkVwDD2VYdwIGqTkl+OGFISgypqzfu7dOe4QNLL2aqcWBmI3PMtLIK233lw==}
engines: {node: '>=18'}
hasBin: true
[email protected]:
resolution: {integrity: sha512-LJlKCCAUFKOuZxipUdYw1NzIITEsPcgyOG9LkvRJvuKj/bRzbuRY0ARXvL0pWGpsZvn8jku+LMep2eU0seHp8g==}
engines: {node: ^10 || ^12 || >=14}
[email protected]:
resolution: {integrity: sha512-H1k2eFB6M45OaiRru3PBXkuCcn2qNmx+gzLb4a9IPMR7tMH8oBRXU5jGbPDYG1Hz+82d88ED0vjR8BmqU3pQdg==}
[email protected]:
resolution: {integrity: sha512-Y0bARz53lhEC1NMCASs0/j+faB/zqt3R8hpvg1e8+61ZVJ4UL0UdC4cBbXfZMcIuhrfgeILTLe+ZeBCavQPtKQ==}
peerDependencies:
react: ^19.3.1
[email protected]:
resolution: {integrity: sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==}
[email protected]:
resolution: {integrity: sha512-U1DGlIQN5AwgjTyOEnI1oCcMuEr1pv1qOtklB2l4nyMGbHzWrI0eFsYK0zos2YWqAolJyG0IWJaqWmWj5ETh0A==}
engines: {node: '>=10'}
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
[email protected]:
resolution: {integrity: sha512-QNhWdt7nrgVWWQG58QuGsAR3jv3Hbe4mb4vz7w2csnHavciZJgda1CPNaldF6eVxv90ud3jUXpKlHL69gO38yw==}
engines: {node: '>=0.10.0'}
[email protected]:
resolution: {integrity: sha512-6odND+fel5zVw3I4Yc2e69gvguDnX0CAAGiNDZSq4ik5WUcaLrkD2GLuog0XcODbor31hZ5ayEMgVDno+KPV5g==}
engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true
[email protected]:
resolution: {integrity: sha512-juorfCmIkIw8tT+p5BXSm6PJjQF/ycEYmKyzURCIt/RaZIhL+PulbQ9Yu2z1HdOJDdqDTlxA1+xKBmHXJsczAw==}
[email protected]:
resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
[email protected]:
resolution: {integrity: sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==}
engines: {node: '>=0.10.0'}
[email protected]:
resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==}
engines: {node: '>=12.0.0'}
[email protected]:
resolution: {integrity: sha512-djviaxuOOh7wkj0paeO1Q/4wMZ8Zrnag5H6yBvzN7AKKe8beOaED9SF5/ByLqsku8NP4zQqsvM2u3ew/tJK8/w==}
peerDependencies:
'@types/react': '*'
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
peerDependenciesMeta:
'@types/react':
optional: true
[email protected]:
resolution: {integrity: sha512-tpZZ+EX0gaghDAiFR37hj5MgY6ZN55kLiPkJsKxBMZ6GZdOSPJXiOzPM984oPYZ5AnehYx5WQp1+ME8I/P/pRA==}
peerDependencies:
'@types/react': '*'
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
peerDependenciesMeta:
'@types/react':
optional: true
[email protected]:
resolution: {integrity: sha512-mhg3xdm9NaM8q+gLT8KryJPnRFOz1/5XPBhmDEVZK1webPzDjrPk7f/mbpeLqTgB9msytYWANxgALOCJKnLvcQ==}
peerDependencies:
'@types/react': '*'
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
peerDependenciesMeta:
'@types/react':
optional: true
[email protected]:
resolution: {integrity: sha512-z1YpjieJ9g0ebTmQpLBv/oq9E3F9EIlOe+7LahW8SrE3LTiG3udBRUXQOlYXP9b+IC2q2phHeVxj9xGlw34OEQ==}
engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true
peerDependencies:
'@types/node': ^20.19.0 || >=22.12.0
'@vitejs/devtools': ^0.7.1 || ^0.8.0
esbuild: ^0.27.0 || ^0.28.0
jiti: '>=1.21.0'
less: ^4.0.0
sass: ^1.70.0
sass-embedded: ^1.70.0
stylus: '>=0.54.8'
sugarss: ^5.0.0
terser: ^5.16.0
tsx: ^4.8.1
yaml: ^2.4.2
peerDependenciesMeta:
'@types/node':
optional: true
'@vitejs/devtools':
optional: true
esbuild:
optional: true
jiti:
optional: true
less:
optional: true
sass:
optional: true
sass-embedded:
optional: true
stylus:
optional: true
sugarss:
optional: true
terser:
optional: true
tsx:
optional: true
yaml:
optional: true
snapshots:
'@babel/[email protected]': {}
'@microlink/[email protected]([email protected]([email protected]))([email protected])':
dependencies:
react: 19.3.1
react-base16-styling: 0.10.0
react-dom: 19.3.1([email protected])
react-lifecycles-compat: 3.0.4
react-textarea-autosize: 8.5.9([email protected])
transitivePeerDependencies:
- '@types/react'
'@oxc-project/[email protected]': {}
'@rolldown/[email protected]':
optional: true
'@rolldown/[email protected]':
optional: true
'@rolldown/[email protected]':
optional: true
'@rolldown/[email protected]':
optional: true
'@rolldown/[email protected]':
optional: true
'@rolldown/[email protected]':
optional: true
'@rolldown/[email protected]':
optional: true
'@rolldown/[email protected]':
optional: true
'@rolldown/[email protected]':
optional: true
'@rolldown/[email protected]':
optional: true
'@rolldown/[email protected]':
optional: true
'@rolldown/[email protected]':
optional: true
'@rolldown/[email protected]':
optional: true
'@rolldown/[email protected]':
optional: true
'@rolldown/[email protected]':
optional: true
'@rolldown/[email protected]': {}
'@types/[email protected]': {}
[email protected]:
dependencies:
color-name: 1.1.4
[email protected]: {}
[email protected]:
dependencies:
color-name: 1.1.4
simple-swizzle: 0.2.2
[email protected]:
dependencies:
color-convert: 2.0.1
color-string: 1.9.1
[email protected]: {}
[email protected]: {}
[email protected]([email protected]):
optionalDependencies:
picomatch: 4.0.7
[email protected]:
optional: true
[email protected]:
optional: true
[email protected]: {}
[email protected]:
optional: true
[email protected]:
optional: true
[email protected]:
optional: true
[email protected]:
optional: true
[email protected]:
optional: true
[email protected]:
optional: true
[email protected]:
optional: true
[email protected]:
optional: true
[email protected]:
optional: true
[email protected]:
optional: true
[email protected]:
optional: true
[email protected]:
optional: true
[email protected]:
dependencies:
detect-libc: 2.1.2
optionalDependencies:
lightningcss-android-arm64: 1.33.0
lightningcss-darwin-arm64: 1.33.0
lightningcss-darwin-x64: 1.33.0
lightningcss-freebsd-x64: 1.33.0
lightningcss-linux-arm-gnueabihf: 1.33.0
lightningcss-linux-arm64-gnu: 1.33.0
lightningcss-linux-arm64-musl: 1.33.0
lightningcss-linux-x64-gnu: 1.33.0
lightningcss-linux-x64-musl: 1.33.0
lightningcss-win32-arm64-msvc: 1.33.0
lightningcss-win32-x64-msvc: 1.33.0
[email protected]: {}
[email protected]: {}
[email protected]: {}
[email protected]: {}
[email protected]: {}
[email protected]:
dependencies:
playwright-core: 1.59.1
optionalDependencies:
fsevents: 2.3.2
[email protected]:
dependencies:
nanoid: 3.3.20
picocolors: 1.1.1
source-map-js: 1.2.2
[email protected]:
dependencies:
'@types/lodash': 4.17.20
color: 4.2.3
csstype: 3.1.3
lodash-es: 4.17.21
[email protected]([email protected]):
dependencies:
react: 19.3.1
scheduler: 0.28.0
[email protected]: {}
[email protected]([email protected]):
dependencies:
'@babel/runtime': 7.28.4
react: 19.3.1
use-composed-ref: 1.4.0([email protected])
use-latest: 1.3.0([email protected])
transitivePeerDependencies:
- '@types/react'
[email protected]: {}
[email protected]:
dependencies:
'@oxc-project/types': 0.155.0
'@rolldown/pluginutils': 1.0.1
optionalDependencies:
'@rolldown/binding-android-arm-eabi': 1.2.15
'@rolldown/binding-android-arm64': 1.2.15
'@rolldown/binding-darwin-arm64': 1.2.15
'@rolldown/binding-darwin-x64': 1.2.15
'@rolldown/binding-freebsd-x64': 1.2.15
'@rolldown/binding-linux-arm-gnueabihf': 1.2.15
'@rolldown/binding-linux-arm64-gnu': 1.2.15
'@rolldown/binding-linux-arm64-musl': 1.2.15
'@rolldown/binding-linux-ppc64-gnu': 1.2.15
'@rolldown/binding-linux-s390x-gnu': 1.2.15
'@rolldown/binding-linux-x64-gnu': 1.2.15
'@rolldown/binding-linux-x64-musl': 1.2.15
'@rolldown/binding-openharmony-arm64': 1.2.15
'@rolldown/binding-win32-arm64-msvc': 1.2.15
'@rolldown/binding-win32-x64-msvc': 1.2.15
[email protected]: {}
[email protected]:
dependencies:
is-arrayish: 0.3.2
[email protected]: {}
[email protected]:
dependencies:
fdir: 6.5.0([email protected])
picomatch: 4.0.7
[email protected]([email protected]):
dependencies:
react: 19.3.1
[email protected]([email protected]):
dependencies:
react: 19.3.1
[email protected]([email protected]):
dependencies:
react: 19.3.1
use-isomorphic-layout-effect: 1.2.1([email protected])
[email protected]([email protected]):
dependencies:
lightningcss: 1.33.0
picomatch: 4.0.7
postcss: 8.5.32
rolldown: 1.2.15
tinyglobby: 0.2.17
optionalDependencies:
fsevents: 2.3.3
jiti: 2.6.1
- 主要言語
- JavaScript
- スター
- 420
- フォーク
- 69
- 平均マージ
- 6時間 33分
- マージ済み PR(30日)
- 6
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
microlinkhq/react-json-view のほかの issue
-
難易度 4/5 3〜5日 初心者へのやさしさ 35/100
microlinkhq/react-json-view#146 · コメント 2 件 ·
-
難易度 4/5 3〜5日 初心者へのやさしさ 35/100
microlinkhq/react-json-view#93 · コメント 1 件 ·
-
難易度 4/5 3〜5日 初心者へのやさしさ 35/100
microlinkhq/react-json-view#91 · リアクション 1 件 ·
-
難易度 3/5 1〜2日 初心者へのやさしさ 35/100
-
難易度 3/5 1〜2日 初心者へのやさしさ 45/100
microlinkhq/react-json-view#83 · コメント 2 件 · リアクション 1 件 ·
microlinkhq/react-json-view の issue をすべて見る
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 85/100
pigeon189/zcode-fox-widget#17 · コメント 1 件 ·
-
難易度 1/5 1時間未満 初心者へのやさしさ 88/100
メンテナーはふだん 1 日以内に返信
-
Let TypeScript accept an initial object in ReactiveDict対応中かも @yograj-vijay-yadav が今日担当しました。 オープンbug good first issue help wanted workshop
難易度 2/5 1〜3時間 初心者へのやさしさ 92/100
meteor/meteor#14919 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
akitaonrails/FrankMD#268 ·
メンテナーはふだん 1 日以内に返信
-
good first issue
難易度 2/5 1〜3時間 初心者へのやさしさ 88/100
メンテナーはふだん 1 日以内に返信