Skip to content

Commit dece15d

Browse files
committed
feat(code-editor): add disabled prop
1 parent 027fbe7 commit dece15d

File tree

2 files changed

+65
-2
lines changed

2 files changed

+65
-2
lines changed

etc/lime-elements.api.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ export namespace Components {
306306
// (undocumented)
307307
export interface LimelCodeEditor {
308308
"colorScheme": ColorScheme;
309+
"disabled": boolean;
309310
"fold": boolean;
310311
"language": Language;
311312
"lineNumbers": boolean;
@@ -1476,6 +1477,7 @@ export namespace JSX {
14761477
// (undocumented)
14771478
export interface LimelCodeEditor {
14781479
"colorScheme"?: ColorScheme;
1480+
"disabled"?: boolean;
14791481
"fold"?: boolean;
14801482
"language"?: Language;
14811483
"lineNumbers"?: boolean;

src/components/code-editor/code-editor.tsx

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,15 @@ export class CodeEditor {
5555
@Prop({ reflect: true })
5656
public readonly = false;
5757

58+
/**
59+
* Set to `true` to disable the editor.
60+
* Use `disabled` to indicate that the editor can normally be interacted
61+
* with, but is currently disabled. This tells the user that if certain
62+
* requirements are met, the editor may become enabled again.
63+
*/
64+
@Prop({ reflect: true })
65+
public disabled = false;
66+
5867
/**
5968
* Displays line numbers in the editor
6069
*/
@@ -150,6 +159,18 @@ export class CodeEditor {
150159
this.editor.getDoc().setValue(newValue || '');
151160
}
152161

162+
@Watch('disabled')
163+
protected watchDisabled() {
164+
this.updateEditorReadOnlyState();
165+
this.updateInputFieldAccessibilityAttributes();
166+
}
167+
168+
@Watch('readonly')
169+
protected watchReadonly() {
170+
this.updateEditorReadOnlyState();
171+
this.updateInputFieldAccessibilityAttributes();
172+
}
173+
153174
private handleChangeDarkMode = () => {
154175
if (this.colorScheme !== 'auto') {
155176
return;
@@ -230,7 +251,7 @@ export class CodeEditor {
230251
mode: mode,
231252
value: this.value || '',
232253
theme: theme,
233-
readOnly: this.readonly,
254+
readOnly: this.getReadOnlyOption(),
234255
tabSize: TAB_SIZE,
235256
indentUnit: TAB_SIZE,
236257
lineNumbers: this.lineNumbers,
@@ -255,7 +276,8 @@ export class CodeEditor {
255276
public render() {
256277
const classList = {
257278
editor: true,
258-
readonly: this.readonly,
279+
readonly: this.readonly || this.disabled,
280+
disabled: this.disabled,
259281
'is-dark-mode': this.isDarkMode(),
260282
'is-light-mode': !this.isDarkMode(),
261283
};
@@ -271,4 +293,43 @@ export class CodeEditor {
271293
private get darkMode(): MediaQueryList {
272294
return matchMedia('(prefers-color-scheme: dark)');
273295
}
296+
297+
private updateEditorReadOnlyState() {
298+
if (!this.editor) {
299+
return;
300+
}
301+
302+
this.editor.setOption('readOnly', this.getReadOnlyOption());
303+
}
304+
305+
private getReadOnlyOption(): boolean | 'nocursor' {
306+
if (this.disabled) {
307+
return 'nocursor';
308+
}
309+
310+
return this.readonly;
311+
}
312+
313+
private updateInputFieldAccessibilityAttributes() {
314+
if (!this.editor) {
315+
return;
316+
}
317+
318+
const inputField = this.editor.getInputField();
319+
if (!inputField) {
320+
return;
321+
}
322+
323+
if (this.disabled) {
324+
inputField.setAttribute('aria-disabled', 'true');
325+
} else {
326+
inputField.removeAttribute('aria-disabled');
327+
}
328+
329+
if (this.readonly || this.disabled) {
330+
inputField.setAttribute('aria-readonly', 'true');
331+
} else {
332+
inputField.removeAttribute('aria-readonly');
333+
}
334+
}
274335
}

0 commit comments

Comments
 (0)