@awcrotwell/motion
Version:
Motion allows you to build reactive, real-time frontend UI components in your Amber application using pure Crystal that are reusable, testable & encapsulated. For brevity, we will call them MotionComponents.
54 lines (53 loc) • 1.55 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.MODE_HANDLE = exports.MODE_LISTEN = void 0;
const identifier = '[^\\s\\(\\)]+';
const binding = `((${identifier})(\\((${identifier})\\))?->)?(${identifier})`;
const regExp = new RegExp(binding, 'g');
const captureIndicies = {
id: 0,
event: 2,
mode: 4,
motion: 5,
};
exports.MODE_LISTEN = 'listen';
exports.MODE_HANDLE = 'handle';
const DEFAULT_EVENT = {
_other: 'click',
FORM: 'submit',
INPUT: ({ type }) => (type === 'submit' ? 'click' : 'change'),
SELECT: 'change',
TEXTAREA: 'change',
};
const DEFAULT_MODE = {
_other: exports.MODE_HANDLE,
change: exports.MODE_LISTEN,
};
function parseBindings(input, element) {
if (!input) {
return [];
}
return Array.from(input.matchAll(regExp), (match) => {
const id = match[captureIndicies.id];
const motion = match[captureIndicies.motion];
const event = match[captureIndicies.event] || defaultEventFor(element);
const mode = match[captureIndicies.mode] || defaultModeFor(event);
return {
id,
motion,
event,
mode,
};
});
}
exports.default = parseBindings;
function defaultEventFor(element) {
const event = DEFAULT_EVENT[element && element.tagName] || DEFAULT_EVENT._other;
if (typeof event === 'function') {
return event(element);
}
return event;
}
function defaultModeFor(event) {
return DEFAULT_MODE[event] || DEFAULT_MODE._other;
}