@synerise/ds-code-area 1.3.27 → 1.3.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/CLAUDE.md +137 -0
- package/package.json +12 -11
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,14 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [1.3.29](https://github.com/Synerise/synerise-design/compare/@synerise/ds-code-area@1.3.28...@synerise/ds-code-area@1.3.29) (2026-07-23)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @synerise/ds-code-area
|
|
9
|
+
|
|
10
|
+
## [1.3.28](https://github.com/Synerise/synerise-design/compare/@synerise/ds-code-area@1.3.27...@synerise/ds-code-area@1.3.28) (2026-07-16)
|
|
11
|
+
|
|
12
|
+
**Note:** Version bump only for package @synerise/ds-code-area
|
|
13
|
+
|
|
6
14
|
## [1.3.27](https://github.com/Synerise/synerise-design/compare/@synerise/ds-code-area@1.3.26...@synerise/ds-code-area@1.3.27) (2026-07-09)
|
|
7
15
|
|
|
8
16
|
**Note:** Version bump only for package @synerise/ds-code-area
|
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# CodeArea (`@synerise/ds-code-area`)
|
|
2
|
+
|
|
3
|
+
> A Monaco Editor wrapper with fullscreen mode (via `createPortal`), syntax switching, character counter, error state, label/tooltip, and customisable footer content.
|
|
4
|
+
|
|
5
|
+
## Package structure
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
src/
|
|
9
|
+
CodeArea.tsx — public-facing component; manages fullscreen state + portal
|
|
10
|
+
CodeArea.types.ts — all type definitions
|
|
11
|
+
CodeArea.styles.ts — all styled-components (also re-exported from index.ts)
|
|
12
|
+
CodeArea.figma.tsx — Figma Code Connect file
|
|
13
|
+
constants.ts — MONACO_DEFAULT_OPTIONS, DS_MONACO_THEME, DS_MONACO_THEME_NAME
|
|
14
|
+
index.ts — public exports
|
|
15
|
+
components/
|
|
16
|
+
CodeAreaEditor.tsx — forwardRef wrapper; handles label, counter, error, fullscreen header
|
|
17
|
+
CodeAreaEditorRaw.tsx — mounts <Editor> from @monaco-editor/react; owns monaco lifecycle
|
|
18
|
+
BottomBar.tsx — syntax select + fullscreen button + custom footer slot
|
|
19
|
+
ContentAbove.tsx — label + top counter row
|
|
20
|
+
ContentBelow.tsx — description + additional description + bottom counter + error text
|
|
21
|
+
FullscreenHeader.tsx — header bar shown only in fullscreen mode
|
|
22
|
+
AriaContainer.tsx — attaches monaco's ARIA container element to the DOM
|
|
23
|
+
index.ts — re-exports all components
|
|
24
|
+
utils/
|
|
25
|
+
getDefaultTexts.tsx — merges react-intl defaults with caller-supplied texts
|
|
26
|
+
getCharCount.ts — returns char count; undefined when over limit
|
|
27
|
+
calculateRequiredSpace.ts — calculates px height stolen by chrome in fullscreen
|
|
28
|
+
index.ts — re-exports utils
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Public exports
|
|
32
|
+
|
|
33
|
+
### `CodeArea` (default export)
|
|
34
|
+
|
|
35
|
+
Generic component: `CodeArea<SyntaxName extends CodeAreaSyntax = CodeAreaSyntax>`.
|
|
36
|
+
|
|
37
|
+
`CodeAreaProps` = `Omit<CodeAreaEditorProps, 'toggleFullscreen' | 'isFullscreen'>` plus:
|
|
38
|
+
|
|
39
|
+
| Prop | Type | Default | Description |
|
|
40
|
+
|------|------|---------|-------------|
|
|
41
|
+
| `currentSyntax` | `CodeAreaSyntax` | — | **Required.** Active language for the editor. |
|
|
42
|
+
| `label` | `ReactNode` | `undefined` | Label rendered above the editor (via `FormFieldLabel`). |
|
|
43
|
+
| `fullscreenLabel` | `ReactNode` | `undefined` | Label shown in the fullscreen header; falls back to `label`. |
|
|
44
|
+
| `description` | `ReactNode` | `undefined` | Text below the editor. |
|
|
45
|
+
| `errorText` | `ReactNode` | `undefined` | Error message below editor; also triggers red border + background. Sets `isValid=false`. |
|
|
46
|
+
| `placeholder` | `ReactNode` | `undefined` | Overlay shown when editor is empty. Positioned `left: 62px` (after line numbers). |
|
|
47
|
+
| `counter` | `{ limit: number; placement?: 'bottom' \| 'top' }` | `undefined` | Character counter. Hard-limits input at `limit` (triggers `undo` on overflow). |
|
|
48
|
+
| `syntaxOptions` | `CodeAreaSyntaxOption<SyntaxName>[]` | `undefined` | Available languages. Syntax select renders in BottomBar when `length > 1` and not `readOnly`. |
|
|
49
|
+
| `allowFullscreen` | `boolean` | `undefined` | Shows the fullscreen button in BottomBar. |
|
|
50
|
+
| `readOnly` | `boolean` | `undefined` | Monaco `readOnly` + `domReadOnly`; grey background; cursor hidden. |
|
|
51
|
+
| `noBorder` | `boolean` | `undefined` | Removes the 1px border from the editor wrapper. |
|
|
52
|
+
| `height` | `string \| number` | `undefined` | Height of the wrapper. When unset, `EditorInnerWrapper` defaults to `295px`. |
|
|
53
|
+
| `zIndex` | `string \| number` | `undefined` | `z-index` of the fullscreen overlay. Defaults to `theme.variables['zindex-modal']`. |
|
|
54
|
+
| `tooltip` | `ReactNode` | `undefined` | Tooltip content shown next to the label. |
|
|
55
|
+
| `tooltipProps` | `TooltipProps` | `undefined` | Full tooltip configuration (merged with `tooltip`). |
|
|
56
|
+
| `style` | `CSSProperties` | `undefined` | Inline styles on the outermost wrapper. |
|
|
57
|
+
| `className` | `string` | `undefined` | Additional class on the outermost wrapper. |
|
|
58
|
+
| `texts` | `Partial<CodeAreaTexts>` | `undefined` | Override i18n strings (see below). |
|
|
59
|
+
| `value` | `string` | `undefined` | Controlled editor value (passed to `@monaco-editor/react`). |
|
|
60
|
+
| `defaultValue` | `string` | `undefined` | Uncontrolled initial value. |
|
|
61
|
+
| `options` | `EditorProps['options']` | `undefined` | Monaco editor options (merged over `MONACO_DEFAULT_OPTIONS`). |
|
|
62
|
+
| `loaderConfig` | `Parameters<typeof loader.config>[0]` | `undefined` | Configure the Monaco CDN/path loader. Applied once on first render. |
|
|
63
|
+
| `renderFooterContent` | `(state: { isFullscreen?, count?, isValid? }) => ReactNode` | `undefined` | Custom content in the right side of BottomBar. |
|
|
64
|
+
| `renderAdditionalDescription` | `(state: { isFullscreen?, count?, isValid? }) => ReactNode` | `undefined` | Custom content above `description`. |
|
|
65
|
+
| `onChange` | `EditorProps['onChange']` | `undefined` | Monaco `onChange` callback. Blocked when content exceeds `counter.limit`. |
|
|
66
|
+
| `onMount` | `EditorProps['onMount']` | `undefined` | Access to the editor + monaco instance after mount. |
|
|
67
|
+
| `beforeMount` | `EditorProps['beforeMount']` | `undefined` | Called before editor mounts; DS theme is registered here. |
|
|
68
|
+
| `onSyntaxChange` | `(newSyntax: SyntaxName) => void` | `undefined` | Fired when user selects a different syntax. |
|
|
69
|
+
| `onFullscreenChange` | `(isFullscreen: boolean) => void` | `undefined` | Fired when fullscreen is toggled. **Note: receives the *old* state**, not the new one (bug). |
|
|
70
|
+
| `getPopupContainer` | `(node: HTMLElement) => HTMLElement` | `getPopupContainer` from `@synerise/ds-utils` | Container for the fullscreen portal. |
|
|
71
|
+
|
|
72
|
+
### `CodeAreaTexts` (type)
|
|
73
|
+
|
|
74
|
+
| Key | Default (react-intl) |
|
|
75
|
+
|-----|----------------------|
|
|
76
|
+
| `fullscreen` | `'Fullscreen'` (`DS.CODE-AREA.FULLSCREEN`) |
|
|
77
|
+
| `closeFullscreen` | `'Close fullscreen'` (`DS.CODE-AREA.CLOSE-FULLSCREEN`) |
|
|
78
|
+
| `fullscreenTitle` | `'Fullscreen editor'` (`DS.CODE-AREA.FULLSCREEN-TITLE`) |
|
|
79
|
+
|
|
80
|
+
### `CodeAreaSyntaxOption<SyntaxName>` (type)
|
|
81
|
+
|
|
82
|
+
| Field | Type | Description |
|
|
83
|
+
|-------|------|-------------|
|
|
84
|
+
| `language` | `SyntaxName` | Language identifier passed to Monaco. |
|
|
85
|
+
| `label` | `string` (optional) | Display name in the syntax select dropdown. |
|
|
86
|
+
|
|
87
|
+
### `CodeAreaSyntax` (type)
|
|
88
|
+
|
|
89
|
+
`'json' | 'html' | 'css' | 'typescript' | 'javascript' | string`
|
|
90
|
+
|
|
91
|
+
### Style exports (`export * from './CodeArea.styles'`)
|
|
92
|
+
|
|
93
|
+
All styled-components are re-exported for targeted overrides: `EditorWrapper`, `BottomBar`, `Counter`, `ErrorText`, `CodeAreaWrapper`, etc.
|
|
94
|
+
|
|
95
|
+
## Usage patterns
|
|
96
|
+
|
|
97
|
+
```tsx
|
|
98
|
+
import CodeArea from '@synerise/ds-code-area';
|
|
99
|
+
|
|
100
|
+
type Syntax = 'json' | 'javascript';
|
|
101
|
+
|
|
102
|
+
<CodeArea<Syntax>
|
|
103
|
+
label="Query"
|
|
104
|
+
currentSyntax="json"
|
|
105
|
+
syntaxOptions={[
|
|
106
|
+
{ language: 'json', label: 'JSON' },
|
|
107
|
+
{ language: 'javascript', label: 'JS' },
|
|
108
|
+
]}
|
|
109
|
+
value={code}
|
|
110
|
+
onChange={(val) => setCode(val ?? '')}
|
|
111
|
+
onSyntaxChange={setSyntax}
|
|
112
|
+
allowFullscreen
|
|
113
|
+
counter={{ limit: 5000, placement: 'bottom' }}
|
|
114
|
+
errorText={hasError ? 'Invalid JSON' : undefined}
|
|
115
|
+
height={400}
|
|
116
|
+
/>
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Key dependencies
|
|
120
|
+
|
|
121
|
+
- `@monaco-editor/react` (4.4.6) — React wrapper for Monaco Editor; provides `<Editor>`, `loader`, and types
|
|
122
|
+
- `monaco-editor` (0.34.1, devDep) — types used in `constants.ts` and `CodeArea.types.ts`
|
|
123
|
+
- `react-intl` — **required peer dep** for default `texts`; app must have `<IntlProvider>`
|
|
124
|
+
- `@synerise/ds-form-field` (`FormFieldLabel`) — renders `label` + `tooltip` above the editor
|
|
125
|
+
- `@synerise/ds-inline-edit` (`InlineSelect`) — syntax switcher in BottomBar
|
|
126
|
+
|
|
127
|
+
## Implementation notes
|
|
128
|
+
|
|
129
|
+
- **Fullscreen uses `createPortal`**: when `isFullscreen=true`, a second `<CodeAreaEditor>` is mounted via portal into `getPopupContainer(wrapperRef.current)`. The in-place editor remains mounted with `isFullscreen={false}` always. This means two Monaco instances exist simultaneously during fullscreen.
|
|
130
|
+
- **`onFullscreenChange` receives the old state**: `onFullscreenChange && onFullscreenChange(isFullscreen)` is called before `setIsFullscreen` — the callback gets the value *before* the toggle (likely a bug).
|
|
131
|
+
- **Counter hard-limit**: when `value.length > counter.limit`, `CodeAreaEditorRaw` triggers `'undo'` on the Monaco instance directly. The `onChange` callback is not called for over-limit input.
|
|
132
|
+
- **`isValid` logic**: `isValid` starts as `true`, is set to `false` when `errorText` is truthy (via `useEffect`), and is also set to `false` when Monaco reports markers (lint/parse errors). Both paths independently drive the error state.
|
|
133
|
+
- **Monaco theme**: `DS_MONACO_THEME` (`'DSTheme'`) is registered in `beforeMount` and uses a transparent background so the wrapper's background colour shows through.
|
|
134
|
+
- **`loaderConfig` is one-shot**: a `loaderConfigSet` ref prevents calling `loader.config()` more than once per component instance — changing `loaderConfig` after mount has no effect.
|
|
135
|
+
- **`placeholder` offset**: positioned `left: 62px` to align with the editor text column after Monaco's line-number gutter. Adjust if `options.lineNumbers` is set to `'off'`.
|
|
136
|
+
- **BottomBar visibility**: shown when at least one of `isSyntaxSelectVisible`, `allowFullscreen && !isFullscreen`, or `renderFooterContent` is truthy.
|
|
137
|
+
- **AriaContainer**: Monaco's accessibility tree is redirected to a detached `<div>` created in `useMemo` and attached to the DOM via `<AriaContainer>`. This prevents Monaco's ARIA announcements from polluting the page structure.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@synerise/ds-code-area",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.29",
|
|
4
4
|
"description": "CodeArea UI Component for the Synerise Design System",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"repository": "Synerise/synerise-design",
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
"files": [
|
|
18
18
|
"/dist",
|
|
19
19
|
"CHANGELOG.md",
|
|
20
|
+
"CLAUDE.md",
|
|
20
21
|
"README.md",
|
|
21
22
|
"package.json",
|
|
22
23
|
"LICENSE.md"
|
|
@@ -42,15 +43,15 @@
|
|
|
42
43
|
"types": "dist/index.d.ts",
|
|
43
44
|
"dependencies": {
|
|
44
45
|
"@monaco-editor/react": "4.4.6",
|
|
45
|
-
"@synerise/ds-button": "^1.5.
|
|
46
|
-
"@synerise/ds-core": "^1.13.
|
|
47
|
-
"@synerise/ds-form-field": "^1.3.
|
|
48
|
-
"@synerise/ds-icon": "^1.18.
|
|
49
|
-
"@synerise/ds-inline-edit": "^1.1.
|
|
50
|
-
"@synerise/ds-loader": "^1.0.
|
|
51
|
-
"@synerise/ds-tooltip": "^1.5.
|
|
52
|
-
"@synerise/ds-typography": "^1.1.
|
|
53
|
-
"@synerise/ds-utils": "^1.10.
|
|
46
|
+
"@synerise/ds-button": "^1.5.35",
|
|
47
|
+
"@synerise/ds-core": "^1.13.1",
|
|
48
|
+
"@synerise/ds-form-field": "^1.3.24",
|
|
49
|
+
"@synerise/ds-icon": "^1.18.5",
|
|
50
|
+
"@synerise/ds-inline-edit": "^1.1.48",
|
|
51
|
+
"@synerise/ds-loader": "^1.0.18",
|
|
52
|
+
"@synerise/ds-tooltip": "^1.5.4",
|
|
53
|
+
"@synerise/ds-typography": "^1.1.27",
|
|
54
|
+
"@synerise/ds-utils": "^1.10.2"
|
|
54
55
|
},
|
|
55
56
|
"peerDependencies": {
|
|
56
57
|
"@synerise/ds-core": "*",
|
|
@@ -63,5 +64,5 @@
|
|
|
63
64
|
"monaco-editor": "0.34.1",
|
|
64
65
|
"vitest": "4"
|
|
65
66
|
},
|
|
66
|
-
"gitHead": "
|
|
67
|
+
"gitHead": "d0a43cc43d8528a36f105aceea52ab470edb71d9"
|
|
67
68
|
}
|