/ Gists

Gists

On gists

code.

code. #

const eventHandler = e => {
  const keyActions = {
    Escape: closeGallery,
    ArrowLeft: prevMedia,
    ArrowRight: nextMedia
  }
  if (e.key === 'ArrowLeft') {
    prevMedia()
  }
  if (e.key === 'ArrowRight') {
    nextMedia()
  }
}


const eventHandler = e => {
  const keyActions = {
    Escape: closeGallery,
    ArrowLeft: prevMedia,
    ArrowRight: nextMedia
  }

  keyActions[e.key]?.()
}

On gists

use cases - computed properties

Vue.js

shopping-cart.js #

<template>
  <div>
    <ul>
      <li v-for="item in cartItems" :key="item.id">
        {{ item.name }} - {{ item.price }} - Quantity: {{ item.quantity }}
      </li>
    </ul>
    <p>Total Price: {{ totalPrice }}</p>
    <p>Total Quantity: {{ totalQuantity }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      cartItems: [
        { id: 1, name: 'Item 1', price: 10, quantity: 2 },
        { id: 2, name: 'Item 2', price: 15, quantity: 1 },
        { id: 3, name: 'Item 3', price: 20, quantity: 3 }
      ]
    };
  },
  computed: {
    totalPrice() {
      return this.cartItems.reduce((total, item) => total + item.price * item.quantity, 0);
    },
    totalQuantity() {
      return this.cartItems.reduce((total, item) => total + item.quantity, 0);
    }
  }
};
</script>

On gists

code.js

code.js #

_

On gists

All events in javascript

JavaScript

code.js #

Object.keys(window).forEach(key => {
  if (/^on/.test(key)) {
    window.addEventListener(key.slice(2), event => {
      console.log(event);
    });
  }
});

On gists

Vývoj softwaru / refactoring

Popular ⭐ Refactoring

readme.txt #

Vývoj software je často o hledání správné rovnováhy mezi:
čistotou kódu vs. praktičností
přehledností vs. flexibilitou
striktními pravidly vs. pragmatickým přístupem
A jak jste správně poznamenal - je to neustálý proces učení a přizpůsobování. Co fungovalo včera, nemusí být nejlepší řešení zítra. A to je v pořádku!
Důležité je:
Dělat informovaná rozhodnutí
Nebát se změny, když je potřeba
Učit se z předchozích zkušeností
Zachovat si zdravý rozum a neupnout se na jeden přístup
Proto je tak důležité mít v týmu otevřenou diskusi o těchto věcech - přesně jako teď! 👍

On gists

Inert - really invisible (screen readers etc)

HTML

index.html #

<!--
The inert attribute completely disables interactivity.
Screen readers and keyboard navigation will ignore it.
It’s a cleaner, more semantic approach to managing hidden elements.
-->
<nav inert>
 <a href="#">Home</a>
  <a href="#">About</a>
  <a href="#">Contact</a>
</nav>

On gists

Centered last row with flex / grid

CSS CSS trick

grid.html #

<!--
https://codepen.io/kevinpowell/pen/OJaBNQE
-->

<div class="grid">
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>

  <div class="grid-item offset"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>
</div>



<style>
 .grid {
  margin: 2rem auto;
  max-width: 900px;
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(8, 1fr);
}

.grid-item {
  padding: 2rem;
  background: lightblue;
  border: 4px solid royalblue;

  grid-column: span 2;
}

.offset {
  grid-column: 2 / span 2;
}
</style>

On gists

Share data among browser tabs

JavaScript

share.js #

/*
  https://javascript.plainenglish.io/3-powerful-ways-to-share-data-across-browser-tabs-in-javascript-a6a98dffa1a3
*/

// 1. local storage
// Sender
localStorage.setItem('sharedData', JSON.stringify({
  message: 'Hello from Tab1!',
  timestamp: Date.now()
}));

// Receiver
window.addEventListener('storage', (e) => {
  if(e.key === 'sharedData') {
    const data = JSON.parse(e.newValue);
    console.log('Received data:', data);
  }
});


// 2.  BroadcastChannel API 
// Create a channel (use the same channel name across all tabs)
const channel = new BroadcastChannel('app-channel');

// Send a message
channel.postMessage({
  type: 'USER_UPDATE',
  payload: { name: 'John' }
});
// Receive messages
channel.onmessage = (e) => {
  console.log('Received broadcast:', e.data);
};
// Close the connection
window.onunload = () => channel.close();



// 3.SharedWorker Shared Thread
// shared-worker.js
let ports = [];
onconnect = (e) => {
  const port = e.ports[0];
  ports.push(port);

  port.onmessage = (e) => {
    // Broadcast to all connected pages
    ports.forEach(p => {
      if(p !== port) p.postMessage(e.data);
    });
  };
};
// Page code
const worker = new SharedWorker('shared-worker.js');
worker.port.start();
// Send a message
worker.port.postMessage('Message from Tab A');
// Receive messages
worker.port.onmessage = (e) => {
  console.log('Shared thread message:', e.data);
};

On gists

Javascript Safe Assignment Operator (?=)

JavaScript

examples.js #

// https://devsmitra.medium.com/javascript-error-handling-just-got-a-whole-lot-easier-meet-the-safe-assignment-operator-c372d892d4ed

// without
async function getData() {
  try {
    const response = await fetch("https://api.example.com/data");
    const json = await response.json();
    return validationSchema.parse(json);
  } catch (error) {
    handleError(error);
  }
}


// with
async function getData() {
  const [fetchError, response]?= await fetch("https://api.example.com/data");
  if (fetchError) return handleFetchError(fetchError);

  const [jsonError, json]?= await response.json();
  if (jsonError) return handleJsonError(jsonError);

  const [validationError, data]?= validationSchema.parse(json);
  if (validationError) return handleValidationError(validationError);

  return data;
}

On gists

Component props stealing

Vue.js

demo.js #

// my version - inspired by https://michaelnthiessen.com/stealing-prop-types/

// iconDefault.js
export const iconDefaults = {
  size: 'medium',
  shape: 'circle',
  icon: 'default',
  animation: 'none'
};


<!-- Icon.vue -->
<script setup>
import { iconDefaults } from './iconDefaults.js';

const props = defineProps({
  size: { type: String, default: iconDefaults.size },
  shape: { type: String, default: iconDefaults.shape },
  icon: { type: String, default: iconDefaults.icon },
  animation: { type: String, default: iconDefaults.animation }
});
</script>

<!-- Panel.vue -->
<script setup>
import Icon from './Icon.vue';
import { iconDefaults } from './iconDefaults.js';
import { computed } from 'vue';

const props = defineProps({
  heading: String,
  withIcons: Boolean,
  iconConfig: {
    type: Object,
    default: () => ({ ...iconDefaults })
  }
});

const finalIconConfig = computed(() => {
  return { ...iconDefaults, ...props.iconConfig };
});
</script>