@mackin.com/styleguide 7.9.1 → 7.12.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 (3) hide show
  1. package/index.d.ts +30 -8
  2. package/index.js +61 -22
  3. package/package.json +1 -1
package/index.d.ts CHANGED
@@ -204,17 +204,21 @@ interface FileUploaderProps {
204
204
  instructionMessage?: string;
205
205
  /** For additional info below the instructionMessage. */
206
206
  infoMessage?: string | JSX.Element;
207
+ /** If false, the 'infoMessage' will be hidden when a file is picked. Defaults to 'true' */
208
+ showInfoOnPick?: boolean;
209
+ disabled?: boolean;
207
210
  }
208
- declare const FileUploader: (p: FileUploaderProps) => JSX.Element;
211
+ declare const FileUploader: (p: FileUploaderProps) => JSX.Element;
212
+ declare const getFileSizeDisplay: (size: number) => string;
209
213
 
210
- declare type FormProps = React.ClassAttributes<HTMLFormElement> & React.FormHTMLAttributes<HTMLFormElement>;
211
- interface IProps extends FormProps {
214
+ declare type BaseProps = React.ClassAttributes<HTMLFormElement> & React.FormHTMLAttributes<HTMLFormElement>;
215
+ interface FormProps extends BaseProps {
212
216
  inline?: boolean;
213
217
  /** If true, preventDefault and stopPropagation will be applied prior to onSubmit being called. Defaults to true. */
214
218
  ajax?: boolean;
215
219
  }
216
220
  /** Use this instead of <form> directly. If we need to fight Chrome's autofill, we can do so at a global level. */
217
- declare const Form: React.ForwardRefExoticComponent<Pick<IProps, "inline" | "ajax" | "key" | "acceptCharset" | "action" | "autoComplete" | "encType" | "method" | "name" | "noValidate" | "target" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "className" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "hidden" | "id" | "lang" | "placeholder" | "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" | "onChange" | "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"> & React.RefAttributes<HTMLFormElement>>;
221
+ declare const Form: React.ForwardRefExoticComponent<Pick<FormProps, "inline" | "ajax" | "key" | "acceptCharset" | "action" | "autoComplete" | "encType" | "method" | "name" | "noValidate" | "target" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "className" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "hidden" | "id" | "lang" | "placeholder" | "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" | "onChange" | "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"> & React.RefAttributes<HTMLFormElement>>;
218
222
  declare const FormFlexRow: (props: {
219
223
  children: React.ReactNode;
220
224
  className?: string;
@@ -285,13 +289,20 @@ interface InfoTipProps {
285
289
  onClose?: () => void;
286
290
  /** Defaults to 'info'. */
287
291
  variant?: 'info' | 'modal';
288
- modalHeader?: string;
289
292
  /** Defaults to nav color. */
290
293
  bgColor?: string;
291
294
  /** Defaults to nav font color. */
292
295
  fontColor?: string;
296
+ /** For variant=modal only. */
297
+ modalHeader?: string;
298
+ /** For variant=modal only. */
293
299
  modalId?: string;
300
+ /** For variant=modal only. */
294
301
  modalDebug?: boolean;
302
+ /** Whether to move the popover on collision with the parent's bounds. Default is false. For variant=info only. */
303
+ reposition?: boolean;
304
+ /** Order of positions as the Popover colides with the window edge. The default order is ['right', 'top', 'left', 'bottom']. For variant=info only. */
305
+ positions?: ("bottom" | "left" | "right" | "top")[] | undefined;
295
306
  }
296
307
  declare const InfoTip: (props: InfoTipProps) => JSX.Element;
297
308
 
@@ -676,7 +687,7 @@ interface PopoverProps {
676
687
  border?: string;
677
688
  /** Popover background. Defaults to theme.colors.bg. */
678
689
  backgroundColor?: string;
679
- /** Order of positions as the Popover colides with the window edge. */
690
+ /** Order of positions as the Popover colides with the window edge. The default order is ['right', 'top', 'left', 'bottom']. */
680
691
  positions?: ("bottom" | "left" | "right" | "top")[] | undefined;
681
692
  }
682
693
  declare const Popover: (p: PopoverProps) => JSX.Element;
@@ -715,7 +726,14 @@ declare const GlobalStyles: () => null;
715
726
 
716
727
  /** @deprecated This will not work correctly with emotion/css. Use 'cx' for adding multiple class names together. */
717
728
  declare const mergeClassNames: (...classes: (string | boolean | undefined)[]) => string | undefined;
718
- declare const getCurrencyDisplay: (value: number, isCents?: boolean | undefined, denomination?: string) => string;
729
+ declare const getCurrencyDisplay: (value: number, isCents?: boolean | undefined, denomination?: string) => string;
730
+ /** Converts an enum to an array of entities with id and name. The enum can be an integer or string enum.*/
731
+ declare const enumToEntities: <T extends {
732
+ [key: string]: string | number;
733
+ }>(enumObj: T) => {
734
+ id: string | number;
735
+ name: string;
736
+ }[];
719
737
 
720
738
  interface MackinTheme {
721
739
  colors: {
@@ -806,6 +824,10 @@ interface MackinTheme {
806
824
  desktop: string;
807
825
  tablet: string;
808
826
  };
827
+ mediaQueries: {
828
+ desktop: string;
829
+ tablet: string;
830
+ };
809
831
  }
810
832
  /** Call this on your theme after messing with the props. It will re-build things that depend on sizes and colors. */
811
833
  declare const calcDynamicThemeProps: <T extends MackinTheme>(theme: T) => void;
@@ -981,4 +1003,4 @@ declare const WaitingIndicator: (p: {
981
1003
  debug?: boolean;
982
1004
  }) => JSX.Element;
983
1005
 
984
- export { Alignment, Autocomplete, AutocompleteProps, AutocompleteValue, Backdrop$1 as Backdrop, Backdrop as Backdrop2, BoundMemoryPager, BoundStaticPager, Button, ButtonProps, Calendar, CalendarProps, Checkbox, CheckboxProps, ConfirmModal, ConfirmModalProps, CopyButton, DateInput, DateInputProps, DatePicker, DatePickerProps, Divider, ErrorModal, FileUploader, Form, FormColumnRow, FormFlexRow, 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, PickerProps, 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, mergeClassNames, useMediaQuery, useThemeSafely };
1006
+ export { Alignment, Autocomplete, AutocompleteProps, AutocompleteValue, Backdrop$1 as Backdrop, Backdrop as Backdrop2, BoundMemoryPager, BoundStaticPager, Button, ButtonProps, Calendar, CalendarProps, Checkbox, CheckboxProps, ConfirmModal, ConfirmModalProps, CopyButton, DateInput, DateInputProps, DatePicker, DatePickerProps, 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, PickerProps, 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, enumToEntities, getCurrencyDisplay, getFileSizeDisplay, mergeClassNames, useMediaQuery, useThemeSafely };
package/index.js CHANGED
@@ -47,6 +47,8 @@ const calcDynamicThemeProps = (theme) => {
47
47
  theme.controls.focusOutlineShadow = `0px 0px 4px 2px ${theme.colors.focusOutline}`;
48
48
  theme.controls.focusOutlineRequiredShadow = `0px 0px 4px 2px ${theme.colors.focusOutlineRequired}`;
49
49
  theme.controls.dividerBorder = `2px solid ${theme.colors.divider}`;
50
+ theme.mediaQueries.desktop = `@media(min-width:${theme.breakpoints.desktop})`;
51
+ theme.mediaQueries.tablet = `@media(min-width:${theme.breakpoints.tablet})`;
50
52
  };
51
53
  const defaultTheme = {
52
54
  colors: {
@@ -135,6 +137,10 @@ const defaultTheme = {
135
137
  breakpoints: {
136
138
  desktop: '800px',
137
139
  tablet: '768px'
140
+ },
141
+ mediaQueries: {
142
+ desktop: '',
143
+ tablet: ''
138
144
  }
139
145
  };
140
146
  calcDynamicThemeProps(defaultTheme);
@@ -1731,7 +1737,7 @@ const hoverClass = css.css({
1731
1737
  backgroundColor: 'rgba(0,0,0,0.25) !important'
1732
1738
  });
1733
1739
  const FileUploader = (p) => {
1734
- var _a, _b, _c, _d, _e, _f, _g;
1740
+ var _a, _b, _c, _d, _e, _f, _g, _h;
1735
1741
  const [message, setMessage] = React.useState(undefined);
1736
1742
  const [canUpload, setCanUpload] = React.useState(false);
1737
1743
  const [uploading, setUploading] = React.useState(false);
@@ -1747,7 +1753,7 @@ const FileUploader = (p) => {
1747
1753
  filesDisplay = (_b = p.instructionMessage) !== null && _b !== void 0 ? _b : `Click or drag and drop files.`;
1748
1754
  }
1749
1755
  else {
1750
- filesDisplay = `${files.length.toLocaleString()} file${files.length > 1 ? 's' : ''} selected (${getSizeString(totalFileSize)}): ${files.files.map(f => f.name).join(', ')}`;
1756
+ filesDisplay = `${files.length.toLocaleString()} file${files.length > 1 ? 's' : ''} selected (${getFileSizeDisplay(totalFileSize)}): ${files.files.map(f => f.name).join(', ')}`;
1751
1757
  }
1752
1758
  }
1753
1759
  const setAllFiles = (inputFiles) => {
@@ -1769,8 +1775,9 @@ const FileUploader = (p) => {
1769
1775
  maxBytes: p.maxBytes
1770
1776
  });
1771
1777
  };
1778
+ const showInfoOnPick = (_c = p.showInfoOnPick) !== null && _c !== void 0 ? _c : true;
1772
1779
  let infoMessage;
1773
- if (p.infoMessage) {
1780
+ if (p.infoMessage && (!files || showInfoOnPick)) {
1774
1781
  if (typeof p.infoMessage === 'string') {
1775
1782
  infoMessage = React__default['default'].createElement(Text, { noPad: true }, p.infoMessage);
1776
1783
  }
@@ -1787,6 +1794,8 @@ const FileUploader = (p) => {
1787
1794
  padding: '1rem',
1788
1795
  overflow: 'hidden',
1789
1796
  backgroundColor: theme.colors.lightBg,
1797
+ }, p.disabled && {
1798
+ opacity: theme.controls.disabledOpacity
1790
1799
  }), onDragOver: e => {
1791
1800
  var _a, _b;
1792
1801
  e.preventDefault();
@@ -1820,7 +1829,7 @@ const FileUploader = (p) => {
1820
1829
  setCanUpload(false);
1821
1830
  });
1822
1831
  } },
1823
- React__default['default'].createElement("input", { ref: input, className: css.css({
1832
+ React__default['default'].createElement("input", { disabled: p.disabled, ref: input, className: css.css({
1824
1833
  position: 'absolute',
1825
1834
  top: -50,
1826
1835
  left: 0,
@@ -1829,6 +1838,8 @@ const FileUploader = (p) => {
1829
1838
  width: '100%',
1830
1839
  cursor: 'pointer',
1831
1840
  opacity: 0
1841
+ }, p.disabled && {
1842
+ cursor: 'not-allowed'
1832
1843
  }), type: "file", multiple: p.multiple, accept: p.accept, onChange: e => {
1833
1844
  try {
1834
1845
  if (!e.target.files) {
@@ -1851,26 +1862,28 @@ const FileUploader = (p) => {
1851
1862
  zIndex: !!(files === null || files === void 0 ? void 0 : files.length) ? 1 : undefined
1852
1863
  }) },
1853
1864
  !(files === null || files === void 0 ? void 0 : files.length) && React__default['default'].createElement(Icon, { style: { fontSize: '2rem' }, id: "upload" }),
1854
- React__default['default'].createElement(Text, { align: "center", noPad: true, spacedOut: true },
1865
+ React__default['default'].createElement(Text, { align: "center", noPad: true, spacedOut: true, className: css.css({
1866
+ width: '100%'
1867
+ }) },
1855
1868
  filesDisplay,
1856
1869
  !!(files === null || files === void 0 ? void 0 : files.length) && (React__default['default'].createElement(Button, { onClick: e => {
1857
1870
  e.stopPropagation();
1858
1871
  onFilesChange(undefined);
1859
1872
  }, className: css.css({ marginLeft: '1rem', color: theme.colors.negative }), rightIcon: React__default['default'].createElement(Icon, { id: "clear" }), variant: "inlineLink" }, "Clear"))),
1860
1873
  infoMessage,
1861
- !!(files === null || files === void 0 ? void 0 : files.invalidFiles.length) && (React__default['default'].createElement(InfoPanel, { variant: "error" },
1874
+ !!(files === null || files === void 0 ? void 0 : files.invalidFiles.length) && (React__default['default'].createElement(InfoPanel, { variant: "error", className: css.css({ width: '100%' }) },
1862
1875
  "Invalid files: ",
1863
1876
  files.invalidFiles.map(f => f.name).join(', '),
1864
1877
  ".")),
1865
- (files === null || files === void 0 ? void 0 : files.overMaxBytes) && (React__default['default'].createElement(InfoPanel, { variant: "error" },
1878
+ (files === null || files === void 0 ? void 0 : files.overMaxBytes) && (React__default['default'].createElement(InfoPanel, { variant: "error", className: css.css({ width: '100%' }) },
1866
1879
  "Max file size exceeded (",
1867
- getSizeString((_c = p.maxBytes) !== null && _c !== void 0 ? _c : 0),
1880
+ getFileSizeDisplay((_d = p.maxBytes) !== null && _d !== void 0 ? _d : 0),
1868
1881
  ").")))),
1869
1882
  canUpload && !(files === null || files === void 0 ? void 0 : files.hasErrors) && (React__default['default'].createElement(Button, { className: css.css({
1870
- width: (_d = p.buttonWidth) !== null && _d !== void 0 ? _d : '10rem',
1883
+ width: (_e = p.buttonWidth) !== null && _e !== void 0 ? _e : '10rem',
1871
1884
  zIndex: 1,
1872
- }), waiting: uploading, type: "submit", variant: (_e = p.buttonVariant) !== null && _e !== void 0 ? _e : 'primary' }, (_f = p.buttonText) !== null && _f !== void 0 ? _f : 'Upload')),
1873
- message === 'success' && (React__default['default'].createElement(UploadInfoPanel, { variant: "positive", message: (_g = p.successMessage) !== null && _g !== void 0 ? _g : 'Upload successful.', onClear: () => setMessage(undefined) })),
1885
+ }), waiting: uploading, type: "submit", variant: (_f = p.buttonVariant) !== null && _f !== void 0 ? _f : 'primary' }, (_g = p.buttonText) !== null && _g !== void 0 ? _g : 'Upload')),
1886
+ message === 'success' && (React__default['default'].createElement(UploadInfoPanel, { variant: "positive", message: (_h = p.successMessage) !== null && _h !== void 0 ? _h : 'Upload successful.', onClear: () => setMessage(undefined) })),
1874
1887
  message === 'failure' && (React__default['default'].createElement(UploadInfoPanel, { variant: "error", message: fullFailureMessage, onClear: () => setMessage(undefined) }))));
1875
1888
  };
1876
1889
  const UploadInfoPanel = (p) => {
@@ -1884,18 +1897,28 @@ const UploadInfoPanel = (p) => {
1884
1897
  p.onClear();
1885
1898
  }, rightIcon: React__default['default'].createElement(Icon, { id: "clear" }), variant: "inlineLink" }, "Clear")));
1886
1899
  };
1887
- const bytesInMb = 1048576;
1888
- const bytesInKb = 1024;
1889
- const getSizeString = (size) => {
1890
- if (size < bytesInKb) {
1891
- return size.toLocaleString() + ' B';
1892
- }
1893
- else if (size < bytesInMb) {
1894
- return (size / bytesInKb).toLocaleString(undefined, { minimumFractionDigits: 1, maximumFractionDigits: 1 }) + ' KB';
1900
+ // OMG this is dumb. We're sticking with decimals for ease of use.
1901
+ // https://stackoverflow.com/questions/40949135/gigabyte-or-gibibyte-1000-or-1024
1902
+ const getFileSizeDisplay = (size) => {
1903
+ let value = 0;
1904
+ let suffix = '';
1905
+ if (size >= 1000000000) {
1906
+ value = size / 1000000000;
1907
+ suffix = 'GB';
1908
+ }
1909
+ else if (size >= 1000000) {
1910
+ value = size / 1000000;
1911
+ suffix = 'MB';
1912
+ }
1913
+ else if (size >= 1000) {
1914
+ value = size / 1000;
1915
+ suffix = 'KB';
1895
1916
  }
1896
1917
  else {
1897
- return (size / bytesInMb).toLocaleString(undefined, { minimumFractionDigits: 1, maximumFractionDigits: 1 }) + ' MB';
1918
+ value = size;
1919
+ suffix = 'B';
1898
1920
  }
1921
+ return value.toLocaleString(undefined, { minimumFractionDigits: 1, maximumFractionDigits: 1 }) + ` ${suffix}`;
1899
1922
  };
1900
1923
 
1901
1924
  /** @deprecated This will not work correctly with emotion/css. Use 'cx' for adding multiple class names together. */
@@ -1914,6 +1937,20 @@ const getCurrencyDisplay = (value, isCents, denomination = '$') => {
1914
1937
  };
1915
1938
  const noop = () => {
1916
1939
  // lil' noop would be a great rap name. (thanks linter)
1940
+ };
1941
+ //TB: this will need to be exposed in v8 on the helpers page.
1942
+ /** Converts an enum to an array of entities with id and name. The enum can be an integer or string enum.*/
1943
+ const enumToEntities = (enumObj) => {
1944
+ const entities = [];
1945
+ for (const key in enumObj) {
1946
+ if (isNaN(parseInt(key, 10))) {
1947
+ entities.push({
1948
+ id: enumObj[key],
1949
+ name: key
1950
+ });
1951
+ }
1952
+ }
1953
+ return entities;
1917
1954
  };
1918
1955
 
1919
1956
  const Header = (props) => {
@@ -2038,7 +2075,7 @@ const Image = (props) => {
2038
2075
  };
2039
2076
 
2040
2077
  const InfoTip = (props) => {
2041
- var _a, _b;
2078
+ var _a, _b, _c;
2042
2079
  const [showTip, setShowTip] = React__namespace.useState(false);
2043
2080
  const theme = useThemeSafely();
2044
2081
  const bgColor = (_a = props.bgColor) !== null && _a !== void 0 ? _a : theme.colors.nav;
@@ -2106,7 +2143,7 @@ const InfoTip = (props) => {
2106
2143
  React__namespace.createElement("div", { className: css.css({ padding: '1rem' }) }, props.content))));
2107
2144
  }
2108
2145
  else {
2109
- return (React__namespace.createElement(Popover, { reposition: false, isOpen: showTip, onClickOutside: closeTip, arrorColor: bgColor, border: '', backgroundColor: bgColor, parent: button, content: (React__namespace.createElement("div", { className: css.css({
2146
+ return (React__namespace.createElement(Popover, { positions: props.positions, reposition: (_c = props.reposition) !== null && _c !== void 0 ? _c : false, isOpen: showTip, onClickOutside: closeTip, arrorColor: bgColor, border: '', backgroundColor: bgColor, parent: button, content: (React__namespace.createElement("div", { className: css.css({
2110
2147
  padding: '0.5rem',
2111
2148
  fontSize: '0.75rem',
2112
2149
  maxWidth: '22rem'
@@ -3862,7 +3899,9 @@ exports.Tr = Tr;
3862
3899
  exports.WaitingIndicator = WaitingIndicator;
3863
3900
  exports.calcDynamicThemeProps = calcDynamicThemeProps;
3864
3901
  exports.defaultTheme = defaultTheme;
3902
+ exports.enumToEntities = enumToEntities;
3865
3903
  exports.getCurrencyDisplay = getCurrencyDisplay;
3904
+ exports.getFileSizeDisplay = getFileSizeDisplay;
3866
3905
  exports.mergeClassNames = mergeClassNames;
3867
3906
  exports.useMediaQuery = useMediaQuery;
3868
3907
  exports.useThemeSafely = useThemeSafely;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mackin.com/styleguide",
3
- "version": "7.9.1",
3
+ "version": "7.12.0",
4
4
  "description": "",
5
5
  "main": "./index.js",
6
6
  "types": "./index.d.ts",