@apple-pie/slice 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/chunks/Avatar-8-wPWe0V.js +68 -0
- package/dist/cjs/chunks/AvatarGroup-CVKmgBbD.js +39 -0
- package/dist/cjs/chunks/Badge-CMapJCij.js +41 -0
- package/dist/cjs/chunks/CheckBox-7AACxrdZ.js +76 -0
- package/dist/cjs/chunks/DivInput-BKKJTFeV.js +204 -0
- package/dist/cjs/chunks/DocIcons-BRWOzK96.js +41 -0
- package/dist/cjs/chunks/Dot-Dnr9M9na.js +80 -0
- package/dist/cjs/chunks/DrggablePanel-C6TPsDB-.js +302 -0
- package/dist/cjs/chunks/DropDown-D9sf_m2I.js +154 -0
- package/dist/cjs/chunks/EditorButtonBar-CUNDgRQd.js +244 -0
- package/dist/cjs/chunks/ErrorSummary-Dv44onsV.js +42 -0
- package/dist/cjs/chunks/FlexDiv-DZBpswHV.js +103 -0
- package/dist/cjs/chunks/Grouper-_kd2nU78.js +50 -0
- package/dist/cjs/chunks/IconButton-BfsPlKTb.js +84 -0
- package/dist/cjs/chunks/Logos-DSlAUz8l.js +119 -0
- package/dist/cjs/chunks/MessageInput-CiHFo2j8.js +399 -0
- package/dist/cjs/chunks/Overlay-DwCPvGB5.js +45 -0
- package/dist/cjs/chunks/Pager-CFtZ0IIW.js +42 -0
- package/dist/cjs/chunks/ProgressIndicator-C5oB7Mky.js +121 -0
- package/dist/cjs/chunks/RadioButton-e_y2qiPE.js +65 -0
- package/dist/cjs/chunks/RadioButtonList-I81UwHmM.js +116 -0
- package/dist/cjs/chunks/Slider-C-gn7Sby.js +285 -0
- package/dist/cjs/chunks/Spacer-BEY2-_PB.js +16 -0
- package/dist/cjs/chunks/Switch-CtkFtogd.js +43 -0
- package/dist/cjs/chunks/TabBar-D3bj4pjj.js +176 -0
- package/dist/cjs/chunks/TextArea-B1oKK3_b.js +153 -0
- package/dist/cjs/chunks/TextField-CiQdPP5E.js +248 -0
- package/dist/cjs/chunks/Tip-C2pzExut.js +91 -0
- package/dist/cjs/chunks/Toast-DrijUwoL.js +141 -0
- package/dist/cjs/chunks/UIButton-CH4p-8yq.js +317 -0
- package/dist/cjs/chunks/UIButtonBar-0fHPB0ww.js +58 -0
- package/dist/cjs/chunks/UICard-DBDSyT7E.js +36 -0
- package/dist/cjs/chunks/UIChip-kjhvRrOV.js +93 -0
- package/dist/cjs/chunks/UIFileIcon-ZrbDIeYz.js +54 -0
- package/dist/cjs/chunks/UILabel-DkBE2AIt.js +116 -0
- package/dist/cjs/chunks/_types-CoWzQFsT.js +714 -0
- package/dist/cjs/chunks/sharedTypes-BvTjh6M5.js +9 -0
- package/dist/cjs/chunks/style-inject.es-XZHJH68X.js +30 -0
- package/dist/cjs/chunks/tipStore-C9oV9SIh.js +23 -0
- package/dist/cjs/chunks/toastStore-C-ETP9H6.js +23 -0
- package/dist/cjs/chunks/tslib.es6-4H29ixHs.js +48 -0
- package/dist/cjs/chunks/utils-CbayehuI.js +126 -0
- package/dist/cjs/hooks/useDoubleClick.js +26 -0
- package/dist/cjs/hooks/useKeyboardShortcuts.js +42 -0
- package/dist/cjs/hooks/useLastUpdated.js +53 -0
- package/dist/cjs/hooks/useLocalStore.js +52 -0
- package/dist/cjs/hooks/useObserveResize.js +56 -0
- package/dist/cjs/hooks/useObserveTheme.js +37 -0
- package/dist/cjs/hooks/useTheme.js +86 -0
- package/dist/cjs/hooks/useToolTip.js +36 -0
- package/dist/cjs/hooks/useTrackRenders.js +38 -0
- package/dist/cjs/hooks/useWindow.js +64 -0
- package/dist/cjs/hooks.js +33 -0
- package/dist/cjs/index.js +124 -0
- package/dist/cjs/providers/ThemeProvider.js +55 -0
- package/dist/cjs/providers.js +14 -0
- package/dist/cjs/stores/tip.js +12 -0
- package/dist/cjs/stores/toast.js +12 -0
- package/dist/cjs/stores.js +18 -0
- package/dist/cjs/theme/colors.js +383 -0
- package/dist/cjs/theme/corners.js +14 -0
- package/dist/cjs/theme/elevations.js +17 -0
- package/dist/cjs/theme/themes.js +26 -0
- package/dist/cjs/theme/type.js +316 -0
- package/dist/cjs/theme.js +16 -0
- package/dist/cjs/uikit/Avatar.js +11 -0
- package/dist/cjs/uikit/AvatarGroup.js +12 -0
- package/dist/cjs/uikit/Badge.js +11 -0
- package/dist/cjs/uikit/CheckBox.js +22 -0
- package/dist/cjs/uikit/DivInput.js +13 -0
- package/dist/cjs/uikit/DocIcon.js +18 -0
- package/dist/cjs/uikit/Dot.js +12 -0
- package/dist/cjs/uikit/DraggablePanel.js +21 -0
- package/dist/cjs/uikit/DropDown.js +21 -0
- package/dist/cjs/uikit/EditorButtonBar.js +28 -0
- package/dist/cjs/uikit/ErrorSummary.js +12 -0
- package/dist/cjs/uikit/FlexDiv.js +12 -0
- package/dist/cjs/uikit/Grouper.js +23 -0
- package/dist/cjs/uikit/Icon.js +23 -0
- package/dist/cjs/uikit/IconButton.js +25 -0
- package/dist/cjs/uikit/Logos.js +18 -0
- package/dist/cjs/uikit/MessageInput.js +30 -0
- package/dist/cjs/uikit/Overlay.js +12 -0
- package/dist/cjs/uikit/Pager.js +12 -0
- package/dist/cjs/uikit/Progress.js +21 -0
- package/dist/cjs/uikit/RadioButton.js +26 -0
- package/dist/cjs/uikit/RadioButtonList.js +27 -0
- package/dist/cjs/uikit/Slider.js +13 -0
- package/dist/cjs/uikit/Spacer.js +10 -0
- package/dist/cjs/uikit/Switch.js +12 -0
- package/dist/cjs/uikit/TabBar.js +26 -0
- package/dist/cjs/uikit/TextArea.js +27 -0
- package/dist/cjs/uikit/Textfield.js +28 -0
- package/dist/cjs/uikit/Tip.js +13 -0
- package/dist/cjs/uikit/Toast.js +26 -0
- package/dist/cjs/uikit/UIButton.js +26 -0
- package/dist/cjs/uikit/UIButtonBar.js +26 -0
- package/dist/cjs/uikit/UICard.js +21 -0
- package/dist/cjs/uikit/UIChip.js +22 -0
- package/dist/cjs/uikit/UIFileIcon.js +18 -0
- package/dist/cjs/uikit/UILabel.js +19 -0
- package/dist/esm/chunks/Avatar-D_muqPrW.js +66 -0
- package/dist/esm/chunks/AvatarGroup-D8Xmrn52.js +37 -0
- package/dist/esm/chunks/Badge-PPf5Uvw3.js +39 -0
- package/dist/esm/chunks/CheckBox-CswFI0Xc.js +74 -0
- package/dist/esm/chunks/DivInput-iKFkeU2F.js +202 -0
- package/dist/esm/chunks/DocIcons-CbOX4n8Y.js +39 -0
- package/dist/esm/chunks/Dot-B84UVs2e.js +78 -0
- package/dist/esm/chunks/DrggablePanel-CYYwTmFd.js +300 -0
- package/dist/esm/chunks/DropDown-D4t6EhKL.js +152 -0
- package/dist/esm/chunks/EditorButtonBar-FnMa8Zv2.js +242 -0
- package/dist/esm/chunks/ErrorSummary-DhU5SKPt.js +40 -0
- package/dist/esm/chunks/FlexDiv-CmMpORgn.js +101 -0
- package/dist/esm/chunks/Grouper-BbreOXI9.js +48 -0
- package/dist/esm/chunks/IconButton-CguHGkBM.js +82 -0
- package/dist/esm/chunks/Logos-DwZP-TR2.js +117 -0
- package/dist/esm/chunks/MessageInput-DMHzCwjO.js +397 -0
- package/dist/esm/chunks/Overlay-CCBy7n7H.js +43 -0
- package/dist/esm/chunks/Pager-BsSti93V.js +40 -0
- package/dist/esm/chunks/ProgressIndicator-BVukxMU6.js +118 -0
- package/dist/esm/chunks/RadioButton-B5BxQI0R.js +63 -0
- package/dist/esm/chunks/RadioButtonList-C2z8McAD.js +114 -0
- package/dist/esm/chunks/Slider-C-PcWqTz.js +283 -0
- package/dist/esm/chunks/Spacer-DbZSG5x3.js +14 -0
- package/dist/esm/chunks/Switch-DjfrSiQz.js +41 -0
- package/dist/esm/chunks/TabBar-BSBcgTbd.js +174 -0
- package/dist/esm/chunks/TextArea-COM0UPo2.js +151 -0
- package/dist/esm/chunks/TextField-Bh24bRWs.js +246 -0
- package/dist/esm/chunks/Tip-Ct19Ljul.js +89 -0
- package/dist/esm/chunks/Toast-BR0oMX6z.js +139 -0
- package/dist/esm/chunks/UIButton-DKx-_O8h.js +315 -0
- package/dist/esm/chunks/UIButtonBar-BNdA5eVq.js +56 -0
- package/dist/esm/chunks/UICard-Dn5f3wg8.js +34 -0
- package/dist/esm/chunks/UIChip-DqnGeVyR.js +91 -0
- package/dist/esm/chunks/UIFileIcon-qGxIPsJJ.js +52 -0
- package/dist/esm/chunks/UILabel-RnbodPCS.js +114 -0
- package/dist/esm/chunks/_types-BaYeLEWK.js +712 -0
- package/dist/esm/chunks/sharedTypes-BfZzG1KX.js +9 -0
- package/dist/esm/chunks/style-inject.es-tgCJW-Cu.js +28 -0
- package/dist/esm/chunks/tipStore-nBYJ6tmE.js +17 -0
- package/dist/esm/chunks/toastStore-r3pvNa28.js +17 -0
- package/dist/esm/chunks/tslib.es6-0pkUdtrF.js +45 -0
- package/dist/esm/chunks/utils-BRZK2Drn.js +119 -0
- package/dist/esm/hooks/useDoubleClick.js +24 -0
- package/dist/esm/hooks/useKeyboardShortcuts.js +40 -0
- package/dist/esm/hooks/useLastUpdated.js +51 -0
- package/dist/esm/hooks/useLocalStore.js +50 -0
- package/dist/esm/hooks/useObserveResize.js +54 -0
- package/dist/esm/hooks/useObserveTheme.js +35 -0
- package/dist/esm/hooks/useTheme.js +84 -0
- package/dist/esm/hooks/useToolTip.js +34 -0
- package/dist/esm/hooks/useTrackRenders.js +36 -0
- package/dist/esm/hooks/useWindow.js +62 -0
- package/dist/esm/hooks.js +15 -0
- package/dist/esm/index.js +58 -0
- package/dist/esm/providers/ThemeProvider.js +53 -0
- package/dist/esm/providers.js +8 -0
- package/dist/esm/stores/tip.js +2 -0
- package/dist/esm/stores/toast.js +2 -0
- package/dist/esm/stores.js +3 -0
- package/dist/esm/theme/colors.js +377 -0
- package/dist/esm/theme/corners.js +12 -0
- package/dist/esm/theme/elevations.js +15 -0
- package/dist/esm/theme/themes.js +23 -0
- package/dist/esm/theme/type.js +312 -0
- package/dist/esm/theme.js +5 -0
- package/dist/esm/uikit/Avatar.js +5 -0
- package/dist/esm/uikit/AvatarGroup.js +6 -0
- package/dist/esm/uikit/Badge.js +5 -0
- package/dist/esm/uikit/CheckBox.js +16 -0
- package/dist/esm/uikit/DivInput.js +7 -0
- package/dist/esm/uikit/DocIcon.js +12 -0
- package/dist/esm/uikit/Dot.js +6 -0
- package/dist/esm/uikit/DraggablePanel.js +15 -0
- package/dist/esm/uikit/DropDown.js +15 -0
- package/dist/esm/uikit/EditorButtonBar.js +22 -0
- package/dist/esm/uikit/ErrorSummary.js +6 -0
- package/dist/esm/uikit/FlexDiv.js +6 -0
- package/dist/esm/uikit/Grouper.js +17 -0
- package/dist/esm/uikit/Icon.js +13 -0
- package/dist/esm/uikit/IconButton.js +19 -0
- package/dist/esm/uikit/Logos.js +12 -0
- package/dist/esm/uikit/MessageInput.js +24 -0
- package/dist/esm/uikit/Overlay.js +6 -0
- package/dist/esm/uikit/Pager.js +6 -0
- package/dist/esm/uikit/Progress.js +14 -0
- package/dist/esm/uikit/RadioButton.js +20 -0
- package/dist/esm/uikit/RadioButtonList.js +21 -0
- package/dist/esm/uikit/Slider.js +7 -0
- package/dist/esm/uikit/Spacer.js +4 -0
- package/dist/esm/uikit/Switch.js +6 -0
- package/dist/esm/uikit/TabBar.js +20 -0
- package/dist/esm/uikit/TextArea.js +21 -0
- package/dist/esm/uikit/Textfield.js +22 -0
- package/dist/esm/uikit/Tip.js +7 -0
- package/dist/esm/uikit/Toast.js +16 -0
- package/dist/esm/uikit/UIButton.js +20 -0
- package/dist/esm/uikit/UIButtonBar.js +20 -0
- package/dist/esm/uikit/UICard.js +15 -0
- package/dist/esm/uikit/UIChip.js +16 -0
- package/dist/esm/uikit/UIFileIcon.js +12 -0
- package/dist/esm/uikit/UILabel.js +13 -0
- package/dist/types/index.d.ts +3 -3
- package/dist/types/providers/ThemeProvider.d.ts +1 -0
- package/dist/types/stores/index.d.ts +2 -0
- package/dist/types/stores/tip/_types.d.ts +8 -0
- package/dist/types/stores/tip/index.d.ts +2 -0
- package/dist/types/stores/tip/tipStore.d.ts +12 -0
- package/dist/types/stores/toast/_types.d.ts +14 -0
- package/dist/types/stores/toast/index.d.ts +2 -0
- package/dist/types/stores/toast/toastStore.d.ts +12 -0
- package/dist/types/theme/elevations/_types.d.ts +10 -0
- package/dist/types/theme/elevations/elevations.d.ts +5 -0
- package/dist/types/theme/index.d.ts +2 -0
- package/dist/types/theme/themes.d.ts +2 -0
- package/dist/types/uikit/FlexDiv/FlexDiv.d.ts +2 -0
- package/dist/types/uikit/FlexDiv/_types.d.ts +1 -0
- package/dist/types/uikit/Toast/Toast.d.ts +1 -1
- package/dist/types/uikit/Toast/_types.d.ts +7 -1
- package/dist/types/uikit/Toast/index.d.ts +1 -1
- package/package.json +84 -5
- package/dist/index.esm.js +0 -5859
- package/dist/index.esm.js.map +0 -1
- package/dist/index.js +0 -5911
- package/dist/index.js.map +0 -1
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
function styleInject(css, ref) {
|
|
2
|
+
if ( ref === void 0 ) ref = {};
|
|
3
|
+
var insertAt = ref.insertAt;
|
|
4
|
+
|
|
5
|
+
if (!css || typeof document === 'undefined') { return; }
|
|
6
|
+
|
|
7
|
+
var head = document.head || document.getElementsByTagName('head')[0];
|
|
8
|
+
var style = document.createElement('style');
|
|
9
|
+
style.type = 'text/css';
|
|
10
|
+
|
|
11
|
+
if (insertAt === 'top') {
|
|
12
|
+
if (head.firstChild) {
|
|
13
|
+
head.insertBefore(style, head.firstChild);
|
|
14
|
+
} else {
|
|
15
|
+
head.appendChild(style);
|
|
16
|
+
}
|
|
17
|
+
} else {
|
|
18
|
+
head.appendChild(style);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (style.styleSheet) {
|
|
22
|
+
style.styleSheet.cssText = css;
|
|
23
|
+
} else {
|
|
24
|
+
style.appendChild(document.createTextNode(css));
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export { styleInject as s };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { create } from 'zustand';
|
|
2
|
+
|
|
3
|
+
const useTipStore = create((set) => ({
|
|
4
|
+
tip: null,
|
|
5
|
+
actions: {
|
|
6
|
+
push: (tip) => set({ tip }),
|
|
7
|
+
clear: () => set({ tip: null }),
|
|
8
|
+
},
|
|
9
|
+
}));
|
|
10
|
+
// atomic hook exports for use in React components
|
|
11
|
+
const useTip = () => useTipStore((state) => state.tip);
|
|
12
|
+
const useTipActions = () => useTipStore((state) => state.actions);
|
|
13
|
+
// non-reactive imperative exports for use outside the React context
|
|
14
|
+
const tipActions = useTipStore.getState().actions;
|
|
15
|
+
const getTip = () => useTipStore.getState().tip;
|
|
16
|
+
|
|
17
|
+
export { useTipActions as a, useTipStore as b, getTip as g, tipActions as t, useTip as u };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { create } from 'zustand';
|
|
2
|
+
|
|
3
|
+
const useToastStore = create((set) => ({
|
|
4
|
+
toast: null,
|
|
5
|
+
actions: {
|
|
6
|
+
push: (toast) => set({ toast }),
|
|
7
|
+
clear: () => set({ toast: null }),
|
|
8
|
+
},
|
|
9
|
+
}));
|
|
10
|
+
// atomic hook exports for use in React components
|
|
11
|
+
const useToast = () => useToastStore((state) => state.toast);
|
|
12
|
+
const useToastActions = () => useToastStore((state) => state.actions);
|
|
13
|
+
// non-reactive imperative exports for use outside the React context
|
|
14
|
+
const toastActions = useToastStore.getState().actions;
|
|
15
|
+
const getToast = () => useToastStore.getState().toast;
|
|
16
|
+
|
|
17
|
+
export { useToastActions as a, useToastStore as b, getToast as g, toastActions as t, useToast as u };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/******************************************************************************
|
|
2
|
+
Copyright (c) Microsoft Corporation.
|
|
3
|
+
|
|
4
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
5
|
+
purpose with or without fee is hereby granted.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
8
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
9
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
10
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
11
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
12
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
13
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
14
|
+
***************************************************************************** */
|
|
15
|
+
/* global Reflect, Promise, SuppressedError, Symbol, Iterator */
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
function __rest(s, e) {
|
|
19
|
+
var t = {};
|
|
20
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
21
|
+
t[p] = s[p];
|
|
22
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
23
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
24
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
25
|
+
t[p[i]] = s[p[i]];
|
|
26
|
+
}
|
|
27
|
+
return t;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function __awaiter(thisArg, _arguments, P, generator) {
|
|
31
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
32
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
33
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
34
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
35
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
36
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
41
|
+
var e = new Error(message);
|
|
42
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export { __rest as _, __awaiter as a };
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clean up string with html
|
|
3
|
+
*/
|
|
4
|
+
function cleanString(input, removeInvisible = true, removeHtml = true) {
|
|
5
|
+
let clean = input;
|
|
6
|
+
const scriptsRegEx = /\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi;
|
|
7
|
+
clean = clean.replaceAll(scriptsRegEx, '');
|
|
8
|
+
if (removeInvisible) {
|
|
9
|
+
const invisibleRegEx = /[\r\n\t]/gi;
|
|
10
|
+
clean = clean.replaceAll(invisibleRegEx, '');
|
|
11
|
+
}
|
|
12
|
+
if (removeHtml) {
|
|
13
|
+
const htmlRegEx = /<\/?[a-z][^>]*>/gi;
|
|
14
|
+
clean = clean.replaceAll(htmlRegEx, '');
|
|
15
|
+
}
|
|
16
|
+
return clean;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Debug component rendering
|
|
20
|
+
* Code removed when built / deployed
|
|
21
|
+
*/
|
|
22
|
+
function debug(previous, updated, name = 'component') {
|
|
23
|
+
if (process.env.NODE_ENV === 'test')
|
|
24
|
+
return; // exit if running tests
|
|
25
|
+
const props = previous.current.props;
|
|
26
|
+
const mount = previous.current.mount;
|
|
27
|
+
const unmount = previous.current.unmount;
|
|
28
|
+
if (mount) {
|
|
29
|
+
console.log({
|
|
30
|
+
component: name,
|
|
31
|
+
'(re)render': true,
|
|
32
|
+
event: 'Component Mount',
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
else if (unmount) {
|
|
36
|
+
console.log({
|
|
37
|
+
component: name,
|
|
38
|
+
'(re)render': false,
|
|
39
|
+
event: 'Component Unmount',
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
const reasons = createPropChangeArray(props, updated);
|
|
44
|
+
console.log({
|
|
45
|
+
component: name,
|
|
46
|
+
'(re)render': true,
|
|
47
|
+
event: 'Props Change',
|
|
48
|
+
props: reasons,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
return { props: updated, mount: false, unmount: false };
|
|
52
|
+
}
|
|
53
|
+
function createPropChangeArray(props, updated) {
|
|
54
|
+
const reasons = [];
|
|
55
|
+
for (const key of Object.keys(updated)) {
|
|
56
|
+
if (updated[key] !== props[key]) {
|
|
57
|
+
try {
|
|
58
|
+
const propName = `${key}:`;
|
|
59
|
+
const prev = JSON.stringify(props[key]);
|
|
60
|
+
const next = JSON.stringify(updated[key]);
|
|
61
|
+
const valueChanged = `${prev} > ${next}`;
|
|
62
|
+
reasons.push(`${propName} ${valueChanged}`);
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
let message = 'Unknown error';
|
|
66
|
+
if (error instanceof Error)
|
|
67
|
+
message = error.message;
|
|
68
|
+
if (typeof error === 'string')
|
|
69
|
+
message = error;
|
|
70
|
+
reasons.push(`${key} ${message}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return reasons;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Utility to accessibility - mimics click event with designated keys event
|
|
78
|
+
*/
|
|
79
|
+
function accessibleKeyDown(e, clickFunction, keys) {
|
|
80
|
+
const activateWith = ['Enter', ' '];
|
|
81
|
+
const match = activateWith.includes(e.key);
|
|
82
|
+
if (match) {
|
|
83
|
+
e.preventDefault();
|
|
84
|
+
clickFunction();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Get the pointer position from a DOM touch or mouse event
|
|
89
|
+
*/
|
|
90
|
+
function pointerPosition(e) {
|
|
91
|
+
if (e.type.startsWith('touch')) {
|
|
92
|
+
const touchEvent = e;
|
|
93
|
+
return touchEvent.touches[0].clientX;
|
|
94
|
+
}
|
|
95
|
+
const mouseEvent = e;
|
|
96
|
+
return mouseEvent.clientX;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Filter and trim class name array
|
|
100
|
+
*/
|
|
101
|
+
function filterClasses(classNames) {
|
|
102
|
+
return classNames
|
|
103
|
+
.filter((item) => item !== '')
|
|
104
|
+
.join(' ')
|
|
105
|
+
.trim();
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Takes a style string or number and returns a valid CSS style string
|
|
109
|
+
*/
|
|
110
|
+
function setStyle(value, defaultVal = undefined) {
|
|
111
|
+
const useValue = value !== null && value !== void 0 ? value : defaultVal;
|
|
112
|
+
if (!useValue)
|
|
113
|
+
return 'unset';
|
|
114
|
+
if (typeof useValue === 'string')
|
|
115
|
+
return useValue;
|
|
116
|
+
return `${useValue}px`;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export { accessibleKeyDown as a, cleanString as c, debug as d, filterClasses as f, pointerPosition as p, setStyle as s };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { useRef } from 'react';
|
|
2
|
+
|
|
3
|
+
function useDoubleClick(onClick, onDblClick, delay = 200) {
|
|
4
|
+
const timer = useRef(null);
|
|
5
|
+
const didClick = (payload) => {
|
|
6
|
+
if (timer.current)
|
|
7
|
+
clearTimeout(timer.current);
|
|
8
|
+
timer.current = setTimeout(() => {
|
|
9
|
+
onClick(payload);
|
|
10
|
+
}, delay);
|
|
11
|
+
return () => {
|
|
12
|
+
if (timer.current)
|
|
13
|
+
clearTimeout(timer.current);
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
const didDblClick = (payload) => {
|
|
17
|
+
if (timer.current)
|
|
18
|
+
clearTimeout(timer.current);
|
|
19
|
+
onDblClick(payload);
|
|
20
|
+
};
|
|
21
|
+
return [didClick, didDblClick];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export { useDoubleClick };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { useCallback, useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
function useKeyboardShortcuts(shortcuts, shortCutHandler, isAppleDevice) {
|
|
4
|
+
// don't process shortcuts on editable elements, like inputs, editable divs, etc.
|
|
5
|
+
const isEditable = useCallback((e) => {
|
|
6
|
+
const target = e.target;
|
|
7
|
+
if (target) {
|
|
8
|
+
const tag = target.tagName;
|
|
9
|
+
return (target.isContentEditable ||
|
|
10
|
+
tag === 'INPUT' ||
|
|
11
|
+
tag === 'TEXTAREA' ||
|
|
12
|
+
tag === 'SELECT');
|
|
13
|
+
}
|
|
14
|
+
return false;
|
|
15
|
+
}, []);
|
|
16
|
+
// get keyboard event check if it's a shortcut
|
|
17
|
+
const handleKeyPress = useCallback((e) => {
|
|
18
|
+
if (isEditable(e))
|
|
19
|
+
return;
|
|
20
|
+
const isMeta = (isAppleDevice && e.metaKey) || (!isAppleDevice && e.ctrlKey);
|
|
21
|
+
for (const s of shortcuts) {
|
|
22
|
+
if (s.key.toLowerCase() === e.key.toLowerCase() && isMeta) {
|
|
23
|
+
e.preventDefault();
|
|
24
|
+
shortCutHandler(s);
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}, [isAppleDevice, shortcuts, shortCutHandler, isEditable]);
|
|
29
|
+
// set keyboard listener
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
if (shortcuts.length === 0)
|
|
32
|
+
return;
|
|
33
|
+
globalThis.addEventListener('keydown', handleKeyPress, false);
|
|
34
|
+
return () => {
|
|
35
|
+
globalThis.removeEventListener('keydown', handleKeyPress, false);
|
|
36
|
+
};
|
|
37
|
+
}, [shortcuts, handleKeyPress]);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export { useKeyboardShortcuts };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { useState, useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
function getTimeDifference(date, labelPrefix) {
|
|
4
|
+
const compareDate = date instanceof Date ? date : new Date(date);
|
|
5
|
+
if (Number.isNaN(compareDate.getTime()))
|
|
6
|
+
return `${labelPrefix}Invalid date`;
|
|
7
|
+
// getTime = milliseconds since Jan 1 1970 UTC
|
|
8
|
+
const secondsDiff = Math.max(0, Math.floor((Date.now() - compareDate.getTime()) / 1000));
|
|
9
|
+
const minutes = Math.floor(secondsDiff / 60);
|
|
10
|
+
const hours = Math.floor(minutes / 60);
|
|
11
|
+
const days = Math.floor(hours / 24);
|
|
12
|
+
if (minutes < 1)
|
|
13
|
+
return `${labelPrefix}Just now`;
|
|
14
|
+
if (minutes === 1)
|
|
15
|
+
return `${labelPrefix}1 min. ago`;
|
|
16
|
+
if (minutes < 60)
|
|
17
|
+
return `${labelPrefix}${minutes} mins. ago`;
|
|
18
|
+
if (hours === 1)
|
|
19
|
+
return `${labelPrefix}1 hour ago`;
|
|
20
|
+
if (hours < 24)
|
|
21
|
+
return `${labelPrefix}${hours} hours ago`;
|
|
22
|
+
if (days === 1)
|
|
23
|
+
return `${labelPrefix}1 day ago`;
|
|
24
|
+
if (days < 15)
|
|
25
|
+
return `${labelPrefix}${days} days ago`;
|
|
26
|
+
return compareDate.toLocaleDateString('en-US', {
|
|
27
|
+
day: '2-digit',
|
|
28
|
+
month: 'short',
|
|
29
|
+
year: 'numeric',
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
function useLastUpdated(timestamp, prefix = '', interval = 1) {
|
|
33
|
+
const [lastUpdated, setLastUpdated] = useState(timestamp ? getTimeDifference(timestamp, prefix) : '');
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
if (!timestamp) {
|
|
36
|
+
setLastUpdated('');
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
setLastUpdated(getTimeDifference(timestamp, prefix));
|
|
40
|
+
const refreshMinutes = Math.max(interval, 1);
|
|
41
|
+
const intervalTimer = setInterval(() => {
|
|
42
|
+
setLastUpdated(getTimeDifference(timestamp, prefix));
|
|
43
|
+
}, refreshMinutes * 60 * 1000);
|
|
44
|
+
return () => {
|
|
45
|
+
clearInterval(intervalTimer);
|
|
46
|
+
};
|
|
47
|
+
}, [interval, prefix, timestamp]);
|
|
48
|
+
return { lastUpdated, timer: interval };
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export { useLastUpdated };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { useState, useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
function canUseLocalStorage() {
|
|
4
|
+
return (typeof globalThis !== 'undefined' &&
|
|
5
|
+
'localStorage' in globalThis &&
|
|
6
|
+
globalThis.localStorage !== undefined &&
|
|
7
|
+
globalThis.localStorage !== null);
|
|
8
|
+
}
|
|
9
|
+
function readLocalStorageValue(key, fallback) {
|
|
10
|
+
if (!canUseLocalStorage())
|
|
11
|
+
return fallback;
|
|
12
|
+
try {
|
|
13
|
+
const raw = globalThis.localStorage.getItem(key);
|
|
14
|
+
if (raw === null) {
|
|
15
|
+
// If not set, initialize with fallback.
|
|
16
|
+
globalThis.localStorage.setItem(key, JSON.stringify(fallback));
|
|
17
|
+
return fallback;
|
|
18
|
+
}
|
|
19
|
+
return JSON.parse(raw);
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
console.error(`Error parsing local storage item for key ${key}:`, {
|
|
23
|
+
error,
|
|
24
|
+
});
|
|
25
|
+
return fallback;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function useLocalStore(key, value) {
|
|
29
|
+
const [item, setItem] = useState(() => readLocalStorageValue(key, value));
|
|
30
|
+
// rehydrate on prop changes
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
setItem(readLocalStorageValue(key, value));
|
|
33
|
+
}, [key, value]);
|
|
34
|
+
function updateItem(data) {
|
|
35
|
+
if (canUseLocalStorage()) {
|
|
36
|
+
try {
|
|
37
|
+
globalThis.localStorage.setItem(key, JSON.stringify(data));
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
console.error(`Error setting local storage item for key ${key}:`, {
|
|
41
|
+
error,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
setItem(data);
|
|
46
|
+
}
|
|
47
|
+
return [item, updateItem];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export { useLocalStore };
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { useState, useCallback, useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
function useObserveResize(element, options) {
|
|
4
|
+
const [size, setSize] = useState({ width: 0, height: 0 });
|
|
5
|
+
const ignore = options === null || options === void 0 ? void 0 : options.ignore;
|
|
6
|
+
const handleResize = useCallback((entries) => {
|
|
7
|
+
var _a, _b;
|
|
8
|
+
if (!entries[0])
|
|
9
|
+
return;
|
|
10
|
+
const width = ((_a = element === null || element === void 0 ? void 0 : element.current) === null || _a === void 0 ? void 0 : _a.offsetWidth) || 0;
|
|
11
|
+
const height = ((_b = element === null || element === void 0 ? void 0 : element.current) === null || _b === void 0 ? void 0 : _b.offsetHeight) || 0;
|
|
12
|
+
setSize((prev) => {
|
|
13
|
+
const next = {
|
|
14
|
+
width: ignore === 'width' ? prev.width : width,
|
|
15
|
+
height: ignore === 'height' ? prev.height : height,
|
|
16
|
+
};
|
|
17
|
+
if (prev.width === next.width && prev.height === next.height) {
|
|
18
|
+
return prev;
|
|
19
|
+
}
|
|
20
|
+
return next;
|
|
21
|
+
});
|
|
22
|
+
}, [element, ignore]);
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
if (element === undefined)
|
|
25
|
+
return;
|
|
26
|
+
const el = element.current;
|
|
27
|
+
if (!el)
|
|
28
|
+
return;
|
|
29
|
+
// Get initial size
|
|
30
|
+
const newWidth = el.offsetWidth || 0;
|
|
31
|
+
const newHeight = el.offsetHeight || 0;
|
|
32
|
+
// set the new size of different to previous
|
|
33
|
+
setSize((prev) => {
|
|
34
|
+
const next = {
|
|
35
|
+
width: ignore === 'width' ? prev.width : newWidth,
|
|
36
|
+
height: ignore === 'height' ? prev.height : newHeight,
|
|
37
|
+
};
|
|
38
|
+
if (prev.width === next.width && prev.height === next.height) {
|
|
39
|
+
return prev; // same so no need to trigger re-renders
|
|
40
|
+
}
|
|
41
|
+
return next;
|
|
42
|
+
});
|
|
43
|
+
// Observe size changes
|
|
44
|
+
const resizeObserver = new ResizeObserver(handleResize);
|
|
45
|
+
resizeObserver.observe(el);
|
|
46
|
+
return () => {
|
|
47
|
+
resizeObserver.unobserve(el);
|
|
48
|
+
resizeObserver.disconnect();
|
|
49
|
+
};
|
|
50
|
+
}, [element, handleResize, ignore]);
|
|
51
|
+
return size;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export { useObserveResize };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { useState, useEffect } from 'react';
|
|
2
|
+
import { lightTheme, darkTheme } from '../theme/themes.js';
|
|
3
|
+
import '../theme/colors.js';
|
|
4
|
+
import '../theme/corners.js';
|
|
5
|
+
import '../theme/elevations.js';
|
|
6
|
+
import '../theme/type.js';
|
|
7
|
+
|
|
8
|
+
function useObserveTheme() {
|
|
9
|
+
const [theme, setTheme] = useState(lightTheme);
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
const observer = new MutationObserver((mutations) => {
|
|
12
|
+
for (const mutation of mutations) {
|
|
13
|
+
if (mutation.type === 'attributes' &&
|
|
14
|
+
mutation.attributeName === 'data-theme') {
|
|
15
|
+
const newTheme = document.documentElement.dataset.theme;
|
|
16
|
+
if (!newTheme ||
|
|
17
|
+
newTheme === '' ||
|
|
18
|
+
newTheme.includes(lightTheme.name))
|
|
19
|
+
setTheme(lightTheme);
|
|
20
|
+
else {
|
|
21
|
+
setTheme(darkTheme);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
observer.observe(document.documentElement, {
|
|
27
|
+
attributes: true,
|
|
28
|
+
attributeFilter: ['data-theme'],
|
|
29
|
+
});
|
|
30
|
+
return () => observer.disconnect();
|
|
31
|
+
}, []);
|
|
32
|
+
return theme;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export { useObserveTheme };
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { useCallback, useMemo } from 'react';
|
|
2
|
+
import { darkTheme, lightTheme } from '../theme/themes.js';
|
|
3
|
+
import { colorClass, colorCssVars } from '../theme/colors.js';
|
|
4
|
+
import { typeStyles, typeCssClasses } from '../theme/type.js';
|
|
5
|
+
import { useObserveTheme } from './useObserveTheme.js';
|
|
6
|
+
import '../theme/corners.js';
|
|
7
|
+
import '../theme/elevations.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Hook to manage Slice theming
|
|
11
|
+
*/
|
|
12
|
+
function useTheme() {
|
|
13
|
+
const current = useObserveTheme();
|
|
14
|
+
const set = useCallback((newTheme) => {
|
|
15
|
+
console.log('set theme', newTheme);
|
|
16
|
+
let theme;
|
|
17
|
+
if (typeof newTheme === 'string') {
|
|
18
|
+
if (newTheme === 'system') {
|
|
19
|
+
const darkModeMediaQuery = globalThis.matchMedia('(prefers-color-scheme: dark)');
|
|
20
|
+
const isDark = darkModeMediaQuery.matches;
|
|
21
|
+
theme = isDark ? darkTheme : lightTheme;
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
theme = newTheme === darkTheme.name ? darkTheme : lightTheme;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
else
|
|
28
|
+
theme = newTheme;
|
|
29
|
+
document.documentElement.dataset.theme = theme.name;
|
|
30
|
+
}, []);
|
|
31
|
+
const toggle = () => {
|
|
32
|
+
const lightMode = current.name === lightTheme.name;
|
|
33
|
+
const newTheme = lightMode ? darkTheme : lightTheme;
|
|
34
|
+
document.documentElement.dataset.theme = newTheme.name;
|
|
35
|
+
};
|
|
36
|
+
const isDark = useMemo(() => {
|
|
37
|
+
return current.name === darkTheme.name;
|
|
38
|
+
}, [current]);
|
|
39
|
+
return {
|
|
40
|
+
/**
|
|
41
|
+
* Slice's default dark theme
|
|
42
|
+
*/
|
|
43
|
+
darkTheme,
|
|
44
|
+
/**
|
|
45
|
+
* Slice's default light theme
|
|
46
|
+
*/
|
|
47
|
+
lightTheme,
|
|
48
|
+
/**
|
|
49
|
+
* The currently active SliceTheme
|
|
50
|
+
*/
|
|
51
|
+
current,
|
|
52
|
+
/**
|
|
53
|
+
* CSS variables for theme colors
|
|
54
|
+
*/
|
|
55
|
+
colors: colorCssVars,
|
|
56
|
+
/**
|
|
57
|
+
* CSS Class names for the theme colors
|
|
58
|
+
*/
|
|
59
|
+
colorsClass: colorClass,
|
|
60
|
+
/**
|
|
61
|
+
* CSS class names for theme typefaces
|
|
62
|
+
*/
|
|
63
|
+
typeClass: typeCssClasses,
|
|
64
|
+
/**
|
|
65
|
+
* CSS typeface styles as inline style properties
|
|
66
|
+
*/
|
|
67
|
+
typeStyle: typeStyles,
|
|
68
|
+
/**
|
|
69
|
+
* Set a new theme by name or passing in a SliceTheme object
|
|
70
|
+
* @param newTheme
|
|
71
|
+
*/
|
|
72
|
+
set,
|
|
73
|
+
/**
|
|
74
|
+
* Toggle between light and dark themes
|
|
75
|
+
*/
|
|
76
|
+
toggle,
|
|
77
|
+
/**
|
|
78
|
+
* If the currently active theme is the Slice's default dark theme'
|
|
79
|
+
*/
|
|
80
|
+
isDark,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export { useTheme };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { useState, useLayoutEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
const hiddenCoords = { x: 0, y: 0 };
|
|
4
|
+
function useToolTip(toolTip, tipElement) {
|
|
5
|
+
const [coords, setCoords] = useState(hiddenCoords);
|
|
6
|
+
useLayoutEffect(() => {
|
|
7
|
+
var _a;
|
|
8
|
+
// remove tooltip from view
|
|
9
|
+
if (!toolTip || !(tipElement === null || tipElement === void 0 ? void 0 : tipElement.current)) {
|
|
10
|
+
setCoords(hiddenCoords);
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
// get the target ref
|
|
14
|
+
const target = (_a = toolTip.ref) === null || _a === void 0 ? void 0 : _a.current;
|
|
15
|
+
if (!target) {
|
|
16
|
+
setCoords(hiddenCoords);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
// get rectangles for parent and tooltip
|
|
20
|
+
const parentRect = target.getBoundingClientRect();
|
|
21
|
+
const tipRect = tipElement.current.getBoundingClientRect();
|
|
22
|
+
// get position and size details
|
|
23
|
+
const { x: parentX, y: parentY, width: parentWidth, height: parentHeight, } = parentRect;
|
|
24
|
+
const { width: tipWidth } = tipRect;
|
|
25
|
+
// calculate the tool tip coords suc that it's placed beneath the parent
|
|
26
|
+
const x = parentX + parentWidth / 2 - tipWidth / 2;
|
|
27
|
+
const y = parentY + parentHeight + 10;
|
|
28
|
+
// set the coords
|
|
29
|
+
setCoords({ x, y });
|
|
30
|
+
}, [toolTip, tipElement]);
|
|
31
|
+
return coords;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export { useToolTip };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { useRef, useEffect } from 'react';
|
|
2
|
+
import { d as debug } from '../chunks/utils-BRZK2Drn.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Hook to log component renders, mounts, and unmounts
|
|
6
|
+
* Note: wrap in comments with START.DEBUG ... {hook} ... END.DEBUG to remove from build
|
|
7
|
+
*/
|
|
8
|
+
function useTrackRenders(props, componentName = 'Component') {
|
|
9
|
+
const prev = useRef({
|
|
10
|
+
props,
|
|
11
|
+
mount: true,
|
|
12
|
+
unmount: false,
|
|
13
|
+
});
|
|
14
|
+
// 5 random letters (uppercase)
|
|
15
|
+
const id = crypto
|
|
16
|
+
.getRandomValues(new Uint8Array(5))
|
|
17
|
+
.reduce((acc, val) => acc + String.fromCodePoint(65 + (val % 26)), '');
|
|
18
|
+
// name the component
|
|
19
|
+
const name = `${componentName} {${id}}`;
|
|
20
|
+
// Track re-renders w/o dependency array
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
prev.current = debug(prev, props, name);
|
|
23
|
+
});
|
|
24
|
+
// Track unmount with empty array on return
|
|
25
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: track unmount only
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
return () => {
|
|
28
|
+
if (prev.current) {
|
|
29
|
+
prev.current.unmount = true;
|
|
30
|
+
debug(prev, prev, name);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
}, []);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export { useTrackRenders };
|