Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade to Svelte 5 #490

Merged
merged 43 commits into from
Oct 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
1ed399b
chore: upgrade dependency to Svelte 5
josdejong Oct 14, 2024
96b2ff0
chore: use `mount`
josdejong Oct 14, 2024
ad8c573
chore: cleanup Svelte workaround for Vitest tests
josdejong Oct 14, 2024
9fbc4ca
chore: get tests running with Svelte 5
josdejong Oct 14, 2024
dc8f174
Merge branch 'refs/heads/main' into chore/svelte5
josdejong Oct 14, 2024
27c3e1e
Merge branch 'refs/heads/main' into chore/svelte5
josdejong Oct 14, 2024
516494f
Merge branch 'refs/heads/main' into chore/svelte5
josdejong Oct 14, 2024
8ba4d52
Merge branch 'refs/heads/main' into chore/svelte5
josdejong Oct 14, 2024
07896ea
Merge branch 'refs/heads/main' into chore/svelte5
josdejong Oct 14, 2024
e85f19b
chore: disable the compiler warnings "Properties of objects and array…
josdejong Oct 15, 2024
c8c5428
chore: fix the styling of selected or hovered recursive nodes
josdejong Oct 15, 2024
9504e12
Merge branch 'refs/heads/main' into chore/svelte5
josdejong Oct 15, 2024
896f055
Merge branch 'refs/heads/main' into chore/svelte5
josdejong Oct 15, 2024
777e11f
chore: add the warningFilter to the Rollup config too
josdejong Oct 15, 2024
6a9db92
chore: fix broken styling of the vanilla package
josdejong Oct 15, 2024
773fb55
feat: allow svelte@5 as peerDependency
josdejong Oct 18, 2024
009d193
chore: refine the peerDependencies versions
josdejong Oct 18, 2024
d3eca8c
chore: update to [email protected], temporarily fix the versions of `svelt…
josdejong Oct 21, 2024
6f0422d
chore: replace the old destroy method with a new one attached to the …
josdejong Oct 22, 2024
3a2664c
chore: refactor `updateProps` to update every property one by one, an…
josdejong Oct 22, 2024
d2f2601
Merge branch 'refs/heads/main' into chore/svelte5
josdejong Oct 22, 2024
e1f35c2
chore: update package-lock.json
josdejong Oct 22, 2024
48fd6f3
Merge branch 'refs/heads/main' into chore/svelte5
josdejong Oct 22, 2024
8192c60
chore: update package-lock.json after solving merge conflicts
josdejong Oct 22, 2024
86a65e2
Merge branch 'refs/heads/main' into chore/svelte5
josdejong Oct 22, 2024
e3bd1b2
chore: upgrade svelte, fix (mostly invalid) svelte compiler warnings
josdejong Oct 22, 2024
660d0c4
fix: double click to edit a value not working
josdejong Oct 22, 2024
14c846c
chore: update test snapshots
josdejong Oct 22, 2024
864bf00
Merge branch 'refs/heads/main' into chore/svelte5
josdejong Oct 22, 2024
64782ee
chore: update to the latest version of `svelte-awesome`, and use inex…
josdejong Oct 22, 2024
ca1c707
Merge branch 'refs/heads/main' into chore/svelte5
josdejong Oct 22, 2024
cdb312a
chore: update package-lock.json
josdejong Oct 22, 2024
eb836a3
chore: suppress svelte compiler warnings inline, without using `warni…
josdejong Oct 22, 2024
1f28038
Merge branch 'refs/heads/main' into chore/svelte5
josdejong Oct 22, 2024
e640046
chore: pass all properties to the value renderers, simplifying the co…
josdejong Oct 23, 2024
1996002
chore: fix `JsonEditor` type export
josdejong Oct 24, 2024
8fded08
docs: explain how to disable the color picker and timestamp tag (see …
josdejong Oct 24, 2024
1e648a8
chore: replace `$set` with `updateProps`
josdejong Oct 24, 2024
219c2b4
Merge branch 'main' into chore/svelte5
josdejong Oct 25, 2024
65a3d4f
chore: update devDependencies
josdejong Oct 25, 2024
22e1fd0
fix: do not throw an error in case when passing an unknown property t…
josdejong Oct 25, 2024
df1c158
chore: fix the expand/collapse test examples
josdejong Oct 28, 2024
11b42e2
chore: update devDependencies
josdejong Oct 28, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ To adjust the text color of keys or values, the color of the classes `.jse-key`
onRenderValue(props: RenderValueProps) : RenderValueComponentDescription[]
```
Customize rendering of the values. By default, `renderValue` is used, which renders a value as an editable div and depending on the value can also render a boolean toggle, a color picker, and a timestamp tag. Multiple components can be rendered alongside each other, like the boolean toggle and color picker being rendered left from the editable div. Built in value renderer components: `EditableValue`, `ReadonlyValue`, `BooleanToggle`, `ColorPicker`, `TimestampTag`, `EnumValue`.
Customize rendering of the values. By default, `renderValue` is used, which renders a value as an editable div and depending on the value can also render a boolean toggle, a color picker, and a timestamp tag. Multiple components can be rendered alongside each other, like the boolean toggle and color picker being rendered left from the editable div. In order to disable for example the built-in color picker or timestamp tag, you can look up the source code of `renderValue`, copy it, and then remove the components that you do not want from the function. Built in value renderer components: `EditableValue`, `ReadonlyValue`, `BooleanToggle`, `ColorPicker`, `TimestampTag`, `EnumValue`.
For JSON Schema enums, there is a ready-made value renderer `renderJSONSchemaEnum` which renders enums using the `EnumValue` component. This can be used like:
Expand Down
2,544 changes: 1,846 additions & 698 deletions package-lock.json

Large diffs are not rendered by default.

19 changes: 10 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,11 @@
"vanilla-picker": "^2.12.3"
},
"peerDependencies": {
"svelte": "^3.54.0 || ^4.0.0"
"svelte": "^3.54.0 || ^4.0.0 || ^5.0.0"
},
"devDependencies": {
"@babel/core": "7.25.9",
"@babel/preset-env": "7.25.9",
"@babel/core": "7.26.0",
"@babel/preset-env": "7.26.0",
"@commitlint/cli": "19.5.0",
"@commitlint/config-conventional": "19.5.0",
"@eslint/compat": "1.2.1",
Expand All @@ -121,10 +121,10 @@
"@rollup/plugin-node-resolve": "15.3.0",
"@rollup/plugin-terser": "0.4.4",
"@rollup/plugin-typescript": "12.1.1",
"@sveltejs/adapter-auto": "3.3.0",
"@sveltejs/kit": "2.7.2",
"@sveltejs/package": "2.3.6",
"@sveltejs/vite-plugin-svelte": "3.1.2",
"@sveltejs/adapter-auto": "3.3.1",
"@sveltejs/kit": "2.7.3",
"@sveltejs/package": "2.3.7",
"@sveltejs/vite-plugin-svelte": "4.0.0",
"@testing-library/jest-dom": "6.6.2",
"@testing-library/svelte": "5.2.4",
"@types/cookie": "0.6.0",
Expand All @@ -147,11 +147,12 @@
"npm-run-all": "4.1.5",
"prettier": "3.3.3",
"prettier-plugin-svelte": "3.2.7",
"rollup": "4.24.0",
"rollup": "4.24.2",
"rollup-plugin-dts": "6.1.1",
"rollup-plugin-postcss": "4.0.2",
"rollup-plugin-svelte": "7.2.2",
"standard-version": "9.5.0",
"svelte": "^4.2.19",
"svelte": "5.1.3",
"svelte-check": "4.0.5",
"svelte-eslint-parser": "0.43.0",
"svelte-preprocess": "6.0.3",
Expand Down
8 changes: 6 additions & 2 deletions rollup.config.vanilla-library.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import commonjs from '@rollup/plugin-commonjs'
import json from '@rollup/plugin-json'
import resolve from '@rollup/plugin-node-resolve'
import typescript from '@rollup/plugin-typescript'
import postcss from 'rollup-plugin-postcss'
import { getBabelOutputPlugin } from '@rollup/plugin-babel'
import path from 'path'
import svelte from 'rollup-plugin-svelte'
Expand Down Expand Up @@ -31,12 +32,15 @@ export default {
dev: !production
},

// we want to embed the CSS in the generated JS bundle
emitCss: false,
emitCss: true,

preprocess: sveltePreprocess()
}),

postcss({
plugins: []
}),

resolve({
browser: true,
exportConditions: ['svelte']
Expand Down
20 changes: 1 addition & 19 deletions rollup.config.vanilla-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,5 @@ export default {
format: 'es'
}
],
plugins: [dts(), exportJsonEditorClass()]
}

// The DTS plugin doesn't export the JsonEditor class that is generated by Svelte whilst compiling,
// so we append an export for it manually. Similarly, the CreateJSONEditorProps interface is not
// exported by DTS, so we add an export for it too.
function exportJsonEditorClass() {
return {
name: 'export-json-editor',
transform: (code, id) => {
if (id.endsWith('index-vanilla.d.ts')) {
const customExports = 'export type { JsonEditor, CreateJSONEditorProps }'

return `${code}\n${customExports}\n`
}

return code
}
}
plugins: [dts()]
}
211 changes: 170 additions & 41 deletions src/lib/components/JSONEditor.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -54,45 +54,73 @@
// TODO: document how to enable debugging in the readme: localStorage.debug="jsoneditor:*", then reload
const debug = createDebug('jsoneditor:JSONEditor')

export let content: Content = { text: '' }
export let selection: JSONEditorSelection | undefined = undefined

export let readOnly = false
export let indentation: number | string = 2
export let tabSize = 4
export let mode: Mode = Mode.tree
export let mainMenuBar = true
export let navigationBar = true
export let statusBar = true
export let askToFormat = true
export let escapeControlCharacters = false
export let escapeUnicodeCharacters = false
export let flattenColumns = true
export let parser: JSONParser = JSON
export let validator: Validator | undefined = undefined
export let validationParser: JSONParser = JSON
export let pathParser: JSONPathParser = {
const contentDefault = { text: '' }
const selectionDefault = undefined
const readOnlyDefault = false
const indentationDefault = 2
const tabSizeDefault = 4
const modeDefault = Mode.tree
const mainMenuBarDefault = true
const navigationBarDefault = true
const statusBarDefault = true
const askToFormatDefault = true
const escapeControlCharactersDefault = false
const escapeUnicodeCharactersDefault = false
const flattenColumnsDefault = true
const parserDefault = JSON
const validatorDefault = undefined
const validationParserDefault = JSON
const pathParserDefault = {
parse: parseJSONPath,
stringify: stringifyJSONPath
}

export let queryLanguages: QueryLanguage[] = [jsonQueryLanguage]
export let queryLanguageId: string = queryLanguages[0].id

export let onChangeQueryLanguage: OnChangeQueryLanguage = noop
export let onChange: OnChange | undefined = undefined
export let onSelect: OnSelect | undefined = undefined
export let onRenderValue: OnRenderValue = renderValue
export let onClassName: OnClassName = () => undefined
export let onRenderMenu: OnRenderMenu = noop
export let onRenderContextMenu: OnRenderContextMenu = noop
export let onChangeMode: OnChangeMode = noop
export let onError: OnError = (err) => {
const queryLanguagesDefault = [jsonQueryLanguage]
const queryLanguageIdDefault = queryLanguagesDefault[0].id
const onChangeQueryLanguageDefault = noop
const onChangeDefault = undefined
const onSelectDefault = undefined
const onRenderValueDefault = renderValue
const onClassNameDefault = noop
const onRenderMenuDefault = noop
const onRenderContextMenuDefault = noop
const onChangeModeDefault = noop
const onErrorDefault: OnError = (err) => {
console.error(err)
alert(err.toString()) // TODO: create a nice alert modal
}
export let onFocus: OnFocus = noop
export let onBlur: OnBlur = noop
const onFocusDefault = noop
const onBlurDefault = noop

export let content: Content = contentDefault
export let selection: JSONEditorSelection | undefined = selectionDefault
export let readOnly: boolean = readOnlyDefault
export let indentation: number | string = indentationDefault
export let tabSize: number = tabSizeDefault
export let mode: Mode = modeDefault
export let mainMenuBar: boolean = mainMenuBarDefault
export let navigationBar: boolean = navigationBarDefault
export let statusBar: boolean = statusBarDefault
export let askToFormat: boolean = askToFormatDefault
export let escapeControlCharacters: boolean = escapeControlCharactersDefault
export let escapeUnicodeCharacters: boolean = escapeUnicodeCharactersDefault
export let flattenColumns: boolean = flattenColumnsDefault
export let parser: JSONParser = parserDefault
export let validator: Validator | undefined = validatorDefault
export let validationParser: JSONParser = validationParserDefault
export let pathParser: JSONPathParser = pathParserDefault
export let queryLanguages: QueryLanguage[] = queryLanguagesDefault
export let queryLanguageId: string = queryLanguageIdDefault
export let onChangeQueryLanguage: OnChangeQueryLanguage = onChangeQueryLanguageDefault
export let onChange: OnChange | undefined = onChangeDefault
export let onSelect: OnSelect | undefined = onSelectDefault
export let onRenderValue: OnRenderValue = onRenderValueDefault
export let onClassName: OnClassName = onClassNameDefault
export let onRenderMenu: OnRenderMenu = onRenderMenuDefault
export let onRenderContextMenu: OnRenderContextMenu = onRenderContextMenuDefault
export let onChangeMode: OnChangeMode = onChangeModeDefault
export let onError: OnError = onErrorDefault
export let onFocus: OnFocus = onFocusDefault
export let onBlur: OnBlur = onBlurDefault

let instanceId = uniqueId()
let hasFocus = false
Expand Down Expand Up @@ -252,19 +280,120 @@
}

export async function updateProps(props: JSONEditorPropsOptional): Promise<void> {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
this.$set(props)
const names = Object.keys(props) as (keyof JSONEditorPropsOptional)[]

for (const name of names) {
switch (name) {
case 'content':
content = props[name] ?? contentDefault
break
case 'readOnly':
readOnly = props[name] ?? readOnlyDefault
break
case 'indentation':
indentation = props[name] ?? indentationDefault
break
case 'tabSize':
tabSize = props[name] ?? tabSizeDefault
break
case 'mode':
mode = props[name] ?? modeDefault
break
case 'mainMenuBar':
mainMenuBar = props[name] ?? mainMenuBarDefault
break
case 'navigationBar':
navigationBar = props[name] ?? navigationBarDefault
break
case 'statusBar':
statusBar = props[name] ?? statusBarDefault
break
case 'askToFormat':
askToFormat = props[name] ?? askToFormatDefault
break
case 'escapeControlCharacters':
escapeControlCharacters = props[name] ?? escapeControlCharactersDefault
break
case 'escapeUnicodeCharacters':
escapeUnicodeCharacters = props[name] ?? escapeUnicodeCharactersDefault
break
case 'flattenColumns':
flattenColumns = props[name] ?? flattenColumnsDefault
break
case 'parser':
parser = props[name] ?? parserDefault
break
case 'validator':
validator = props[name] ?? validatorDefault
break
case 'validationParser':
validationParser = props[name] ?? validationParserDefault
break
case 'pathParser':
pathParser = props[name] ?? pathParserDefault
break
case 'queryLanguages':
queryLanguages = props[name] ?? queryLanguagesDefault
break
case 'queryLanguageId':
queryLanguageId = props[name] ?? queryLanguageIdDefault
break
case 'onChangeQueryLanguage':
onChangeQueryLanguage = props[name] ?? onChangeQueryLanguageDefault
break
case 'onChange':
onChange = props[name] ?? onChangeDefault
break
case 'onRenderValue':
onRenderValue = props[name] ?? onRenderValueDefault
break
case 'onClassName':
onClassName = props[name] ?? onClassNameDefault
break
case 'onRenderMenu':
onRenderMenu = props[name] ?? onRenderMenuDefault
break
case 'onRenderContextMenu':
onRenderContextMenu = props[name] ?? onRenderContextMenuDefault
break
case 'onChangeMode':
onChangeMode = props[name] ?? onChangeModeDefault
break
case 'onSelect':
onSelect = props[name] ?? onSelectDefault
break
case 'onError':
onError = props[name] ?? onErrorDefault
break
case 'onFocus':
onFocus = props[name] ?? onFocusDefault
break
case 'onBlur':
onBlur = props[name] ?? onBlurDefault
break

default:
// We should never reach this default case
unknownProperty(name)
}
}

if (!queryLanguages.some((queryLanguage) => queryLanguage.id === queryLanguageId)) {
queryLanguageId = queryLanguages[0].id
}

function unknownProperty(name: never) {
debug(`Unknown property "${name}"`)
}

await tick() // await rerender
}

export async function destroy() {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
this.$destroy()

await tick() // await destroying
throw new Error(
'class method destroy() is deprecated. ' +
'It is replaced with a method destroy() in the vanilla library.'
)
}

function handleChange(updatedContent: Content, previousContent: Content, status: OnChangeStatus) {
Expand Down
Loading