<script setup>
import { ref } from 'vue'
import Modal from './Modal.vue'
const openByRef = ref(false)
setTimeout(() => {
  openByRef.value = true
}, 2000)
</script>
<template>
  <Modal v-model="openByRef">
    <template #buttons="slotProps">
      inner state: {{ slotProps.opened }} <br />
      outer state: {{ openByRef }} <br /><br />
      <button @click="slotProps.open()">open</button> | 
      <button @click="slotProps.close()">close</button>
  
      <br /><br />
    </template>
    <template #default="slotProps">
      OBSAH MODALU
    </template>
  </Modal>
</template>
                                 
                                 
                        Original source: https://michaelnthiessen.com/12-design-patterns-vue
<?php
// rest ... a,b,c,d,e => []
function concatenate($transform, ...$strings) {
  $string = '';
  foreach($strings as $piece) {
    $string .= $piece;
  }
  return($transform($string));
}
echo concatenate("strtoupper", "I'm ", 20 + 2, " years", " old."); // I'M 22 YEARS OLD.
// spread ... []
function add($a, $b, $c) {
    return $a + $b + $c;
}
$operators = [2, 3];
echo add(1, ...$operators); // 6
                                 
                                 
                        enum Direction {
  Up,
  Down,
  Left,
  Right
}
const Colors = Object.freeze({
    RED:   Symbol("red"),
    BLUE:  Symbol("blue"),
    GREEN: Symbol("green")
});
/**
 * Enum for common colors.
 * @readonly
 * @enum {{name: string, hex: string}}
 */
const Colors = Object.freeze({
  RED:   { name: "red", hex: "#f00" },
  BLUE:  { name: "blue", hex: "#00f" },
  GREEN: { name: "green", hex: "#0f0" }
});
function createEnum(values) {
  const enumObject = {};
  for (const val of values) {
    enumObject[val] = val;
  }
  return Object.freeze(enumObject);
}
// { Up: 'Up', Down: 'Down', Left: 'Left', Right: 'Right' }
createEnum(['Up', 'Down', 'Left', 'Right']);
class Direction {
  static Up = new Direction('Up');
  static Down = new Direction('Down');
  static Left = new Direction('Left');
  static Right = new Direction('Right');
  constructor(name) {
    this.name = name;
  }
  toString() {
    return `Direction.${this.name}`;
  }
}
                                 
                                 
                        const toggle = (...list) => 
{
    // To track the cycle.
    let current = -1;
    const length = list.length;
    return function () 
    {
        // Increment current and used modulo to cycle back to the start.
        current = (current + 1) % length;
        // Returing the current element.
        return list[current];
    };
};
const toggleFunction = toggle("ON","OF");
console.log(toggleFunction()); // Prints "ON"
console.log(toggleFunction()); // Prints "OF"
console.log(toggleFunction()); // Prints "ON"
                                 
                                 
                        // https://javascript.plainenglish.io/structuredclone-the-easiest-way-to-deep-clone-objects-in-javascript-c503b536266b
const testData = {
  number: 123,
  string: "test",
  undefined: undefined,
  null: null,
  boolean: true,
  object: { a: 1, b: { c: 2 } },
  array: [1, 2, { d: 3 }],
  // function: function() { return "hello"; },
  map: new Map([["key1", "value1"], ["key2", "value2"]]),
  set: new Set([1, 2, 3]),
  date: new Date(),
  error: new Error("An error occurred"),
  regex: /test/i,
  // domNode: document.createElement("div")
}
const structuredCloneResult = structuredClone(testData)
console.log(structuredCloneResult)
/*
{
  number: 123,
  string: "test",
  undefined: undefined,
  null: null,
  boolean: true,
  object: { a: 1, b: { c: 2 } },
  array: [1, 2, { d: 3 }],
  function: undefined, // Functions are not cloned
  map: Map { 'key1' => 'value1', 'key2' => 'value2' },
  set: Set { 1, 2, 3 },
  date: 2023-05-23T09:00:00.000Z,
  error: Error: An error occurred,
  regex: /test/i,
  domNode: undefined // DOM nodes are not cloned
}
*/
                                 
                                 
                        DELETE FROM your_table
WHERE rowid NOT IN (
    SELECT MAX(rowid)
    FROM your_table
    GROUP BY column1, column2, ...
);
                                 
                                 
                        import { ref } from 'vue'
// keep track of component to render
const component = ref();
// keep track of whether to show modal
const show = ref(false);
export function useModal() {
    return {
        component,
        show,
        // methods to show/hide modal
        showModal: () => show.value = true,
        hideModal: () => show.value = false,
    }
}
                                 
                                 
                        /* eslint-disable no-unused-vars */
import { ref, readonly } from 'vue'
const stepsMax = {
  parts: 16,
  weight: 7
}
const selected = {
  type: null,
  amount: null
}
const amount = ref(0)
let step = 0
const calcMethods = {
  increaseWeight: () => {
    if (step >= stepsMax[selected.type]) {
      return
    }
    amount.value *= 2
    step++
  },
  decreaseWeight: () => {
    if (amount.value <= selected.amount) {
      return
    }
    amount.value /= 2
    step--
  },
  increaseParts: () => {
    if (step >= stepsMax[selected.type]) {
      return
    }
    amount.value++
    step++
  },
  decreaseParts: () => {
    if (amount.value <= 1) {
      return
    }
    amount.value--
    step--
  }
}
const increase = () => {
  const fn = `increase${selected.type.charAt(0).toUpperCase() + selected.type.slice(1)}`
  calcMethods[fn]()
}
const decrease = () => {
  const fn = `decrease${selected.type.charAt(0).toUpperCase() + selected.type.slice(1)}`
  calcMethods[fn]()
}
/**
 * @param {string} type - The type of ratio, must be 'parts' or 'weight'.
 * @param {number} recipeAmount - The amount of ratio.
 * @returns {{ amount: Readonly<number>, increase: () => void, decrease: () => void }}
 */
export const useRecipeCalculator = (type, recipeAmount) => {
  selected.type = type
  selected.amount = recipeAmount
  amount.value = recipeAmount
  return {
    amount: readonly(amount),
    increase,
    decrease
  }
}