Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ Kotlin Multiplatform Compose JSON viewer and editor component for Android, iOS,
- **Multiple Themes** — Dark, Light, Monokai, Dracula, Solarized Dark (+ custom themes)
- **KMP** — Android, iOS, and JVM Desktop support via Compose Multiplatform

<p align="center">
<img src="docs/screenshots/viewer/viewer-hero.png" width="320" alt="JSON Viewer"/>
&nbsp;&nbsp;
<img src="docs/screenshots/editor/editor-hero.png" width="320" alt="JSON Editor"/>
</p>

## Installation

Add `mavenCentral()` to your repositories in `settings.gradle.kts`:
Expand Down Expand Up @@ -82,6 +88,10 @@ fun MyEditor() {

## Themes

| Dark | Light | Monokai | Dracula | Solarized Dark |
|:---:|:---:|:---:|:---:|:---:|
| <img src="docs/screenshots/viewer/theme/dark.png" width="150" alt="Dark"/> | <img src="docs/screenshots/viewer/theme/light.png" width="150" alt="Light"/> | <img src="docs/screenshots/viewer/theme/monokai.png" width="150" alt="Monokai"/> | <img src="docs/screenshots/viewer/theme/dracula.png" width="150" alt="Dracula"/> | <img src="docs/screenshots/viewer/theme/solarized.png" width="150" alt="Solarized Dark"/> |

```kotlin
JsonViewerCMP(
state = state,
Expand Down
10 changes: 10 additions & 0 deletions docs/features/editor.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

`JsonEditorCMP` provides inline text editing with real-time validation, formatting, and sorting.

<figure markdown="span">
![JSON Editor](../screenshots/editor/editor-hero.png){ width="350" }
<figcaption>Editor with toolbar controls for formatting, sorting, and folding</figcaption>
</figure>

## Size Limit

The editor enforces a **50 KB write limit**. Content exceeding 50 KB is truncated — both for `initialJson` passed to `rememberJsonEditorState` and for user input during editing.
Expand Down Expand Up @@ -38,6 +43,11 @@ When the JSON is invalid, an error banner appears below the toolbar showing:
- Error message
- Line and column position of the error

<figure markdown="span">
![Error Banner](../screenshots/editor/editor-error.png){ width="350" }
<figcaption>Error banner showing parse error with position details</figcaption>
</figure>

## Real-time Validation

Observe changes reactively via Compose state properties on `JsonEditorState`:
Expand Down
36 changes: 29 additions & 7 deletions docs/features/themes.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,35 @@ JsonCMP ships with five built-in color themes and supports custom themes via `Js

## Built-in Themes

| Theme | Constant | Style |
|-------|----------|-------|
| VS Code Dark+ | `JsonTheme.Dark` | Dark background, blue keys, orange strings |
| VS Code Light+ | `JsonTheme.Light` | White background, blue keys, red strings |
| Monokai | `JsonTheme.Monokai` | Dark green background, pink keys, yellow strings |
| Dracula | `JsonTheme.Dracula` | Dark purple background, cyan keys, yellow strings |
| Solarized Dark | `JsonTheme.SolarizedDark` | Dark blue-green background, blue keys, teal strings |
=== "Dark"

![Dark Theme](../screenshots/viewer/theme/dark.png){ width="350" }

`JsonTheme.Dark` — Dark background, blue keys, orange strings (VS Code Dark+)

=== "Light"

![Light Theme](../screenshots/viewer/theme/light.png){ width="350" }

`JsonTheme.Light` — White background, blue keys, red strings (VS Code Light+)

=== "Monokai"

![Monokai Theme](../screenshots/viewer/theme/monokai.png){ width="350" }

`JsonTheme.Monokai` — Dark green background, pink keys, yellow strings

=== "Dracula"

![Dracula Theme](../screenshots/viewer/theme/dracula.png){ width="350" }

`JsonTheme.Dracula` — Dark purple background, cyan keys, yellow strings

=== "Solarized Dark"

![Solarized Dark Theme](../screenshots/viewer/theme/solarized.png){ width="350" }

`JsonTheme.SolarizedDark` — Dark blue-green background, blue keys, teal strings

## Usage

Expand Down
15 changes: 15 additions & 0 deletions docs/features/viewer.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

`JsonViewerCMP` renders JSON as a read-only, syntax-highlighted tree with line numbers, code folding, and virtualized rendering.

<figure markdown="span">
![JSON Viewer](../screenshots/viewer/viewer-hero.png){ width="350" }
<figcaption>Viewer with syntax highlighting, line numbers, and code folding</figcaption>
</figure>

## Size Limits

- **Valid JSON** — Virtually no size limit. The viewer uses virtualized rendering to handle large documents efficiently.
Expand All @@ -22,6 +27,11 @@ Each JSON token type is rendered in a distinct color:

Objects and arrays can be collapsed by clicking the fold indicator in the gutter. Collapsed sections show an ellipsis with the element count.

<figure markdown="span">
![Code Folding](../screenshots/viewer/viewer-hero.png){ width="350" }
<figcaption>Collapsed "zip" object showing ellipsis with element count</figcaption>
</figure>

## Line Numbers

Line numbers are displayed in a gutter column with a subtle border separator.
Expand All @@ -40,6 +50,11 @@ JsonViewerCMP(

Matches are highlighted with the `highlight` and `highlightFg` colors from the active theme.

<figure markdown="span">
![Search Highlighting](../screenshots/viewer/viewer-search.png){ width="350" }
<figcaption>Search results highlighted with match counter and navigation</figcaption>
</figure>

## Nested Scrolling

`JsonViewerCMP` uses `LazyColumn` internally for virtualized rendering. If you place it inside a vertically scrollable parent (e.g. `Column` with `verticalScroll`, or another `LazyColumn`), you must give `JsonViewerCMP` a bounded height (e.g. `Modifier.height(400.dp)` or `Modifier.weight(1f)`) and handle nested scroll coordination on the client side using Compose's `nestedScroll` modifier.
Expand Down
10 changes: 10 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ Kotlin Multiplatform Compose JSON viewer and editor component. Two separate comp

## JSON Viewer

<figure markdown="span">
![JSON Viewer](screenshots/viewer/viewer-hero.png){ width="350" }
<figcaption>Syntax-highlighted viewer with code folding and line numbers</figcaption>
</figure>

Drop-in read-only JSON renderer with virtualized rendering:

- Syntax highlighting (keys, strings, numbers, booleans, null, punctuation)
Expand All @@ -38,6 +43,11 @@ fun MyScreen() {

## JSON Editor

<figure markdown="span">
![JSON Editor](screenshots/editor/editor-hero.png){ width="350" }
<figcaption>Editable JSON with toolbar and real-time validation</figcaption>
</figure>

Full editing mode with real-time validation:

- Inline text editing with live parse feedback
Expand Down
Binary file added docs/screenshots/editor/editor-error.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/screenshots/editor/editor-hero.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/screenshots/viewer/theme/dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/screenshots/viewer/theme/dracula.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/screenshots/viewer/theme/light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/screenshots/viewer/theme/monokai.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/screenshots/viewer/theme/solarized.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/screenshots/viewer/viewer-hero.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/screenshots/viewer/viewer-search.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ android.r8.strictFullModeForKeepRules=false

#Publishing
jsoncmp.group=dev.skymansandy
jsoncmp.version=1.0.0-RC1
jsoncmp.version=1.0.0-RC2
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Copyright (c) 2026 skymansandy. All rights reserved.
*/

package dev.skymansandy.jsoncmp.domain

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Copyright (c) 2026 skymansandy. All rights reserved.
*/

package dev.skymansandy.jsoncmp.domain.highlighter

/** A highlighted span within the raw JSON text. */
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Copyright (c) 2026 skymansandy. All rights reserved.
*/

package dev.skymansandy.jsoncmp.domain.highlighter

/** Classification of a JSON syntax token for highlighting. */
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Copyright (c) 2026 skymansandy. All rights reserved.
*/

package dev.skymansandy.jsoncmp.domain.line

import dev.skymansandy.jsoncmp.domain.model.FoldType
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Copyright (c) 2026 skymansandy. All rights reserved.
*/

package dev.skymansandy.jsoncmp.domain.line

import dev.skymansandy.jsoncmp.domain.model.FoldType
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Copyright (c) 2026 skymansandy. All rights reserved.
*/

package dev.skymansandy.jsoncmp.domain.line

/** A typed segment of text within a [JsonLine], used for syntax colouring. */
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Copyright (c) 2026 skymansandy. All rights reserved.
*/

package dev.skymansandy.jsoncmp.domain.model

/** Whether a foldable line opens a JSON object or array. */
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Copyright (c) 2026 skymansandy. All rights reserved.
*/

package dev.skymansandy.jsoncmp.domain.model

/** Parsed JSON abstract syntax tree. */
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Copyright (c) 2026 skymansandy. All rights reserved.
*/

package dev.skymansandy.jsoncmp.domain.model

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Copyright (c) 2026 skymansandy. All rights reserved.
*/

package dev.skymansandy.jsoncmp.domain.parser

/** Describes a JSON parse failure with an optional character position. */
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Copyright (c) 2026 skymansandy. All rights reserved.
*/

package dev.skymansandy.jsoncmp.domain.parser

import dev.skymansandy.jsoncmp.domain.line.buildDisplayLines
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Copyright (c) 2026 skymansandy. All rights reserved.
*/

package dev.skymansandy.jsoncmp.domain.parser

import dev.skymansandy.jsoncmp.domain.line.JsonLine
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Copyright (c) 2026 skymansandy. All rights reserved.
*/

package dev.skymansandy.jsoncmp.domain.serializer

import dev.skymansandy.jsoncmp.domain.model.JsonNode
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Copyright (c) 2026 skymansandy. All rights reserved.
*/

package dev.skymansandy.jsoncmp.domain.store

/** User-driven actions dispatched to [JsonHolder]. */
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Copyright (c) 2026 skymansandy. All rights reserved.
*/

package dev.skymansandy.jsoncmp.domain.store

import androidx.compose.runtime.Stable
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Copyright (c) 2026 skymansandy. All rights reserved.
*/

package dev.skymansandy.jsoncmp.domain.store

import androidx.compose.runtime.Stable
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Copyright (c) 2026 skymansandy. All rights reserved.
*/

package dev.skymansandy.jsoncmp.domain.store

import dev.skymansandy.jsoncmp.domain.line.JsonLine
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Copyright (c) 2026 skymansandy. All rights reserved.
*/

package dev.skymansandy.jsoncmp.helper.mocks

import dev.skymansandy.jsoncmp.domain.line.JsonLine
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Copyright (c) 2026 skymansandy. All rights reserved.
*/

package dev.skymansandy.jsoncmp.helper.util

import androidx.compose.ui.unit.dp
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Copyright (c) 2026 skymansandy. All rights reserved.
*/

package dev.skymansandy.jsoncmp.theme

import androidx.compose.runtime.compositionLocalOf
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Copyright (c) 2026 skymansandy. All rights reserved.
*/

package dev.skymansandy.jsoncmp.theme

/** Named theme wrapping a [JsonCmpColors] palette. Use [Custom] for user-defined colors. */
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Copyright (c) 2026 skymansandy. All rights reserved.
*/

package dev.skymansandy.jsoncmp.theme

import androidx.compose.ui.text.TextStyle
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Copyright (c) 2026 skymansandy. All rights reserved.
*/

package dev.skymansandy.jsoncmp.ui.common

import androidx.compose.foundation.gestures.detectTapGestures
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Copyright (c) 2026 skymansandy. All rights reserved.
*/

package dev.skymansandy.jsoncmp.ui.common

import androidx.compose.ui.text.AnnotatedString
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Copyright (c) 2026 skymansandy. All rights reserved.
*/

package dev.skymansandy.jsoncmp.ui.common

import androidx.compose.foundation.background
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Copyright (c) 2026 skymansandy. All rights reserved.
*/

package dev.skymansandy.jsoncmp.ui.common

import androidx.compose.foundation.background
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Copyright (c) 2026 skymansandy. All rights reserved.
*/

package dev.skymansandy.jsoncmp.ui.editor

import androidx.compose.foundation.background
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Copyright (c) 2026 skymansandy. All rights reserved.
*/

package dev.skymansandy.jsoncmp.ui.editor

import androidx.compose.runtime.Composable
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Copyright (c) 2026 skymansandy. All rights reserved.
*/

package dev.skymansandy.jsoncmp.ui.editor

import androidx.compose.runtime.Composable
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Copyright (c) 2026 skymansandy. All rights reserved.
*/

package dev.skymansandy.jsoncmp.ui.editor.component

import androidx.compose.foundation.background
Expand Down
Loading
Loading