@mackin.com/styleguide 8.6.2 → 8.8.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 +29 -3
  2. package/index.js +300 -232
  3. package/package.json +1 -1
package/index.d.ts CHANGED
@@ -212,15 +212,19 @@ interface FormProps extends BaseProps$3 {
212
212
  inline?: boolean;
213
213
  /** If true, preventDefault and stopPropagation will be applied prior to onSubmit being called. Defaults to true. */
214
214
  ajax?: boolean;
215
+ /** Removes the opinionated flex styling. 'inline' will be ignored. */
216
+ unstyled?: boolean;
215
217
  }
216
218
  /** 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<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>>;
219
+ declare const Form: React.ForwardRefExoticComponent<Pick<FormProps, "inline" | "ajax" | "unstyled" | "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>>;
220
+ /** @deprecated Just style normally using flex, grid, etc. */
218
221
  declare const FormFlexRow: (props: {
219
222
  children: React.ReactNode;
220
223
  className?: string;
221
224
  style?: React.CSSProperties;
222
225
  justifyContent?: "space-around" | "space-between" | "space-evenly" | "stretch" | "center" | "end" | "flex-end" | "flex-start" | "start";
223
226
  }) => JSX.Element;
227
+ /** @deprecated Just style normally using flex, grid, etc. */
224
228
  declare const FormColumnRow: (props: {
225
229
  children: React.ReactNode;
226
230
  cols: number;
@@ -461,6 +465,8 @@ interface ModalProps {
461
465
  __debug?: boolean;
462
466
  onClick?: () => void;
463
467
  }
468
+ /** Add to fixed positioned elements so their contents do not jump around when scrolling is disabled. */
469
+ declare const modalScrollFixClassName = "modal-scroll-fix";
464
470
  declare const Modal: (p: ModalProps) => React__default.ReactPortal | null;
465
471
 
466
472
  declare const Nav: (props: {
@@ -709,11 +715,14 @@ interface SearchBoxProps {
709
715
  id?: string;
710
716
  placeholder?: string;
711
717
  round?: boolean;
712
- className?: string;
713
718
  onSubmit?: () => Promise<void>;
714
719
  /** Defaults to 250ms */
715
720
  debounceMs?: number;
716
721
  autoFocus?: boolean;
722
+ /** This will be applied to the containing element (Form). */
723
+ className?: string;
724
+ buttonClassName?: string;
725
+ inputClassName?: string;
717
726
  }
718
727
  declare const SearchBox: (props: SearchBoxProps) => JSX.Element;
719
728
 
@@ -728,7 +737,9 @@ interface MackinTheme {
728
737
  primary2: string;
729
738
  primary2Font: string;
730
739
  secondary: string;
740
+ /** @deprecated Bad name. Use 'secondaryFont'. */
731
741
  secondary2Font: string;
742
+ secondaryFont: string;
732
743
  info: string;
733
744
  infoFont: string;
734
745
  warning: string;
@@ -781,7 +792,10 @@ interface MackinTheme {
781
792
  height: string;
782
793
  heightSmall: string;
783
794
  boxShadow: string;
795
+ /** For controls with a background color. */
784
796
  hoverBrightness: string;
797
+ /** For controls without a background color. */
798
+ hoverBackground: string;
785
799
  transitionDuration: string;
786
800
  transitionEasing: string;
787
801
  transition: string;
@@ -859,6 +873,18 @@ interface SliderProps<T extends SliderValue> {
859
873
  renderValue?: (value: number) => string;
860
874
  /** Used with renderValue for the custom element width. Defaults to theme.controls.height * 2. */
861
875
  renderValueWidth?: string;
876
+ /** Styles of the overall slider. */
877
+ className?: string;
878
+ /** Styles for the slider handles. */
879
+ handleClassName?: string;
880
+ /** Styles for the first handle. */
881
+ handle1ClassName?: string;
882
+ /** Styles for the second handle. Ignored if the value is not an array. */
883
+ handle2ClassName?: string;
884
+ /** Styles of the track. */
885
+ trackClassName?: string;
886
+ /** Styles applied to the track between two handlers. Ignored if the value is not an array. */
887
+ innerTrackClassName?: string;
862
888
  }
863
889
  declare const Slider: <T extends SliderValue>(p: SliderProps<T>) => JSX.Element;
864
890
 
@@ -1104,4 +1130,4 @@ interface TabContainerProps {
1104
1130
  }
1105
1131
  declare const TabContainer: (p: TabContainerProps) => JSX.Element;
1106
1132
 
1107
- 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, ImageProps, InfoPanel, InfoTip, InfoTipProps, Input, InputProps, ItemPager, Label, LabelProps, Link, LinkProps, List, ListItem, ListItemProps, ListProps, MackinTheme, Modal, ModalProps, Nav, NormalizeCss, NumberInput, NumberInputProps, OmniLink, OmniLinkProps, PagedResult, Pager, PagerProps, Picker, PickerOption, PickerProps, PickerValue, Popover, ProgressBar, ProgressBarProps, SearchBox, SearchBoxProps, Slider, TabContainer, TabContainerProps, TabHeader, TabHeaderProps, TabLocker, Table, Td, TdCurrency, TdNumber, Text, TextArea, TextAreaProps, TextInput, TextInputProps, TextProps, Th, ThSort, ThemeProvider, ThemeRenderer, ToggleButton, ToggleButtonGroup, ToggleButtonGroupProps, ToggleButtonProps, TogglePasswordInput, Tr, WaitingIndicator, calcDynamicThemeProps, defaultTheme, enumToEntities, getCurrencyDisplay, getFileSizeDisplay, useAccordianState, useBooleanChanged, useIgnoreMount, useMediaQuery, useScrollbarSize, useThemeSafely, useWaiting };
1133
+ 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, ImageProps, InfoPanel, InfoTip, InfoTipProps, Input, InputProps, ItemPager, Label, LabelProps, Link, LinkProps, List, ListItem, ListItemProps, ListProps, MackinTheme, Modal, ModalProps, Nav, NormalizeCss, NumberInput, NumberInputProps, OmniLink, OmniLinkProps, PagedResult, Pager, PagerProps, Picker, PickerOption, PickerProps, PickerValue, Popover, ProgressBar, ProgressBarProps, SearchBox, SearchBoxProps, Slider, TabContainer, TabContainerProps, TabHeader, TabHeaderProps, TabLocker, Table, Td, TdCurrency, TdNumber, Text, TextArea, TextAreaProps, TextInput, TextInputProps, TextProps, Th, ThSort, ThemeProvider, ThemeRenderer, ToggleButton, ToggleButtonGroup, ToggleButtonGroupProps, ToggleButtonProps, TogglePasswordInput, Tr, WaitingIndicator, calcDynamicThemeProps, defaultTheme, enumToEntities, getCurrencyDisplay, getFileSizeDisplay, modalScrollFixClassName, useAccordianState, useBooleanChanged, useIgnoreMount, useMediaQuery, useScrollbarSize, useThemeSafely, useWaiting };
package/index.js CHANGED
@@ -128,6 +128,7 @@ const defaultTheme = {
128
128
  primary2: '#007bff',
129
129
  primary2Font: 'rgba(255, 255, 255, 0.9)',
130
130
  secondary: '#9e9e9e',
131
+ secondaryFont: 'rgba(255, 255, 255, 0.9)',
131
132
  secondary2Font: 'rgba(255, 255, 255, 0.9)',
132
133
  info: '#7851a9',
133
134
  infoFont: 'rgba(255, 255, 255, 0.9)',
@@ -182,7 +183,8 @@ const defaultTheme = {
182
183
  boxShadow: '2px 2px 4px rgba(0, 0, 0, 0.25)',
183
184
  headerBoxShadow: '0px 2px 12px 6px rgba(0, 0, 0, 0.2)',
184
185
  buttonBoxShadow: '2px 2px 4px rgba(0, 0, 0, 0.25)',
185
- hoverBrightness: 'brightness(0.75)',
186
+ hoverBrightness: 'brightness(0.8)',
187
+ hoverBackground: 'rgba(0, 0, 0, 0.1)',
186
188
  transitionDuration: '0.25s',
187
189
  transitionEasing: 'ease-in-out',
188
190
  transition: '',
@@ -282,6 +284,13 @@ const Text = (props) => {
282
284
  if (props.leftPad) {
283
285
  style.paddingLeft = props.leftPad;
284
286
  }
287
+ let fontWeight;
288
+ if (props.bold) {
289
+ fontWeight = 'bold';
290
+ }
291
+ else if (props.bold === false) {
292
+ fontWeight = 'normal';
293
+ }
285
294
  const styles = css.css(getTagStyles(theme, tagChoice), {
286
295
  userSelect: 'text',
287
296
  label: 'Text',
@@ -295,7 +304,7 @@ const Text = (props) => {
295
304
  overflow: 'hidden',
296
305
  textOverflow: 'ellipsis',
297
306
  display: '-webkit-box'
298
- }, props.spacedOut && { lineHeight: '1.5rem' }, props.bold && { fontWeight: 'bold' }, props.noPad && { margin: 0, padding: 0 }, headerRegex.test((_b = props.tag) !== null && _b !== void 0 ? _b : '') && {
307
+ }, props.spacedOut && { lineHeight: '1.5rem' }, { fontWeight }, props.noPad && { margin: 0, padding: 0 }, headerRegex.test((_b = props.tag) !== null && _b !== void 0 ? _b : '') && {
299
308
  fontFamily: theme.fonts.headerFamily
300
309
  });
301
310
  return React__namespace.createElement(tagChoice, {
@@ -304,6 +313,7 @@ const Text = (props) => {
304
313
  }, props.children);
305
314
  };
306
315
 
316
+ //TB: FUTURE de-dup these styles. create individual styles and compose them manually.
307
317
  const Button = React__namespace.forwardRef((props, ref) => {
308
318
  var _a;
309
319
  const { variant, round, rightIcon, leftIcon, iconBlock, small, readOnly, waiting, enforceMinWidth, controlAlign } = props, nativeProps = __rest(props, ["variant", "round", "rightIcon", "leftIcon", "iconBlock", "small", "readOnly", "waiting", "enforceMinWidth", "controlAlign"]);
@@ -368,6 +378,9 @@ const Button = React__namespace.forwardRef((props, ref) => {
368
378
  justify-content: center;
369
379
  align-items: center;
370
380
  background-color: transparent;
381
+ &:hover:not(:disabled) {
382
+ background-color: ${theme.controls.hoverBackground};
383
+ }
371
384
  ${props.small && `
372
385
  width: ${theme.controls.heightSmall};
373
386
  min-width: ${theme.controls.heightSmall};
@@ -380,6 +393,9 @@ const Button = React__namespace.forwardRef((props, ref) => {
380
393
  box-shadow: none;
381
394
  border: none;
382
395
  background-color: transparent;
396
+ &:hover:not(:disabled) {
397
+ background-color: ${theme.controls.hoverBackground};
398
+ }
383
399
  `}
384
400
  ${(props.variant === 'text') && `
385
401
  background-color: transparent;
@@ -496,7 +512,6 @@ const Button = React__namespace.forwardRef((props, ref) => {
496
512
  if (props.controlAlign) {
497
513
  return (React__namespace.createElement("span", { className: css.css({
498
514
  display: 'inline-block',
499
- width: '100%',
500
515
  paddingBottom: theme.controls.inputErrorMinHeight
501
516
  }) }, content));
502
517
  }
@@ -1154,6 +1169,240 @@ const Backdrop$1 = (props) => {
1154
1169
  }, ref: backdrop, className: css.cx('backdrop', styles, props.className) }, props.children));
1155
1170
  };
1156
1171
 
1172
+ /** useEffect but it will only fire when the actual truthiness of the value changes.
1173
+ * Use for comparing previous states to next states without all the bullshit around useEffect and component mounting.
1174
+ */
1175
+ const useBooleanChanged = (effect, dep) => {
1176
+ /*
1177
+ Why?
1178
+ useEffect with a dependency array will fire once on mount even though the dependency list doesn't change.
1179
+ Components like Modal need to communicate when their show status changes.
1180
+ useIgnoreMount is not enough because it only ignores the first render and is therefore a kludge.
1181
+ This is what we want regardless of mount status:
1182
+ true > false = Change
1183
+ false > true = Change
1184
+ true > true = No Change
1185
+ false > false = No Change
1186
+ undefined > false = No Change
1187
+ undefined > true = Change
1188
+ */
1189
+ const lastValue = React.useRef(undefined);
1190
+ React.useEffect(() => {
1191
+ //console.log('[useBooleanChanged] useEffect called with', dep, 'was', lastValue.current ?? 'undefined')
1192
+ if (!!lastValue.current !== !!dep) {
1193
+ const previous = lastValue.current;
1194
+ lastValue.current = dep;
1195
+ effect(!!lastValue.current, !!previous);
1196
+ //console.log('[useBooleanChanged] change called')
1197
+ }
1198
+ }, [dep]);
1199
+ };
1200
+
1201
+ const useLogger = (componentName, enabled) => {
1202
+ return (...messages) => {
1203
+ if (enabled) {
1204
+ // tslint:disable-next-line
1205
+ console.log(`[${componentName}]`, ...messages);
1206
+ }
1207
+ };
1208
+ };
1209
+
1210
+ // Taken from: https://github.com/react-bootstrap/dom-helpers/blob/master/src/scrollbarSize.ts
1211
+ const canUseDom = !!(typeof window !== 'undefined' &&
1212
+ window.document &&
1213
+ window.document.createElement);
1214
+ let size;
1215
+ /** Tells you actual width of the scroll bar. This can vary by browser. */
1216
+ const useScrollbarSize = (recalc) => {
1217
+ if ((!size && size !== 0) || recalc) {
1218
+ if (canUseDom) {
1219
+ const scrollDiv = document.createElement('div');
1220
+ scrollDiv.style.position = 'absolute';
1221
+ scrollDiv.style.top = '-9999px';
1222
+ scrollDiv.style.width = '50px';
1223
+ scrollDiv.style.height = '50px';
1224
+ scrollDiv.style.overflow = 'scroll';
1225
+ document.body.appendChild(scrollDiv);
1226
+ size = scrollDiv.offsetWidth - scrollDiv.clientWidth;
1227
+ document.body.removeChild(scrollDiv);
1228
+ }
1229
+ }
1230
+ return size;
1231
+ };
1232
+
1233
+ /** Add to fixed positioned elements so their contents do not jump around when scrolling is disabled. */
1234
+ const modalScrollFixClassName = 'modal-scroll-fix';
1235
+ const Modal = (p) => {
1236
+ var _a, _b, _c, _d;
1237
+ const backdrop = React.useContext(BackdropContext);
1238
+ const mouseDownElement = React.useRef(undefined);
1239
+ const theme = useThemeSafely();
1240
+ const hasHeader = p.closeButton || p.heading;
1241
+ const contentRef = React__default['default'].useRef(null);
1242
+ const log = useLogger((_a = p.id) !== null && _a !== void 0 ? _a : 'Modal', (_b = p.__debug) !== null && _b !== void 0 ? _b : false);
1243
+ const showing = React.useRef(p.show);
1244
+ const bodyStyles = React.useRef('');
1245
+ const fixedElementStyles = React.useRef('');
1246
+ const addScrollStyles = () => {
1247
+ var _a, _b, _c, _d;
1248
+ if (!bodyStyles.current) {
1249
+ bodyStyles.current = css.css({
1250
+ label: 'ModalBodyOverrides_' + ((_b = (_a = p.id) === null || _a === void 0 ? void 0 : _a.replace(/\s+/, '')) !== null && _b !== void 0 ? _b : nanoid.nanoid()),
1251
+ overflow: 'hidden',
1252
+ paddingRight: `${useScrollbarSize()}px`
1253
+ });
1254
+ log('creating singleton bodyStyles', bodyStyles.current);
1255
+ }
1256
+ if (!fixedElementStyles.current) {
1257
+ fixedElementStyles.current = css.css({
1258
+ label: 'ModalElementOverrides_' + ((_d = (_c = p.id) === null || _c === void 0 ? void 0 : _c.replace(/\s+/, '')) !== null && _d !== void 0 ? _d : nanoid.nanoid()),
1259
+ paddingRight: `${useScrollbarSize()}px`
1260
+ });
1261
+ }
1262
+ document.body.classList.add(bodyStyles.current);
1263
+ Array.from(document.querySelectorAll(`.${modalScrollFixClassName}`)).forEach(e => {
1264
+ e.classList.add(fixedElementStyles.current);
1265
+ });
1266
+ };
1267
+ const tryRemoveScrollStyles = () => {
1268
+ if (bodyStyles.current) {
1269
+ log('removing singleton', bodyStyles.current);
1270
+ document.body.classList.remove(bodyStyles.current);
1271
+ }
1272
+ if (fixedElementStyles.current) {
1273
+ Array.from(document.querySelectorAll(`.${modalScrollFixClassName}`)).forEach(e => {
1274
+ e.classList.remove(fixedElementStyles.current);
1275
+ });
1276
+ }
1277
+ };
1278
+ React.useEffect(() => {
1279
+ log('mounted');
1280
+ return () => {
1281
+ var _a;
1282
+ if (showing.current) {
1283
+ log(`un-mount in progress and this modal is showing. decrement the backdrop and try to remove singleton body styles.`);
1284
+ backdrop.setShow(false, (_a = p.id) !== null && _a !== void 0 ? _a : 'Modal');
1285
+ log('backdrop.setShow', false);
1286
+ tryRemoveScrollStyles();
1287
+ }
1288
+ else {
1289
+ log(`un-mount in progress but this modal is not showing. do nothing with the backdrop.`);
1290
+ }
1291
+ log('un-mounted');
1292
+ };
1293
+ }, []);
1294
+ useBooleanChanged((show, previousShow) => {
1295
+ var _a;
1296
+ log('show changed', `${previousShow !== null && previousShow !== void 0 ? previousShow : 'undefined'} > ${show}`);
1297
+ backdrop.setShow(show, (_a = p.id) !== null && _a !== void 0 ? _a : 'Modal');
1298
+ showing.current = show;
1299
+ log('backdrop.setShow', show);
1300
+ if (show) {
1301
+ log('this modal is showing. adding singleton bodyStyles', bodyStyles.current);
1302
+ addScrollStyles();
1303
+ }
1304
+ else {
1305
+ log('this modal is hiding. try removing singleton bodyStyles');
1306
+ tryRemoveScrollStyles();
1307
+ }
1308
+ }, p.show);
1309
+ React__default['default'].useLayoutEffect(() => {
1310
+ var _a;
1311
+ if (p.show === true) {
1312
+ const focusSelector = (_a = p.focusSelector) !== null && _a !== void 0 ? _a : '.modalCloseButton';
1313
+ // still need to wait for the next tick so the children are all rendered.
1314
+ setTimeout(() => {
1315
+ var _a;
1316
+ const element = (_a = contentRef.current) === null || _a === void 0 ? void 0 : _a.querySelector(focusSelector);
1317
+ element === null || element === void 0 ? void 0 : element.focus();
1318
+ log('set focus', focusSelector);
1319
+ });
1320
+ }
1321
+ }, [p.show]);
1322
+ const modalBodyStyles = css.css({
1323
+ maxHeight: p.scrollable ? undefined : '99vh',
1324
+ overflow: 'hidden',
1325
+ zIndex: theme.zIndexes.modal,
1326
+ cursor: 'default',
1327
+ margin: '1rem',
1328
+ backgroundColor: p.noBackground ? undefined : theme.colors.modalBg,
1329
+ border: p.noBackground ? undefined : theme.controls.border,
1330
+ boxShadow: p.noBackground ? undefined : theme.controls.boxShadow,
1331
+ maxWidth: (_c = p.maxWidth) !== null && _c !== void 0 ? _c : theme.breakpoints.tablet,
1332
+ minWidth: (_d = p.minWidth) !== null && _d !== void 0 ? _d : (hasHeader ? '250px' : undefined),
1333
+ opacity: p.show ? 1 : 0,
1334
+ fontSize: theme.fonts.size,
1335
+ fontFamily: theme.fonts.family,
1336
+ fontWeight: 'normal',
1337
+ '&:focus': {
1338
+ outline: 'none'
1339
+ }
1340
+ });
1341
+ const modalHeaderStyles = css.cx(css.css({
1342
+ display: 'flex',
1343
+ justifyContent: 'space-between',
1344
+ alignItems: 'center',
1345
+ backgroundColor: theme.colors.header,
1346
+ padding: '1rem',
1347
+ color: theme.colors.headerFont
1348
+ }), p.headerClassName);
1349
+ const modalContainerStyles = css.css([{
1350
+ position: 'fixed',
1351
+ height: '100%',
1352
+ width: '100%',
1353
+ backgroundColor: "transparent",
1354
+ display: 'flex',
1355
+ justifyContent: 'center',
1356
+ alignItems: 'center',
1357
+ cursor: p.onClick ? 'pointer' : 'default'
1358
+ }, p.scrollable && {
1359
+ overflowY: 'auto',
1360
+ overflowX: 'hidden',
1361
+ alignItems: 'flex-start'
1362
+ }]);
1363
+ if (p.show) {
1364
+ const backdropContainer = document.getElementById(backdrop.portalId);
1365
+ if (backdropContainer) {
1366
+ return reactDom.createPortal((React__default['default'].createElement("div", { onClick: e => {
1367
+ e.stopPropagation();
1368
+ if (!mouseDownElement.current) {
1369
+ if (p.onClick) {
1370
+ log('backdropContainer onClick');
1371
+ p.onClick();
1372
+ }
1373
+ }
1374
+ mouseDownElement.current = undefined;
1375
+ }, className: css.cx('modalContainer', modalContainerStyles) },
1376
+ React__default['default'].createElement("div", { id: p.id, ref: contentRef, onClick: e => e.stopPropagation(), onMouseDown: e => {
1377
+ mouseDownElement.current = e.target;
1378
+ e.stopPropagation();
1379
+ }, onMouseUp: e => {
1380
+ mouseDownElement.current = undefined;
1381
+ /*
1382
+ MouseDown and MouseUp stopPropagation was added to fix bugs while clicking within the modal.
1383
+ At least in the case of MouseUp, this breaks sliders and the handle grab logic appears to live on window.
1384
+ Turning this off now. Should not cause any issues for MouseUp unlike MouseDown.
1385
+ */
1386
+ // e.stopPropagation()
1387
+ }, className: css.cx('modalBody', modalBodyStyles, p.className) },
1388
+ React__default['default'].createElement(TabLocker, null,
1389
+ hasHeader && (React__default['default'].createElement("header", { className: css.cx('modalHeader', modalHeaderStyles) },
1390
+ p.heading ? React__default['default'].createElement(Text, { className: css.css({
1391
+ margin: 0,
1392
+ flexGrow: 1
1393
+ }), tag: "h1", bold: true }, p.heading) : React__default['default'].createElement("span", null),
1394
+ p.closeButton && p.onClick ? React__default['default'].createElement(Button, { className: css.cx('modalCloseButton', css.css({
1395
+ color: theme.colors.headerFont,
1396
+ marginLeft: '1rem',
1397
+ backgroundColor: 'transparent'
1398
+ })), variant: "icon", onClick: p.onClick },
1399
+ React__default['default'].createElement(Icon, { id: "close" })) : React__default['default'].createElement("span", null))),
1400
+ p.children)))), backdropContainer);
1401
+ }
1402
+ }
1403
+ return null;
1404
+ };
1405
+
1157
1406
  /** useEffect but ignores the first call on component mount. */
1158
1407
  const useIgnoreMount = (effect, deps) => {
1159
1408
  const mounted = React__default['default'].useRef(false);
@@ -1167,15 +1416,6 @@ const useIgnoreMount = (effect, deps) => {
1167
1416
  }, deps);
1168
1417
  };
1169
1418
 
1170
- const useLogger = (componentName, enabled) => {
1171
- return (...messages) => {
1172
- if (enabled) {
1173
- // tslint:disable-next-line
1174
- console.log(`[${componentName}]`, ...messages);
1175
- }
1176
- };
1177
- };
1178
-
1179
1419
  const portalId = 'backdrop';
1180
1420
  const BackdropContext = React__default['default'].createContext({
1181
1421
  showing: false,
@@ -1222,7 +1462,7 @@ const BackdropContextProvider = (p) => {
1222
1462
  }
1223
1463
  } },
1224
1464
  p.children,
1225
- p.__debug && (React__default['default'].createElement("p", { className: css.css({
1465
+ p.__debug && (React__default['default'].createElement("p", { className: css.cx(modalScrollFixClassName, css.css({
1226
1466
  position: 'fixed',
1227
1467
  top: 0, right: 0,
1228
1468
  backgroundColor: '#ff00004f',
@@ -1230,7 +1470,7 @@ const BackdropContextProvider = (p) => {
1230
1470
  padding: '0.5rem',
1231
1471
  margin: 0,
1232
1472
  zIndex: 9999
1233
- }) },
1473
+ })) },
1234
1474
  "Backdrop showCount: ",
1235
1475
  showCount))));
1236
1476
  };
@@ -1445,210 +1685,6 @@ const Checkbox = (props) => {
1445
1685
  props.children)));
1446
1686
  };
1447
1687
 
1448
- /** useEffect but it will only fire when the actual truthiness of the value changes.
1449
- * Use for comparing previous states to next states without all the bullshit around useEffect and component mounting.
1450
- */
1451
- const useBooleanChanged = (effect, dep) => {
1452
- /*
1453
- Why?
1454
- useEffect with a dependency array will fire once on mount even though the dependency list doesn't change.
1455
- Components like Modal need to communicate when their show status changes.
1456
- useIgnoreMount is not enough because it only ignores the first render and is therefore a kludge.
1457
- This is what we want regardless of mount status:
1458
- true > false = Change
1459
- false > true = Change
1460
- true > true = No Change
1461
- false > false = No Change
1462
- undefined > false = No Change
1463
- undefined > true = Change
1464
- */
1465
- const lastValue = React.useRef(undefined);
1466
- React.useEffect(() => {
1467
- //console.log('[useBooleanChanged] useEffect called with', dep, 'was', lastValue.current ?? 'undefined')
1468
- if (!!lastValue.current !== !!dep) {
1469
- const previous = lastValue.current;
1470
- lastValue.current = dep;
1471
- effect(!!lastValue.current, !!previous);
1472
- //console.log('[useBooleanChanged] change called')
1473
- }
1474
- }, [dep]);
1475
- };
1476
-
1477
- // Taken from: https://github.com/react-bootstrap/dom-helpers/blob/master/src/scrollbarSize.ts
1478
- const canUseDom = !!(typeof window !== 'undefined' &&
1479
- window.document &&
1480
- window.document.createElement);
1481
- let size;
1482
- /** Tells you actual width of the scroll bar. This can vary by browser. */
1483
- const useScrollbarSize = (recalc) => {
1484
- if ((!size && size !== 0) || recalc) {
1485
- if (canUseDom) {
1486
- const scrollDiv = document.createElement('div');
1487
- scrollDiv.style.position = 'absolute';
1488
- scrollDiv.style.top = '-9999px';
1489
- scrollDiv.style.width = '50px';
1490
- scrollDiv.style.height = '50px';
1491
- scrollDiv.style.overflow = 'scroll';
1492
- document.body.appendChild(scrollDiv);
1493
- size = scrollDiv.offsetWidth - scrollDiv.clientWidth;
1494
- document.body.removeChild(scrollDiv);
1495
- }
1496
- }
1497
- return size;
1498
- };
1499
-
1500
- const Modal = (p) => {
1501
- var _a, _b, _c, _d;
1502
- const backdrop = React.useContext(BackdropContext);
1503
- const mouseDownElement = React.useRef(undefined);
1504
- const theme = useThemeSafely();
1505
- const hasHeader = p.closeButton || p.heading;
1506
- const contentRef = React__default['default'].useRef(null);
1507
- const log = useLogger((_a = p.id) !== null && _a !== void 0 ? _a : 'Modal', (_b = p.__debug) !== null && _b !== void 0 ? _b : false);
1508
- const showing = React.useRef(p.show);
1509
- const bodyStyles = React.useRef('');
1510
- const tryRemoveBodyStyles = () => {
1511
- if (bodyStyles.current) {
1512
- log('removing singleton', bodyStyles.current);
1513
- document.body.classList.remove(bodyStyles.current);
1514
- }
1515
- };
1516
- React.useEffect(() => {
1517
- log('mounted');
1518
- return () => {
1519
- var _a;
1520
- if (showing.current) {
1521
- log(`un-mount in progress and this modal is showing. decrement the backdrop and try to remove singleton body styles.`);
1522
- backdrop.setShow(false, (_a = p.id) !== null && _a !== void 0 ? _a : 'Modal');
1523
- log('backdrop.setShow', false);
1524
- tryRemoveBodyStyles();
1525
- }
1526
- else {
1527
- log(`un-mount in progress but this modal is not showing. do nothing with the backdrop.`);
1528
- }
1529
- log('un-mounted');
1530
- };
1531
- }, []);
1532
- useBooleanChanged((show, previousShow) => {
1533
- var _a, _b, _c;
1534
- log('show changed', `${previousShow !== null && previousShow !== void 0 ? previousShow : 'undefined'} > ${show}`);
1535
- backdrop.setShow(show, (_a = p.id) !== null && _a !== void 0 ? _a : 'Modal');
1536
- showing.current = show;
1537
- log('backdrop.setShow', show);
1538
- if (!bodyStyles.current) {
1539
- bodyStyles.current = css.css({
1540
- label: 'ModalBodyOverrides_' + ((_c = (_b = p.id) === null || _b === void 0 ? void 0 : _b.replace(/\s+/, '')) !== null && _c !== void 0 ? _c : nanoid.nanoid()),
1541
- overflow: 'hidden',
1542
- paddingRight: `${useScrollbarSize()}px`
1543
- });
1544
- log('creating singleton bodyStyles', bodyStyles.current);
1545
- }
1546
- if (show) {
1547
- log('this modal is showing. adding singleton bodyStyles', bodyStyles.current);
1548
- document.body.classList.add(bodyStyles.current);
1549
- }
1550
- else {
1551
- log('this modal is hiding. try removing singleton bodyStyles');
1552
- tryRemoveBodyStyles();
1553
- }
1554
- }, p.show);
1555
- React__default['default'].useLayoutEffect(() => {
1556
- var _a;
1557
- if (p.show === true) {
1558
- const focusSelector = (_a = p.focusSelector) !== null && _a !== void 0 ? _a : '.modalCloseButton';
1559
- // still need to wait for the next tick so the children are all rendered.
1560
- setTimeout(() => {
1561
- var _a;
1562
- const element = (_a = contentRef.current) === null || _a === void 0 ? void 0 : _a.querySelector(focusSelector);
1563
- element === null || element === void 0 ? void 0 : element.focus();
1564
- log('set focus', focusSelector);
1565
- });
1566
- }
1567
- }, [p.show]);
1568
- const modalBodyStyles = css.css({
1569
- maxHeight: p.scrollable ? undefined : '99vh',
1570
- overflow: 'hidden',
1571
- zIndex: theme.zIndexes.modal,
1572
- cursor: 'default',
1573
- margin: '1rem',
1574
- backgroundColor: p.noBackground ? undefined : theme.colors.modalBg,
1575
- border: p.noBackground ? undefined : theme.controls.border,
1576
- boxShadow: p.noBackground ? undefined : theme.controls.boxShadow,
1577
- maxWidth: (_c = p.maxWidth) !== null && _c !== void 0 ? _c : theme.breakpoints.tablet,
1578
- minWidth: (_d = p.minWidth) !== null && _d !== void 0 ? _d : (hasHeader ? '250px' : undefined),
1579
- opacity: p.show ? 1 : 0,
1580
- fontSize: theme.fonts.size,
1581
- fontFamily: theme.fonts.family,
1582
- fontWeight: 'normal',
1583
- '&:focus': {
1584
- outline: 'none'
1585
- }
1586
- });
1587
- const modalHeaderStyles = css.cx(css.css({
1588
- display: 'flex',
1589
- justifyContent: 'space-between',
1590
- alignItems: 'center',
1591
- backgroundColor: theme.colors.header,
1592
- padding: '1rem',
1593
- color: theme.colors.headerFont
1594
- }), p.headerClassName);
1595
- const modalContainerStyles = css.css([{
1596
- position: 'fixed',
1597
- height: '100%',
1598
- width: '100%',
1599
- backgroundColor: "transparent",
1600
- display: 'flex',
1601
- justifyContent: 'center',
1602
- alignItems: 'center',
1603
- cursor: p.onClick ? 'pointer' : 'default'
1604
- }, p.scrollable && {
1605
- overflowY: 'auto',
1606
- overflowX: 'hidden',
1607
- alignItems: 'flex-start'
1608
- }]);
1609
- if (p.show) {
1610
- const backdropContainer = document.getElementById(backdrop.portalId);
1611
- if (backdropContainer) {
1612
- return reactDom.createPortal((React__default['default'].createElement("div", { onClick: e => {
1613
- e.stopPropagation();
1614
- if (!mouseDownElement.current) {
1615
- if (p.onClick) {
1616
- log('backdropContainer onClick');
1617
- p.onClick();
1618
- }
1619
- }
1620
- mouseDownElement.current = undefined;
1621
- }, className: css.cx('modalContainer', modalContainerStyles) },
1622
- React__default['default'].createElement("div", { id: p.id, ref: contentRef, onClick: e => e.stopPropagation(), onMouseDown: e => {
1623
- mouseDownElement.current = e.target;
1624
- e.stopPropagation();
1625
- }, onMouseUp: e => {
1626
- mouseDownElement.current = undefined;
1627
- /*
1628
- MouseDown and MouseUp stopPropagation was added to fix bugs while clicking within the modal.
1629
- At least in the case of MouseUp, this breaks sliders and the handle grab logic appears to live on window.
1630
- Turning this off now. Should not cause any issues for MouseUp unlike MouseDown.
1631
- */
1632
- // e.stopPropagation()
1633
- }, className: css.cx('modalBody', modalBodyStyles, p.className) },
1634
- React__default['default'].createElement(TabLocker, null,
1635
- hasHeader && (React__default['default'].createElement("header", { className: css.cx('modalHeader', modalHeaderStyles) },
1636
- p.heading ? React__default['default'].createElement(Text, { className: css.css({
1637
- margin: 0,
1638
- flexGrow: 1
1639
- }), tag: "h1", bold: true }, p.heading) : React__default['default'].createElement("span", null),
1640
- p.closeButton && p.onClick ? React__default['default'].createElement(Button, { className: css.cx('modalCloseButton', css.css({
1641
- color: theme.colors.headerFont,
1642
- marginLeft: '1rem',
1643
- backgroundColor: 'transparent'
1644
- })), variant: "icon", onClick: p.onClick },
1645
- React__default['default'].createElement(Icon, { id: "close" })) : React__default['default'].createElement("span", null))),
1646
- p.children)))), backdropContainer);
1647
- }
1648
- }
1649
- return null;
1650
- };
1651
-
1652
1688
  const ConfirmModal = (props) => {
1653
1689
  const theme = useThemeSafely();
1654
1690
  const modalStyle = css.css `
@@ -1717,14 +1753,19 @@ const ErrorModal = (props) => {
1717
1753
 
1718
1754
  /** Use this instead of <form> directly. If we need to fight Chrome's autofill, we can do so at a global level. */
1719
1755
  const Form = React__namespace.forwardRef((props, ref) => {
1720
- const { inline, children, onSubmit, className, ajax } = props, rest = __rest(props, ["inline", "children", "onSubmit", "className", "ajax"]);
1756
+ const { inline, children, onSubmit, className, ajax, unstyled } = props, rest = __rest(props, ["inline", "children", "onSubmit", "className", "ajax", "unstyled"]);
1721
1757
  const theme = useThemeSafely();
1722
- return (React__namespace.createElement("form", Object.assign({}, rest, { ref: ref, className: css.cx('form', css.css({
1758
+ let defaultStyle;
1759
+ if (!props.unstyled) {
1760
+ defaultStyle = css.css({
1761
+ label: 'Form',
1723
1762
  display: 'flex',
1724
1763
  flexDirection: props.inline ? 'row' : 'column',
1725
1764
  alignItems: props.inline ? 'flex-end' : 'normal',
1726
1765
  gap: theme.controls.gap
1727
- }), props.className), onSubmit: e => {
1766
+ });
1767
+ }
1768
+ return (React__namespace.createElement("form", Object.assign({}, rest, { ref: ref, className: css.cx('form', defaultStyle, props.className), onSubmit: e => {
1728
1769
  if (ajax !== false) {
1729
1770
  e.preventDefault();
1730
1771
  e.stopPropagation();
@@ -1734,6 +1775,7 @@ const Form = React__namespace.forwardRef((props, ref) => {
1734
1775
  }
1735
1776
  } }), children));
1736
1777
  });
1778
+ /** @deprecated Just style normally using flex, grid, etc. */
1737
1779
  const FormFlexRow = (props) => {
1738
1780
  var _a;
1739
1781
  const theme = useThemeSafely();
@@ -1743,6 +1785,7 @@ const FormFlexRow = (props) => {
1743
1785
  justifyContent: (_a = props.justifyContent) !== null && _a !== void 0 ? _a : 'normal'
1744
1786
  }), props.className) }, props.children));
1745
1787
  };
1788
+ /** @deprecated Just style normally using flex, grid, etc. */
1746
1789
  const FormColumnRow = (props) => {
1747
1790
  const theme = useThemeSafely();
1748
1791
  return (React__namespace.createElement("div", { style: props.style, className: css.cx('formColumnRow', css.css({
@@ -2260,6 +2303,7 @@ const BaseInput = React__namespace.forwardRef((props, ref) => {
2260
2303
  const theme = useThemeSafely();
2261
2304
  const { rightControl, round, wrapperClassName, showErrorDisplay } = props, nativeProps = __rest(props, ["rightControl", "round", "wrapperClassName", "showErrorDisplay"]);
2262
2305
  const inputStyles = css.css({
2306
+ backgroundColor: theme.colors.bg,
2263
2307
  fontFamily: theme.fonts.family,
2264
2308
  fontSize: theme.fonts.size,
2265
2309
  width: '100%',
@@ -2326,7 +2370,8 @@ const BaseInput = React__namespace.forwardRef((props, ref) => {
2326
2370
  `}
2327
2371
  `;
2328
2372
  return (React__namespace.createElement("div", { className: css.css({
2329
- width: '100%'
2373
+ width: '100%',
2374
+ label: 'BaseInput'
2330
2375
  }) },
2331
2376
  React__namespace.createElement("div", { className: css.cx('input', inputWrapperStyles, wrapperClassName) },
2332
2377
  inputElement,
@@ -2840,7 +2885,7 @@ const Label = (props) => {
2840
2885
  * https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia
2841
2886
  */
2842
2887
  const useMediaQuery = (query) => {
2843
- const [matches, setMatches] = React.useState(false);
2888
+ const [matches, setMatches] = React.useState(window.matchMedia(query).matches);
2844
2889
  React.useEffect(() => {
2845
2890
  const media = window.matchMedia(query);
2846
2891
  if (media.matches !== matches) {
@@ -2976,6 +3021,7 @@ const LinkContent = (props) => {
2976
3021
  }) }, props.rightIcon)));
2977
3022
  };
2978
3023
 
3024
+ //TB: FUTURE de-dup these styles. create individual styles and compose them manually.
2979
3025
  const generateLinkStyles = (props, theme) => {
2980
3026
  var _a, _b, _c, _d, _e;
2981
3027
  const linkStyles = css.css `
@@ -3027,9 +3073,15 @@ const generateLinkStyles = (props, theme) => {
3027
3073
  `}
3028
3074
  ${props.variant === 'button' && `
3029
3075
  text-align: center;
3076
+ &:hover {
3077
+ background-color: ${theme.controls.hoverBackground};
3078
+ }
3030
3079
  `}
3031
3080
  ${props.variant === 'circle' && `
3032
3081
  text-align: center;
3082
+ &:hover {
3083
+ background-color: ${theme.controls.hoverBackground};
3084
+ }
3033
3085
  width: ${theme.controls.height};
3034
3086
  border-radius: 100%;
3035
3087
  display: flex;
@@ -3103,6 +3155,9 @@ const generateLinkStyles = (props, theme) => {
3103
3155
  ${props.variant === 'label' && `
3104
3156
  box-shadow: none;
3105
3157
  border: none;
3158
+ &:hover {
3159
+ background-color: ${theme.controls.hoverBackground};
3160
+ }
3106
3161
  `}
3107
3162
  ${props.variant === 'text' && `
3108
3163
  font-weight: normal;
@@ -3119,6 +3174,9 @@ const generateLinkStyles = (props, theme) => {
3119
3174
  font-size: 1.6rem;
3120
3175
  padding-left: 0;
3121
3176
  padding-right: 0;
3177
+ &:hover {
3178
+ background-color: ${theme.controls.hoverBackground};
3179
+ }
3122
3180
  `}
3123
3181
  ${props.block && `
3124
3182
  display: block;
@@ -3267,7 +3325,7 @@ const Picker = (props) => {
3267
3325
  !props.readOnly && (React__namespace.createElement(Icon, { id: "sortDesc", className: css.css({
3268
3326
  position: 'absolute',
3269
3327
  right: `calc(${theme.controls.padding} + ${props.round ? roundPxPadding : '0px'})`,
3270
- height: theme.controls.height,
3328
+ height: '100%',
3271
3329
  pointerEvents: 'none'
3272
3330
  }) }))));
3273
3331
  };
@@ -3772,14 +3830,14 @@ const SearchBox = (props) => {
3772
3830
  return (_c = props.onSubmit) === null || _c === void 0 ? void 0 : _c.call(props);
3773
3831
  });
3774
3832
  const theme = useThemeSafely();
3775
- const submitButton = (React__namespace.createElement(Button, { tabIndex: -1, disabled: waiting, readOnly: !props.onSubmit, type: "submit", className: css.css({
3833
+ const submitButton = (React__namespace.createElement(Button, { tabIndex: -1, disabled: waiting, readOnly: !props.onSubmit, type: "submit", className: css.cx(css.css({
3776
3834
  color: `${theme.colors.font} !important;`,
3777
3835
  fontSize: '1rem'
3778
- }), variant: "icon", small: true },
3836
+ }), props.buttonClassName), variant: "icon", small: true },
3779
3837
  React__namespace.createElement(Icon, { id: waiting ? 'waiting' : 'search', spin: waiting })));
3780
3838
  //TB: FUTURE replace with new inputs
3781
3839
  return (React__namespace.createElement(Form, { role: "search", className: css.cx('searchBox', props.className), onSubmit: onSubmit },
3782
- React__namespace.createElement(Input, { autoFocus: props.autoFocus, id: props.id, debounceMs: props.debounceMs, disabled: waiting, type: "text", value: props.value, placeholder: props.placeholder, round: props.round, onChange: props.onChange, rightControl: submitButton })));
3840
+ React__namespace.createElement(Input, { inputClassName: props.inputClassName, autoFocus: props.autoFocus, id: props.id, debounceMs: props.debounceMs, disabled: waiting, type: "text", value: props.value, placeholder: props.placeholder, round: props.round, onChange: props.onChange, rightControl: submitButton })));
3783
3841
  };
3784
3842
 
3785
3843
  const GlobalStyles = (p) => {
@@ -3815,10 +3873,11 @@ const Slider = (p) => {
3815
3873
  const currentValue = React.useRef(p.value);
3816
3874
  const sliderContainer = React.useRef(null);
3817
3875
  const height = p.showValue ? `calc(${theme.controls.height} + 1.5rem)` : theme.controls.height;
3818
- return (React__default['default'].createElement("div", { ref: sliderContainer, className: css.css({
3876
+ return (React__default['default'].createElement("div", { ref: sliderContainer, className: css.cx(css.css({
3877
+ label: 'Slider',
3819
3878
  width: '100%',
3820
3879
  height,
3821
- }) },
3880
+ }), p.className) },
3822
3881
  React__default['default'].createElement(ReactSlider__default['default'], { step: p.step, min: p.min, max: p.max, value: p.value, onAfterChange: (value, index) => {
3823
3882
  p.onChange(value);
3824
3883
  }, onChange: p.onUpdate || p.showValue ? (value, index) => {
@@ -3831,15 +3890,22 @@ const Slider = (p) => {
3831
3890
  display: 'flex',
3832
3891
  alignItems: 'center',
3833
3892
  height: theme.controls.height
3834
- })) }, rest),
3893
+ }), p.trackClassName) }, rest),
3835
3894
  React__default['default'].createElement("div", { className: css.css({
3836
3895
  backgroundColor: theme.colors.secondary,
3837
3896
  height: `calc(${theme.controls.height} / 4)`,
3838
3897
  borderRadius: theme.controls.roundRadius,
3839
3898
  width: '100%'
3840
- }) }));
3899
+ }, p.innerTrackClassName && rest.key === 'track-1' && Array.isArray(p.value) ? p.innerTrackClassName : undefined) }));
3841
3900
  }, renderThumb: (props, state) => {
3842
3901
  const { className } = props, rest = __rest(props, ["className"]);
3902
+ let specificThumbStyles;
3903
+ if (p.handle1ClassName && props.key === 'thumb-0') {
3904
+ specificThumbStyles = p.handle1ClassName;
3905
+ }
3906
+ else if (p.handle2ClassName && props.key === 'thumb-1') {
3907
+ specificThumbStyles = p.handle2ClassName;
3908
+ }
3843
3909
  return (React__default['default'].createElement("div", Object.assign({ className: css.cx(className, css.css({
3844
3910
  width: theme.controls.height,
3845
3911
  height: theme.controls.height,
@@ -3860,7 +3926,7 @@ const Slider = (p) => {
3860
3926
  '&:hover': {
3861
3927
  filter: theme.controls.hoverBrightness
3862
3928
  }
3863
- })) }, rest), p.showValue && (React__default['default'].createElement(HandleText, { index: state.index, parentElement: sliderContainer.current, value: Array.isArray(currentValue.current) ? currentValue.current[state.index] : currentValue.current, renderValue: p.renderValue, renderValueWidth: p.renderValueWidth }))));
3929
+ }), specificThumbStyles, p.handleClassName) }, rest), p.showValue && (React__default['default'].createElement(HandleText, { index: state.index, parentElement: sliderContainer.current, value: Array.isArray(currentValue.current) ? currentValue.current[state.index] : currentValue.current, renderValue: p.renderValue, renderValueWidth: p.renderValueWidth }))));
3864
3930
  } })));
3865
3931
  };
3866
3932
  const rectsCollideX = (r1, r2) => {
@@ -4150,6 +4216,7 @@ const TextArea = React__namespace.forwardRef((props, ref) => {
4150
4216
  updateErrorMessage();
4151
4217
  }, [props.value]);
4152
4218
  const styles = css.css({
4219
+ backgroundColor: theme.colors.bg,
4153
4220
  maxWidth: '100%',
4154
4221
  minHeight: theme.controls.height,
4155
4222
  fontFamily: theme.fonts.family,
@@ -4830,6 +4897,7 @@ exports.defaultTheme = defaultTheme;
4830
4897
  exports.enumToEntities = enumToEntities;
4831
4898
  exports.getCurrencyDisplay = getCurrencyDisplay;
4832
4899
  exports.getFileSizeDisplay = getFileSizeDisplay;
4900
+ exports.modalScrollFixClassName = modalScrollFixClassName;
4833
4901
  exports.useAccordianState = useAccordianState;
4834
4902
  exports.useBooleanChanged = useBooleanChanged;
4835
4903
  exports.useIgnoreMount = useIgnoreMount;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mackin.com/styleguide",
3
- "version": "8.6.2",
3
+ "version": "8.8.0",
4
4
  "description": "",
5
5
  "main": "./index.js",
6
6
  "types": "./index.d.ts",