Skip to content

Commit 2585f04

Browse files
committed
feat: enhance README and release notes with new features, accessibility improvements, and updated descriptions
1 parent f4967a3 commit 2585f04

4 files changed

Lines changed: 103 additions & 24 deletions

File tree

README.md

Lines changed: 91 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,36 @@ A Web Component for displaying syntax-highlighted code with interactive bindings
77
- **Syntax Highlighting**: HTML, SCSS, TypeScript, and Shell
88
- **Interactive Bindings**: Click to edit values directly in the code
99
- **Multiple Types**: boolean, number, string, select, color, comment, attribute
10+
- **Theme System**: Built-in IntelliJ default + 4 external CSS themes (vscode, github, solarized, catppuccin) with light/dark variants
11+
- **Mixed Content Highlighting**: HTML with embedded `<style>` (SCSS) and `<script>` (TypeScript) blocks
12+
- **Copy to Clipboard**: Optional copy button with visual feedback
13+
- **Line Numbers**: Optional gutter line numbers
14+
- **Accessibility**: ARIA attributes, keyboard navigation (Enter/Space, ArrowUp/Down)
1015
- **Framework Agnostic**: Works with Angular, React, Vue, or vanilla JS
1116
- **Zero Dependencies**: Pure Web Components
1217

1318
## Installation
1419

20+
### npm
21+
1522
```bash
1623
npm install @softwarity/interactive-code
1724
```
1825

19-
## Usage
20-
2126
```typescript
2227
import '@softwarity/interactive-code';
2328
```
2429

30+
### CDN
31+
32+
```html
33+
<script type="module" src="https://cdn.jsdelivr.net/npm/@softwarity/interactive-code"></script>
34+
```
35+
36+
No build step required — the custom elements `<interactive-code>` and `<code-binding>` are registered automatically.
37+
38+
## Usage
39+
2540
```html
2641
<interactive-code language="scss">
2742
<textarea>
@@ -42,7 +57,7 @@ import '@softwarity/interactive-code';
4257
| `boolean` | true/false value | Click to toggle |
4358
| `number` | Numeric value | Click to edit, supports min/max/step |
4459
| `string` | Text value | Click to edit |
45-
| `select` | Option from list | Click to toggle (2 options) or dropdown (3+) |
60+
| `select` | Option from list | Click to toggle (2 options), dropdown (3+), or carousel (`carousel` attribute) |
4661
| `color` | Color value | Click to open color picker |
4762
| `comment` | Line/block toggle | Click indicator to comment/uncomment (`//`, `#`, `<!-- -->`, `/* */`) |
4863
| `attribute` | HTML attribute toggle | Click to toggle (strikethrough when disabled) |
@@ -55,7 +70,10 @@ import '@softwarity/interactive-code';
5570
| Attribute | Type | Description |
5671
|-----------|------|-------------|
5772
| `language` | `'html' \| 'scss' \| 'typescript' \| 'shell'` | Syntax highlighting language |
73+
| `color-scheme` | `'light' \| 'dark'` | Color scheme override (inherits from parent by default) |
5874
| `show-separators` | `boolean` | Show visual separators between textarea sections |
75+
| `show-copy` | `boolean` | Show copy-to-clipboard button (top-right corner) |
76+
| `show-line-numbers` | `boolean` | Show line numbers in the gutter |
5977

6078
| Property | Type | Description |
6179
|----------|------|-------------|
@@ -73,6 +91,7 @@ import '@softwarity/interactive-code';
7391
| `max` | `number` | Maximum value (for `number` type) |
7492
| `step` | `number` | Step increment (for `number` type) |
7593
| `options` | `string` | Comma-separated options (for `select` type) |
94+
| `carousel` | `boolean` | Cycle through options on click instead of dropdown (for `select` type) |
7695

7796
| Event | Description |
7897
|-------|-------------|
@@ -202,18 +221,80 @@ console.log(result.groups);</textarea>
202221

203222
- `condition="key"` - Show when binding value is truthy
204223
- `condition="!key"` - Show when binding value is falsy
224+
- `condition="key=value"` - Show when binding value equals a specific value
225+
- `condition="!key=value"` - Show when binding value does NOT equal a specific value
205226
- `show-separators` - Add visual separators between sections (customizable via `--code-separator-color`)
206227

228+
## Themes
229+
230+
The built-in default is IntelliJ (Light/Darcula). Four external CSS themes are available as separate stylesheets:
231+
232+
| Theme | File | Light | Dark |
233+
|-------|------|-------|------|
234+
| VS Code | `themes/vscode.css` | Light+ | Dark+ |
235+
| GitHub | `themes/github.css` | Light | Dark |
236+
| Solarized | `themes/solarized.css` | Light | Dark |
237+
| Catppuccin | `themes/catppuccin.css` | Latte | Mocha |
238+
239+
Load a theme by adding a `<link>` stylesheet:
240+
241+
```html
242+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@softwarity/interactive-code/themes/vscode.css">
243+
```
244+
245+
Use `color-scheme` to override light/dark mode per element:
246+
247+
```html
248+
<interactive-code language="typescript" color-scheme="light">
249+
...
250+
</interactive-code>
251+
```
252+
207253
## CSS Customization
208254

