@linzjs/step-ag-grid 2.1.3 → 2.2.0

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.
Files changed (30) hide show
  1. package/dist/index.js +106 -14
  2. package/dist/index.js.map +1 -1
  3. package/dist/src/index.d.ts +1 -0
  4. package/dist/src/lui/ActionButton.d.ts +15 -0
  5. package/dist/src/lui/reactUtils.d.ts +6 -0
  6. package/dist/src/lui/reactUtils.test.d.ts +1 -0
  7. package/dist/src/lui/stateDeferredHook.d.ts +4 -0
  8. package/dist/src/lui/timeoutHook.d.ts +8 -0
  9. package/dist/src/lui/timeoutHook.test.d.ts +1 -0
  10. package/dist/step-ag-grid.esm.js +107 -16
  11. package/dist/step-ag-grid.esm.js.map +1 -1
  12. package/package.json +4 -3
  13. package/src/index.ts +2 -0
  14. package/src/lui/ActionButton.scss +32 -0
  15. package/src/lui/ActionButton.tsx +76 -0
  16. package/src/lui/reactUtils.test.tsx +47 -0
  17. package/src/lui/reactUtils.tsx +14 -0
  18. package/src/lui/stateDeferredHook.tsx +29 -0
  19. package/src/lui/timeoutHook.test.tsx +38 -0
  20. package/src/lui/timeoutHook.tsx +40 -0
  21. package/src/stories/components/ActionButton.stories.tsx +33 -0
  22. package/src/stories/{components → grid}/FormTest.scss +0 -0
  23. package/src/stories/{components → grid}/FormTest.tsx +0 -0
  24. package/src/stories/{components → grid}/GridPopoutBearing.stories.tsx +7 -10
  25. package/src/stories/{components → grid}/GridPopoutEditDropDown.stories.tsx +20 -23
  26. package/src/stories/{components → grid}/GridPopoutEditGeneric.stories.tsx +6 -9
  27. package/src/stories/{components → grid}/GridPopoutEditGenericTextArea.stories.tsx +57 -18
  28. package/src/stories/{components → grid}/GridPopoutEditMultiSelect.stories.tsx +6 -9
  29. package/src/stories/{components → grid}/GridReadOnly.stories.tsx +6 -8
  30. /package/src/stories/{components → react-menu}/ReactMenu.stories.tsx +0 -0
@@ -27,5 +27,6 @@ export { GridHeaderSelect } from "./components/gridHeader/GridHeaderSelect";
27
27
  export { TextAreaInput } from "./lui/TextAreaInput";
28
28
  export { TextInputFormatted } from "./lui/TextInputFormatted";
29
29
  export { GridSubComponentTextArea } from "./components/GridSubComponentTextArea";
30
+ export * from "./lui/ActionButton";
30
31
  export * from "./utils/bearing";
31
32
  export * from "./utils/util";
@@ -0,0 +1,15 @@
1
+ /// <reference types="react" />
2
+ import "./ActionButton.scss";
3
+ import { IconName } from "@linzjs/lui/dist/components/LuiIcon/LuiIcon";
4
+ export interface ActionButtonProps {
5
+ icon: IconName;
6
+ name: string;
7
+ inProgressName?: string;
8
+ title?: string;
9
+ dataTestId?: string;
10
+ size?: "xs" | "sm" | "md" | "lg" | "xl" | "ns";
11
+ className?: string;
12
+ onClick?: () => void;
13
+ inProgress?: boolean;
14
+ }
15
+ export declare const ActionButton: ({ icon, name, inProgressName, dataTestId, inProgress, className, title, onClick, size, }: ActionButtonProps) => JSX.Element;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Track previous values of states.
3
+ *
4
+ * @param value Value to track.
5
+ */
6
+ export declare const usePrevious: <T extends unknown>(value: T) => T | undefined;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Defers state change up to a minimum time since last state change.
3
+ */
4
+ export declare const useStateDeferred: <T extends unknown>(initialValue: T) => [T, (v: T) => void, (v: T, w: number) => void];
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Cancels timeouts on scope being destroyed.
3
+ *
4
+ * This could almost be a debounce, but debounce tracks by function reference, this tracks by hook reference.
5
+ * This could have been implemented using debounce if the callers function was wrapped in useCallback,
6
+ * but there's no way to enforce that, so it would lead to bugs.
7
+ */
8
+ export declare const useTimeoutHook: () => (fn: () => void, waitTimeMs: number) => void;
@@ -0,0 +1 @@
1
+ export {};
@@ -3,7 +3,7 @@ import { unstable_batchedUpdates, flushSync, createPortal } from 'react-dom';
3
3
  import { findIndex, isEmpty, castArray, remove, flatten, delay, sortBy, last, difference, xorBy, fromPairs } from 'lodash-es';
