diff --git a/README.md b/README.md index 7cc38d8..294fa8a 100644 --- a/README.md +++ b/README.md @@ -206,6 +206,7 @@ This is a reference list of *all* possible props, divided into related sections. | `collapseClickZones` | `Array<"left" \| "header" \| "property">` | `["left", "header"]` | Aside from the `⌄` icon, you can specify other regions of the UI to be clickable for collapsing/opening a collection. | | `rootName` | `string` | `"data"` | A name to display in the editor as the root of the data object. | | `showArrayIndices` | `boolean` | `true` | Whether or not to display the index (as a property key) for array elements. | +| `arrayIndexFromOne` | `boolean` | `false` | When displaying array indices, first item will be labelled "1" (as opposed to "0"). | | `showStringQuotes` | `boolean` | `true` | Whether or not to display string values in "quotes". | | `showCollectionCount` | `boolean\|"when-closed"` | `true` | Whether or not to display the number of items in each collection (object or array). | | `stringTruncate` | `number` | `250` | String values longer than this many characters will be displayed truncated (with `...`). The full string will always be visible when editing. | @@ -1241,6 +1242,7 @@ This component is heavily inspired by [react-json-view](https://github.com/mac-s ## Changelog +- **1.28.3**: Option to display array indexes starting at "1" ([#62](https://github.com/CarlosNZ/json-edit-react/issues/62)) - **1.28.2**: When switching data type, only keep editing if new type is primitive ([#216](https://github.com/CarlosNZ/json-edit-react/issues/216)) - **1.28.1**: Fix left padding of root node when value is primitive ([#214](https://github.com/CarlosNZ/json-edit-react/issues/214)) - **1.28.0**: diff --git a/demo/src/App.tsx b/demo/src/App.tsx index 48c460f..a7cd78b 100644 --- a/demo/src/App.tsx +++ b/demo/src/App.tsx @@ -67,6 +67,7 @@ interface AppState { allowCopy: boolean sortKeys: boolean showIndices: boolean + arraysFromOne: boolean showStringQuotes: boolean defaultNewValue: string searchText: string @@ -111,6 +112,7 @@ function App() { allowCopy: true, sortKeys: false, showIndices: true, + arraysFromOne: false, showStringQuotes: true, defaultNewValue: 'New data!', searchText: '', @@ -176,6 +178,7 @@ function App() { collapseTime, showCount, showIndices, + arraysFromOne, sortKeys, showStringQuotes, allowCopy, @@ -508,6 +511,7 @@ function App() { defaultValue={dataDefinition?.defaultValue ?? defaultNewValue} newKeyOptions={dataDefinition?.newKeyOptions} showArrayIndices={showIndices} + arrayIndexFromOne={arraysFromOne} showStringQuotes={showStringQuotes} minWidth={'min(500px, 95vw)'} maxWidth="min(670px, 90vw)" @@ -825,6 +829,16 @@ function App() { > Show String quotes + toggleState('sortKeys')} + w="50%" + > + Sort Object keys + + + Show Array indices - - toggleState('sortKeys')} + id="arraysFromOneCheckbox" + isChecked={arraysFromOne} + onChange={() => toggleState('arraysFromOne')} w="50%" > - Sort Object keys + Arrays index from 1 + + = (props) => { indent, sort, showArrayIndices, + arrayIndexFromOne, defaultValue, newKeyOptions, translate, @@ -444,7 +445,8 @@ export const CollectionNode: React.FC = (props) => { isEditingKey, pathString, path, - name: name as string, + name, + arrayIndexFromOne, handleKeyboard, handleEditKey, handleCancel, diff --git a/src/JsonEditor.tsx b/src/JsonEditor.tsx index 68bd73e..7b4af14 100644 --- a/src/JsonEditor.tsx +++ b/src/JsonEditor.tsx @@ -63,6 +63,7 @@ const Editor: React.FC = ({ searchDebounceTime = 350, keySort = false, showArrayIndices = true, + arrayIndexFromOne = false, showStringQuotes = true, showIconTooltips = false, defaultValue = null, @@ -368,6 +369,7 @@ const Editor: React.FC = ({ keySort, sort, showArrayIndices, + arrayIndexFromOne, showStringQuotes, showIconTooltips, indent, diff --git a/src/KeyDisplay.tsx b/src/KeyDisplay.tsx index 72547f3..fd36f92 100644 --- a/src/KeyDisplay.tsx +++ b/src/KeyDisplay.tsx @@ -11,7 +11,8 @@ interface KeyDisplayProps { isEditingKey: boolean pathString: string path: CollectionKey[] - name: string + name: string | number + arrayIndexFromOne: boolean handleKeyboard: ( e: React.KeyboardEvent, eventMap: Partial void>> @@ -31,6 +32,7 @@ export const KeyDisplay: React.FC = ({ pathString, path, name, + arrayIndexFromOne, handleKeyboard, handleEditKey, handleCancel, @@ -42,20 +44,22 @@ export const KeyDisplay: React.FC = ({ }) => { const { setCurrentlyEditingElement } = useTreeState() + const displayKey = typeof name === 'number' ? String(name + (arrayIndexFromOne ? 1 : 0)) : name + if (!isEditingKey) return ( 10 ? 1 : 0, + minWidth: `${Math.min(displayKey.length + 1, 5)}ch`, + flexShrink: displayKey.length > 10 ? 1 : 0, }} onDoubleClick={() => canEditKey && setCurrentlyEditingElement(path, 'key')} onClick={handleClick} > - {emptyStringKey ? {emptyStringKey} : name} - {name !== '' || emptyStringKey ? : : null} + {emptyStringKey ? {emptyStringKey} : displayKey} + {displayKey !== '' || emptyStringKey ? : : null} ) @@ -64,7 +68,7 @@ export const KeyDisplay: React.FC = ({ className="jer-input-text jer-key-edit" type="text" name={pathString} - defaultValue={name} + defaultValue={displayKey} autoFocus onFocus={(e) => e.target.select()} onKeyDown={(e: React.KeyboardEvent) => @@ -86,7 +90,7 @@ export const KeyDisplay: React.FC = ({ }, }) } - style={{ width: `${String(name).length / 1.5 + 0.5}em` }} + style={{ width: `${displayKey.length / 1.5 + 0.5}em` }} /> ) } diff --git a/src/ValueNodeWrapper.tsx b/src/ValueNodeWrapper.tsx index fc74c6d..e4a9d27 100644 --- a/src/ValueNodeWrapper.tsx +++ b/src/ValueNodeWrapper.tsx @@ -40,6 +40,7 @@ export const ValueNodeWrapper: React.FC = (props) => { showLabel, stringTruncate, showStringQuotes, + arrayIndexFromOne, indent, translate, customNodeDefinitions, @@ -305,7 +306,8 @@ export const ValueNodeWrapper: React.FC = (props) => { isEditingKey, pathString, path, - name: name as string, + name, + arrayIndexFromOne, handleKeyboard, handleEditKey, handleCancel, diff --git a/src/types.ts b/src/types.ts index 5ed8fdf..5196307 100644 --- a/src/types.ts +++ b/src/types.ts @@ -37,6 +37,7 @@ export interface JsonEditorProps { searchDebounceTime?: number keySort?: boolean | CompareFunction showArrayIndices?: boolean + arrayIndexFromOne?: boolean showStringQuotes?: boolean showIconTooltips?: boolean defaultValue?: string | number | boolean | null | object | DefaultValueFunction @@ -272,6 +273,7 @@ interface BaseNodeProps { restrictTypeSelection: boolean | TypeOptions | TypeFilterFunction stringTruncate: number indent: number + arrayIndexFromOne: boolean sort: SortFunction translate: TranslateFunction customNodeDefinitions: CustomNodeDefinition[]