Skip to content

Instantly share code, notes, and snippets.

View nanxiaobei's full-sized avatar

南小北 nanxiaobei

View GitHub Profile
@nanxiaobei
nanxiaobei / rollup-plugin-update.ts
Created September 16, 2023 20:08
rollup-plugin-update
import { OutputBundle, OutputChunk, OutputOptions, Plugin } from 'rollup';
const rollupPluginUpdate = (update: (code: string) => string): Plugin => {
function generateBundle(_: OutputOptions, bundle: OutputBundle) {
for (const fileName in bundle) {
const entryFile = bundle[fileName] as OutputChunk;
if (entryFile.isEntry) {
entryFile.code = update(entryFile.code);
}
}
@nanxiaobei
nanxiaobei / useControlValue.ts
Created July 14, 2022 08:55
同时处理受控和非受控组件
import { SetStateAction, useCallback, useReducer, useRef } from 'react';
// useControlValue
// 同时处理受控和非受控组件
// based on https://github.com/alibaba/hooks/blob/master/packages/hooks/src/useControllableValue/index.ts
function useControlValue<V = any>(props: Record<string, any> = {}) {
const isControlled = 'value' in props;
// value
@nanxiaobei
nanxiaobei / useDarkMode.ts
Last active July 14, 2022 08:56
returns isDark state, and a switch function for dark mode button
const useDarkMode = (): [boolean, () => void] => {
const [isDark, setIsDark] = useState(false);
const setDark = (newDark: boolean) => {
document.documentElement.classList[newDark ? 'add' : 'remove']('dark');
localStorage.setItem('dark', `${newDark}`);
setIsDark(newDark);
};
useEffect(() => {
@nanxiaobei
nanxiaobei / useControlState.ts
Last active October 21, 2022 05:48
同时处理受控与非受控组件,且内部 state 与 onChange 传出 value 不同步的 hook
import { SetStateAction, useCallback, useReducer, useRef } from 'react';
// useControlState
// 同时处理受控和非受控组件,但与 useControlValue 不同
// 本 hook 用于此种情况:内部 state 与 onChange 时传出 value 不同步 (如内部 state 情况复杂,超前于 value)
// 此时需同步 value -> state (若 props.value 变化),同时同步 state -> value (若 state 变化且需要传出)
function useControlState<S = any, V = any>({
props = {},
valueToState,
@nanxiaobei
nanxiaobei / MyPromise.js
Created October 29, 2021 20:18
MyPromise
class MyPromise {
constructor(fn) {
this.status = 'PENDING';
const resolve = (data) => {
if (this.status !== 'PENDING') return;
this.status = 'FULLFILLED';
this.value = data;
this.onChange?.();
@nanxiaobei
nanxiaobei / Scheduler.js
Last active August 30, 2021 10:12
Scheduler for limit Promises
class Scheduler {
constructor(limit) {
this.count = 0;
this.limit = limit;
this.list = [];
}
add(fn) {
return new Promise((resolve) => {
this.list.push((...args) => fn(...args).then(resolve));
this.run();
@nanxiaobei
nanxiaobei / ImageGallery.jsx
Created August 25, 2021 21:25
Image gallery with lazy load and dynamic list features
import React, { useEffect, useRef } from "react";
const ImageGallery = (props) => {
const {
type = "lazy-load",
list = [],
width = 300,
height = 300,
size = 3,
emitHeight = 150,
@nanxiaobei
nanxiaobei / chooseGeo.js
Last active April 18, 2024 19:54
小程序位置选择 wx.chooseLocation() 封装一劳永逸 QTMD 版
/**
* chooseGeo.js
*
* 小程序 wx.chooseLocation() 获取地理位置,会先请求授权,
* 如果用户未授权,那么再次调用,嗯 ... 就没反应了,还以为微信 API 有问题,崩溃了。
*
* 这当然是微信为了良好的用户体验,就不让你问了,
* 当然,开发的体验就非常不好了,因为这个 API 干了一半的活,罢工了,
* 然后,当然就得自己封装一个了。
*
@nanxiaobei
nanxiaobei / chain.js
Last active February 25, 2020 12:53
Inspired by optional chaining
const isObj = (val) => Object.prototype.toString.call(val) === '[object Object]';
const isArr = (val) => Array.isArray(val);
const isNum = (val) => val === `${+val}`;
const strToNum = (str) => (isNum(str) ? +str : str);
/**
* Used to change undefined keys to object or array, similar effect to the 'optional chaining'.
* Received an object and an array of keys, returns a formatted object.
*
* e.g.