@@ -168,10 +175,12 @@ const App = () => (
Pass labelRenderer
or valueRenderer
.
+
Additionally, you may pass an ArrowComponentOverride
(({raw})):}
valueRenderer={(raw) => (
diff --git a/packages/react-json-tree/src/ItemRange.tsx b/packages/react-json-tree/src/ItemRange.tsx
index a051a01598..9b40c36129 100644
--- a/packages/react-json-tree/src/ItemRange.tsx
+++ b/packages/react-json-tree/src/ItemRange.tsx
@@ -1,6 +1,6 @@
import React, { useCallback, useState } from 'react';
import JSONArrow from './JSONArrow.js';
-import type { CircularCache, CommonInternalProps } from './types.js';
+import type { CircularCache, CommonInternalProps, KeyPath } from './types.js';
interface Props extends CommonInternalProps {
data: unknown;
@@ -10,6 +10,7 @@ interface Props extends CommonInternalProps {
renderChildNodes: (props: Props, from: number, to: number) => React.ReactNode;
circularCache: CircularCache;
level: number;
+ keyPath: KeyPath;
}
export default function ItemRange(props: Props) {
@@ -32,6 +33,8 @@ export default function ItemRange(props: Props) {
expanded={false}
onClick={handleClick}
arrowStyle="double"
+ ariaLabel={`Expand Array from ${from} to ${to}`}
+ OverrideComponent={props.ArrowComponentOverride}
/>
{`${from} ... ${to}`}
diff --git a/packages/react-json-tree/src/JSONArrow.tsx b/packages/react-json-tree/src/JSONArrow.tsx
index e00fe456c4..f0e7aaaf29 100644
--- a/packages/react-json-tree/src/JSONArrow.tsx
+++ b/packages/react-json-tree/src/JSONArrow.tsx
@@ -1,29 +1,39 @@
-import React from 'react';
+import React, { ComponentType } from 'react';
import type { StylingFunction } from 'react-base16-styling';
-interface Props {
+export interface JSONArrowProps {
styling: StylingFunction;
arrowStyle?: 'single' | 'double';
expanded: boolean;
nodeType: string;
- onClick: React.MouseEventHandler
;
+ onClick: React.MouseEventHandler;
+ ariaControls?: string;
+ ariaLabel?: string
+ OverrideComponent?: ComponentType;
}
-export default function JSONArrow({
- styling,
- arrowStyle = 'single',
- expanded,
- nodeType,
- onClick,
-}: Props) {
+export default function JSONArrow({OverrideComponent, ...props}: JSONArrowProps) {
+ const {
+ styling,
+ arrowStyle = 'single',
+ expanded,
+ nodeType,
+ onClick,
+ ariaControls,
+ ariaLabel
+ } = props
+ if(OverrideComponent) {
+ return
+ }
+
return (
-
+
+
);
}
diff --git a/packages/react-json-tree/src/JSONNestedNode.tsx b/packages/react-json-tree/src/JSONNestedNode.tsx
index fbc9a47b61..58b468899c 100644
--- a/packages/react-json-tree/src/JSONNestedNode.tsx
+++ b/packages/react-json-tree/src/JSONNestedNode.tsx
@@ -4,6 +4,7 @@ import getCollectionEntries from './getCollectionEntries.js';
import JSONNode from './JSONNode.js';
import ItemRange from './ItemRange.js';
import type { CircularCache, CommonInternalProps } from './types.js';
+import getAriaPropsFromKeyPath from './getAriaPropsFromKeyPath.js';
/**
* Renders nested values (eg. objects, arrays, lists, etc.)
@@ -62,6 +63,7 @@ function renderChildNodes(
from={entry.from}
to={entry.to}
renderChildNodes={renderChildNodes}
+ keyPath={[entry.from, ...keyPath]}
/>,
);
} else {
@@ -141,6 +143,8 @@ export default function JSONNestedNode(props: Props) {
);
const stylingArgs = [keyPath, nodeType, expanded, expandable] as const;
+ const {ariaControls, ariaLabel} = getAriaPropsFromKeyPath(keyPath)
+
return hideRoot ? (
@@ -155,6 +159,9 @@ export default function JSONNestedNode(props: Props) {
nodeType={nodeType}
expanded={expanded}
onClick={handleClick}
+ ariaControls={ariaControls}
+ ariaLabel={ariaLabel}
+ OverrideComponent={props.ArrowComponentOverride}
/>
)}
diff --git a/packages/react-json-tree/src/createStylingFromTheme.ts b/packages/react-json-tree/src/createStylingFromTheme.ts
index 47665c1994..4adaccb45e 100644
--- a/packages/react-json-tree/src/createStylingFromTheme.ts
+++ b/packages/react-json-tree/src/createStylingFromTheme.ts
@@ -122,6 +122,11 @@ const getDefaultThemeStyling = (theme: Base16Theme): StylingConfig => {
arrowContainer: ({ style }, arrowStyle) => ({
style: {
...style,
+ background: 'none',
+ color: 'inherit',
+ border: 'none',
+ padding: 0,
+ font: 'inherit',
display: 'inline-block',
paddingRight: '0.5em',
paddingLeft: arrowStyle === 'double' ? '1em' : 0,
diff --git a/packages/react-json-tree/src/getAriaPropsFromKeyPath.ts b/packages/react-json-tree/src/getAriaPropsFromKeyPath.ts
new file mode 100644
index 0000000000..528cefb608
--- /dev/null
+++ b/packages/react-json-tree/src/getAriaPropsFromKeyPath.ts
@@ -0,0 +1,21 @@
+import { KeyPath } from "./types.js";
+
+const replaceSpacesRegex = / /g;
+
+const getAriaPropsFromKeyPath = (
+ keyPath: KeyPath
+) => {
+ let ariaControls = '';
+ let ariaLabel = 'JSON Tree Node: ';
+ for(let i = keyPath.length - 1; i >= 0; i--) {
+ const key = keyPath[i];
+ ariaControls += `${key}`.replace(replaceSpacesRegex, '-');
+ ariaLabel += `${key} `;
+ }
+
+ ariaLabel = ariaLabel.trim();
+
+ return { ariaControls, ariaLabel };
+}
+
+export default getAriaPropsFromKeyPath;
\ No newline at end of file
diff --git a/packages/react-json-tree/src/index.tsx b/packages/react-json-tree/src/index.tsx
index 6f298f0eb6..8edd565171 100644
--- a/packages/react-json-tree/src/index.tsx
+++ b/packages/react-json-tree/src/index.tsx
@@ -47,6 +47,7 @@ export function JSONTree({
isCustomNode = noCustomNode,
collectionLimit = 50,
sortObjectKeys = false,
+ ArrowComponentOverride
}: Props) {
const styling = useMemo(
() =>
@@ -69,6 +70,7 @@ export function JSONTree({
postprocessValue={postprocessValue}
collectionLimit={collectionLimit}
sortObjectKeys={sortObjectKeys}
+ ArrowComponentOverride={ArrowComponentOverride}
/>
);
@@ -87,4 +89,7 @@ export type {
Styling,
CommonExternalProps,
} from './types.js';
+
+export type { JSONArrowProps } from './JSONArrow.js';
+
export type { StylingValue };
diff --git a/packages/react-json-tree/src/types.ts b/packages/react-json-tree/src/types.ts
index e046126101..08033aa2c9 100644
--- a/packages/react-json-tree/src/types.ts
+++ b/packages/react-json-tree/src/types.ts
@@ -1,5 +1,6 @@
-import React from 'react';
+import React, { ComponentType } from 'react';
import { StylingFunction } from 'react-base16-styling';
+import { JSONArrowProps } from './JSONArrow.js';
export type Key = string | number;
@@ -46,6 +47,7 @@ export interface CommonExternalProps {
keyPath: KeyPath;
labelRenderer: LabelRenderer;
valueRenderer: ValueRenderer;
+ ArrowComponentOverride?: ComponentType;
shouldExpandNodeInitially: ShouldExpandNodeInitially;
hideRoot: boolean;
getItemString: GetItemString;