mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-11 05:38:34 +00:00
allow any web component to become a widget
This commit is contained in:
parent
29dab578e7
commit
82c4926f19
@ -1,18 +1,14 @@
|
||||
export * from './Claviature.jsx';
|
||||
import { Pattern } from '@strudel/core';
|
||||
import { registerWidget } from '@strudel/transpiler';
|
||||
|
||||
Pattern.prototype.claviature = function (options = {}) {
|
||||
if (!window.claviature) {
|
||||
window.claviature = document.createElement('strudel-claviature');
|
||||
window.claviature.style.position = 'absolute';
|
||||
window.claviature.style.bottom = 0;
|
||||
window.claviature.style.left = 0;
|
||||
document.body.append(window.claviature);
|
||||
}
|
||||
registerWidget('claviature', 'strudel-claviature');
|
||||
|
||||
Pattern.prototype.claviature = function (id, options = {}) {
|
||||
return this.onFrame((haps) => {
|
||||
const keys = haps.map((h) => h.value.note);
|
||||
// console.log('keys',keys);
|
||||
window.claviature.setAttribute(
|
||||
let el = document.getElementById(id);
|
||||
el?.setAttribute(
|
||||
'options',
|
||||
JSON.stringify({
|
||||
...options,
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
"homepage": "https://github.com/tidalcycles/strudel#readme",
|
||||
"dependencies": {
|
||||
"@strudel/core": "workspace:*",
|
||||
"@strudel/transpiler": "workspace:*",
|
||||
"claviature": "^0.1.0",
|
||||
"solid-element": "^1.8.0",
|
||||
"solid-js": "^1.8.15",
|
||||
|
||||
@ -1,27 +1,7 @@
|
||||
import { StateEffect, StateField } from '@codemirror/state';
|
||||
import { Decoration, EditorView, WidgetType } from '@codemirror/view';
|
||||
import { Pattern } from '@strudel/core';
|
||||
|
||||
const getWidgetID = (from) => `ui_${from}`;
|
||||
|
||||
Pattern.prototype.ui = function (id, value) {
|
||||
// TODO: make this work with any web component
|
||||
return this.onFrame((haps) => {
|
||||
let el = document.getElementById(id);
|
||||
if (el) {
|
||||
let options = {};
|
||||
const keys = haps.map((h) => h.value.note);
|
||||
el.setAttribute(
|
||||
'options',
|
||||
JSON.stringify({
|
||||
...options,
|
||||
range: options.range || ['A2', 'C6'],
|
||||
colorize: [{ keys: keys, color: options.color || 'steelblue' }],
|
||||
}),
|
||||
);
|
||||
}
|
||||
});
|
||||
};
|
||||
const getWidgetID = (from) => `widget_${from}`;
|
||||
|
||||
export const addWidget = StateEffect.define({
|
||||
map: ({ from, to }, change) => {
|
||||
@ -33,10 +13,10 @@ export const updateWidgets = (view, widgets) => {
|
||||
view.dispatch({ effects: addWidget.of(widgets) });
|
||||
};
|
||||
|
||||
function getWidgets(widgetConfigs, view) {
|
||||
return widgetConfigs.map(({ from, to }) => {
|
||||
function getWidgets(widgetConfigs) {
|
||||
return widgetConfigs.map(({ to, type }) => {
|
||||
return Decoration.widget({
|
||||
widget: new BlockWidget(view, from),
|
||||
widget: new BlockWidget(to, type),
|
||||
side: 0,
|
||||
block: true,
|
||||
}).range(to);
|
||||
@ -69,20 +49,19 @@ const widgetField = StateField.define(
|
||||
);
|
||||
|
||||
export class BlockWidget extends WidgetType {
|
||||
constructor(view, from) {
|
||||
constructor(col, type) {
|
||||
super();
|
||||
this.view = view;
|
||||
this.from = from;
|
||||
this.col = col;
|
||||
this.type = type;
|
||||
}
|
||||
eq() {
|
||||
return true;
|
||||
}
|
||||
toDOM() {
|
||||
const id = getWidgetID(this.from); // matches id generated in transpiler
|
||||
const id = getWidgetID(this.col); // matches id generated in transpiler
|
||||
let el = document.getElementById(id);
|
||||
if (!el) {
|
||||
// TODO: make this work with any web component
|
||||
el = document.createElement('strudel-claviature');
|
||||
el = document.createElement(this.type);
|
||||
el.id = id;
|
||||
}
|
||||
return el;
|
||||
|
||||
@ -3,6 +3,18 @@ import { parse } from 'acorn';
|
||||
import escodegen from 'escodegen';
|
||||
import { walk } from 'estree-walker';
|
||||
|
||||
let widgetComponents = {};
|
||||
// this function allows registering a pattern method name and component name
|
||||
// e.g. register('claviature', 'strudel-claviature')
|
||||
// .. will map the Pattern method 'claviature' to the web component 'strudel-claviature'
|
||||
// the transpiler will turn .claviature(...args) into .claviature(id, ...args)
|
||||
// the widgetPlugin of @strudel/codemirror will automatically create an instance of 'strudel-claviature'
|
||||
// .. so you only have to implement the actual .claviature method (or what you've called it..)
|
||||
|
||||
export function registerWidget(name, tagName) {
|
||||
widgetComponents[name] = tagName;
|
||||
}
|
||||
|
||||
export function transpiler(input, options = {}) {
|
||||
const { wrapAsync = false, addReturn = true, emitMiniLocations = true, emitWidgets = true } = options;
|
||||
|
||||
@ -47,12 +59,11 @@ export function transpiler(input, options = {}) {
|
||||
});
|
||||
return this.replace(sliderWithLocation(node));
|
||||
}
|
||||
if (isUIFunction(node)) {
|
||||
if (isWidgetMethod(node)) {
|
||||
emitWidgets &&
|
||||
widgets.push({
|
||||
from: node.arguments[0].start,
|
||||
to: node.end,
|
||||
type: node.arguments[0].value,
|
||||
type: widgetComponents[node.callee.property.name],
|
||||
});
|
||||
return this.replace(widgetWithLocation(node));
|
||||
}
|
||||
@ -119,8 +130,8 @@ function isSliderFunction(node) {
|
||||
return node.type === 'CallExpression' && node.callee.name === 'slider';
|
||||
}
|
||||
|
||||
function isUIFunction(node) {
|
||||
return node.type === 'CallExpression' && node.callee.property?.name === 'ui';
|
||||
function isWidgetMethod(node) {
|
||||
return node.type === 'CallExpression' && Object.keys(widgetComponents).includes(node.callee.property?.name);
|
||||
}
|
||||
|
||||
function sliderWithLocation(node) {
|
||||
@ -137,7 +148,7 @@ function sliderWithLocation(node) {
|
||||
}
|
||||
|
||||
function widgetWithLocation(node) {
|
||||
const id = 'ui_' + node.arguments[0].start; // use loc of first arg for id
|
||||
const id = 'widget_' + node.end;
|
||||
// add loc as identifier to first argument
|
||||
// the sliderWithID function is assumed to be sliderWithID(id, value, min?, max?)
|
||||
node.arguments.unshift({
|
||||
|
||||
3
pnpm-lock.yaml
generated
3
pnpm-lock.yaml
generated
@ -145,6 +145,9 @@ importers:
|
||||
'@strudel/core':
|
||||
specifier: workspace:*
|
||||
version: link:../core
|
||||
'@strudel/transpiler':
|
||||
specifier: workspace:*
|
||||
version: link:../transpiler
|
||||
claviature:
|
||||
specifier: ^0.1.0
|
||||
version: 0.1.0
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user