dce-reactkit 3.1.3 → 3.1.6
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/index.js +236 -10
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/components/CheckboxButton.d.ts +1 -0
- package/dist/cjs/types/components/ItemPicker/NestableItemList.d.ts +17 -0
- package/dist/cjs/types/components/ItemPicker/index.d.ts +18 -0
- package/dist/cjs/types/components/ItemPicker/index.test.d.ts +1 -0
- package/dist/cjs/types/components/ItemPicker/types/PickableItem.d.ts +16 -0
- package/dist/cjs/types/helpers/parallelLimit.d.ts +12 -0
- package/dist/cjs/types/index.d.ts +3 -1
- package/dist/esm/index.js +236 -12
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/components/CheckboxButton.d.ts +1 -0
- package/dist/esm/types/components/ItemPicker/NestableItemList.d.ts +17 -0
- package/dist/esm/types/components/ItemPicker/index.d.ts +18 -0
- package/dist/esm/types/components/ItemPicker/index.test.d.ts +1 -0
- package/dist/esm/types/components/ItemPicker/types/PickableItem.d.ts +16 -0
- package/dist/esm/types/helpers/parallelLimit.d.ts +12 -0
- package/dist/esm/types/index.d.ts +3 -1
- package/dist/index.d.ts +73 -27
- package/package.json +12 -2
- package/sandbox.js +21 -0
- package/src/components/CheckboxButton.tsx +4 -1
- package/src/components/ItemPicker/NestableItemList.tsx +288 -0
- package/src/components/ItemPicker/index.test.tsx +783 -0
- package/src/components/ItemPicker/index.tsx +85 -0
- package/src/components/ItemPicker/types/PickableItem.tsx +30 -0
- package/src/helpers/parallelLimit.ts +61 -0
- package/src/index.ts +4 -0
package/dist/cjs/index.js
CHANGED
|
@@ -937,7 +937,7 @@ const CheckboxButton = (props) => {
|
|
|
937
937
|
/* Setup */
|
|
938
938
|
/*------------------------------------------------------------------------*/
|
|
939
939
|
/* -------------- Props ------------- */
|
|
940
|
-
const { text, onChanged, ariaLabel, title, checked, id, noMarginOnRight, checkedVariant = Variant$1.Secondary, uncheckedVariant = Variant$1.Light, small, dashed, } = props;
|
|
940
|
+
const { text, onChanged, ariaLabel, title, checked, id, className, noMarginOnRight, checkedVariant = Variant$1.Secondary, uncheckedVariant = Variant$1.Light, small, dashed, } = props;
|
|
941
941
|
/*------------------------------------------------------------------------*/
|
|
942
942
|
/* Render */
|
|
943
943
|
/*------------------------------------------------------------------------*/
|
|
@@ -955,7 +955,7 @@ const CheckboxButton = (props) => {
|
|
|
955
955
|
: freeRegularSvgIcons.faSquare);
|
|
956
956
|
}
|
|
957
957
|
// Create the button
|
|
958
|
-
return (React__default["default"].createElement("button", { type: "button", id: id, title: title, className: `CheckboxButton-status-${checked ? 'checked' : 'unchecked'} ${dashed ? 'CheckboxButton-dashed ' : ''}btn btn-${checked ? checkedVariant : uncheckedVariant}${checked ? ' selected' : ''}${small ? ' btn-sm' : ''} m-0${noMarginOnRight ? '' : ' me-1'}`, "aria-label": `${ariaLabel}${checked ? ': currently checked' : ''}`, onClick: () => {
|
|
958
|
+
return (React__default["default"].createElement("button", { type: "button", id: id, title: title, className: `CheckboxButton-status-${checked ? 'checked' : 'unchecked'} ${dashed ? 'CheckboxButton-dashed ' : ''}btn btn-${checked ? checkedVariant : uncheckedVariant}${checked ? ' selected' : ''}${small ? ' btn-sm' : ''} m-0${noMarginOnRight ? '' : ' me-1'} ${className !== null && className !== void 0 ? className : ''}`, "aria-label": `${ariaLabel}${checked ? ': currently checked' : ''}`, onClick: () => {
|
|
959
959
|
onChanged(!checked);
|
|
960
960
|
} },
|
|
961
961
|
React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: icon, className: "me-1" }),
|
|
@@ -1543,27 +1543,27 @@ const PopPendingMark = (props) => {
|
|
|
1543
1543
|
*/
|
|
1544
1544
|
/* ------------- Actions ------------ */
|
|
1545
1545
|
// Types of actions
|
|
1546
|
-
var ActionType;
|
|
1546
|
+
var ActionType$1;
|
|
1547
1547
|
(function (ActionType) {
|
|
1548
1548
|
// Indicate that the text was recently copied
|
|
1549
1549
|
ActionType["IndicateRecentlyCopied"] = "indicate-recently-copied";
|
|
1550
1550
|
// Clear the status
|
|
1551
1551
|
ActionType["ClearRecentlyCopiedStatus"] = "clear-recently-copied-status";
|
|
1552
|
-
})(ActionType || (ActionType = {}));
|
|
1552
|
+
})(ActionType$1 || (ActionType$1 = {}));
|
|
1553
1553
|
/**
|
|
1554
1554
|
* Reducer that executes actions
|
|
1555
1555
|
* @author Gabe Abrams
|
|
1556
1556
|
* @param state current state
|
|
1557
1557
|
* @param action action to execute
|
|
1558
1558
|
*/
|
|
1559
|
-
const reducer = (state, action) => {
|
|
1559
|
+
const reducer$1 = (state, action) => {
|
|
1560
1560
|
switch (action.type) {
|
|
1561
|
-
case ActionType.IndicateRecentlyCopied: {
|
|
1561
|
+
case ActionType$1.IndicateRecentlyCopied: {
|
|
1562
1562
|
return {
|
|
1563
1563
|
recentlyCopied: true,
|
|
1564
1564
|
};
|
|
1565
1565
|
}
|
|
1566
|
-
case ActionType.ClearRecentlyCopiedStatus: {
|
|
1566
|
+
case ActionType$1.ClearRecentlyCopiedStatus: {
|
|
1567
1567
|
return {
|
|
1568
1568
|
recentlyCopied: false,
|
|
1569
1569
|
};
|
|
@@ -1589,7 +1589,7 @@ const CopiableBox = (props) => {
|
|
|
1589
1589
|
recentlyCopied: false,
|
|
1590
1590
|
};
|
|
1591
1591
|
// Initialize state
|
|
1592
|
-
const [state, dispatch] = React.useReducer(reducer, initialState);
|
|
1592
|
+
const [state, dispatch] = React.useReducer(reducer$1, initialState);
|
|
1593
1593
|
// Destructure common state
|
|
1594
1594
|
const { recentlyCopied, } = state;
|
|
1595
1595
|
/*------------------------------------------------------------------------*/
|
|
@@ -1609,13 +1609,13 @@ const CopiableBox = (props) => {
|
|
|
1609
1609
|
}
|
|
1610
1610
|
// Show copied notice
|
|
1611
1611
|
dispatch({
|
|
1612
|
-
type: ActionType.IndicateRecentlyCopied,
|
|
1612
|
+
type: ActionType$1.IndicateRecentlyCopied,
|
|
1613
1613
|
});
|
|
1614
1614
|
// Wait a moment
|
|
1615
1615
|
yield waitMs(4000);
|
|
1616
1616
|
// Hide copied notice
|
|
1617
1617
|
dispatch({
|
|
1618
|
-
type: ActionType.ClearRecentlyCopiedStatus,
|
|
1618
|
+
type: ActionType$1.ClearRecentlyCopiedStatus,
|
|
1619
1619
|
});
|
|
1620
1620
|
});
|
|
1621
1621
|
/*------------------------------------------------------------------------*/
|
|
@@ -1664,6 +1664,183 @@ const CopiableBox = (props) => {
|
|
|
1664
1664
|
"Copy")))));
|
|
1665
1665
|
};
|
|
1666
1666
|
|
|
1667
|
+
/**
|
|
1668
|
+
* Reusable nested item picker
|
|
1669
|
+
* @author Yuen Ler Chow
|
|
1670
|
+
*/
|
|
1671
|
+
/* ------------- Actions ------------ */
|
|
1672
|
+
// Types of actions
|
|
1673
|
+
var ActionType;
|
|
1674
|
+
(function (ActionType) {
|
|
1675
|
+
// Toggle whether the children are being shown
|
|
1676
|
+
ActionType["ToggleItems"] = "toggle-items";
|
|
1677
|
+
})(ActionType || (ActionType = {}));
|
|
1678
|
+
/**
|
|
1679
|
+
* Reducer that executes actions
|
|
1680
|
+
* @author Yuen Ler Chow
|
|
1681
|
+
* @param state current state
|
|
1682
|
+
* @param action action to execute
|
|
1683
|
+
*/
|
|
1684
|
+
const reducer = (state, action) => {
|
|
1685
|
+
switch (action.type) {
|
|
1686
|
+
case ActionType.ToggleItems: {
|
|
1687
|
+
return { isShowingItems: !state.isShowingItems };
|
|
1688
|
+
}
|
|
1689
|
+
default: {
|
|
1690
|
+
return state;
|
|
1691
|
+
}
|
|
1692
|
+
}
|
|
1693
|
+
};
|
|
1694
|
+
/*------------------------------------------------------------------------*/
|
|
1695
|
+
/* Component */
|
|
1696
|
+
/*------------------------------------------------------------------------*/
|
|
1697
|
+
const NestableItemList = (props) => {
|
|
1698
|
+
/*------------------------------------------------------------------------*/
|
|
1699
|
+
/* Setup */
|
|
1700
|
+
/*------------------------------------------------------------------------*/
|
|
1701
|
+
/* -------------- Props ------------- */
|
|
1702
|
+
// Destructure all props
|
|
1703
|
+
const { items, onChanged, } = props;
|
|
1704
|
+
/* -------------- State ------------- */
|
|
1705
|
+
// Initial state
|
|
1706
|
+
const initialState = {
|
|
1707
|
+
isShowingItems: true,
|
|
1708
|
+
};
|
|
1709
|
+
// Initialize state
|
|
1710
|
+
const [state, dispatch] = React.useReducer(reducer, initialState);
|
|
1711
|
+
// Destructure common state
|
|
1712
|
+
const { isShowingItems, } = state;
|
|
1713
|
+
/*------------------------------------------------------------------------*/
|
|
1714
|
+
/* Component Functions */
|
|
1715
|
+
/*------------------------------------------------------------------------*/
|
|
1716
|
+
/**
|
|
1717
|
+
* Checks if all items in a list are checked
|
|
1718
|
+
* @author Yuen Ler Chow
|
|
1719
|
+
* @param pickableItems a list of items
|
|
1720
|
+
* @returns true if all items are checked. If any item is a group,
|
|
1721
|
+
* we recursively check its children
|
|
1722
|
+
*/
|
|
1723
|
+
const allChecked = (pickableItems) => {
|
|
1724
|
+
return pickableItems.every((item) => {
|
|
1725
|
+
if (item.isGroup) {
|
|
1726
|
+
return allChecked(item.children);
|
|
1727
|
+
}
|
|
1728
|
+
return item.checked;
|
|
1729
|
+
});
|
|
1730
|
+
};
|
|
1731
|
+
/**
|
|
1732
|
+
* Checks if none of the items in a list are checked
|
|
1733
|
+
* @author Yuen Ler Chow
|
|
1734
|
+
* @param pickableItems a list of items
|
|
1735
|
+
* @returns true if all items are unchecked. If any item is a group, we
|
|
1736
|
+
* recursively check its children
|
|
1737
|
+
*/
|
|
1738
|
+
const noneChecked = (pickableItems) => {
|
|
1739
|
+
return pickableItems.every((item) => {
|
|
1740
|
+
if (item.isGroup) {
|
|
1741
|
+
return noneChecked(item.children);
|
|
1742
|
+
}
|
|
1743
|
+
return !item.checked;
|
|
1744
|
+
});
|
|
1745
|
+
};
|
|
1746
|
+
/**
|
|
1747
|
+
* Change whether specific items are checked
|
|
1748
|
+
* @author Yuen Ler Chow
|
|
1749
|
+
* @param id the id of the item we want to check or uncheck OR true if
|
|
1750
|
+
* we are checking/unchecking all items, independent of their id
|
|
1751
|
+
* @param checked if true, the item will be checked.
|
|
1752
|
+
* @param pickableItems the list of items we iterate through to find the item
|
|
1753
|
+
* we want to check/uncheck
|
|
1754
|
+
* @returns a list of items with the item now checked/unchecked.
|
|
1755
|
+
* If it is a group, its children will also become checked/unchecked
|
|
1756
|
+
*/
|
|
1757
|
+
const changeChecked = (id, checked, pickableItems) => {
|
|
1758
|
+
const updatedItems = pickableItems.map((item) => {
|
|
1759
|
+
if (item.id === id || id === true) {
|
|
1760
|
+
if (item.isGroup) {
|
|
1761
|
+
return Object.assign(Object.assign({}, item), { children: changeChecked(true, checked, item.children) });
|
|
1762
|
+
}
|
|
1763
|
+
return Object.assign(Object.assign({}, item), { checked });
|
|
1764
|
+
}
|
|
1765
|
+
if (item.isGroup) {
|
|
1766
|
+
return Object.assign(Object.assign({}, item), { children: changeChecked(id, checked, item.children) });
|
|
1767
|
+
}
|
|
1768
|
+
return item;
|
|
1769
|
+
});
|
|
1770
|
+
return updatedItems;
|
|
1771
|
+
};
|
|
1772
|
+
/**
|
|
1773
|
+
* Within a tree of items, swap in the list of updated items into the spot
|
|
1774
|
+
* indicated by the id
|
|
1775
|
+
* @author Yuen Ler Chow
|
|
1776
|
+
* @param id the id of the item group we want to change
|
|
1777
|
+
* @param updatedItems the list of items we want to change the items in the group to
|
|
1778
|
+
* @returns a list of all items containing the updated items
|
|
1779
|
+
*/
|
|
1780
|
+
const changeItems = (id, updatedItems) => {
|
|
1781
|
+
return items.map((item) => {
|
|
1782
|
+
if (item.id === id) {
|
|
1783
|
+
return Object.assign(Object.assign({}, item), { children: updatedItems });
|
|
1784
|
+
}
|
|
1785
|
+
return item;
|
|
1786
|
+
});
|
|
1787
|
+
};
|
|
1788
|
+
/*------------------------------------------------------------------------*/
|
|
1789
|
+
/* Render */
|
|
1790
|
+
/*------------------------------------------------------------------------*/
|
|
1791
|
+
return (React__default["default"].createElement("div", null, items.map((item) => {
|
|
1792
|
+
return (React__default["default"].createElement("div", { key: item.id },
|
|
1793
|
+
React__default["default"].createElement("span", { className: "NestableItemList-dropdown-button-container d-inline-block", style: {
|
|
1794
|
+
minWidth: '2rem',
|
|
1795
|
+
} }, item.isGroup && (React__default["default"].createElement("button", { className: `NestableItemList-dropdown-button NestableItemList-dropdown-button-${item.id}`, style: {
|
|
1796
|
+
border: 0,
|
|
1797
|
+
backgroundColor: 'transparent',
|
|
1798
|
+
}, type: "button", onClick: () => {
|
|
1799
|
+
dispatch({
|
|
1800
|
+
type: ActionType.ToggleItems,
|
|
1801
|
+
});
|
|
1802
|
+
}, "aria-label": `${isShowingItems ? 'Hide' : 'Show'} items in ${item.name}` },
|
|
1803
|
+
React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: isShowingItems ? freeSolidSvgIcons.faChevronDown : freeSolidSvgIcons.faChevronRight })))),
|
|
1804
|
+
React__default["default"].createElement(CheckboxButton, { className: `NestableItemList-CheckboxButton-${item.id}`, text: item.name, checked: item.isGroup ? allChecked(item.children) : item.checked, dashed: item.isGroup ? !noneChecked(item.children) : false, onChanged: (checked) => {
|
|
1805
|
+
onChanged(changeChecked(item.id, checked, items));
|
|
1806
|
+
}, ariaLabel: `Select ${item.name}`, checkedVariant: Variant$1.Light }),
|
|
1807
|
+
item.isGroup && isShowingItems && (React__default["default"].createElement("div", { className: "NestableItemList-children-container", style: {
|
|
1808
|
+
paddingLeft: '2.2rem',
|
|
1809
|
+
} },
|
|
1810
|
+
React__default["default"].createElement(NestableItemList, { items: item.children, onChanged: (updatedItems) => {
|
|
1811
|
+
onChanged(changeItems(item.id, updatedItems));
|
|
1812
|
+
} })))));
|
|
1813
|
+
})));
|
|
1814
|
+
};
|
|
1815
|
+
|
|
1816
|
+
/**
|
|
1817
|
+
* Reusable nested item picker
|
|
1818
|
+
* @author Yuen Ler Chow
|
|
1819
|
+
*/
|
|
1820
|
+
/*------------------------------------------------------------------------*/
|
|
1821
|
+
/* Component */
|
|
1822
|
+
/*------------------------------------------------------------------------*/
|
|
1823
|
+
const ItemPicker = (props) => {
|
|
1824
|
+
/*------------------------------------------------------------------------*/
|
|
1825
|
+
/* Setup */
|
|
1826
|
+
/*------------------------------------------------------------------------*/
|
|
1827
|
+
/* -------------- Props ------------- */
|
|
1828
|
+
// Destructure all props
|
|
1829
|
+
const { title, items, onChanged, } = props;
|
|
1830
|
+
/*------------------------------------------------------------------------*/
|
|
1831
|
+
/* Component Functions */
|
|
1832
|
+
/*------------------------------------------------------------------------*/
|
|
1833
|
+
/*------------------------------------------------------------------------*/
|
|
1834
|
+
/* Render */
|
|
1835
|
+
/*------------------------------------------------------------------------*/
|
|
1836
|
+
/*----------------------------------------*/
|
|
1837
|
+
/* Main UI */
|
|
1838
|
+
/*----------------------------------------*/
|
|
1839
|
+
return (React__default["default"].createElement(TabBox, { title: title },
|
|
1840
|
+
React__default["default"].createElement("div", { style: { overflowX: 'scroll' } },
|
|
1841
|
+
React__default["default"].createElement(NestableItemList, { items: items, onChanged: onChanged }))));
|
|
1842
|
+
};
|
|
1843
|
+
|
|
1667
1844
|
/**
|
|
1668
1845
|
* One minute in ms
|
|
1669
1846
|
* @author Gabe Abrams
|
|
@@ -2489,6 +2666,53 @@ const onlyKeepLetters = (str) => {
|
|
|
2489
2666
|
return str.replace(/[^a-zA-Z]+/g, '');
|
|
2490
2667
|
};
|
|
2491
2668
|
|
|
2669
|
+
/**
|
|
2670
|
+
* Run tasks in parallel with a limit on how many tasks can execute at once.
|
|
2671
|
+
* No guarantees are made about the order of task execution
|
|
2672
|
+
* @author Gabe Abrams
|
|
2673
|
+
* @param taskFunctions functions that start asynchronous tasks and optionally
|
|
2674
|
+
* resolve with values
|
|
2675
|
+
* @param limit maximum number of asynchronous tasks to permit to run at
|
|
2676
|
+
* once
|
|
2677
|
+
* @returns array of resolved values in the same order as the task functions
|
|
2678
|
+
*/
|
|
2679
|
+
const parallelLimit = (taskFunctions, limit) => __awaiter(void 0, void 0, void 0, function* () {
|
|
2680
|
+
const results = [];
|
|
2681
|
+
// Wait until finished with all tasks
|
|
2682
|
+
yield new Promise((resolve) => {
|
|
2683
|
+
/* ------------- Helpers ------------ */
|
|
2684
|
+
let nextTaskIndex = 0;
|
|
2685
|
+
let numFinishedTasks = 0;
|
|
2686
|
+
/**
|
|
2687
|
+
* Start the next task
|
|
2688
|
+
* @author Gabe Abrams
|
|
2689
|
+
*/
|
|
2690
|
+
const startTask = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
2691
|
+
const taskIndex = nextTaskIndex++;
|
|
2692
|
+
// Get the task
|
|
2693
|
+
const taskFunction = taskFunctions[taskIndex];
|
|
2694
|
+
if (!taskFunction) {
|
|
2695
|
+
return;
|
|
2696
|
+
}
|
|
2697
|
+
// Execute task
|
|
2698
|
+
const result = yield taskFunction();
|
|
2699
|
+
// Add results
|
|
2700
|
+
results[taskIndex] = result;
|
|
2701
|
+
// Tally and finish
|
|
2702
|
+
if (++numFinishedTasks === taskFunctions.length) {
|
|
2703
|
+
return resolve();
|
|
2704
|
+
}
|
|
2705
|
+
// Not finished! Start another task
|
|
2706
|
+
startTask();
|
|
2707
|
+
});
|
|
2708
|
+
/* ----------- Start Tasks ---------- */
|
|
2709
|
+
for (let i = 0; i < limit; i++) {
|
|
2710
|
+
startTask();
|
|
2711
|
+
}
|
|
2712
|
+
});
|
|
2713
|
+
return results;
|
|
2714
|
+
});
|
|
2715
|
+
|
|
2492
2716
|
/**
|
|
2493
2717
|
* Days of the week
|
|
2494
2718
|
* @author Gabe Abrams
|
|
@@ -2515,6 +2739,7 @@ exports.Drawer = Drawer;
|
|
|
2515
2739
|
exports.ErrorBox = ErrorBox;
|
|
2516
2740
|
exports.ErrorWithCode = ErrorWithCode;
|
|
2517
2741
|
exports.HOUR_IN_MS = HOUR_IN_MS;
|
|
2742
|
+
exports.ItemPicker = ItemPicker;
|
|
2518
2743
|
exports.LoadingSpinner = LoadingSpinner;
|
|
2519
2744
|
exports.MINUTE_IN_MS = MINUTE_IN_MS;
|
|
2520
2745
|
exports.Modal = Modal;
|
|
@@ -2548,6 +2773,7 @@ exports.initServer = initServer;
|
|
|
2548
2773
|
exports.onlyKeepLetters = onlyKeepLetters;
|
|
2549
2774
|
exports.padDecimalZeros = padDecimalZeros;
|
|
2550
2775
|
exports.padZerosLeft = padZerosLeft;
|
|
2776
|
+
exports.parallelLimit = parallelLimit;
|
|
2551
2777
|
exports.roundToNumDecimals = roundToNumDecimals;
|
|
2552
2778
|
exports.showFatalError = showFatalError;
|
|
2553
2779
|
exports.startMinWait = startMinWait;
|