@mackin.com/styleguide 8.0.0-beta.19 → 8.0.0-beta.21

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 (3) hide show
  1. package/index.d.ts +19 -3
  2. package/index.js +67 -27
  3. package/package.json +1 -1
package/index.d.ts CHANGED
@@ -455,6 +455,7 @@ declare const Nav: (props: {
455
455
  children?: React.ReactNode;
456
456
  responsive?: boolean | undefined;
457
457
  className?: string | undefined;
458
+ __debug?: boolean | undefined;
458
459
  }) => JSX.Element;
459
460
 
460
461
  interface OmniLinkProps {
@@ -498,7 +499,7 @@ interface PagerOptions<TItem> {
498
499
  sortOptions?: PagerSortOption<TItem>[];
499
500
  previous?: ItemPager<TItem>;
500
501
  }
501
- /** For in-memory paging. */
502
+ /** In-memory pager. */
502
503
  declare class ItemPager<TItem> {
503
504
  constructor(allItems: TItem[], options?: PagerOptions<TItem>);
504
505
  get allItems(): TItem[];
@@ -614,6 +615,7 @@ interface Props<T> extends PagerStyleProps {
614
615
  }
615
616
  declare const BoundStaticPager: <T>(p: Props<T>) => JSX.Element;
616
617
 
618
+ /** A page of data with helpers props. */
617
619
  declare class PagedResult<T> {
618
620
  constructor(items?: T[], total?: number, page?: number, limit?: number);
619
621
  static fromDto<T>(dto: {
@@ -823,6 +825,9 @@ declare const ThemeProvider: <T extends MackinTheme>(p: {
823
825
  theme: T;
824
826
  }) => JSX.Element;
825
827
 
828
+ /** React wrapper around window resizing and window.matchMedia.
829
+ * https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia
830
+ */
826
831
  declare const useMediaQuery: (query: string) => boolean;
827
832
 
828
833
  /** Returns a user-provided theme if ThemeProvider was used correctly, or the default theme. */
@@ -983,7 +988,7 @@ interface ToggleButtonGroupProps {
983
988
  }
984
989
  declare const ToggleButtonGroup: (props: ToggleButtonGroupProps) => JSX.Element;
985
990
 
986
- declare const TogglePasswordInput: React.ForwardRefExoticComponent<Pick<TextInputProps, "type" | "rightControl" | "value" | "round" | "wrapperClassName" | "key" | "accept" | "alt" | "autoComplete" | "autoFocus" | "capture" | "checked" | "crossOrigin" | "disabled" | "enterKeyHint" | "form" | "formAction" | "formEncType" | "formMethod" | "formNoValidate" | "formTarget" | "height" | "list" | "maxLength" | "minLength" | "multiple" | "name" | "pattern" | "placeholder" | "readOnly" | "required" | "size" | "src" | "width" | "onChange" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "className" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "hidden" | "id" | "lang" | "slot" | "spellCheck" | "style" | "tabIndex" | "title" | "translate" | "radioGroup" | "role" | "about" | "datatype" | "inlist" | "prefix" | "property" | "resource" | "typeof" | "vocab" | "autoCapitalize" | "autoCorrect" | "autoSave" | "color" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "children" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "onValueChange" | "customError" | "patternErrorMessage"> & React.RefAttributes<HTMLInputElement>>;
991
+ declare const TogglePasswordInput: React.ForwardRefExoticComponent<Pick<TextInputProps, "type" | "rightControl" | "value" | "round" | "wrapperClassName" | "key" | "accept" | "alt" | "autoComplete" | "autoFocus" | "capture" | "checked" | "crossOrigin" | "disabled" | "enterKeyHint" | "form" | "formAction" | "formEncType" | "formMethod" | "formNoValidate" | "formTarget" | "height" | "list" | "maxLength" | "minLength" | "multiple" | "name" | "pattern" | "placeholder" | "readOnly" | "required" | "size" | "src" | "width" | "onChange" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "className" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "hidden" | "id" | "lang" | "slot" | "spellCheck" | "style" | "tabIndex" | "title" | "translate" | "radioGroup" | "role" | "about" | "datatype" | "inlist" | "prefix" | "property" | "resource" | "typeof" | "vocab" | "autoCapitalize" | "autoCorrect" | "autoSave" | "color" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "children" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "trim" | "emptyString" | "onValueChange" | "customError" | "patternErrorMessage"> & React.RefAttributes<HTMLInputElement>>;
987
992
 
988
993
  declare const WaitingIndicator: (p: {
989
994
  show: boolean;
@@ -992,4 +997,15 @@ declare const WaitingIndicator: (p: {
992
997
  __debug?: boolean;
993
998
  }) => JSX.Element;
994
999
 
995
- export { Accordian, AccordianProps, Alignment, Autocomplete, AutocompleteProps, AutocompleteValue, Backdrop$1 as Backdrop, Backdrop as Backdrop2, BoundMemoryPager, BoundStaticPager, Button, ButtonProps, Calendar, CalendarProps, Checkbox, CheckboxProps, ConfirmModal, ConfirmModalProps, CopyButton, DateInput, DateInputProps, Divider, ErrorModal, FileUploader, Form, FormColumnRow, FormFlexRow, FormProps, GlobalStyles, Header, Highlight, ICONS, Icon, Image, InfoPanel, InfoTip, InfoTipProps, Input, InputProps, ItemPager, Label, LabelProps, List, ListItem, ListItemProps, ListProps, MackinTheme, Modal, Nav, NumberInput, NumberInputProps, OmniLink, OmniLinkProps, PagedResult, Pager, PagerProps, Picker, PickerOption, PickerProps, PickerValue, Popover, ProgressBar, ProgressBarProps, SearchBox, SearchBoxProps, Slider, TabHeader, TabHeaderProps, TabLocker, Table, Td, TdCurrency, TdNumber, Text, TextArea, TextAreaProps, TextInput, TextInputProps, TextProps, Th, ThSort, ThemeProvider, ToggleButton, ToggleButtonGroup, ToggleButtonGroupProps, ToggleButtonProps, TogglePasswordInput, Tr, WaitingIndicator, calcDynamicThemeProps, defaultTheme, getCurrencyDisplay, getFileSizeDisplay, useAccordianState, useIgnoreMount, useMediaQuery, useThemeSafely };
1000
+ /** Tells you actual width of the scroll bar. This can vary by browser. */
1001
+ declare const useScrollbarSize: (recalc?: boolean | undefined) => number;
1002
+
1003
+ /** Provides stateful notifications around async calls. */
1004
+ declare const useWaiting: <TArgs extends any[], TReturn>(func: (...args: TArgs) => Promise<TReturn>) => [boolean, (...args: TArgs) => Promise<TReturn>];
1005
+
1006
+ /** useEffect but it will only fire when the actual truthiness of the value changes.
1007
+ * Use for comparing previous states to next states without all the bullshit around useEffect and component mounting.
1008
+ */
1009
+ declare const useBooleanChanged: (effect: (current: boolean, previous: boolean) => void, dep: boolean | undefined) => void;
1010
+
1011
+ export { Accordian, AccordianProps, Alignment, Autocomplete, AutocompleteProps, AutocompleteValue, Backdrop$1 as Backdrop, Backdrop as Backdrop2, BoundMemoryPager, BoundStaticPager, Button, ButtonProps, Calendar, CalendarProps, Checkbox, CheckboxProps, ConfirmModal, ConfirmModalProps, CopyButton, DateInput, DateInputProps, Divider, ErrorModal, FileUploader, Form, FormColumnRow, FormFlexRow, FormProps, GlobalStyles, Header, Highlight, ICONS, Icon, Image, InfoPanel, InfoTip, InfoTipProps, Input, InputProps, ItemPager, Label, LabelProps, List, ListItem, ListItemProps, ListProps, MackinTheme, Modal, Nav, NumberInput, NumberInputProps, OmniLink, OmniLinkProps, PagedResult, Pager, PagerProps, Picker, PickerOption, PickerProps, PickerValue, Popover, ProgressBar, ProgressBarProps, SearchBox, SearchBoxProps, Slider, TabHeader, TabHeaderProps, TabLocker, Table, Td, TdCurrency, TdNumber, Text, TextArea, TextAreaProps, TextInput, TextInputProps, TextProps, Th, ThSort, ThemeProvider, ToggleButton, ToggleButtonGroup, ToggleButtonGroupProps, ToggleButtonProps, TogglePasswordInput, Tr, WaitingIndicator, calcDynamicThemeProps, defaultTheme, getCurrencyDisplay, getFileSizeDisplay, useAccordianState, useBooleanChanged, useIgnoreMount, useMediaQuery, useScrollbarSize, useThemeSafely, useWaiting };
package/index.js CHANGED
@@ -1123,7 +1123,7 @@ const useLogger = (componentName, enabled) => {
1123
1123
  return (...messages) => {
1124
1124
  if (enabled) {
1125
1125
  // tslint:disable-next-line
1126
- console.log(componentName, ...messages);
1126
+ console.log(`[${componentName}]`, ...messages);
1127
1127
  }
1128
1128
  };
1129
1129
  };
@@ -1403,11 +1403,41 @@ const Checkbox = (props) => {
1403
1403
  props.children)));
1404
1404
  };
1405
1405
 
1406
+ /** useEffect but it will only fire when the actual truthiness of the value changes.
1407
+ * Use for comparing previous states to next states without all the bullshit around useEffect and component mounting.
1408
+ */
1409
+ const useBooleanChanged = (effect, dep) => {
1410
+ /*
1411
+ Why?
1412
+ useEffect with a dependency array will fire once on mount even though the dependency list doesn't change.
1413
+ Components like Modal need to communicate when their show status changes.
1414
+ useIgnoreMount is not enough because it only ignores the first render and is therefore a kludge.
1415
+ This is what we want regardless of mount status:
1416
+ true > false = Change
1417
+ false > true = Change
1418
+ true > true = No Change
1419
+ false > false = No Change
1420
+ undefined > false = No Change
1421
+ undefined > true = Change
1422
+ */
1423
+ const lastValue = React.useRef(undefined);
1424
+ React.useEffect(() => {
1425
+ //console.log('[useBooleanChanged] useEffect called with', dep, 'was', lastValue.current ?? 'undefined')
1426
+ if (!!lastValue.current !== !!dep) {
1427
+ const previous = lastValue.current;
1428
+ lastValue.current = dep;
1429
+ effect(!!lastValue.current, !!previous);
1430
+ //console.log('[useBooleanChanged] change called')
1431
+ }
1432
+ }, [dep]);
1433
+ };
1434
+
1406
1435
  // Taken from: https://github.com/react-bootstrap/dom-helpers/blob/master/src/scrollbarSize.ts
1407
1436
  const canUseDom = !!(typeof window !== 'undefined' &&
1408
1437
  window.document &&
1409
1438
  window.document.createElement);
1410
1439
  let size;
1440
+ /** Tells you actual width of the scroll bar. This can vary by browser. */
1411
1441
  const useScrollbarSize = (recalc) => {
1412
1442
  if ((!size && size !== 0) || recalc) {
1413
1443
  if (canUseDom) {
@@ -1433,26 +1463,31 @@ const Modal = (p) => {
1433
1463
  const theme = useThemeSafely();
1434
1464
  const hasHeader = p.closeButton || p.heading;
1435
1465
  const contentRef = React__default['default'].useRef(null);
1436
- const log = useLogger(`Modal ${(_a = p.id) !== null && _a !== void 0 ? _a : '?'}`, (_b = p.__debug) !== null && _b !== void 0 ? _b : false);
1466
+ const log = useLogger((_a = p.id) !== null && _a !== void 0 ? _a : 'Modal', (_b = p.__debug) !== null && _b !== void 0 ? _b : false);
1467
+ const tryRemoveBodyStyles = () => {
1468
+ if (backdrop.showCount <= 1 && htmlBodyStyles) {
1469
+ log('backdrop.showCount', backdrop.showCount, 'removing singleton htmlBodyStyles');
1470
+ document.body.classList.remove(htmlBodyStyles);
1471
+ }
1472
+ };
1437
1473
  React.useEffect(() => {
1438
1474
  log('mounted');
1439
1475
  return () => {
1440
1476
  var _a;
1441
1477
  // handle the use of modals that are rendered only as show=true and then unmounted.
1442
- backdrop.setShow(false, (_a = p.id) !== null && _a !== void 0 ? _a : 'Modal');
1443
- log('backdrop.setShow', false);
1444
- if (backdrop.showCount <= 1 && htmlBodyStyles) {
1445
- log('backdrop.showCount', backdrop.showCount, 'removing htmlBodyStyles');
1446
- document.body.classList.remove(htmlBodyStyles);
1478
+ if (p.show) {
1479
+ backdrop.setShow(false, (_a = p.id) !== null && _a !== void 0 ? _a : 'Modal');
1480
+ log('backdrop.setShow', false);
1481
+ tryRemoveBodyStyles();
1447
1482
  }
1448
1483
  log('un-mounted');
1449
1484
  };
1450
1485
  }, []);
1451
- useIgnoreMount(() => {
1486
+ useBooleanChanged((show, previousShow) => {
1452
1487
  var _a;
1453
- log('show changed', p.show);
1454
- backdrop.setShow(p.show, (_a = p.id) !== null && _a !== void 0 ? _a : 'Modal');
1455
- log('backdrop.setShow', p.show);
1488
+ log('show changed', `${previousShow !== null && previousShow !== void 0 ? previousShow : 'undefined'} > ${show}`);
1489
+ backdrop.setShow(show, (_a = p.id) !== null && _a !== void 0 ? _a : 'Modal');
1490
+ log('backdrop.setShow', show);
1456
1491
  if (!htmlBodyStyles) {
1457
1492
  log('creating singleton htmlBodyStyles');
1458
1493
  htmlBodyStyles = css.css({
@@ -1460,17 +1495,14 @@ const Modal = (p) => {
1460
1495
  paddingRight: `${useScrollbarSize()}px`
1461
1496
  });
1462
1497
  }
1463
- if (p.show) {
1464
- log('adding htmlBodyStyles');
1498
+ if (show) {
1499
+ log('adding singleton htmlBodyStyles');
1465
1500
  document.body.classList.add(htmlBodyStyles);
1466
1501
  }
1467
1502
  else {
1468
- if (backdrop.showCount <= 1) {
1469
- log('backdrop.showCount', backdrop.showCount, 'removing htmlBodyStyles');
1470
- document.body.classList.remove(htmlBodyStyles);
1471
- }
1503
+ tryRemoveBodyStyles();
1472
1504
  }
1473
- }, [p.show]);
1505
+ }, p.show);
1474
1506
  React__default['default'].useLayoutEffect(() => {
1475
1507
  var _a;
1476
1508
  if (p.show === true) {
@@ -2241,7 +2273,7 @@ const BaseInput = React__namespace.forwardRef((props, ref) => {
2241
2273
  React__namespace.createElement("div", { className: css.cx('input', inputWrapperStyles, wrapperClassName) },
2242
2274
  inputElement,
2243
2275
  props.rightControl && (React__namespace.createElement("div", { className: rightControlStyles }, props.rightControl))),
2244
- React__namespace.createElement(InputErrorDisplay, { error: props.error })));
2276
+ React__namespace.createElement(InputErrorDisplay, { error: props.readOnly ? undefined : props.error })));
2245
2277
  });
2246
2278
 
2247
2279
  const tryClampRange = (value, min, max) => {
@@ -2738,6 +2770,9 @@ const Label = (props) => {
2738
2770
  From https://fireship.io/snippets/use-media-query-hook/.
2739
2771
  Tried using https://www.npmjs.com/package/react-media, but it cause Webpack build issues.
2740
2772
  */
2773
+ /** React wrapper around window resizing and window.matchMedia.
2774
+ * https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia
2775
+ */
2741
2776
  const useMediaQuery = (query) => {
2742
2777
  const [matches, setMatches] = React.useState(false);
2743
2778
  React.useEffect(() => {
@@ -2753,11 +2788,13 @@ const useMediaQuery = (query) => {
2753
2788
  };
2754
2789
 
2755
2790
  const Nav = (props) => {
2791
+ var _a, _b;
2756
2792
  const nav = React__namespace.useRef(null);
2757
2793
  const theme = useThemeSafely();
2758
2794
  const totalNavOffset = `calc(${theme.layout.navWidth} + 20px)`;
2759
2795
  const backdrop = React__namespace.useContext(BackdropContext);
2760
2796
  const isLargeScreen = useMediaQuery(`(min-width:${theme.breakpoints.desktop})`);
2797
+ const log = useLogger(`Nav ${(_a = props.id) !== null && _a !== void 0 ? _a : '?'}`, (_b = props.__debug) !== null && _b !== void 0 ? _b : false);
2761
2798
  const slideRight = css.keyframes `
2762
2799
  0% {
2763
2800
  transform: translateX(0);
@@ -2818,10 +2855,11 @@ const Nav = (props) => {
2818
2855
  props.toggle(false);
2819
2856
  }
2820
2857
  }, [backdrop.showing]);
2821
- useIgnoreMount(() => {
2858
+ useBooleanChanged((current, previous) => {
2822
2859
  var _a;
2823
- backdrop.setShow(props.show, (_a = props.id) !== null && _a !== void 0 ? _a : 'Nav');
2824
- }, [props.show]);
2860
+ log('show changed', `${previous !== null && previous !== void 0 ? previous : 'undefined'} > ${current}`);
2861
+ backdrop.setShow(current, (_a = props.id) !== null && _a !== void 0 ? _a : 'Nav');
2862
+ }, props.show);
2825
2863
  React__namespace.useLayoutEffect(() => {
2826
2864
  if (nav && nav.current) {
2827
2865
  if (props.show) {
@@ -2852,6 +2890,7 @@ const Nav = (props) => {
2852
2890
  return (React__namespace.createElement("nav", { ref: nav, className: css.cx('nav', navStyles, props.className) }, props.children));
2853
2891
  };
2854
2892
 
2893
+ //TB: FUTURE make just a basic styled link so you don't have to go with React Router if you don't want to.
2855
2894
  const OmniLink = (props) => {
2856
2895
  var _a, _b, _c;
2857
2896
  const theme = useThemeSafely();
@@ -3215,6 +3254,7 @@ const BoundStaticPager = (p) => {
3215
3254
  } })));
3216
3255
  };
3217
3256
 
3257
+ /** A page of data with helpers props. */
3218
3258
  class PagedResult {
3219
3259
  constructor(items = [], total = 0, page = 0, limit = 0) {
3220
3260
  this.items = items;
@@ -3225,10 +3265,6 @@ class PagedResult {
3225
3265
  static fromDto(dto) {
3226
3266
  return new PagedResult(dto.items, dto.total, dto.page, dto.limit);
3227
3267
  }
3228
- // allItems: T[]
3229
- // get pageItems(): T[] {
3230
- // return this.allItems.slice(this.minPageItemIndex, this.maxPageItemIndex + 1)
3231
- // }
3232
3268
  /** Helper for items.length */
3233
3269
  get length() {
3234
3270
  return this.items ? this.items.length : 0;
@@ -3352,7 +3388,7 @@ class PagedResult {
3352
3388
  }
3353
3389
  }
3354
3390
 
3355
- /** For in-memory paging. */
3391
+ /** In-memory pager. */
3356
3392
  class ItemPager {
3357
3393
  constructor(allItems, options) {
3358
3394
  var _a, _b, _c, _d;
@@ -3602,6 +3638,7 @@ const cleanPct = (value) => {
3602
3638
  return 0;
3603
3639
  };
3604
3640
 
3641
+ /** Provides stateful notifications around async calls. */
3605
3642
  const useWaiting = (func) => {
3606
3643
  // Guard against the owner of this hook being unmounted at the time of .finally.
3607
3644
  const isCancelled = React.useRef(false);
@@ -4244,7 +4281,10 @@ exports.defaultTheme = defaultTheme;
4244
4281
  exports.getCurrencyDisplay = getCurrencyDisplay;
4245
4282
  exports.getFileSizeDisplay = getFileSizeDisplay;
4246
4283
  exports.useAccordianState = useAccordianState;
4284
+ exports.useBooleanChanged = useBooleanChanged;
4247
4285
  exports.useIgnoreMount = useIgnoreMount;
4248
4286
  exports.useMediaQuery = useMediaQuery;
4287
+ exports.useScrollbarSize = useScrollbarSize;
4249
4288
  exports.useThemeSafely = useThemeSafely;
4289
+ exports.useWaiting = useWaiting;
4250
4290
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mackin.com/styleguide",
3
- "version": "8.0.0-beta.19",
3
+ "version": "8.0.0-beta.21",
4
4
  "description": "",
5
5
  "main": "./index.js",
6
6
  "types": "./index.d.ts",