@wener/console
Version:
Base console UI toolkit
111 lines (110 loc) • 4.63 kB
JavaScript
import React, { memo, useCallback, useDebugValue, useEffect, useId } from "react";
import { useCompareEffect } from "@wener/reaction";
import { createStore } from "zustand";
import { immer } from "zustand/middleware/immer";
import { shallow } from "zustand/shallow";
import { createStoreContext } from "../../zustand/index.js";
var createSlotStore = function () {
return createStore()(immer(function () {
return {
slots: {}
};
}));
};
export function createSlotContext() {
var _createStoreContext = createStoreContext(), Provider = _createStoreContext.Provider, useStore = _createStoreContext.useStore, useStoreApi = _createStoreContext.useStoreApi;
var SlotProvider = function (param) {
var children = param.children;
return /*#__PURE__*/ React.createElement(Provider, {
createStore: createSlotStore
}, children);
};
var Slot = /*#__PURE__*/ memo(function (param) {
var name = param.name, _param_placement = param.placement, placement = _param_placement === void 0 ? "default" : _param_placement, _param_order = param.order, order = _param_order === void 0 ? 0 : _param_order, children = param.children;
var api = useStoreApi();
var slotId = useId();
placement || (placement = "default");
order || (order = 0);
var slotPlace = "".concat(name, "/").concat(placement);
useCompareEffect(function () {
// wrap children with key
api.setState(function (s) {
var _s_slots;
var _slotPlace;
var slots = (_s_slots = s.slots)[_slotPlace = slotPlace] || (_s_slots[_slotPlace] = []);
var slot = slots.find(function (v) {
return v.id === slotId;
});
if (slot) {
Object.assign(slot, {
name: name,
placement: placement,
order: order,
children: children
});
}
else {
slots.push({
id: slotId,
name: name,
placement: placement,
order: order,
children: children
});
}
slots.sort(function (a, b) {
return b.order - a.order;
});
});
}, [
slotPlace,
order,
children
]);
useEffect(function () {
return function () {
api.setState(function (s) {
var _s_slots_slotPlace;
s.slots[slotPlace] = (_s_slots_slotPlace = s.slots[slotPlace]) === null || _s_slots_slotPlace === void 0 ? void 0 : _s_slots_slotPlace.filter(function (v) {
return v.id !== slotId;
});
});
};
}, []);
useDebugValue("Slot ".concat(slotPlace, "@{").concat(slotId));
return null;
});
Slot.displayName = "Slot";
function useSlot(param) {
var name = param.name, placement = param.placement;
var slotPlace = "".concat(name, "/").concat(placement || "default");
return useStore(useCallback(function (s) {
return s.slots[slotPlace] || [];
}, [
slotPlace
]), shallow);
}
var SlotPlaceholder = /*#__PURE__*/ memo(function (param) {
var name = param.name, placement = param.placement, placeholder = param.placeholder;
var slotPlace = "".concat(name, "/").concat(placement || "default");
var slot = useStore(useCallback(function (s) {
return s.slots[slotPlace] || [];
}, [
slotPlace
]), shallow);
useDebugValue("SlotPlaceholder ".concat(name).concat(placement ? "@".concat(placement) : ""));
var children = slot.length ? slot.map(function (v) {
return v.children;
}) : placeholder;
return /*#__PURE__*/ React.createElement(React.Fragment, null, children);
});
SlotPlaceholder.displayName = "SlotPlaceholder";
return {
Slot: Slot,
useSlot: useSlot,
SlotPlaceholder: SlotPlaceholder,
SlotProvider: SlotProvider
};
}
var _createSlotContext = createSlotContext();
export var Slot = _createSlotContext.Slot, SlotPlaceholder = _createSlotContext.SlotPlaceholder, SlotProvider = _createSlotContext.SlotProvider, useSlot = _createSlotContext.useSlot;