4
4
  import { jsx, jsxs, Fragment as Fragment$1 } from 'react/jsx-runtime';
5
5
  import { AgGridReact } from 'ag-grid-react';
6
- import { LuiMiniSpinner, LuiIcon, LuiCheckboxInput } from '@linzjs/lui';
6
+ import { LuiMiniSpinner, LuiIcon, LuiCheckboxInput, LuiButton } from '@linzjs/lui';
7
7
 
8
8
  // Generate className following BEM methodology: http://getbem.com/naming/
9
9
  // Modifier value can be one of the following types: boolean, string, undefined
@@ -2518,11 +2518,11 @@ function styleInject(css, ref) {
2518
2518
  }
2519
2519
  }
2520
2520
 
2521
- var css_248z$6 = ".AgGridGenericCellRenderer-icon{margin-right:4px}.AgGridGenericCellRenderer-ic_infoIcon{fill:#3a7cdf;margin-right:4px}.AgGridGenericCellRenderer-ic_warningIcon{fill:#ea6a2e;margin-right:4px}";
2522
- styleInject(css_248z$6);
2521
+ var css_248z$7 = ".AgGridGenericCellRenderer-icon{margin-right:4px}.AgGridGenericCellRenderer-ic_infoIcon{fill:#3a7cdf;margin-right:4px}.AgGridGenericCellRenderer-ic_warningIcon{fill:#ea6a2e;margin-right:4px}";
2522
+ styleInject(css_248z$7);
2523
2523
 
2524
- var css_248z$5 = ".GridLoadableCell-container{align-items:center;display:flex}";
2525
- styleInject(css_248z$5);
2524
+ var css_248z$6 = ".GridLoadableCell-container{align-items:center;display:flex}";
2525
+ styleInject(css_248z$6);
2526
2526
 
