Vue 3 composable to create a reactive Map to use as a small local database.
In memory by default, users can pass a custom map object to override that behavior.
The returned reactive Map is extended with ability to standardize custom key generation.
| export const formatFileSize = (bytes, fSExt = ['Bytes', 'KB', 'MB', 'GB']) => { | |
| // fSExt is an Array of unit labels | |
| let i = 0 // Index to track which unit to use | |
| while (bytes > 900) { // While the size is bigger than 900 in the current unit | |
| bytes /= 1024 // Convert to the next bigger unit | |
| i++ // Move to the next unit in the array | |
| } | |
| return (Math.round(bytes * 100) / 100) + ' ' + fSExt[i] // Round to 2 decimal places and append unit | |
| } |
| function roundTo(n, digits) { | |
| const factor = Math.pow(10, digits); | |
| return Math.round(n * factor) / factor; | |
| } | |
| // roundTo(3.14159, 3); // 3.142 | |
| // roundTo(3.14159, 2); // 3.14 | |
| // roundTo(3.14159, 1); // 3.1 | |
| // roundTo(3.14159, 0); // 3 |
| /* | |
| * Create a fully responsive column layout while defining the max width of the columns. | |
| * On small screens, columns width will be the min between 100% and the defined width. | |
| * | |
| * Add `--col-size` and / or `--col-size-*` variables to your tailwind theme for customization | |
| * Ex: | |
| * ``` | |
| * --col-size: 320px; | |
| * --col-size-xl: 448px; | |
| * --col-size-wathever: 1024px; |
| import { useStepper } from '@vueuse/core' | |
| import { ref, toValue } from 'vue' | |
| /** | |
| * A wrapper around VueUse's `useStepper` that adds async-aware navigation methods. | |
| * It tracks direction of navigation (forward/backward) and only transitions between steps | |
| * if the provided async action succeeds. | |
| * | |
| * The transition functions (`goXXX`) return a tuple `[success, error, result]`: | |
| * - `success`: Boolean indicating whether the async action succeeded. |
| // Types for the result object with discriminated union | |
| type Success<T> = { | |
| data: T; | |
| error: null; | |
| }; | |
| type Failure<E> = { | |
| data: null; | |
| error: E; | |
| }; |
| // auth middleware | |
| import { useAuthStore } from "@/stores/auth"; | |
| export default async function auth({ next }) { | |
| const authStore = useAuthStore(); | |
| const user = await authStore.checkAuth(); | |
| if (!( 'id' in user)) { | |
| console.log("Not logged in"); |
Reactive watcher to load effect scopes dynamically depending on the watched value. Typically, the effect scope you load is a function that contains reactive logic in the same way you would have in a component setup function.
Example use:
const watchSource = ref(...) // anything
| // Copied from this article https://kentcdodds.com/blog/implementing-a-simple-state-machine-library-in-javascript | |
| function createMachine(stateMachineDefinition) { | |
| const machine = { | |
| value: stateMachineDefinition.initialState, | |
| transition(currentState, event) { | |
| const currentStateDefinition = stateMachineDefinition[currentState] | |
| const destinationTransition = currentStateDefinition.transitions[event] | |
| if (!destinationTransition) { | |
| return | |
| } |
| <script lang="ts"> | |
| import { h, VNodeData, mergeProps, defineComponent } from 'vue' | |
| /** | |
| * Use this component to render raw SVG content | |
| * without the need to use the `v-html` directive | |
| * which requires a parent node in Vue (ex: `<div v-html="..."></div>`). | |
| * `<NSvgFragment :content="..." />` will directly render the svg tag with its content. | |
| * */ | |
| export default defineComponent({ |