209-
The component supports CSS custom properties for styling:
255+
The component exposes CSS custom properties for styling. Themes and custom overrides use these variables.
256+
257+
### UI Variables
258+
259+
| Property | Description |
260+
|----------|-------------|
261+
| `--code-bg` | Background color |
262+
| `--code-text` | Foreground text color |
263+
| `--code-border-radius` | Border radius |
264+
| `--code-line-number` | Line number color |
265+
| `--code-separator-color` | Separator color between textarea sections |
266+
| `--code-focus-outline` | Focus ring color |
267+
| `--code-input-bg` | Inline input background |
268+
| `--code-input-border` | Inline input border |
269+
| `--code-hover-bg` | Hover background |
270+
| `--code-copy-color` | Copy button color |
271+
| `--code-copy-border` | Copy button border |
272+
| `--code-copy-accent` | Copy success accent |
273+
| `--code-color-preview-border` | Color swatch border |
274+
| `--code-interactive-highlight` | Interactive zone accent color |
275+
| `--code-interactive-color` | Interactive zone text color |
276+
| `--code-interactive-bg-color` | Interactive zone background |
277+
| `--code-interactive-border-color` | Interactive zone border color |
278+
| `--code-comment-color` | Comment indicator color |
279+
280+
### Token Variables
281+
282+
All syntax token colors: `--token-keyword`, `--token-string`, `--token-number`, `--token-comment`, `--token-tag`, `--token-attr-name`, `--token-attr-value`, `--token-punctuation`, `--token-property`, `--token-variable`, `--token-function`, `--token-decorator`, `--token-type`, `--token-class-name`, `--token-template-string`, `--token-value`, `--token-unknown`, `--token-binding-key`
283+
284+
### Interactive Zone Styling
285+
286+
Interactive controls expose `part="interactive"` for external CSS styling:
287+
288+
```css
289+
interactive-code::part(interactive) {
290+
text-decoration: underline wavy var(--code-interactive-highlight);
291+
}
292+
interactive-code::part(interactive):hover {
293+
background: var(--code-interactive-bg-color);
294+
}
295+
```
210296

211-
| Property | Default | Description |
212-
|----------|---------|-------------|
213-
| `--code-bg` | `#1e1e1e` | Background color of the code block |
214-
| `--code-border-radius` | `8px` | Border radius of the code block |
215-
| `--code-separator-color` | `rgba(255, 255, 255, 0.1)` | Color of separators between textarea sections |
216-
| `--code-editable-underline` | `#4ec9b0` | Color of wavy underline on editable values |
297+
Built-in styles: wavy (default), dotted, dashed, highlight, outline, pill, hand-drawn, none.
217298

