diff --git a/public/index.html b/public/index.html index 34132f3..85703bf 100644 --- a/public/index.html +++ b/public/index.html @@ -22,7 +22,6 @@ margin: 0; padding: 8px; box-sizing: border-box; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; } h1 { diff --git a/src/components/modals/Modal.scss b/src/components/modals/Modal.scss index 6a03b7f..f20d71e 100644 --- a/src/components/modals/Modal.scss +++ b/src/components/modals/Modal.scss @@ -7,6 +7,9 @@ --clearSelectTop: 2px; --clearSelectBottom: 2px; --itemIsActiveBG: #3883fa; // theme-color + + font-family: $font-family; + font-size: $font-size; .contents { padding: 20px; diff --git a/src/components/modals/SortModal.scss b/src/components/modals/SortModal.scss index 5d44a84..cbb0552 100644 --- a/src/components/modals/SortModal.scss +++ b/src/components/modals/SortModal.scss @@ -12,6 +12,19 @@ vertical-align: middle; font-weight: normal; padding-bottom: $padding; + + input.path { + width: 100%; + box-sizing: border-box; + padding: 6px 16px; // TODO: define variables for those props + border: 1px solid $border-gray; + border-radius: $border-radius; + font-family: $font-family; + font-size: $font-size; + color: $black; + outline: none; + } + } } } diff --git a/src/components/modals/SortModal.svelte b/src/components/modals/SortModal.svelte index 1e25fc2..ea679db 100644 --- a/src/components/modals/SortModal.svelte +++ b/src/components/modals/SortModal.svelte @@ -8,6 +8,7 @@ import { getNestedPaths } from '../../utils/arrayUtils.js' import { getIn, setIn } from '../../utils/immutabilityHelpers.js' import { isObject } from '../../utils/typeUtils.js' + import { stringifyPath } from '../../utils/pathUtils.js' export let json export let path @@ -33,10 +34,17 @@ let selectedProperty = undefined let selectedDirection = asc + $: { + // if there is only one option, select it and do not render the select box + if (selectedProperty === undefined && properties && properties.length === 1) { + selectedProperty = properties[0] + } + } + function pathToOption (path) { return { value: path, - label: path.join('.') + label: stringifyPath(path) } } @@ -125,10 +133,17 @@ {#if path.length > 0} Path - {path.join('.')} + + + {/if} - {#if isArray} + {#if isArray && (properties.length > 1 || selectedProperty === undefined) } Property diff --git a/src/components/treemode/JSONNode.scss b/src/components/treemode/JSONNode.scss index 2651f8d..7d72d00 100644 --- a/src/components/treemode/JSONNode.scss +++ b/src/components/treemode/JSONNode.scss @@ -2,8 +2,8 @@ .json-node { position: relative; - font-family: $font-family; - font-size: $font-size; + font-family: $font-family-mono; + font-size: $font-size-mono; color: $black; &.root { @@ -130,7 +130,7 @@ cursor: pointer; background: transparent; color: $gray-icon; - font-size: $font-size; + font-size: $font-size-mono; line-height: $line-height; } @@ -160,7 +160,7 @@ vertical-align: top; border: none; font-size: $font-size-small; - font-family: $font-family-menu; + font-family: $font-family; color: white; background: $light-gray; border-radius: 2px; diff --git a/src/components/treemode/Menu.scss b/src/components/treemode/Menu.scss index 14b5032..fa06c74 100644 --- a/src/components/treemode/Menu.scss +++ b/src/components/treemode/Menu.scss @@ -1,7 +1,7 @@ @import '../../styles.scss'; .menu { - font-family: $font-family-menu; + font-family: $font-family; font-size: $font-size; background: $theme-color; color: $white; diff --git a/src/components/treemode/TreeMode.svelte b/src/components/treemode/TreeMode.svelte index a2a5e5a..9682bd7 100644 --- a/src/components/treemode/TreeMode.svelte +++ b/src/components/treemode/TreeMode.svelte @@ -31,12 +31,13 @@ import { keyComboFromEvent } from '../../utils/keyBindings.js' import { search, searchNext, searchPrevious } from '../../logic/search.js' import { immutableJSONPatch } from '../../utils/immutableJSONPatch' - import { last, cloneDeep } from 'lodash-es' + import { first, last, initial, cloneDeep } from 'lodash-es' import jump from '../../assets/jump.js/src/jump.js' import { expandPath, syncState, patchProps } from '../../logic/documentState.js' import Menu from './Menu.svelte' import { isObjectOrArray } from '../../utils/typeUtils.js' import { mapValidationErrors } from '../../logic/validation.js' + import { stringifyPath } from '../../utils/pathUtils.js' import SortModal from '../modals/SortModal.svelte' import TransformModal from '../modals/TransformModal.svelte' @@ -262,9 +263,15 @@ } function handleSort () { + const path = selection && selection.paths + ? selection.paths.length > 1 + ? initial(first(selection.paths)) // the parent path of the paths + : first(selection.paths) // the first and only path + : [] + open(SortModal, { json: doc, - path: [], // FIXME: based on selection + path, onSort: sortedDoc => { console.log('onSort', sortedDoc) doc = sortedDoc diff --git a/src/styles.scss b/src/styles.scss index d1b6bec..d508367 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -1,8 +1,9 @@ -$font-family: consolas, monaco, "lucida console", "courier new", "dejavu sans mono", "droid sans mono", courier, monospace, sans-serif; -$font-size: 14px; +$font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; +$font-family-mono: consolas, monaco, "lucida console", "courier new", "dejavu sans mono", "droid sans mono", courier, monospace, sans-serif; +$font-size-mono: 14px; +$font-size: 16px; $font-size-small: 11px; -$font-family-menu: arial, "sans-serif"; $white: #fff; $black: #1A1A1A; @@ -27,6 +28,7 @@ $light-gray: #c0c0c0; $selection-background: #e0e0e0; $hovered-background: #f0f0f0; $background-gray: #f5f5f5; +$border-gray: #d8dbdf; $line-height: 18px; $indentation-width: 18px; // IMPORTANT: keep in sync with js constant INDENTATION_WIDTH @@ -46,7 +48,7 @@ button { background: transparent; color: inherit; cursor: pointer; - font-family: $font-family-menu; + font-family: $font-family; font-size: $font-size; padding: $menu-padding; } diff --git a/src/utils/pathUtils.js b/src/utils/pathUtils.js new file mode 100644 index 0000000..f4a22dd --- /dev/null +++ b/src/utils/pathUtils.js @@ -0,0 +1,20 @@ + +/** + * Stringify a path like + * + * ["data", 2, "nested", "property"] + * + * into a string: + * + * ".data[2].nested.property" + * + * @param {Path} + * @return {string} + */ +export function stringifyPath (path) { + return path.map(prop => { + return typeof prop === 'number' + ? `[${prop}]` + : `.${prop}` + }).join('') +} diff --git a/src/utils/pathUtils.test.js b/src/utils/pathUtils.test.js new file mode 100644 index 0000000..dea79fb --- /dev/null +++ b/src/utils/pathUtils.test.js @@ -0,0 +1,10 @@ +import assert from 'assert' +import { stringifyPath } from './pathUtils.js' + +describe('pathUtils', () => { + it('stringifyPath', () => { + assert.strictEqual(stringifyPath(["data", 2, "nested", "property"]), '.data[2].nested.property') + assert.strictEqual(stringifyPath(['']), '.') + assert.strictEqual(stringifyPath([]), '') + }) +}) \ No newline at end of file