Skip to content
Open
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
2 changes: 1 addition & 1 deletion apps/jaspr_pad/lib/adapters/html.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ import 'package:jaspr/jaspr.dart';

@Import.onWeb(
'dart:html',
show: [#window, #document, #HtmlDocument, #Element, #CustomEvent, #MouseEvent, #Event, #InputElement],
show: [#window, #document, #HtmlDocument, #Element, #CustomEvent, #MouseEvent, #KeyboardEvent, #Event, #InputElement],
)
export 'html.imports.dart';
2 changes: 2 additions & 0 deletions apps/jaspr_pad/lib/adapters/html.imports.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ export '../generated/imports/_web.dart'
CustomEventOrStubbed,
MouseEvent,
MouseEventOrStubbed,
KeyboardEvent,
KeyboardEventOrStubbed,
Event,
EventOrStubbed,
InputElement,
Expand Down
26 changes: 26 additions & 0 deletions apps/jaspr_pad/lib/components/playground/editing/editor.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import 'package:collection/collection.dart';
import 'package:jaspr/dom.dart' hide Position;
import 'package:jaspr/jaspr.dart';
import 'package:jaspr_riverpod/jaspr_riverpod.dart';

import '../../../adapters/html.dart';
import '../../../models/api_models.dart';
import '../../../providers/settings_provider.dart';
import '../../utils/node_reader.dart';
import 'codemirror_options.dart';
@Import.onWeb('package:codemirror/codemirror.dart', show: [#CodeMirror, #Doc, #Position])
Expand Down Expand Up @@ -43,13 +45,28 @@ class EditorState extends State<Editor> {

Map<String, DocOrStubbed> docs = {};

ProviderSubscription<String>? _keyMapSub;

@override
void initState() {
super.initState();
docs = {
for (var doc in component.documents) //
doc.key: createDoc(doc.key, doc.source, doc.mode),
};

// Listen for keymap changes
_keyMapSub = context.listenManual<String>(keyMapProvider, (_, keyMap) {
if (kIsWeb && _editor != null) {
_editor!.setKeyMap(keyMap);
}
});
}

@override
void dispose() {
_keyMapSub?.close();
super.dispose();
}

void createEditor(ElementOrStubbed node) {
Expand All @@ -59,6 +76,15 @@ class EditorState extends State<Editor> {
_editor?.dispose();
_editorElement = node;
_editor = CodeMirror.fromElement(_editorElement!, options: codeMirrorOptions);

// Apply current keymap after editor creation
if (kIsWeb) {
final keyMap = context.read(keyMapProvider);
if (keyMap != 'default') {
_editor!.setKeyMap(keyMap);
}
}

if (component.activeDoc != null) {
Future.microtask(() => _editor!.swapDoc(docs[component.activeDoc!]!));
}
Expand Down
25 changes: 19 additions & 6 deletions apps/jaspr_pad/lib/components/playground/footer.dart
Original file line number Diff line number Diff line change
@@ -1,18 +1,31 @@
import 'package:jaspr/dom.dart';
import 'package:jaspr/jaspr.dart';
import 'package:jaspr_riverpod/jaspr_riverpod.dart';

import '../../providers/settings_provider.dart';

class PlaygroundFooter extends StatelessComponent {
const PlaygroundFooter({super.key});

@override
Component build(BuildContext context) {
return footer([
// i(
// id: 'keyboard-button',
// classes: ['material-icons', 'footer-item'],
// attributes: {'aria-hidden': 'true'},
// [text('keyboard')],
// ),
Builder(builder: (context) {
final isVim = context.watch(keyMapProvider) == 'vim';
return i(
id: 'keyboard-button',
classes: 'material-icons footer-item',
styles: isVim ? Styles(raw: {'color': '#4CAF50'}) : null,
attributes: {
'aria-hidden': 'true',
'title': isVim ? 'Vim mode enabled (Cmd+Shift+/ to toggle)' : 'Enable vim mode (Cmd+Shift+/ to toggle)',
},
events: {
'click': (_) => toggleVimMode(context),
},
[.text('keyboard')],
);
}),
div(classes: 'footer-item', [
a(href: 'https://docs.jaspr.site', target: Target.blank, classes: 'footer-item', [.text('Jaspr Docs')]),
a(href: 'https://discord.gg/XGXrGEk4c6', target: Target.blank, classes: 'footer-item', [
Expand Down
10 changes: 10 additions & 0 deletions apps/jaspr_pad/lib/components/playground/playground.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import 'package:jaspr/jaspr.dart';
import 'package:jaspr_riverpod/jaspr_riverpod.dart';

import '../../adapters/html.dart';
import '../../providers/logic_provider.dart';
import '../../providers/project_provider.dart';
import '../../providers/settings_provider.dart';
import '../elements/dialog.dart';
import 'footer.dart';
import 'header.dart';
Expand All @@ -19,6 +21,14 @@ class Playground extends StatelessComponent {
Future(() => context.read(logicProvider).compileFiles());
}
}, fireImmediately: true);

// Global keyboard shortcut for vim toggle (Cmd/Ctrl+Shift+/)
document.onKeyDown.listen((event) {
if ((event.metaKey || event.ctrlKey) && event.shiftKey && event.key == '/') {
event.preventDefault();
toggleVimMode(context);
}
});
}

return .fragment([PlaygroundHeader(), MainSection(), PlaygroundFooter(), DialogSlot(slotId: 'dialog')]);
Expand Down
2 changes: 2 additions & 0 deletions apps/jaspr_pad/lib/generated/imports/_stubs.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ dynamic CustomEvent;
typedef CustomEventOrStubbed = dynamic;
dynamic MouseEvent;
typedef MouseEventOrStubbed = dynamic;
dynamic KeyboardEvent;
typedef KeyboardEventOrStubbed = dynamic;
dynamic Event;
typedef EventOrStubbed = dynamic;
dynamic InputElement;
Expand Down
3 changes: 3 additions & 0 deletions apps/jaspr_pad/lib/generated/imports/_web.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import 'dart:html'
Element,
CustomEvent,
MouseEvent,
KeyboardEvent,
Event,
InputElement,
IFrameElement,
Expand All @@ -35,6 +36,7 @@ export 'dart:html'
Element,
CustomEvent,
MouseEvent,
KeyboardEvent,
Event,
InputElement,
IFrameElement,
Expand All @@ -59,6 +61,7 @@ typedef EventOrStubbed = Event;
typedef HtmlDocumentOrStubbed = HtmlDocument;
typedef IFrameElementOrStubbed = IFrameElement;
typedef InputElementOrStubbed = InputElement;
typedef KeyboardEventOrStubbed = KeyboardEvent;
typedef MDCDialogOrStubbed = MDCDialog;
typedef MDCMenuOrStubbed = MDCMenu;
typedef MDCRippleOrStubbed = MDCRipple;
Expand Down
1 change: 1 addition & 0 deletions apps/jaspr_pad/lib/models/api_models.mapper.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions apps/jaspr_pad/lib/models/gist.mapper.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions apps/jaspr_pad/lib/models/project.mapper.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions apps/jaspr_pad/lib/models/sample.mapper.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions apps/jaspr_pad/lib/models/tutorial.mapper.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 23 additions & 0 deletions apps/jaspr_pad/lib/providers/settings_provider.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import 'package:jaspr/jaspr.dart';
import 'package:jaspr_riverpod/jaspr_riverpod.dart';
import 'package:jaspr_riverpod/legacy.dart';

import '../adapters/html.dart';

/// Editor keymap setting. Valid values: 'default', 'vim', 'emacs', 'sublime'
final keyMapProvider = StateProvider<String>((ref) {
if (kIsWeb) {
return window.localStorage['editorKeyMap'] ?? 'default';
}
return 'default';
});

/// Updates keymap and persists to localStorage
void toggleVimMode(BuildContext context) {
final current = context.read(keyMapProvider);
final next = current == 'vim' ? 'default' : 'vim';
context.read(keyMapProvider.notifier).state = next;
if (kIsWeb) {
window.localStorage['editorKeyMap'] = next;
}
}
1 change: 1 addition & 0 deletions apps/jaspr_pad/web/main.template.html
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
<!-- codemirror -->
<link href="./packages/codemirror/css/codemirror.css" rel="stylesheet" media="screen">
<script src="./packages/codemirror/codemirror.js" defer></script>
<script src="./packages/codemirror/keymap/vim.js" defer></script>

<!-- codemirror themes -->
<link href="./styles/cm-scrollbars.css" rel="stylesheet" media="screen">
Expand Down