2527
2527
  var GridLoadableCell = function (props) {
2528
2528
  if (props.isLoading) {
@@ -2744,11 +2744,11 @@ var GridRenderPopoutMenuCell = function (props) {
2744
2744
  return (jsx(GridLoadableCell, __assign({ isLoading: isLoading, className: disabled ? "GridPopoutMenu-burgerDisabled" : "GridPopoutMenu-burger" }, { children: jsx(LuiIcon, { name: "ic_more_vert", alt: "More actions", size: "md" }) })));
2745
2745
  };
2746
2746
 
2747
- var css_248z$4 = ".GridMultiSelect-containerSmall .GridFormMultiSelect-options{max-height:130px;overflow-y:auto}.GridMultiSelect-containerMedium .GridFormMultiSelect-options{max-height:190px;overflow-y:auto}.GridMultiSelect-containerLarge .GridFormMultiSelect-options{max-height:320px;overflow-y:auto}.GridMultiSelect-containerUnlimited .GridFormMultiSelect-options{overflow-y:auto}";
2748
- styleInject(css_248z$4);
2747
+ var css_248z$5 = ".GridMultiSelect-containerSmall .GridFormMultiSelect-options{max-height:130px;overflow-y:auto}.GridMultiSelect-containerMedium .GridFormMultiSelect-options{max-height:190px;overflow-y:auto}.GridMultiSelect-containerLarge .GridFormMultiSelect-options{max-height:320px;overflow-y:auto}.GridMultiSelect-containerUnlimited .GridFormMultiSelect-options{overflow-y:auto}";
2748
+ styleInject(css_248z$5);
2749
2749
 
2750
- var css_248z$3 = ".GridPopoverEditDropDown-containerSmall .GridFormDropDown-options{max-height:120px;overflow-y:auto}.GridPopoverEditDropDown-containerMedium .GridFormDropDown-options{max-height:200px;overflow-y:auto}.GridPopoverEditDropDown-containerLarge .GridFormDropDown-options{max-height:400px;overflow-y:auto}.GridPopoverEditDropDown-containerUnlimited .GridFormDropDown-options{overflow-y:auto}";
2751
- styleInject(css_248z$3);
2750
+ var css_248z$4 = ".GridPopoverEditDropDown-containerSmall .GridFormDropDown-options{max-height:120px;overflow-y:auto}.GridPopoverEditDropDown-containerMedium .GridFormDropDown-options{max-height:200px;overflow-y:auto}.GridPopoverEditDropDown-containerLarge .GridFormDropDown-options{max-height:400px;overflow-y:auto}.GridPopoverEditDropDown-containerUnlimited .GridFormDropDown-options{overflow-y:auto}";
2751
+ styleInject(css_248z$4);
2752
2752
 
2753
2753
  /* global setTimeout, clearTimeout */
2754
2754
 
@@ -3120,8 +3120,8 @@ var GridPopoutEditMultiSelect = function (colDef, props) {
3120
3120
  return GridCell(__assign({ initialWidth: 65, maxWidth: 150 }, colDef), __assign(__assign({ editor: GridFormMultiSelect }, props), { editorParams: __assign({ className: "GridMultiSelect-containerMedium" }, props.editorParams) }));
3121
3121
  };
3122
3122
 
3123
- var css_248z$2 = ".GridPopoutMenu-burger{cursor:pointer}.GridPopoutMenu-burger svg{fill:#007198}.GridPopoutMenu-burgerDisabled svg{fill:#989189}";
3124
- styleInject(css_248z$2);
3123
+ var css_248z$3 = ".GridPopoutMenu-burger{cursor:pointer}.GridPopoutMenu-burger svg{fill:#007198}.GridPopoutMenu-burgerDisabled svg{fill:#989189}";
3124
+ styleInject(css_248z$3);
3125
3125
 
3126
3126
  /** Menu configuration types **/
3127
3127
  var PopoutMenuSeparator = Object.freeze({ __isMenuSeparator__: true });
@@ -3284,11 +3284,11 @@ var convertDDToDMS = function (dd, showPositiveSymbol, addTrailingZeros) {
3284
3284
  return dmsString;
3285
3285
  };
3286
3286
 
3287
- var css_248z$1 = ".GridFormEditBearing-input{width:320px}";
3288
- styleInject(css_248z$1);
3287
+ var css_248z$2 = ".GridFormEditBearing-input{width:320px}";
3288
+ styleInject(css_248z$2);
3289
3289
 
3290
- var css_248z = ".LuiTextInput{margin-bottom:0}.LuiTextInput-formatted{color:#beb9b4;line-height:48px;position:absolute;right:14px;top:0}";
3291
- styleInject(css_248z);
3290
+ var css_248z$1 = ".LuiTextInput{margin-bottom:0}.LuiTextInput-formatted{color:#beb9b4;line-height:48px;position:absolute;right:14px;top:0}";
3291
+ styleInject(css_248z$1);
3292
3292
 
3293
3293
  var TextInputFormatted = function (props) {
3294
3294
  return (jsxs("div", __assign({ className: clsx("LuiTextInput Grid-popoverContainer", props.error && "hasError", props.warning && "hasWarning", props.className) }, { children: [jsxs("span", __assign({ className: "LuiTextInput-inputWrapper" }, { children: [jsx("input", __assign({ type: "text", className: "LuiTextInput-input", min: "0", value: props.value, onChange: props.onChange }, props.inputProps)), jsx("span", __assign({ className: "LuiTextInput-formatted" }, { children: props.formatted }))] })), props.error && (jsxs("span", __assign({ className: "LuiTextInput-error" }, { children: [jsx(LuiIcon, { alt: "error", name: "ic_error", className: "LuiTextInput-error-icon", size: "sm", status: "error" }), props.error] }))), props.warning && (jsxs("span", __assign({ className: "LuiTextInput-warning" }, { children: [jsx(LuiIcon, { alt: "warning", name: "ic_warning", className: "LuiTextInput-warning-icon", size: "sm", status: "warning" }), props.warning] })))] })));
@@ -3590,5 +3590,96 @@ var GridSubComponentTextArea = function (props) {
3590
3590
  return (jsx("div", __assign({ className: "FreeTextInput LuiDeprecatedForms" }, { children: jsx("textarea", { autoFocus: true, maxLength: 10000, spellCheck: true, className: "free-text-input", onChange: function (e) { return setValue(e.target.value); }, defaultValue: value }) })));
3591
3591
  };
3592
3592
 
3593
- export { ComponentLoadingWrapper, ControlledMenu, FocusableItem, GenericCellEditorComponent, GenericMultiEditCellClass, Grid, GridCell, GridCellRenderer, GridContext, GridContextProvider, GridHeaderSelect, GridIcon, GridLoadableCell, GridPopoutEditMultiSelect, GridPopoverEditBearing, GridPopoverEditBearingCorrection, GridPopoverEditDropDown, GridPopoverMenu, GridPopoverMessage, GridPopoverTextArea, GridPopoverTextInput, GridRenderPopoutMenuCell, GridRendererGenericCell, GridSubComponentTextArea, GridUpdatingContext, GridUpdatingContextProvider, Menu, MenuButton, MenuDivider, MenuGroup, MenuHeader, MenuItem, MenuRadioGroup, SubMenu, TextAreaInput, TextInputFormatted, bearingCorrectionValueFormatter, bearingNumberParser, bearingStringValidator, bearingValueFormatter, convertDDToDMS, hasParentClass, isFloat, isNotEmpty, useGridPopoverHook, useMenuState, usePostSortRowsHook, wait };
3593
+ var css_248z = ".ActionButton{align-items:center;display:flex}.ActionButton .LuiIcon{margin:0 4px!important}.ActionButton-minimalArea{position:relative}.ActionButton-minimalAreaDisplay{position:absolute}.ActionButton-minimalAreaExpand{visibility:hidden}.ActionButton-inProgress{background-color:#e2f3f7!important;color:#007198!important;cursor:progress}.ActionButton-inProgress svg *{fill:#0000!important}";
3594
+ styleInject(css_248z);
3595
+
3596
+ /**
3597
+ * Track previous values of states.
3598
+ *
3599
+ * @param value Value to track.
3600
+ */
3601
+ var usePrevious = function (value) {
3602
+ var ref = useRef();
3603
+ useEffect(function () {
3604
+ ref.current = value;
3605
+ }, [value]);
3606
+ return ref.current;
3607
+ };
3608
+
3609
+ /**
3610
+ * Cancels timeouts on scope being destroyed.
3611
+ *
3612
+ * This could almost be a debounce, but debounce tracks by function reference, this tracks by hook reference.
3613
+ * This could have been implemented using debounce if the callers function was wrapped in useCallback,
3614
+ * but there's no way to enforce that, so it would lead to bugs.
3615
+ */
3616
+ var useTimeoutHook = function () {
3617
+ var timeout = useRef();
3618
+ /**
3619
+ * Clear any pending timeouts.
3620
+ */
3621
+ var clearTimeouts = function () {
3622
+ if (timeout.current) {
3623
+ var tc = timeout.current;
3624
+ timeout.current = undefined;
3625
+ clearTimeout(tc);
3626
+ }
3627
+ };
3628
+ /**
3629
+ * Call this when your action has completed.
3630
+ */
3631
+ var invoke = useCallback(function (fn, waitTimeMs) {
3632
+ clearTimeouts();
3633
+ timeout.current = setTimeout(fn, waitTimeMs);
3634
+ }, []);
3635
+ /**
3636
+ * Clear timeout on loss of scope.
3637
+ */
3638
+ useEffect(function () {
3639
+ return function () { return clearTimeouts(); };
3640
+ }, []);
3641
+ return invoke;
3642
+ };
3643
+
3644
+ /**
3645
+ * Defers state change up to a minimum time since last state change.
3646
+ */
3647
+ var useStateDeferred = function (initialValue) {
3648
+ var startTime = useRef(0);
3649
+ var timeoutHook = useTimeoutHook();
3650
+ var _a = useState(initialValue), value = _a[0], _setValue = _a[1];
3651
+ var setValue = useCallback(function (newValue) {
3652
+ startTime.current = Date.now();
3653
+ _setValue(newValue);
3654
+ }, []);
3655
+ var setValueDeferred = useCallback(function (newValue, minimumWaitTimeMs) {
3656
+ var waitTimeMs = Math.max(minimumWaitTimeMs - (Date.now() - startTime.current), 0);
3657
+ timeoutHook(function () { return _setValue(newValue); }, waitTimeMs);
3658
+ }, [timeoutHook]);
3659
+ return [value, setValue, setValueDeferred];
3660
+ };
3661
+
3662
+ // Kept this less than one second, so I don't have issues with waitFor as it defaults to 1s
3663
+ var minimumInProgressTimeMs = 950;
3664
+ var ActionButton = function (_a) {
3665
+ var _b;
3666
+ var _c;
3667
+ var icon = _a.icon, name = _a.name, inProgressName = _a.inProgressName, dataTestId = _a.dataTestId, inProgress = _a.inProgress, className = _a.className, title = _a.title, onClick = _a.onClick, _d = _a.size, size = _d === void 0 ? "sm" : _d;
3668
+ var lastInProgress = usePrevious(inProgress !== null && inProgress !== void 0 ? inProgress : false);
3669
+ var _e = useStateDeferred(!!inProgress), localInProgress = _e[0], setLocalInProgress = _e[1], setLocalInProgressDeferred = _e[2];
3670
+ useEffect(function () {
3671
+ if (inProgress == lastInProgress)
3672
+ return;
3673
+ inProgress ? setLocalInProgress(true) : setLocalInProgressDeferred(false, minimumInProgressTimeMs);
3674
+ }, [inProgress, lastInProgress, setLocalInProgress, setLocalInProgressDeferred]);
3675
+ return (jsxs(LuiButton, __assign({ "data-testid": dataTestId, type: "button", level: "tertiary", title: title !== null && title !== void 0 ? title : name, "aria-label": name, className: clsx("lui-button-icon", "ActionButton", className, localInProgress && "ActionButton-inProgress"), size: "lg", onClick: onClick, disabled: localInProgress }, { children: [localInProgress ? (jsx(LuiMiniSpinner, { size: 16, divProps: (_b = {
3676
+ "data-testid": "loading-spinner",
3677
+ style: { padding: 0, margin: 0, paddingRight: 8 },
3678
+ role: "status"
3679
+ },
3680
+ _b["aria-label"] = "Loading",
3681
+ _b) })) : (jsx(LuiIcon, { name: icon, alt: name, size: size })), jsxs("span", __assign({ className: "ActionButton-minimalArea" }, { children: [jsx("span", __assign({ className: "ActionButton-minimalAreaDisplay" }, { children: (_c = (localInProgress ? inProgressName : name)) !== null && _c !== void 0 ? _c : name })), jsx("span", __assign({ className: "ActionButton-minimalAreaExpand" }, { children: name }))] }))] })));
3682
+ };
3683
+
3684
+ export { ActionButton, ComponentLoadingWrapper, ControlledMenu, FocusableItem, GenericCellEditorComponent, GenericMultiEditCellClass, Grid, GridCell, GridCellRenderer, GridContext, GridContextProvider, GridHeaderSelect, GridIcon, GridLoadableCell, GridPopoutEditMultiSelect, GridPopoverEditBearing, GridPopoverEditBearingCorrection, GridPopoverEditDropDown, GridPopoverMenu, GridPopoverMessage, GridPopoverTextArea, GridPopoverTextInput, GridRenderPopoutMenuCell, GridRendererGenericCell, GridSubComponentTextArea, GridUpdatingContext, GridUpdatingContextProvider, Menu, MenuButton, MenuDivider, MenuGroup, MenuHeader, MenuItem, MenuRadioGroup, SubMenu, TextAreaInput, TextInputFormatted, bearingCorrectionValueFormatter, bearingNumberParser, bearingStringValidator, bearingValueFormatter, convertDDToDMS, hasParentClass, isFloat, isNotEmpty, useGridPopoverHook, useMenuState, usePostSortRowsHook, wait };
3594
3685
  //# sourceMappingURL=step-ag-grid.esm.js.map