218299
```css
219300
interactive-code {

RELEASE_NOTES.md

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@
1010
- **CSS custom properties**: All 18 token colors and 10 UI colors exposed as `--token-*` and `--code-*` variables for external customization.
1111
- **Interactive zone styling**: Interactive controls expose `part="interactive"` for external CSS styling (supports `:hover`). Themes provide color hooks: `--code-interactive-highlight` (accent), `--code-interactive-color` (text), `--code-interactive-bg-color` (background), `--code-interactive-border-color` (border). Shadow DOM decoration customizable via `--code-interactive-text-decoration`, `--code-interactive-border`, etc. Built-in styles: wavy (default), dotted, dashed, highlight, outline, pill, hand-drawn, none.
1212
- **Condition value matching**: Conditional textareas now support `condition="key=value"` syntax to show content when a binding equals a specific value (in addition to existing truthy/falsy checks).
13-
- **Select carousel mode**: New `carousel` boolean attribute on `<code-binding type="select">` cycles through options on click instead of opening a dropdown. Supports keyboard navigation (ArrowUp/ArrowDown).
13+
- **Select carousel mode**: New `carousel` boolean attribute on `<code-binding type="select">` cycles through options on click instead of opening a dropdown. Supports keyboard navigation (ArrowUp/ArrowDown) and Shift+click to cycle backward.
14+
- **Copy to clipboard button**: New `show-copy` attribute displays a copy button (top-right corner) with SVG clipboard/check icons and visual feedback (green check for 2 seconds after copy). Hidden by default.
15+
- **Line numbers**: New `show-line-numbers` attribute displays line numbers in the gutter. Numbers are excluded from copy/paste via `user-select: none`. Section separators have no line number.
16+
- **Hyphenated binding keys**: Binding keys now support hyphens (e.g., `${show-line-numbers}`) for use with the `attribute` binding type on HTML attributes.
17+
- **Accessibility**: Interactive controls now have `role`, `aria-label`, and `tabindex` attributes. Keyboard navigation supports Enter/Space for toggle actions, ArrowUp/Down for number increment/decrement. Focus-visible outline on all interactive elements.
1418

1519
### Bug Fixes
1620

@@ -19,13 +23,6 @@
1923
- **XSS risk in binding rendering**: String, number, color, and select values were inserted into HTML attributes without escaping. All dynamic values are now escaped with `escapeHtml()`.
2024
- **Fragile `_internalChange` flag**: If `binding.value = newValue` threw an error, the flag remained stuck at `true`. Now wrapped in `try/finally` blocks.
2125

22-
### Features
23-
24-
- **Copy to clipboard button**: New `show-copy` attribute displays a copy button (top-right corner) with SVG clipboard/check icons and visual feedback (green check for 2 seconds after copy). Hidden by default.
25-
- **Line numbers**: New `show-line-numbers` attribute displays line numbers in the gutter. Numbers are excluded from copy/paste via `user-select: none`. Section separators have no line number.
26-
- **Hyphenated binding keys**: Binding keys now support hyphens (e.g., `${show-line-numbers}`) for use with the `attribute` binding type on HTML attributes.
27-
- **Accessibility**: Interactive controls now have `role`, `aria-label`, and `tabindex` attributes. Keyboard navigation supports Enter/Space for toggle actions, ArrowUp/Down for number increment/decrement. Focus-visible outline on all interactive elements.
28-
2926
### Improvements
3027

3128
- **Consolidated input listeners**: Three separate `input` event listeners merged into a single `_handleShadowInput()` with extracted helper methods (`_handleInlineNumberInput`, `_handleInlineStringInput`, `_handleInlineColorInput`)
@@ -35,8 +32,7 @@
3532

3633
### Tests
3734

38-
- Added 52 new tests: cleanup (3), XSS (3), conditional inline (1), copy button (8), line numbers (5), accessibility (6), condition value matching (5), part="interactive" (5), interactive zone CSS (4), carousel (6 rendering + 6 code-binding)
39-
- Updated tests: theme system (7), mixed content highlighting (7) — 177 tests total
35+
- 178 tests total (+68 new): cleanup (3), XSS (3), conditional inline (1), copy button (8), line numbers (5), accessibility (6), condition value matching (5), interactive zone (9), carousel (13), theme system (7), mixed content highlighting (7)
4036

4137
---
4238

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@softwarity/interactive-code",
33
"version": "1.0.6",
4-
"description": "A Web Component for displaying syntax-highlighted code with interactive bindings. Supports HTML, SCSS, TypeScript, and Shell with editable values (boolean, number, string, select, color).",
4+
"description": "A Web Component for displaying syntax-highlighted code with interactive bindings. Supports HTML, SCSS, TypeScript, and Shell with interactive values (boolean, number, string, select, color, comment, attribute).",
55
"type": "module",
66
"main": "./dist/interactive-code.js",
77
"module": "./dist/interactive-code.js",

src/interactive-code.element.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export class InteractiveCodeElement extends HTMLElement {
5656
private _initialized = false;
5757
private _internalChange = false;
5858

59-
// References for cleanup (Bug 2)
59+
// References for cleanup
6060
private _observer: MutationObserver | null = null;
6161
private _fallbackTimeout: ReturnType<typeof setTimeout> | null = null;
6262
private _copyTimeout: ReturnType<typeof setTimeout> | null = null;
@@ -387,7 +387,7 @@ export class InteractiveCodeElement extends HTMLElement {
387387
} finally {
388388
this._internalChange = false;
389389
}
390-
// Bug 1: Re-evaluate conditions if this binding is used in a condition
390+
// Re-evaluate conditions if this binding is used in a condition
391391
if (this.hasConditionDependency(key)) {
392392
this.updateCode();
393393
}
@@ -403,8 +403,10 @@ export class InteractiveCodeElement extends HTMLElement {
403403
e.stopPropagation();
404404
this._handleInlineNumberInput(target);
405405
} else if (target.classList.contains('inline-string-input')) {
406+
e.stopPropagation();
406407
this._handleInlineStringInput(target);
407408
} else if (target.type === 'color') {
409+
e.stopPropagation();
408410
this._handleInlineColorInput(target);
409411
}
410412
}
@@ -797,7 +799,7 @@ export class InteractiveCodeElement extends HTMLElement {
797799
const disabledClass = binding.disabled ? ' disabled' : '';
798800
const tabindex = binding.disabled ? '-1' : '0';
799801

800-
// Escape values for safe HTML insertion (Bug 3: XSS prevention)
802+
// Escape values for safe HTML insertion (XSS prevention)
801803
const escValue = this.escapeHtml(String(value ?? ''));
802804
const escKey = this.escapeHtml(key);
803805

0 commit comments

Comments
 (0)