Skip to content

Instantly share code, notes, and snippets.

View vdsabev's full-sized avatar

Vlad Sabev vdsabev

View GitHub Profile
@vdsabev
vdsabev / reactive.js
Last active October 15, 2023 05:58
Vue's `reactive` in React
const useReactive = (object, dependencies = []) => {
const [_, setState] = useState(0);
return useMemo(
() => toReactive(object, () => setState((state) => state + 1)),
dependencies
);
};
const toReactive = (object, callback) => {
if (!object || typeof object !== 'object') return object;
@vdsabev
vdsabev / lob-scripting.html
Last active October 6, 2023 12:32
Locality of Behavior scripting
<!DOCTYPE html>
<html>
<head>
<title>LoB Scripting</title>
</head>
<body>
<template id="hello">
<h1></h1>
<select>
@vdsabev
vdsabev / css-scope-inline.js
Created September 9, 2023 12:40
Modified css-scope-inline
// Original: https://github.com/gnat/css-scope-inline
// Modified: https://gist.github.com/Gyanreyer/a9d5fe8b91055ea4dc302c1d0ff17452
(() => {
let cssScopeCount = 0;
const scopedSelectorRegex = new RegExp('(:scope)(?![A-Za-z0-9_-])', 'g');
/** @returns {Node[]} */
const getAllChildNodes = (/** @type {NodeList} */ childNodes) =>
[...childNodes].flatMap((childNode) => [
childNode,
@vdsabev
vdsabev / mutagen.html
Last active October 6, 2023 13:01
Mutagen - a mini templating engine based on htmx and Mutation Observer
<!DOCTYPE html>
<html>
<head>
<script src="/mutagen.js"></script>
</head>
<body>
<mg-component src="/profile.html" data='{ "user": { "name": "John Doe", "pictureUrl": "https://placehold.co/128" } }' />
</body>
</html>
describe('Counter', () => {
...
it('should emit value incremented by step', async () => {
await component.setProps({ step: 10 });
component.vm.increment();
expect(component.emitted('input')).toEqual([[10]]);
});
it('should emit value decremented by step', async () => {
import { mount } from '@vue/test-utils';
import Counter from './Counter';
describe('Counter', () => {
let component;
beforeEach(() => {
component = mount(Counter);
});
it('should emit value set to a specific number', async () => {
<template>
<div>
<button type="button" @click="decrement">-</button>
<input type="text" :value="value" @input="setValue" /> <!-- we removed the argument here -->
<button type="button" @click="increment">+</button>
</div>
</template>
<template>
<div>
<button type="button" @click="decrement" aria-label="Decrement">-</button>
<input type="text" :value="value" @input="setValue($event.target.value)" />
<button type="button" @click="increment" aria-label="Increment">+</button>
</div>
</template>
<template>
<div>
<button type="button" @click="decrement">-</button> <!-- we removed the argument here -->
<input type="text" :value="value" @input="setValue($event.target.value)" />
<button type="button" @click="increment">+</button> <!-- we removed the argument here -->
</div>
</template>
<script>
export default {
import { mount } from '@vue/test-utils';
import Counter from './Counter';
describe('Counter', () => {
let component;
beforeEach(() => {
component = mount(Counter);
});
it('should emit value set to a specific number', () => {