forked from viamrobotics/prime
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
APP-5855 - Move JSON editors to PRIME (viamrobotics#553)
- Loading branch information
1 parent
5210f7b
commit 9ebb0af
Showing
29 changed files
with
1,143 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
.svelte-kit | ||
dist |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
'use strict'; | ||
|
||
/** @type {import('node:path')} */ | ||
const path = require('node:path'); | ||
|
||
module.exports = { | ||
root: true, | ||
extends: ['@viamrobotics/eslint-config/svelte'], | ||
parserOptions: { | ||
project: ['./tsconfig.json'], | ||
tsconfigRootDir: __dirname, | ||
}, | ||
settings: { | ||
tailwindcss: { | ||
config: path.join(__dirname, 'tailwind.config.ts'), | ||
}, | ||
}, | ||
env: { | ||
browser: true, | ||
node: true, | ||
}, | ||
rules: { | ||
// TODO(mc, 2024-01-03): move to base config? | ||
'multiline-comment-style': 'off', | ||
}, | ||
overrides: [ | ||
{ | ||
files: 'src/routes/**/*', | ||
rules: { | ||
'no-console': 'off', | ||
'sonarjs/no-duplicate-string': 'off', | ||
}, | ||
}, | ||
{ | ||
files: ['.eslintrc.cjs', '.prettierrc.cjs'], | ||
rules: { | ||
'@typescript-eslint/no-unsafe-assignment': 'off', | ||
}, | ||
}, | ||
], | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
.svelte-kit | ||
dist |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
'use strict'; | ||
|
||
/** @type {import('node:path')} */ | ||
const path = require('node:path'); | ||
|
||
/** @type {import('@viamrobotics/prettier-config/svelte')} */ | ||
const baseConfig = require('@viamrobotics/prettier-config/svelte'); | ||
|
||
module.exports = { | ||
...baseConfig, | ||
tailwindConfig: path.join(__dirname, 'tailwind.config.ts'), | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# `@viamrobotics/prime-editor` | ||
|
||
## Getting started | ||
|
||
`@viamrobotics/prime-editor` is a collection of Svelte components that wrap code-editing tools. | ||
|
||
This primarily based around [Codemirror](https://codemirror.net/) | ||
|
||
## Installation | ||
|
||
Install use the README instructions at [@viamrobotics/prime-core](https://github.com/viamrobotics/prime/tree/main/packages/core) to install prime-core. Then install prime-editor using your package manager of choice: | ||
|
||
``` | ||
pnpm add --save-dev @viamrobotics/prime-editor | ||
``` | ||
|
||
<strong>These components require that ssr is disabled.</strong> | ||
Ensure that you have a `+layout.ts` above all pages that use these components: | ||
|
||
```js | ||
export const prerender = false; | ||
export const ssr = false; | ||
``` | ||
|
||
## Usage | ||
|
||
Once installed, you can use the components in your app: | ||
|
||
```html | ||
<script lang="ts"> | ||
import { JsonEditor } from '@viamrobotics/prime-editor'; | ||
</script> | ||
|
||
<JsonEditor | ||
initialValue={'{"a": "b"}'} | ||
label="editor" | ||
onChange={(e) => console.log(e)} | ||
/> | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
{ | ||
"name": "@viamrobotics/prime-editor", | ||
"version": "0.0.1", | ||
"publishConfig": { | ||
"access": "public" | ||
}, | ||
"scripts": { | ||
"prepare": "svelte-kit sync", | ||
"dev": "vite dev", | ||
"build": "vite build && pnpm run package", | ||
"preview": "vite preview", | ||
"package": "svelte-kit sync && svelte-package && publint", | ||
"check": "concurrently -g pnpm:check-*", | ||
"check-svelte": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", | ||
"check-lint": "pnpm run _prettier --check && pnpm run _eslint", | ||
"format": "pnpm run _prettier --write", | ||
"test": "svelte-kit sync && vitest run", | ||
"test:watch": "vitest", | ||
"_prettier": "prettier \"**/*.{js,cjs,ts,svelte,css,json,yml,yaml,md,mdx}\"", | ||
"_eslint": "eslint \".*.cjs\" \"**/*.{js,cjs,ts,svelte}\"" | ||
}, | ||
"exports": { | ||
".": { | ||
"types": "./dist/index.d.ts", | ||
"svelte": "./dist/index.js" | ||
} | ||
}, | ||
"files": [ | ||
"dist", | ||
"!__tests__" | ||
], | ||
"peerDependencies": { | ||
"svelte": ">=4.0.0 <5", | ||
"@codemirror/lang-json": ">=6 <7", | ||
"@codemirror/merge": ">=6 <7", | ||
"@codemirror/state": ">=6 <7", | ||
"@codemirror/view": ">=6 <7", | ||
"classnames": ">=2 <3", | ||
"codemirror": ">=6 <7", | ||
"lodash-es": ">=4 <5", | ||
"@viamrobotics/prime-core": ">=0.0.141" | ||
}, | ||
"devDependencies": { | ||
"@codemirror/lang-json": "^6.0.1", | ||
"@codemirror/merge": "^6.6.1", | ||
"@codemirror/state": "^6.3.1", | ||
"@codemirror/view": "^6.22.0", | ||
"classnames": "^2.3.2", | ||
"codemirror": "^6.0.1", | ||
"lodash-es": "^4.17.21", | ||
"@sveltejs/adapter-auto": "^3.0.0", | ||
"@sveltejs/kit": "^2.0.3", | ||
"@sveltejs/package": "^2.2.3", | ||
"@sveltejs/vite-plugin-svelte": "^3.0.0", | ||
"@testing-library/dom": "^9.3.3", | ||
"@testing-library/jest-dom": "^6.1.5", | ||
"@testing-library/svelte": "^4.1.0", | ||
"@testing-library/user-event": "^14.5.1", | ||
"@types/lodash-es": "^4.17.12", | ||
"@types/prismjs": "^1.26.3", | ||
"@typescript-eslint/eslint-plugin": "^6.15.0", | ||
"@typescript-eslint/parser": "^6.15.0", | ||
"@viamrobotics/eslint-config": "^0.3.0", | ||
"@viamrobotics/prettier-config": "^0.3.4", | ||
"@viamrobotics/prime-core": "workspace:^", | ||
"@viamrobotics/typescript-config": "^0.1.0", | ||
"autoprefixer": "^10.4.16", | ||
"concurrently": "^8.2.2", | ||
"eslint": "^8.56.0", | ||
"eslint-config-prettier": "^9.1.0", | ||
"eslint-plugin-sonarjs": "^0.23.0", | ||
"eslint-plugin-svelte": "^2.35.1", | ||
"eslint-plugin-tailwindcss": "^3.13.0", | ||
"eslint-plugin-unicorn": "^49.0.0", | ||
"jsdom": "^23.0.1", | ||
"postcss": "^8.4.32", | ||
"prettier": "^3.1.1", | ||
"prettier-plugin-svelte": "^3.1.2", | ||
"prettier-plugin-tailwindcss": "^0.5.9", | ||
"publint": "^0.2.6", | ||
"svelte": "^4.2.8", | ||
"svelte-check": "^3.6.2", | ||
"tailwindcss": "^3.3.7", | ||
"tslib": "^2.6.2", | ||
"type-fest": "^4.8.3", | ||
"typescript": "^5.3.3", | ||
"vite": "^5.0.10", | ||
"vitest": "^1.1.0" | ||
}, | ||
"svelte": "./dist/index.js", | ||
"types": "./dist/index.d.ts", | ||
"type": "module" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
export default { | ||
plugins: { | ||
tailwindcss: {}, | ||
autoprefixer: {}, | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
/* | ||
* See https://kit.svelte.dev/docs/types#app | ||
* for information about these interfaces | ||
*/ | ||
declare global { | ||
namespace App { | ||
/* | ||
* interface Error {} | ||
* interface Locals {} | ||
* interface PageData {} | ||
* interface Platform {} | ||
*/ | ||
} | ||
} | ||
|
||
export {}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<!doctype html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="utf-8" /> | ||
<link | ||
rel="icon" | ||
href="%sveltekit.assets%/favicon.png" | ||
/> | ||
<meta | ||
name="viewport" | ||
content="width=device-width, initial-scale=1" | ||
/> | ||
%sveltekit.head% | ||
</head> | ||
<body data-sveltekit-preload-data="hover"> | ||
<div>%sveltekit.body%</div> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { describe, expect, it } from 'vitest'; | ||
import type { ComponentProps } from 'svelte'; | ||
import { render, screen } from '@testing-library/svelte'; | ||
|
||
import Subject from '../json-diff.svelte'; | ||
|
||
const renderSubject = (props?: Partial<ComponentProps<Subject>>) => { | ||
return render(Subject, { | ||
labelPrefix: 'test', | ||
beforeValue: '', | ||
afterValue: '', | ||
...props, | ||
}); | ||
}; | ||
|
||
describe('json diff', () => { | ||
it('should render both read-only editors with sorted JSON', async () => { | ||
const beforeJson = { aa: 1, bb: 2 }; | ||
const afterJson = { aa: 1, cc: 4, bb: 3 }; | ||
renderSubject({ | ||
beforeValue: JSON.stringify(beforeJson, null, 2), | ||
afterValue: JSON.stringify(afterJson, null, 2), | ||
}); | ||
const beforeEditor = await screen.findByLabelText('test-before'); | ||
const afterEditor = await screen.findByLabelText('test-after'); | ||
expect(beforeEditor).toHaveTextContent(/\{ "aa": 1, "bb": 2\}/iu); | ||
expect(afterEditor).toHaveTextContent(/\{ "aa": 1, "cc": 4, "bb": 3\}/iu); | ||
}); | ||
|
||
it('should destroy the MergeView when the component is unmounted', () => { | ||
const { unmount } = renderSubject(); | ||
// Check that the editor elements are in the DOM before destruction | ||
expect(screen.queryAllByLabelText(/test-(?:before|after)/iu)).toHaveLength( | ||
2 | ||
); | ||
unmount(); | ||
// Check that the editor elements are no longer in the DOM | ||
expect(screen.queryAllByLabelText(/test-(?:before|after)/iu)).toHaveLength( | ||
0 | ||
); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import { describe, expect, it, vi } from 'vitest'; | ||
import type { ComponentProps } from 'svelte'; | ||
import { render, screen } from '@testing-library/svelte'; | ||
import userEvent from '@testing-library/user-event'; | ||
|
||
import Subject from '../json-editor.svelte'; | ||
|
||
const renderSubject = (props?: Partial<ComponentProps<Subject>>) => { | ||
return render(Subject, { | ||
label: 'test-editor', | ||
initialValue: '', | ||
debouncePeriodMS: 0, | ||
...props, | ||
}); | ||
}; | ||
|
||
describe('json editor', () => { | ||
it('should render an editor with initial value', async () => { | ||
const initialJson = { foo: 'bar', baz: 42 }; | ||
renderSubject({ | ||
initialValue: JSON.stringify(initialJson, null, 2), | ||
}); | ||
const editor = await screen.findByLabelText('test-editor'); | ||
expect(editor).toHaveTextContent(/\{\s*"foo": "bar",\s*"baz": 42\s*\}/u); | ||
}); | ||
|
||
it('should call onChange when content changes', async () => { | ||
const onChange = vi.fn(); | ||
renderSubject({ onChange }); | ||
const editor = await screen.findByLabelText('test-editor'); | ||
|
||
await userEvent.type(editor, '{{"key": "value"}'); | ||
|
||
expect(onChange).toHaveBeenCalledWith('{"key": "value"}'); | ||
}); | ||
|
||
it('should set readonly mode correctly', async () => { | ||
renderSubject({ readonly: true }); | ||
const editor = await screen.findByLabelText('test-editor'); | ||
expect(editor).toHaveAttribute('aria-readonly', 'true'); | ||
}); | ||
|
||
it('should show error state when isInvalid is true', async () => { | ||
renderSubject({ isInvalid: true, errorMessageID: 'error-message' }); | ||
const editor = await screen.findByLabelText('test-editor'); | ||
expect(editor).toHaveAttribute('aria-invalid', 'true'); | ||
expect(editor).toHaveAttribute('aria-errormessage', 'error-message'); | ||
}); | ||
|
||
it('should update when initialValue prop changes', async () => { | ||
const { rerender } = renderSubject({ | ||
initialValue: '{"initial": "value"}', | ||
}); | ||
let editor = await screen.findByLabelText('test-editor'); | ||
expect(editor).toHaveTextContent(/"initial": "value"/u); | ||
|
||
rerender({ initialValue: '{"updated": "value"}', label: 'test-editor' }); | ||
editor = await screen.findByLabelText('test-editor'); | ||
expect(editor).toHaveTextContent(/"updated": "value"/u); | ||
}); | ||
|
||
it('should destroy the editor when the component is unmounted', () => { | ||
const { unmount } = renderSubject(); | ||
expect(screen.queryByLabelText('test-editor')).toBeInTheDocument(); | ||
unmount(); | ||
expect(screen.queryByLabelText('test-editor')).not.toBeInTheDocument(); | ||
}); | ||
}); |
Oops, something went wrong.