From d0fccd1050f5d6ccc24c1e4d2b7d1c0ed94fb2a7 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Sun, 23 Mar 2025 10:27:28 -0400
Subject: updated more [DocData] to .$ things

---
 src/client/views/collections/CollectionMenu.tsx | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

(limited to 'src/client/views/collections/CollectionMenu.tsx')

diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index de999c91a..26aca458c 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -9,7 +9,6 @@ import * as React from 'react';
 import { ClientUtils, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents } from '../../../ClientUtils';
 import { emptyFunction } from '../../../Utils';
 import { Doc, DocListCast, Opt, returnEmptyDoclist } from '../../../fields/Doc';
-import { DocData } from '../../../fields/DocSymbols';
 import { List } from '../../../fields/List';
 import { ObjectField } from '../../../fields/ObjectField';
 import { RichTextField } from '../../../fields/RichTextField';
@@ -213,7 +212,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu
         title: 'set content',
         script: 'getProto(this.target).data = copyField(this.source);',
         immediate: undoable((source: Doc[]) => {
-            this.target[DocData].data = new List<Doc>(source);
+            this.target.$data = new List<Doc>(source);
         }, ''),
         initialize: emptyFunction,
     };
-- 
cgit v1.2.3-70-g09d2


From 7d54c52528be4f5a4f7dd94acfd4d4bb67b81f74 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Sun, 23 Mar 2025 10:33:05 -0400
Subject: from last

---
 src/client/views/collections/CollectionMenu.tsx    | 6 +-----
 src/client/views/collections/TreeView.tsx          | 2 +-
 src/client/views/nodes/LinkDescriptionPopup.tsx    | 5 ++---
 src/client/views/nodes/PDFBox.tsx                  | 2 +-
 src/client/views/nodes/calendarBox/CalendarBox.tsx | 1 -
 5 files changed, 5 insertions(+), 11 deletions(-)

(limited to 'src/client/views/collections/CollectionMenu.tsx')

diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 26aca458c..c79610595 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -1,5 +1,3 @@
-/* eslint-disable react/no-unused-class-component-methods */
-/* eslint-disable react/sort-comp */
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { Tooltip } from '@mui/material';
 import { Toggle, ToggleType, Type } from '@dash/components';
@@ -157,9 +155,7 @@ export class CollectionMenu extends AntimodeMenu<CollectionMenuProps> {
 }
 
 interface CollectionViewMenuProps {
-    // eslint-disable-next-line react/no-unused-prop-types
     type: CollectionViewType;
-    // eslint-disable-next-line react/no-unused-prop-types
     fieldKey: string;
     docView: DocumentView;
 }
@@ -184,7 +180,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu
             let formatStr = source.length && Cast(source[0].text, RichTextField, null)?.Text;
             try {
                 formatStr && JSON.parse(formatStr);
-            } catch (e) {
+            } catch {
                 formatStr = '';
             }
             if (source.length === 1 && formatStr) {
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index d6a19e88e..5ac283d22 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -834,7 +834,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
 
     @observable headerEleWidth = 0;
     @computed get titleButtons() {
-        const customHeaderButtons = this._props.styleProvider?.(this.Document, this.treeView._props, StyleProp.Decorations);
+        const customHeaderButtons = this._props.styleProvider?.(this.Document, this.treeView._props, StyleProp.Decorations) as JSX.Element;
         const color = SettingsManager.userColor;
         return this._props.treeViewHideHeaderFields() || this.Document.treeView_HideHeaderFields ? null : (
             <>
diff --git a/src/client/views/nodes/LinkDescriptionPopup.tsx b/src/client/views/nodes/LinkDescriptionPopup.tsx
index 6bec9c53d..9dff55bf1 100644
--- a/src/client/views/nodes/LinkDescriptionPopup.tsx
+++ b/src/client/views/nodes/LinkDescriptionPopup.tsx
@@ -7,18 +7,17 @@ import './LinkDescriptionPopup.scss';
 import { TaskCompletionBox } from './TaskCompletedBox';
 
 @observer
-export class LinkDescriptionPopup extends React.Component<{}> {
+export class LinkDescriptionPopup extends React.Component<object> {
     // eslint-disable-next-line no-use-before-define
     public static Instance: LinkDescriptionPopup;
     @observable public display: boolean = false;
-    // eslint-disable-next-line react/no-unused-class-component-methods
     @observable public showDescriptions: string = 'ON';
     @observable public popupX: number = 700;
     @observable public popupY: number = 350;
     @observable description: string = '';
     @observable popupRef = React.createRef<HTMLDivElement>();
 
-    constructor(props: any) {
+    constructor(props: object) {
         super(props);
         makeObservable(this);
         LinkDescriptionPopup.Instance = this;
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 1f72206fc..5484179be 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -156,7 +156,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
                 ClientUtils.convertDataUri(dataUrl, region[Id]).then(returnedfilename =>
                     setTimeout(
                         action(() => {
-                            croppingProto.data = new ImageField(returnedfilename);
+                            cropping.$data = new ImageField(returnedfilename);
                         }),
                         500
                     )
diff --git a/src/client/views/nodes/calendarBox/CalendarBox.tsx b/src/client/views/nodes/calendarBox/CalendarBox.tsx
index e3408696b..6f1f58a4c 100644
--- a/src/client/views/nodes/calendarBox/CalendarBox.tsx
+++ b/src/client/views/nodes/calendarBox/CalendarBox.tsx
@@ -8,7 +8,6 @@ import { observer } from 'mobx-react';
 import * as React from 'react';
 import { dateRangeStrToDates } from '../../../../ClientUtils';
 import { Doc } from '../../../../fields/Doc';
-import { DocData } from '../../../../fields/DocSymbols';
 import { Id } from '../../../../fields/FieldSymbols';
 import { BoolCast, NumCast, StrCast } from '../../../../fields/Types';
 import { DocServer } from '../../../DocServer';
-- 
cgit v1.2.3-70-g09d2


From 29a1fe16297c99ddbed7974b7c602294da9a311d Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Tue, 25 Mar 2025 22:40:30 -0400
Subject: fixes to components so that things highlight reasonably in different
 skins.  fixed color picker alternate selection.

---
 .../components/src/components/Button/Button.scss   |  12 +-
 .../components/src/components/Button/Button.tsx    | 345 ++++++++++-----------
 .../src/components/ColorPicker/ColorPicker.tsx     |  44 ++-
 .../src/components/Dropdown/Dropdown.tsx           |  13 +-
 .../components/DropdownSearch/DropdownSearch.tsx   | 190 +++++-------
 .../src/components/EditableText/EditableText.tsx   | 309 +++++++++---------
 .../src/components/IconButton/IconButton.scss      |  17 +-
 .../src/components/IconButton/IconButton.tsx       |  27 +-
 .../src/components/ListItem/ListItem.tsx           |   2 +-
 .../src/components/MultiToggle/MultiToggle.tsx     | 143 +++++----
 .../components/NumberDropdown/NumberDropdown.tsx   |  46 ++-
 .../src/components/NumberInput/NumberInput.tsx     | 137 ++++----
 packages/components/src/components/Popup/Popup.tsx |   8 +-
 .../components/src/components/Slider/Slider.tsx    |  16 +-
 .../components/src/components/Toggle/Toggle.tsx    | 309 +++++++++---------
 packages/components/src/global/globalEnums.tsx     |  67 ++--
 packages/components/src/global/globalUtils.tsx     | 163 +++++-----
 src/client/util/CalendarManager.tsx                |   2 +-
 src/client/util/GroupManager.tsx                   |  14 +-
 src/client/util/SettingsManager.tsx                |  28 +-
 src/client/util/SharingManager.tsx                 |   4 +-
 src/client/util/SnappingManager.ts                 |  54 ++--
 src/client/views/StyleProvider.tsx                 |   4 +-
 src/client/views/collections/CollectionMenu.tsx    |  11 +-
 src/client/views/nodes/FontIconBox/FontIconBox.tsx |  36 ++-
 src/client/views/pdf/GPTPopup/GPTPopup.scss        |   4 +-
 src/client/views/pdf/GPTPopup/GPTPopup.tsx         |  46 +--
 src/client/views/topbar/TopBar.tsx                 |  23 +-
 28 files changed, 1048 insertions(+), 1026 deletions(-)

(limited to 'src/client/views/collections/CollectionMenu.tsx')

diff --git a/packages/components/src/components/Button/Button.scss b/packages/components/src/components/Button/Button.scss
index bbe2e2470..b2fb48344 100644
--- a/packages/components/src/components/Button/Button.scss
+++ b/packages/components/src/components/Button/Button.scss
@@ -53,7 +53,7 @@
     &.inactive {
         &:hover {
             .background {
-                filter: opacity(0) !important;
+                filter: opacity(0);
             }
         }
     }
@@ -63,13 +63,13 @@
             filter: opacity(0);
 
             &.active {
-                filter: opacity(0.2) !important;
+                filter: opacity(0.5);
             }
         }
 
         &:hover {
             .background {
-                filter: opacity(0.2);
+                filter: opacity(0.3);
             }
         }
     }
@@ -79,7 +79,7 @@
             filter: opacity(0);
 
             &.active {
-                filter: opacity(0.2) !important;
+                filter: opacity(0.2);
             }
         }
 
@@ -96,12 +96,12 @@
         }
 
         .background {
-            filter: opacity(1) !important;
+            filter: opacity(1);
         }
 
         &:hover {
             .background {
-                filter: brightness(0.8);
+                filter: opacity(0.3);
             }
         }
     }
diff --git a/packages/components/src/components/Button/Button.tsx b/packages/components/src/components/Button/Button.tsx
index a91c74a4c..885403640 100644
--- a/packages/components/src/components/Button/Button.tsx
+++ b/packages/components/src/components/Button/Button.tsx
@@ -1,195 +1,188 @@
-import { Tooltip } from '@mui/material'
-import React from 'react'
-import { Alignment, IGlobalProps, Placement, Type , getFormLabelSize } from '../../global'
-import { Colors, Size } from '../../global/globalEnums'
-import { getFontSize, getHeight, isDark } from '../../global/globalUtils'
-import { IconButton } from '../IconButton'
-import './Button.scss'
+import { Tooltip } from '@mui/material';
+import React from 'react';
+import { Alignment, IGlobalProps, Placement, Type, getFormLabelSize } from '../../global';
+import { Colors, Size } from '../../global/globalEnums';
+import { getFontSize, getHeight } from '../../global/globalUtils';
+import { IconButton } from '../IconButton';
+import './Button.scss';
 
 export interface IButtonProps extends IGlobalProps {
-  onClick?: (event: React.MouseEvent) => void
-  onDoubleClick?: (event: React.MouseEvent) => void
-  type?: Type
-  active?: boolean
+    onClick?: (event: React.MouseEvent) => void;
+    onDoubleClick?: (event: React.MouseEvent) => void;
+    type?: Type;
+    active?: boolean;
 
-  // Content
-  text?: string
-  icon?: JSX.Element | string
+    // Content
+    text?: string;
+    icon?: JSX.Element | string;
 
-  // Additional stylization
-  iconPlacement?: Placement
-  color?: string
-  colorPicker?: string,
-  uppercase?: boolean,
-  align?: Alignment 
+    // Additional stylization
+    iconPlacement?: Placement;
+    color?: string;
+    colorPicker?: string;
+    uppercase?: boolean;
+    align?: Alignment;
+    filter?: string;
 }
 
 export const Button = (props: IButtonProps) => {
-  const {
-    text,
-    icon,
-    onClick,
-    onDoubleClick,
-    onPointerDown,
-    active,
-    height,
-    inactive,
-    type = Type.PRIM,
-    label,
-    uppercase = false,
-    iconPlacement = 'right',
-    size = Size.SMALL,
-    color = Colors.MEDIUM_BLUE,
-    background,
-    style,
-    tooltip,
-    tooltipPlacement = 'top',
-    colorPicker,
-    formLabel,
-    formLabelPlacement,
-    fillWidth,
-    align = fillWidth ? 'flex-start' : 'center'
-  } = props
+    const {
+        text,
+        icon,
+        onClick,
+        onDoubleClick,
+        onPointerDown,
+        active,
+        height,
+        inactive,
+        type = Type.PRIM,
+        filter,
+        uppercase = false,
+        iconPlacement = 'right',
+        size = Size.SMALL,
+        color = Colors.MEDIUM_BLUE,
+        background,
+        style,
+        tooltip,
+        tooltipPlacement = 'top',
+        colorPicker,
+        formLabel,
+        formLabelPlacement,
+        fillWidth,
+        align = fillWidth ? 'flex-start' : 'center',
+    } = props;
 
-  if (!text) {
-    return <IconButton {...props}/>
-  }
-
-  /**
-   * Pointer down
-   * @param e
-   */
-  const handlePointerDown = (e: React.PointerEvent) => {
-    
-    if (!inactive && onPointerDown) {
-      e.stopPropagation();
-      e.preventDefault();
-      onPointerDown(e)
+    if (!text) {
+        return <IconButton {...props} />;
     }
-  }
 
-  /**
-   * In the event that there is a single click
-   * @param e
-   */
-  const handleClick = (e: React.MouseEvent) => {
-    if (!inactive && onClick) {
-      e.stopPropagation();
-      e.preventDefault();
-      onClick(e)
-    } 
-  }
+    /**
+     * Pointer down
+     * @param e
+     */
+    const handlePointerDown = (e: React.PointerEvent) => {
+        if (!inactive && onPointerDown) {
+            e.stopPropagation();
+            e.preventDefault();
+            onPointerDown(e);
+        }
+    };
 
-  /**
-   * Double click
-   * @param e
-   */
-  const handleDoubleClick = (e: React.MouseEvent) => {
-    if (!inactive && onDoubleClick){
-      e.stopPropagation();
-      e.preventDefault();
-      onDoubleClick(e)
-    } 
-  }
+    /**
+     * In the event that there is a single click
+     * @param e
+     */
+    const handleClick = (e: React.MouseEvent) => {
+        if (!inactive && onClick) {
+            e.stopPropagation();
+            e.preventDefault();
+            onClick(e);
+        }
+    };
 
-  const getBorderColor = (): Colors | string | undefined => {
-    switch(type){
-      case Type.PRIM:
-        return undefined;
-      case Type.SEC:
-        if (colorPicker) return colorPicker;
-        return color;
-      case Type.TERT:
-        if (colorPicker) return colorPicker;
-        if (active) return color;
-        else return color;
-    }
-  }
+    /**
+     * Double click
+     * @param e
+     */
+    const handleDoubleClick = (e: React.MouseEvent) => {
+        if (!inactive && onDoubleClick) {
+            e.stopPropagation();
+            e.preventDefault();
+            onDoubleClick(e);
+        }
+    };
 
-  const getColor = (): Colors | string | undefined => {
-    if (color && background) return color;
-    switch(type){
-      case Type.PRIM:
-        if (colorPicker) return colorPicker
-        return color;
-      case Type.SEC:
-        if (colorPicker) return colorPicker
-        return color;
-      case Type.TERT:
-        if (colorPicker) {
-          if (isDark(colorPicker)) return Colors.WHITE;
-          else return Colors.BLACK
+    const getBorderColor = (): Colors | string | undefined => {
+        switch (type) {
+            case Type.PRIM:
+                return undefined;
+            case Type.SEC:
+                if (colorPicker) return colorPicker;
+                return color;
+            case Type.TERT:
+                return color;
         }
-        if (isDark(color)) return Colors.WHITE;
-        else return Colors.BLACK
-    }
-  }
+    };
 
-  const getBackground = (): Colors | string | undefined => {
-    if (background) return background;
-    switch(type) {
-      case Type.PRIM:
-        if (colorPicker) return colorPicker
-        return color;
-      case Type.SEC:
-        if (colorPicker) return colorPicker
-        return color;
-      case Type.TERT:
-        if (colorPicker) return colorPicker
-        else return color
-    }
-  }
+    const getColor = (): Colors | string | undefined => {
+        if (color && background) return color;
+        switch (type) {
+            case Type.PRIM:
+            case Type.SEC:
+                if (colorPicker) return colorPicker;
+                return color;
+            case Type.TERT:
+                return '';
+        }
+    };
 
-  const defaultProperties: React.CSSProperties = {
-    height: getHeight(height, size),
-    minHeight: getHeight(height, size),
-    width: fillWidth ? '100%' : 'fit-content',
-    justifyContent: align ? align : undefined,
-    padding: fillWidth && align === 'center' ? 0 : undefined,
-    fontWeight: 500,
-    fontSize: getFontSize(size),
-    fontFamily: 'sans-serif',
-    textTransform: uppercase ? 'uppercase' : undefined,
-    borderColor: getBorderColor(),
-    color: getColor(),
-  }
+    const getBackground = (): Colors | string | undefined => {
+        if (background) return background;
+        switch (type) {
+            case Type.PRIM:
+            case Type.SEC:
+                if (colorPicker) return colorPicker;
+                return color;
+            case Type.TERT:
+        }
+    };
 
-  const backgroundProperties: React.CSSProperties = {
-    background: getBackground()
-  }
+    const defaultProperties: React.CSSProperties = {
+        height: getHeight(height, size),
+        minHeight: getHeight(height, size),
+        width: fillWidth ? '100%' : 'fit-content',
+        justifyContent: align ? align : undefined,
+        padding: fillWidth && align === 'center' ? 0 : undefined,
+        fontWeight: 500,
+        fontSize: getFontSize(size),
+        fontFamily: 'sans-serif',
+        textTransform: uppercase ? 'uppercase' : undefined,
+        borderColor: getBorderColor(),
+        color: getColor(),
+    };
 
-  const button: JSX.Element = (
-    <Tooltip disableInteractive={true} arrow={true} placement={tooltipPlacement} title={tooltip}>
-      <div
-        className={`button-container ${type} ${active && 'active'} ${inactive && 'inactive'}`}
-        onClick={handleClick}
-        onDoubleClick={handleDoubleClick}
-        onPointerDown={handlePointerDown}
-        style={{...defaultProperties, ...style}}
-      >
-        <div className={`button-content`} 
-          style={{justifyContent: align}}
-        >
-          {iconPlacement == 'left' && icon ? <div className={`icon`} style={{
-            fontSize: getFontSize(size, true)
-          }}>{icon}</div> : null}
-          {text}
-          {iconPlacement == 'right' && icon ? <div className={`icon`} style={{
-            fontSize: getFontSize(size, true)
-          }}>{icon}</div> : null}
-        </div>
-        <div className={`background ${active && 'active'}`} style={backgroundProperties}/>
-      </div>
-    </Tooltip>
-  )
+    const backgroundProperties: React.CSSProperties = {
+        background: getBackground(),
+        filter,
+    };
 
-  return (
-    formLabel ? 
-      <div className={`form-wrapper ${formLabelPlacement}`} style={{ width: fillWidth ? '100%' : undefined}}>
-        <div className={'formLabel'} style={{fontSize: getFormLabelSize(size)}}>{formLabel}</div>
-        {button}
-      </div>
-    :
-      button
-  )
-}
+    const button: JSX.Element = (
+        <Tooltip disableInteractive={true} arrow={true} placement={tooltipPlacement} title={tooltip}>
+            <div className={`button-container ${type} ${active && 'active'} ${inactive && 'inactive'}`} onClick={handleClick} onDoubleClick={handleDoubleClick} onPointerDown={handlePointerDown} style={{ ...defaultProperties, ...style }}>
+                <div className="button-content" style={{ justifyContent: align }}>
+                    {iconPlacement == 'left' && icon ? (
+                        <div
+                            className="icon"
+                            style={{
+                                fontSize: getFontSize(size, true),
+                            }}>
+                            {icon}
+                        </div>
+                    ) : null}
+                    {text}
+                    {iconPlacement == 'right' && icon ? (
+                        <div
+                            className="icon"
+                            style={{
+                                fontSize: getFontSize(size, true),
+                            }}>
+                            {icon}
+                        </div>
+                    ) : null}
+                </div>
+                <div className={`background ${active && 'active'}`} style={backgroundProperties} />
+            </div>
+        </Tooltip>
+    );
+
+    return formLabel ? (
+        <div className={`form-wrapper ${formLabelPlacement}`} style={{ width: fillWidth ? '100%' : undefined }}>
+            <div className="formLabel" style={{ fontSize: getFormLabelSize(size) }}>
+                {formLabel}
+            </div>
+            {button}
+        </div>
+    ) : (
+        button
+    );
+};
diff --git a/packages/components/src/components/ColorPicker/ColorPicker.tsx b/packages/components/src/components/ColorPicker/ColorPicker.tsx
index 632b470f0..72e02d955 100644
--- a/packages/components/src/components/ColorPicker/ColorPicker.tsx
+++ b/packages/components/src/components/ColorPicker/ColorPicker.tsx
@@ -1,5 +1,5 @@
 import React, { useRef, useState } from 'react';
-import { GithubPicker, ChromePicker, BlockPicker, SliderPicker, SketchPicker } from 'react-color';
+import { GithubPicker, ChromePicker, BlockPicker, SliderPicker, SketchPicker, ColorResult } from 'react-color';
 import { IGlobalProps, Size, Type, getFormLabelSize } from '../../global';
 import { Button } from '../Button';
 import { IconButton } from '../IconButton';
@@ -16,12 +16,12 @@ export interface IColorPickerProps extends IGlobalProps {
     colorPickerType?: ColorPickerType;
     defaultPickerType?: ColorPickerType;
     selectedColor?: string;
-    setSelectedColor: (color: any) => unknown;
-    setFinalColor: (color: any) => unknown;
+    setSelectedColor: (color: string) => unknown;
+    setFinalColor: (color: string) => unknown;
 }
 
 export const ColorPicker = (props: IColorPickerProps) => {
-    const [selectedColorLoc, setSelectedColorLoc] = useState();
+    const [selectedColorLoc, setSelectedColorLoc] = useState<string>();
     const {
         defaultPickerType,
         text,
@@ -31,6 +31,7 @@ export const ColorPicker = (props: IColorPickerProps) => {
         size = Size.SMALL,
         type = Type.TERT,
         icon,
+        background,
         selectedColor = selectedColorLoc,
         setSelectedColor = setSelectedColorLoc,
         setFinalColor = setSelectedColorLoc,
@@ -40,32 +41,25 @@ export const ColorPicker = (props: IColorPickerProps) => {
     } = props;
     const [isOpen, setOpen] = useState<boolean>(false);
     const [pickerSelectorOpen, setPickerSelectorOpen] = useState<boolean>(false);
-    const decimalToHexString = (number: number) => {
+    const decimalToHexString = (numberIn: number) => {
+        let number = numberIn;
         if (number < 0) {
             number = 0xffffffff + number + 1;
         }
         return (number < 16 ? '0' : '') + number.toString(16).toUpperCase();
     };
-    const colorString = (color: any) => {
-        return color.hex === 'transparent' ? color.hex : color.hex + (color.rgb.a ? decimalToHexString(Math.round(color.rgb.a * 255)) : 'ff');
-    };
-    const onChange = (color: any) => {
-        setSelectedColor(colorString(color) as any);
-    };
-    const onChangeComplete = (color: any) => {
-        setFinalColor(colorString(color) as any);
-    };
+    const colorString = (c: ColorResult) => (c.hex === 'transparent' ? c.hex : c.hex + (c.rgb.a ? decimalToHexString(Math.round(c.rgb.a * 255)) : 'ff'));
+    const onChange = (c: ColorResult) => setSelectedColor(colorString(c));
+    const onChangeComplete = (c: ColorResult) => setFinalColor(colorString(c));
     const [picker, setPicker] = useState<string>(defaultPickerType ?? 'Classic');
 
     const toggleRef = useRef<HTMLDivElement | null>(null);
     const getToggle = () => (
         <div ref={toggleRef}>
-            {icon && !text ? (
-                <IconButton active={isOpen} tooltip={tooltip} type={type} color={color} size={size} icon={icon} colorPicker={selectedColor} fillWidth={fillWidth} />
-            ) : text ? (
-                <Button active={isOpen} tooltip={tooltip} size={size} type={type} color={color} text={text} icon={icon} align={'flex-start'} iconPlacement={'left'} colorPicker={selectedColor} fillWidth={fillWidth} />
+            {text && !icon ? (
+                <Button active={isOpen} tooltip={tooltip} size={size} type={type} background={background} color={color} text={text} icon={icon} align="flex-start" iconPlacement="left" colorPicker={selectedColor} fillWidth={fillWidth} />
             ) : (
-                <IconButton active={isOpen} tooltip={tooltip} type={type} color={color} size={size} icon={icon} colorPicker={selectedColor} fillWidth={fillWidth} />
+                <IconButton active={isOpen} tooltip={tooltip} type={type} color={color} background={background} size={size} icon={icon} colorPicker={selectedColor} fillWidth={fillWidth} />
             )}
         </div>
     );
@@ -92,14 +86,12 @@ export const ColorPicker = (props: IColorPickerProps) => {
                 );
         } // prettier-ignore
     };
-    const openChanged = (isOpen: boolean) => setPickerSelectorOpen(isOpen);
+    const openChanged = (state: boolean) => setPickerSelectorOpen(state);
 
     const getPopup = (): JSX.Element => {
         if (colorPickerType) {
             return getColorPicker(colorPickerType);
         } else {
-            // Todo: this would be much easier if the selectedColor was a Color, not a string.
-            const newColor = selectedColor === 'transparent' ? 'white' : selectedColor?.startsWith('#') ? selectedColor.substring(0, 7) : selectedColor?.startsWith('rgba') ? selectedColor?.replace(/,[0-9]*\)/, '1)') : selectedColor;
             return (
                 <div style={{ height: 'fit-content' }}>
                     <Dropdown
@@ -109,9 +101,10 @@ export const ColorPicker = (props: IColorPickerProps) => {
                                 val: item,
                             };
                         })}
+                        background={background}
                         activeChanged={openChanged}
                         placement={'right'}
-                        color={newColor}
+                        color={color}
                         type={Type.PRIM}
                         dropdownType={DropdownType.SELECT}
                         selectedVal={picker}
@@ -126,7 +119,7 @@ export const ColorPicker = (props: IColorPickerProps) => {
 
     const popupContainsPt = (x: number, y: number) => {
         const rect = toggleRef.current?.getBoundingClientRect();
-        return rect && rect.left < x && rect.top < y && rect.right > x && rect.bottom > y;
+        return pickerSelectorOpen || (rect && rect.left < x && rect.top < y && rect.right > x && rect.bottom > y) ? true : false;
     };
 
     const colorPicker: JSX.Element = (
@@ -138,6 +131,7 @@ export const ColorPicker = (props: IColorPickerProps) => {
             tooltip={tooltip}
             size={size}
             color={selectedColor}
+            background={background}
             popup={getPopup()}
             popupContainsPt={popupContainsPt} // this should prohbably test to see if the click pt is actually within the picker selector list popup.
         />
@@ -145,7 +139,7 @@ export const ColorPicker = (props: IColorPickerProps) => {
 
     return formLabel ? (
         <div className={`form-wrapper ${formLabelPlacement}`} style={{ width: fillWidth ? '100%' : undefined }}>
-            <div className={'formLabel'} style={{ fontSize: getFormLabelSize(size) }}>
+            <div className="formLabel" style={{ fontSize: getFormLabelSize(size) }}>
                 {formLabel}
             </div>
             {colorPicker}
diff --git a/packages/components/src/components/Dropdown/Dropdown.tsx b/packages/components/src/components/Dropdown/Dropdown.tsx
index b9b6f01b8..783c7daa4 100644
--- a/packages/components/src/components/Dropdown/Dropdown.tsx
+++ b/packages/components/src/components/Dropdown/Dropdown.tsx
@@ -1,7 +1,7 @@
 import React, { useState } from 'react';
 import { FaCaretDown, FaCaretLeft, FaCaretRight, FaCaretUp } from 'react-icons/fa';
 import { Popup, PopupTrigger } from '..';
-import { Colors, IGlobalProps, Placement, Type, getFontSize, getHeight, isDark, getFormLabelSize } from '../../global';
+import { Colors, IGlobalProps, Placement, Type, getFontSize, getHeight, getFormLabelSize } from '../../global';
 import { IconButton } from '../IconButton';
 import { ListBox } from '../ListBox';
 import { IListItemProps, ListItem } from '../ListItem';
@@ -92,7 +92,7 @@ export const Dropdown = (props: IDropdownProps) => {
         textTransform: uppercase ? 'uppercase' : undefined,
         borderColor: getBorderColor(),
         background,
-        color: color && background ? color : type == Type.TERT ? (isDark(color) ? Colors.WHITE : Colors.BLACK) : color,
+        color: color,
     };
 
     const backgroundProperties: React.CSSProperties = {
@@ -116,9 +116,9 @@ export const Dropdown = (props: IDropdownProps) => {
                     <div className={`dropdown-toggle${!selectedVal ? '-mini' : ''} ${type} ${inactive && 'inactive'}`} style={{ ...defaultProperties, height: getHeight(height, size), width: width }}>
                         {selectedVal && <ListItem size={size} {...itemsMap.get(selectedVal)} style={{ color: defaultProperties.color, background: defaultProperties.background }} inactive />}
                         <div className="toggle-caret">
-                            <IconButton size={size} icon={getCaretDirection(active, placement)} color={defaultProperties.color} inactive />
+                            <IconButton size={size} background={background} icon={getCaretDirection(active, placement)} color={defaultProperties.color} inactive />
                         </div>
-                        <div className={`background ${active && 'active'}`} style={{ ...backgroundProperties }} />
+                        <div className={`background ${active && 'active'}`} style={{ ...backgroundProperties, filter: selectedVal ? 'opacity(0.3)' : 'opacity(0)' }} />
                     </div>
                 );
             case DropdownType.CLICK:
@@ -127,9 +127,9 @@ export const Dropdown = (props: IDropdownProps) => {
                     <div className={`dropdown-toggle${!selectedVal ? '-mini' : ''} ${type} ${inactive && 'inactive'}`} style={{ ...defaultProperties, height: getHeight(height, size), width: width }}>
                         <ListItem val="title" text={title} size={size} style={{ color: defaultProperties.color, background: defaultProperties.backdropFilter }} inactive />
                         <div className="toggle-caret">
-                            <IconButton size={size} icon={getCaretDirection(active, placement)} color={defaultProperties.color} inactive />
+                            <IconButton size={size} background={background} icon={getCaretDirection(active, placement)} color={defaultProperties.color} inactive />
                         </div>
-                        <div className={`background ${active && 'active'}`} style={{ ...backgroundProperties }} />
+                        <div className={`background ${active && 'active'}`} style={{ ...backgroundProperties, filter: selectedVal ? 'opacity(0.3)' : 'opacity(0)' }} />
                     </div>
                 );
         }
@@ -157,6 +157,7 @@ export const Dropdown = (props: IDropdownProps) => {
                 size={size}
                 fillWidth={true}
                 color={color}
+                background={background}
                 popup={
                     <ListBox
                         maxItems={maxItems}
diff --git a/packages/components/src/components/DropdownSearch/DropdownSearch.tsx b/packages/components/src/components/DropdownSearch/DropdownSearch.tsx
index 5ec01b44e..bdf114140 100644
--- a/packages/components/src/components/DropdownSearch/DropdownSearch.tsx
+++ b/packages/components/src/components/DropdownSearch/DropdownSearch.tsx
@@ -1,24 +1,24 @@
-import React, { useState } from 'react'
-import * as fa from 'react-icons/fa'
-import { EditableText, Popup, PopupTrigger } from '..'
-import { IGlobalProps, Placement, Size, getHeight , getFormLabelSize } from '../../global'
-import { IconButton } from '../IconButton'
-import { ListBox } from '../ListBox'
-import { IListItemProps } from '../ListItem'
-import './DropdownSearch.scss'
+import React, { useState } from 'react';
+import * as fa from 'react-icons/fa';
+import { EditableText, Popup, PopupTrigger } from '..';
+import { IGlobalProps, Placement, Size, getHeight } from '../../global';
+import { IconButton } from '../IconButton';
+import { ListBox } from '../ListBox';
+import { IListItemProps } from '../ListItem';
+import './DropdownSearch.scss';
 
 export enum DropdownSearchType {
-  SELECT = "select",
-  CLICK = "click"
+    SELECT = 'select',
+    CLICK = 'click',
 }
 
 export interface IDropdownSearchProps extends IGlobalProps {
-  items: IListItemProps[]
-  placement: Placement
-  dropdownSearchType: DropdownSearchType
-  title?: string
-  selectedVal?: string | number
-  maxItems?: number
+    items: IListItemProps[];
+    placement: Placement;
+    dropdownSearchType: DropdownSearchType;
+    title?: string;
+    selectedVal?: string | number;
+    maxItems?: number;
 }
 
 /**
@@ -30,100 +30,76 @@ export interface IDropdownSearchProps extends IGlobalProps {
  * Look at: import Select from "react-select";
  */
 export const DropdownSearch = (props: IDropdownSearchProps) => {
-  const {
-    size,
-    height,
-    maxItems,
-    items,
-    dropdownSearchType,
-    selectedVal,
-    // setSelectedVal,
-    tooltip,
-    title = "DropdownSearch",
-    type, 
-    width,
-    color
-  } = props
+    const { size, height, maxItems, items, dropdownSearchType, type, width, color } = props;
 
-  // const [selectedItem, setSelectedItem] = useState<
-  //   IListItemProps | undefined
-  // >(selectedVal)
+    // const [selectedItem, setSelectedItem] = useState<
+    //   IListItemProps | undefined
+    // >(selectedVal)
 
-  const [searchTerm, setSearchTerm] = useState<string | undefined>(undefined)
-  const [isEditing, setIsEditing] = useState<boolean>(false)
-  const [active, setActive] = useState<boolean>(false)
+    const [searchTerm, setSearchTerm] = useState<string | undefined>(undefined);
+    const [isEditing, setIsEditing] = useState<boolean>(false);
+    const [active, setActive] = useState<boolean>(false);
 
-  const getToggle = () => {
-    switch (dropdownSearchType) {
-      case DropdownSearchType.SELECT:
-        return (<div
-            className={`dropdownsearch-toggle ${type}`}
-            style={{ height: getHeight(height, size), width: width }}
-            onClick={(e) => {
-              e.stopPropagation()
-              !isEditing && setIsEditing(true)
-            }}
-          >
-            {/* {selectedItem && !isEditing ? (
+    const getToggle = () => {
+        switch (dropdownSearchType) {
+            case DropdownSearchType.SELECT:
+                return (
+                    <div
+                        className={`dropdownsearch-toggle ${type}`}
+                        style={{ height: getHeight(height, size), width: width }}
+                        onClick={e => {
+                            e.stopPropagation();
+                            !isEditing && setIsEditing(true);
+                        }}>
+                        {/* {selectedItem && !isEditing ? (
               <ListItem {...selectedItem} inactive />
             ) : ( */}
-              <div className="toggle-button">
-                <EditableText
-                  type={type}
-                  val={searchTerm}
-                  placeholder={'...'}
-                  editing={true}
-                  // onEdit={(val) => {
-                  //   setSearchTerm(val)
-                  // }}
-                  size={Size.SMALL}
-                  setEditing={setIsEditing}
-                />
-              </div>
-            {/* )} */}
-            <div className="toggle-caret">
-              <IconButton
-                size={Size.SMALL}
-                icon={<fa.FaSearch />}
-                inactive
-              />
-            </div>
-            <div className={`toggle-background ${isEditing && 'active'}`}/>
-          </div>);
-      case DropdownSearchType.CLICK:
-      default:
-        return (
-          <div
-            className={`dropdownsearch-toggle ${type}`}
-            style={{ height: getHeight(height, size), width: width }}
-          >
-          </div>
-        )
-    }
-  }
+                        <div className="toggle-button">
+                            <EditableText
+                                type={type}
+                                val={searchTerm}
+                                placeholder={'...'}
+                                editing={true}
+                                // onEdit={(val) => {
+                                //   setSearchTerm(val)
+                                // }}
+                                size={Size.SMALL}
+                                setEditing={setIsEditing}
+                            />
+                        </div>
+                        {/* )} */}
+                        <div className="toggle-caret">
+                            <IconButton size={Size.SMALL} icon={<fa.FaSearch />} inactive />
+                        </div>
+                        <div className={`toggle-background ${isEditing && 'active'}`} />
+                    </div>
+                );
+            case DropdownSearchType.CLICK:
+            default:
+                return <div className={`dropdownsearch-toggle ${type}`} style={{ height: getHeight(height, size), width: width }}></div>;
+        }
+    };
 
-  return (
-    <div
-      className="dropdownsearch-container"
-    >
-      <Popup
-        toggle={getToggle()}
-        trigger={PopupTrigger.CLICK}
-        isOpen={active}
-        setOpen={setActive}
-        size={size}
-        color={color}
-        popup={
-          <ListBox
-            maxItems={maxItems}
-            items={items}
-            filter={searchTerm}
-            // selectedVal={selectedVal}
-            // setSelectedVal={setSelectedItem}
-            size={size}
-          />
-        } 
-        />
-    </div>
-  )
-}
+    return (
+        <div className="dropdownsearch-container">
+            <Popup
+                toggle={getToggle()}
+                trigger={PopupTrigger.CLICK}
+                isOpen={active}
+                setOpen={setActive}
+                size={size}
+                color={color}
+                popup={
+                    <ListBox
+                        maxItems={maxItems}
+                        items={items}
+                        filter={searchTerm}
+                        // selectedVal={selectedVal}
+                        // setSelectedVal={setSelectedItem}
+                        size={size}
+                    />
+                }
+            />
+        </div>
+    );
+};
diff --git a/packages/components/src/components/EditableText/EditableText.tsx b/packages/components/src/components/EditableText/EditableText.tsx
index c361cf183..56cbc064d 100644
--- a/packages/components/src/components/EditableText/EditableText.tsx
+++ b/packages/components/src/components/EditableText/EditableText.tsx
@@ -1,21 +1,21 @@
-import React, { useState } from 'react'
-import { Colors, IGlobalProps, Size, TextAlignment, Type, getFontSize, getFormLabelSize, getHeight, isDark } from '../../global'
-import './EditableText.scss'
-import { Toggle, ToggleType } from '../Toggle'
-import { FaEye, FaEyeSlash} from 'react-icons/fa'
+import React, { useState } from 'react';
+import { Colors, IGlobalProps, Size, TextAlignment, Type, getFontSize, getFormLabelSize, getHeight, isDark } from '../../global';
+import './EditableText.scss';
+import { Toggle, ToggleType } from '../Toggle';
+import { FaEye, FaEyeSlash } from 'react-icons/fa';
 
 export interface IEditableTextProps extends IGlobalProps {
-  val?: string | number
-  setVal?: (newText: string | number) => unknown
-  onEnter?: (newText: string | number) => unknown
-  setEditing?: (bool: boolean) => unknown
-  placeholder?: string
-  editing?: boolean
-  size?: Size
-  height?: number
-  multiline?: boolean
-  textAlign?: TextAlignment
-  password?: boolean
+    val?: string | number;
+    setVal?: (newText: string | number) => unknown;
+    onEnter?: (newText: string | number) => unknown;
+    setEditing?: (bool: boolean) => unknown;
+    placeholder?: string;
+    editing?: boolean;
+    size?: Size;
+    height?: number;
+    multiline?: boolean;
+    textAlign?: TextAlignment;
+    password?: boolean;
 }
 
 /**
@@ -25,152 +25,149 @@ export interface IEditableTextProps extends IGlobalProps {
  * @returns
  */
 export const EditableText = (props: IEditableTextProps) => {
-  const [valLoc, setValLoc] = useState<string>('')
-  const [editingLoc, setEditingLoc] = useState<boolean>(false)
-  const {
-    height,
-    size,
-    val = valLoc,
-    setVal = setValLoc,
-    onEnter,
-    setEditing = setEditingLoc,
-    color = Colors.MEDIUM_BLUE,
-    background,
-    type = Type.PRIM,
-    placeholder,
-    width,
-    multiline,
-    textAlign = 'left',
-    formLabel,
-    formLabelPlacement,
-    fillWidth,
-    password,
-    editing = password ? true : editingLoc,
-    style
-  } = props
-  const [showPassword, setShowPassword] = useState<boolean>(false)
+    const [valLoc, setValLoc] = useState<string>('');
+    const [editingLoc, setEditingLoc] = useState<boolean>(false);
+    const {
+        height,
+        size,
+        val = valLoc,
+        setVal = setValLoc,
+        onEnter,
+        setEditing = setEditingLoc,
+        color = Colors.MEDIUM_BLUE,
+        background,
+        type = Type.PRIM,
+        placeholder,
+        width,
+        textAlign = 'left',
+        formLabel,
+        formLabelPlacement,
+        fillWidth,
+        password,
+        editing = password ? true : editingLoc,
+        style,
+    } = props;
+    const [showPassword, setShowPassword] = useState<boolean>(false);
 
-  const handleOnChange = (event: React.ChangeEvent<HTMLInputElement>) => {
-    setVal(event.target.value)
-  }
-  const handleKeyPress = (event: React.KeyboardEvent) => {
-    if (event.key === 'Enter') {
-      onEnter?.((event.target as HTMLInputElement).value)
-    }
-  }
+    const handleOnChange = (event: React.ChangeEvent<HTMLInputElement>) => {
+        setVal(event.target.value);
+    };
+    const handleKeyPress = (event: React.KeyboardEvent) => {
+        if (event.key === 'Enter') {
+            onEnter?.((event.target as HTMLInputElement).value);
+        }
+    };
 
-  const getBorderColor = (): Colors | string | undefined => {
-    switch(type){
-      case Type.PRIM:
-        return undefined;
-      case Type.SEC:
-        return color;
-      case Type.TERT:
-        if (editing) return color;
-        else return color;
-    }
-  }
+    const getBorderColor = (): Colors | string | undefined => {
+        switch (type) {
+            case Type.PRIM:
+                return undefined;
+            case Type.SEC:
+                return color;
+            case Type.TERT:
+                if (editing) return color;
+                else return color;
+        }
+    };
 
-  const getColor = (): Colors | string | undefined => {
-    if (color && background) return color;
-    switch(type){
-      case Type.PRIM:
-        return color;
-      case Type.SEC:
-        return color;
-      case Type.TERT:
-        if (isDark(color)) return Colors.WHITE;
-        else return Colors.BLACK
-    }
-  }
+    const getColor = (): Colors | string | undefined => {
+        if (color && background) return color;
+        switch (type) {
+            case Type.PRIM:
+                return color;
+            case Type.SEC:
+                return color;
+            case Type.TERT:
+                if (isDark(color)) return Colors.WHITE;
+                else return Colors.BLACK;
+        }
+    };
 
-  const getBackground = (): Colors | string | undefined => {
-    if (background) return background;
-    switch(type){
-      case Type.PRIM:
-        return color;
-      case Type.SEC:
-        return color;
-      case Type.TERT:
-        return color
-    }
-  }
+    const getBackground = (): Colors | string | undefined => {
+        if (background) return background;
+        switch (type) {
+            case Type.PRIM:
+                return color;
+            case Type.SEC:
+                return color;
+            case Type.TERT:
+                return color;
+        }
+    };
 
-  const defaultProperties: React.CSSProperties = {
-    height: getHeight(height, size),
-    minHeight: getHeight(height, size),
-    width: fillWidth ? '100%' : width,
-    padding: undefined,
-    fontWeight: 500,
-    fontSize: getFontSize(size),
-    fontFamily: 'sans-serif',
-    borderColor: getBorderColor(),
-    color: getColor()
-  }
+    const defaultProperties: React.CSSProperties = {
+        height: getHeight(height, size),
+        minHeight: getHeight(height, size),
+        width: fillWidth ? '100%' : width,
+        padding: undefined,
+        fontWeight: 500,
+        fontSize: getFontSize(size),
+        fontFamily: 'sans-serif',
+        borderColor: getBorderColor(),
+        color: getColor(),
+    };
 
-  const backgroundProperties: React.CSSProperties = {
-    background: getBackground()
-  }
+    const backgroundProperties: React.CSSProperties = {
+        background: getBackground(),
+    };
 
-  const editableText: JSX.Element = (
-    <div className={`editableText-container ${type}`}
-      style={{...defaultProperties, ...style}}
-      onClick={() => setEditing(true)}
-    > 
-      {editing ? (
-      <input
-        className={`editableText ${type} ${textAlign}`}
-        style={{ 
-          height: getHeight(height, size), 
-          textAlign: textAlign,
-          width: fillWidth ? '100%' : width
-        }}
-        placeholder={placeholder}
-        type={password && !showPassword ? 'password' : undefined}
-        autoFocus
-        onChange={handleOnChange}
-        onKeyPress={handleKeyPress}
-        onBlur={() => {
-          !password && setEditing(false)
-        }}
-        defaultValue={val}
-      ></input>
-      ) : (
-        <div 
-          className={`displayText ${type} ${textAlign}`}
-          style={{ 
-            height: getHeight(height, size), 
-            textAlign: textAlign,
-            width: fillWidth ? '100%' : width
-          }}
-        >
-          {val ? val : placeholder}
+    const editableText: JSX.Element = (
+        <div className={`editableText-container ${type}`} style={{ ...defaultProperties, ...style }} onClick={() => setEditing(true)}>
+            {editing ? (
+                <input
+                    className={`editableText ${type} ${textAlign}`}
+                    style={{
+                        height: getHeight(height, size),
+                        textAlign: textAlign,
+                        width: fillWidth ? '100%' : width,
+                    }}
+                    placeholder={placeholder}
+                    type={password && !showPassword ? 'password' : undefined}
+                    autoFocus
+                    onChange={handleOnChange}
+                    onKeyPress={handleKeyPress}
+                    onBlur={() => {
+                        !password && setEditing(false);
+                    }}
+                    defaultValue={val}></input>
+            ) : (
+                <div
+                    className={`displayText ${type} ${textAlign}`}
+                    style={{
+                        height: getHeight(height, size),
+                        textAlign: textAlign,
+                        width: fillWidth ? '100%' : width,
+                    }}>
+                    {val ? val : placeholder}
+                </div>
+            )}
+            {password && (
+                <div className={`password`}>
+                    <Toggle
+                        toggleType={ToggleType.BUTTON}
+                        type={Type.PRIM}
+                        size={size}
+                        color={color}
+                        toggleStatus={showPassword}
+                        onClick={() => setShowPassword(!showPassword)}
+                        tooltip={`${showPassword ? 'Hide' : 'Show'} Password`}
+                        icon={<FaEyeSlash />}
+                        iconFalse={<FaEye />}
+                    />
+                </div>
+            )}
+            <div className={`editableText-background ${type}`} style={backgroundProperties} />
         </div>
-      )}
-      {password && <div className={`password`}>
-        <Toggle
-          toggleType={ToggleType.BUTTON}
-          type={Type.PRIM}
-          size={size}
-          color={color}
-          toggleStatus={showPassword}
-          onClick={() => setShowPassword(!showPassword)}
-          tooltip={`${showPassword ? 'Hide' : 'Show'} Password`}
-          icon={<FaEyeSlash/>}
-          iconFalse={<FaEye/>}
-        />
-      </div>}
-      <div className={`editableText-background ${type}`} style={backgroundProperties}/>
-    </div>
-  )
+    );
 
-return (
-  formLabel ? 
-    <div className={`form-wrapper ${formLabelPlacement}`}>
-      <div className={'formLabel'} style={{fontSize: getFormLabelSize(size)}}>{formLabel}</div>
-      {editableText}
-    </div>
-  :
-    editableText
-  )
-}
+    return formLabel ? (
+        <div className={`form-wrapper ${formLabelPlacement}`}>
+            <div className={'formLabel'} style={{ fontSize: getFormLabelSize(size) }}>
+                {formLabel}
+            </div>
+            {editableText}
+        </div>
+    ) : (
+        editableText
+    );
+};
diff --git a/packages/components/src/components/IconButton/IconButton.scss b/packages/components/src/components/IconButton/IconButton.scss
index f899dc50f..3f0dd26ea 100644
--- a/packages/components/src/components/IconButton/IconButton.scss
+++ b/packages/components/src/components/IconButton/IconButton.scss
@@ -45,7 +45,7 @@
 
     &.inactive {
         .background {
-            filter: opacity(0) !important;
+            filter: opacity(0);
         }
     }
 
@@ -54,13 +54,13 @@
             filter: opacity(0);
 
             &.active {
-                filter: opacity(0.2) !important;
+                filter: opacity(0.5);
             }
         }
 
         &:hover {
             .background {
-                filter: opacity(0.2);
+                filter: opacity(0.3);
             }
         }
     }
@@ -70,7 +70,7 @@
             filter: opacity(0);
 
             &.active {
-                filter: opacity(0.2) !important;
+                filter: opacity(0.2);
             }
         }
 
@@ -85,10 +85,17 @@
         &:hover {
             box-shadow: global.$standard-button-shadow;
         }
+        .background {
+            filter: opacity(0);
+
+            &.active {
+                filter: opacity(0.5);
+            }
+        }
 
         &:hover {
             .background {
-                filter: brightness(0.8);
+                filter: opacity(0.3);
             }
         }
     }
diff --git a/packages/components/src/components/IconButton/IconButton.tsx b/packages/components/src/components/IconButton/IconButton.tsx
index 048048b20..f61f589b9 100644
--- a/packages/components/src/components/IconButton/IconButton.tsx
+++ b/packages/components/src/components/IconButton/IconButton.tsx
@@ -1,6 +1,6 @@
 import { Tooltip } from '@mui/material';
 import React from 'react';
-import { Colors, Size, Type, getFontSize, getHeight, isDark, getFormLabelSize } from '../../global';
+import { Colors, Size, Type, getFontSize, getHeight, getFormLabelSize } from '../../global';
 import { IButtonProps } from '../Button';
 import './IconButton.scss';
 
@@ -15,6 +15,7 @@ export const IconButton = (props: IButtonProps) => {
         type = Type.PRIM,
         color = Colors.MEDIUM_BLUE,
         background,
+        filter,
         label,
         height,
         size = Size.SMALL,
@@ -71,6 +72,7 @@ export const IconButton = (props: IButtonProps) => {
             case Type.SEC:
                 return color;
             case Type.TERT:
+                return '';
                 if (colorPicker) return colorPicker;
                 if (active) return color;
                 else return color;
@@ -85,12 +87,7 @@ export const IconButton = (props: IButtonProps) => {
             case Type.SEC:
                 return color;
             case Type.TERT:
-                if (colorPicker) {
-                    if (isDark(colorPicker)) return Colors.WHITE;
-                    else return Colors.BLACK;
-                }
-                if (isDark(color)) return Colors.WHITE;
-                else return Colors.BLACK;
+                return '';
         }
     };
 
@@ -102,15 +99,14 @@ export const IconButton = (props: IButtonProps) => {
             case Type.SEC:
                 return color;
             case Type.TERT:
-                if (colorPicker) return colorPicker;
-                else return color;
+                return ''; //color;
         }
     };
 
     const defaultProperties: React.CSSProperties = {
-        height: getHeight(+(height ?? 0), size),
-        width: fillWidth ? '100%' : getHeight(+(height ?? 0), size),
-        minWidth: getHeight(+(height ?? 0), size),
+        height: getHeight(height, size),
+        width: fillWidth ? '100%' : getHeight(height, size),
+        minWidth: getHeight(height, size),
         fontWeight: 500,
         fontSize: getFontSize(size, true),
         borderColor: getBorderColor(),
@@ -119,6 +115,7 @@ export const IconButton = (props: IButtonProps) => {
 
     const backgroundProperties: React.CSSProperties = {
         background: getBackground(),
+        filter,
     };
 
     const iconButton: JSX.Element = (
@@ -126,9 +123,9 @@ export const IconButton = (props: IButtonProps) => {
             <div className={`iconButton-container ${type} ${inactive && 'inactive'}`} onClick={handleClick} onDoubleClick={handleDoubleClick} onPointerDown={handlePointerDown} style={{ ...defaultProperties, ...style }} tabIndex={-1}>
                 <div className="iconButton-content">
                     {icon}
-                    {colorPicker && type !== Type.TERT && <div className={`color`} style={{ background: colorPicker, outlineColor: defaultProperties.color }} />}
+                    {colorPicker && <div className="color" style={{ background: colorPicker, outlineColor: defaultProperties.color }} />}
                     {label && !hideLabel && (
-                        <div className={'iconButton-label'} style={{ color: defaultProperties.color }}>
+                        <div className="iconButton-label" style={{ color: defaultProperties.color }}>
                             {label}
                         </div>
                     )}
@@ -140,7 +137,7 @@ export const IconButton = (props: IButtonProps) => {
 
     return formLabel ? (
         <div className={`form-wrapper ${formLabelPlacement}`} style={{ width: fillWidth ? '100%' : undefined }}>
-            <div className={'formLabel'} style={{ fontSize: getFormLabelSize(size) }}>
+            <div className="formLabel" style={{ fontSize: getFormLabelSize(size) }}>
                 {formLabel}
             </div>
             {iconButton}
diff --git a/packages/components/src/components/ListItem/ListItem.tsx b/packages/components/src/components/ListItem/ListItem.tsx
index e04c6fbee..6bb3e3824 100644
--- a/packages/components/src/components/ListItem/ListItem.tsx
+++ b/packages/components/src/components/ListItem/ListItem.tsx
@@ -85,7 +85,7 @@ export const ListItem = (props: IListItemProps) => {
             <div
                 className="listItem-background"
                 style={{
-                    background: background ? background : style?.color ? style.color : color,
+                    background: background ?? style?.color ?? color,
                     filter: selected ? 'opacity(0.3)' : isHovered && !inactive ? 'opacity(0.2)' : 'opacity(0)',
                 }}
             />
diff --git a/packages/components/src/components/MultiToggle/MultiToggle.tsx b/packages/components/src/components/MultiToggle/MultiToggle.tsx
index 7fff12c8e..0f659c5ca 100644
--- a/packages/components/src/components/MultiToggle/MultiToggle.tsx
+++ b/packages/components/src/components/MultiToggle/MultiToggle.tsx
@@ -1,29 +1,29 @@
-import * as React from 'react'
-import { useState } from 'react'
-import { Colors, IGlobalProps, Type } from '../../global'
-import { Group } from '../Group'
-import { IconButton } from '../IconButton'
-import { Popup } from '../Popup'
-import { IToggleProps, Toggle, ToggleType } from '../Toggle'
+import * as React from 'react';
+import { useState } from 'react';
+import { Colors, IGlobalProps, Type } from '../../global';
+import { Group } from '../Group';
+import { IconButton } from '../IconButton';
+import { Popup } from '../Popup';
+import { IToggleProps, Toggle, ToggleType } from '../Toggle';
 
 export interface IToggleItemProps extends IToggleProps {
-    val: string
+    val: string;
 }
 
 export interface IMultiToggleProps extends IGlobalProps {
-    items: IToggleItemProps[]
+    items: IToggleItemProps[];
     multiSelect?: boolean;
-    defaultSelectedItems?: (string|number) | ((string|number)[]),
-    selectedItems?: (string | number) | ((string|number)[]),
-    onSelectionChange?: (val: (string|number) | (string|number)[], added: boolean) => unknown,
+    defaultSelectedItems?: (string | number) | (string | number)[];
+    selectedItems?: (string | number) | (string | number)[];
+    onSelectionChange?: (val: (string | number) | (string | number)[], added: boolean) => unknown;
     isToggle?: boolean;
     toggleStatus?: boolean;
 }
 
-function promoteToArrayOrUndefined(d : (string|number)[]|(string|number)|undefined) {
-   return d instanceof Array || d === undefined ? d: [d];
+function promoteToArrayOrUndefined(d: (string | number)[] | (string | number) | undefined) {
+    return d instanceof Array || d === undefined ? d : [d];
 }
-function promoteToArray(d : (string|number)[]|(string|number)|undefined) {
+function promoteToArray(d: (string | number)[] | (string | number) | undefined) {
     return promoteToArrayOrUndefined(d) ?? [];
 }
 
@@ -32,56 +32,67 @@ export const MultiToggle = (props: IMultiToggleProps) => {
     const initVal = (!init ? undefined : promoteToArrayOrUndefined(props.defaultSelectedItems)) ?? promoteToArrayOrUndefined(props.selectedItems) ?? [];
     init = false;
 
-    const [selectedItemsLocal, setSelectedItemsLocal] = useState(initVal as (string|number) | ((string|number)[]));
+    const [selectedItemsLocal, setSelectedItemsLocal] = useState(initVal as (string | number) | (string | number)[]);
     const { items, selectedItems = selectedItemsLocal, tooltip, tooltipPlacement = 'top', onSelectionChange, color, background } = props;
     const itemsMap = new Map();
-    items.forEach((item) => itemsMap.set(item.val, item));
-    return <div className={`multiToggle-container`}>
-        <Popup
-            toggle={props.isToggle? undefined : <div style={{position: "relative"}}>
-                <IconButton
-                    color={color}
-                    borderColor={background ? color : undefined}
-                    label={props.label}
-                    active={props.toggleStatus}
-                    background={background}
-                    type={color && background ? Type.TERT : undefined}
-                    {...(itemsMap.get(promoteToArray(selectedItems)[0]) ?? {})}
-                    tooltip={tooltip}
-                    tooltipPlacement={tooltipPlacement}
-                />
-                {promoteToArray(selectedItems).length < 2 ? null : 
-                    <div style={{position: "absolute", top: "0", left: "0", color: color ?? Colors.MEDIUM_BLUE}}>
-                        +
-                    </div>}
-            </div>}
-            isToggle={props.isToggle}
-            toggleFunc={() => {
-                const selItem = items.find(item => promoteToArray(selectedItems).includes(item.val));
-                selItem && setSelectedItemsLocal([selItem.val]);
-            }}
-            type={props.type}
-            label={props.isToggle ? props.label : undefined}
-            toggleStatus={props.isToggle ? props.toggleStatus : undefined}
-            color={color}
-            popup={<Group padding={5} color={color} columnGap={0} style={{overflow: 'hidden'}}>
-                {items.map((item, i) =>
-                    <Toggle key={i} color={color} icon={item.icon} tooltip={item.tooltip}
-                        toggleStatus={promoteToArray(selectedItems).includes(item.val)} 
-                        type={Type.PRIM}
-                        toggleType={ToggleType.BUTTON}
-                        onClick={e => {
-                            const selected = new Set<string|number>();
-                            promoteToArray(selectedItems).forEach(val => val && selected.add(val));
-                            const toAdd = !props.multiSelect || !selected.has(item.val)
-                            if (!toAdd) selected.delete(item.val);
-                            else item.val && selected.add(item.val);
-                            onSelectionChange?.(item.val, toAdd);
-                            setSelectedItemsLocal(props.multiSelect ? Array.from(selected) : item.val);
-                            e.stopPropagation();
-                        }}/>
-                )}
-            </Group>}
-        />
-    </div>
-}
\ No newline at end of file
+    items.forEach(item => itemsMap.set(item.val, item));
+    return (
+        <div className={`multiToggle-container`}>
+            <Popup
+                toggle={
+                    props.isToggle ? undefined : (
+                        <div style={{ position: 'relative' }}>
+                            <IconButton
+                                color={color}
+                                borderColor={background ? color : undefined}
+                                label={props.label}
+                                active={props.toggleStatus}
+                                background={color}
+                                {...(itemsMap.get(promoteToArray(selectedItems)[0]) ?? {})}
+                                tooltip={tooltip}
+                                tooltipPlacement={tooltipPlacement}
+                            />
+                            {promoteToArray(selectedItems).length < 2 ? null : <div style={{ position: 'absolute', top: '0', left: '0', color: color ?? Colors.MEDIUM_BLUE }}>+</div>}
+                        </div>
+                    )
+                }
+                isToggle={props.isToggle}
+                toggleFunc={() => {
+                    const selItem = items.find(item => promoteToArray(selectedItems).includes(item.val));
+                    selItem && setSelectedItemsLocal([selItem.val]);
+                }}
+                type={props.type}
+                label={props.isToggle ? props.label : undefined}
+                toggleStatus={props.isToggle ? props.toggleStatus : undefined}
+                color={color}
+                background={background}
+                popup={
+                    <Group padding={5} color={color} background={background} columnGap={0} style={{ overflow: 'hidden' }}>
+                        {items.map((item, i) => (
+                            <Toggle
+                                key={i}
+                                color={color}
+                                background={color}
+                                icon={item.icon}
+                                tooltip={item.tooltip}
+                                toggleStatus={promoteToArray(selectedItems).includes(item.val)}
+                                type={Type.PRIM}
+                                toggleType={ToggleType.BUTTON}
+                                onClick={e => {
+                                    const selected = new Set<string | number>();
+                                    promoteToArray(selectedItems).forEach(val => val && selected.add(val));
+                                    const toAdd = !props.multiSelect || !selected.has(item.val);
+                                    if (!toAdd) selected.delete(item.val);
+                                    else item.val && selected.add(item.val);
+                                    onSelectionChange?.(item.val, toAdd);
+                                    setSelectedItemsLocal(props.multiSelect ? Array.from(selected) : item.val);
+                                    e.stopPropagation();
+                                }}
+                            />
+                        ))}
+                    </Group>
+                }
+            />
+        </div>
+    );
+};
diff --git a/packages/components/src/components/NumberDropdown/NumberDropdown.tsx b/packages/components/src/components/NumberDropdown/NumberDropdown.tsx
index 7f12198d5..b5f55bacf 100644
--- a/packages/components/src/components/NumberDropdown/NumberDropdown.tsx
+++ b/packages/components/src/components/NumberDropdown/NumberDropdown.tsx
@@ -20,11 +20,41 @@ export interface INumberDropdownProps extends INumberProps {
 
 export const NumberDropdown = (props: INumberDropdownProps) => {
     const [numberLoc, setNumberLoc] = useState<number>(0);
-    const { fillWidth, numberDropdownType = false, color = Colors.MEDIUM_BLUE, type, formLabelPlacement, showPlusMinus, min, max, unit, step = 1, number = numberLoc, setNumber = setNumberLoc, size, formLabel, tooltip } = props;
+    const {
+        fillWidth, //
+        numberDropdownType = false,
+        color = Colors.MEDIUM_BLUE,
+        type,
+        formLabelPlacement,
+        showPlusMinus,
+        min,
+        max,
+        unit,
+        background,
+        step = 1,
+        number = numberLoc,
+        setNumber = setNumberLoc,
+        size,
+        formLabel,
+        tooltip,
+    } = props;
     const [isOpen, setOpen] = useState<boolean>(false);
     let toggleText = number.toString();
     if (unit) toggleText = toggleText + unit;
-    let toggle = <Toggle tooltip={tooltip} color={color} fillWidth={fillWidth} type={type} size={size} align={'center'} text={toggleText} toggleType={ToggleType.BUTTON} toggleStatus={isOpen} onPointerDown={() => setOpen(!isOpen)} />;
+    let toggle = (
+        <Toggle
+            tooltip={tooltip} //
+            color={color}
+            fillWidth={fillWidth}
+            type={type}
+            size={size}
+            align="center"
+            text={toggleText}
+            toggleType={ToggleType.BUTTON}
+            toggleStatus={isOpen}
+            onPointerDown={() => setOpen(!isOpen)}
+        />
+    );
 
     if (showPlusMinus) {
         toggle = (
@@ -75,23 +105,23 @@ export const NumberDropdown = (props: INumberDropdownProps) => {
             break;
         case 'slider':
         default:
-            popup = <Slider size={Size.SMALL} unit={unit} multithumb={false} min={min} max={max} step={step} number={number} setNumber={setNumber} />;
+            popup = <Slider size={Size.SMALL} unit={unit} background={background} multithumb={false} min={min} max={max} step={step} number={number} setNumber={setNumber} />;
             break;
         case 'input':
-            popup = <Slider multithumb={false} min={min} max={max} step={step} number={number} />;
+            popup = <Slider multithumb={false} min={min} background={background} max={max} step={step} number={number} />;
             break;
     }
 
     const numberDropdown: JSX.Element = (
-        <div className={`numberDropdown-container`} style={{ height: '75%', width: fillWidth ? '100%' : 'fit-content' }}>
-            <Popup setOpen={setOpen} placement={'bottom'} size={size} isOpen={isOpen} popup={popup} toggle={toggle} fillWidth={fillWidth} color={color} />
+        <div className="numberDropdown-container" style={{ height: '75%', width: fillWidth ? '100%' : 'fit-content' }}>
+            <Popup setOpen={setOpen} placement="bottom" size={size} isOpen={isOpen} popup={popup} toggle={toggle} fillWidth={fillWidth} color={color} background={background} />
         </div>
     );
 
     return formLabel ? (
-        <div className={`form-wrapper ${formLabelPlacement}`} style={{ height: '100%', width: fillWidth ? '100%' : undefined }}>
+        <div className={`form-wrapper ${formLabelPlacement}`} style={{ color, height: '100%', width: fillWidth ? '100%' : undefined }}>
             {numberDropdown}
-            <div className="iconButton-label" style={{ fontSize: getFormLabelSize(size) }}>
+            <div className="iconButton-label" onPointerDown={() => setOpen(!isOpen)} style={{ cursor: 'pointer', height: '25%', fontSize: getFormLabelSize(size) }}>
                 {formLabel}
             </div>
         </div>
diff --git a/packages/components/src/components/NumberInput/NumberInput.tsx b/packages/components/src/components/NumberInput/NumberInput.tsx
index 33573d000..56c61a41e 100644
--- a/packages/components/src/components/NumberInput/NumberInput.tsx
+++ b/packages/components/src/components/NumberInput/NumberInput.tsx
@@ -1,89 +1,76 @@
-import * as React from 'react'
-import { Colors, INumberProps , Type, getFormLabelSize, getHeight } from '../../global'
-import './NumberInput.scss'
-import { useState } from 'react'
-import { Group } from '../Group'
-import { Toggle, ToggleType } from '../Toggle'
-import { IconButton } from '../IconButton'
-import * as fa from 'react-icons/fa'
-import { EditableText } from '../EditableText'
+import * as React from 'react';
+import { Colors, INumberProps, getFormLabelSize, getHeight } from '../../global';
+import './NumberInput.scss';
+import { useState } from 'react';
+import { Group } from '../Group';
+import { IconButton } from '../IconButton';
+import * as fa from 'react-icons/fa';
+import { EditableText } from '../EditableText';
 
 export interface INumberInputProps extends INumberProps {
-    showPlusMinus?: boolean
+    showPlusMinus?: boolean;
 }
 
 export const NumberInput = (props: INumberInputProps) => {
-    const [numberLoc, setNumberLoc] = useState<number>(10)
-    const { 
-        color = Colors.MEDIUM_BLUE, 
-        type,
-        formLabelPlacement, 
-        showPlusMinus, 
-        min, 
-        max, 
-        unit = '', 
-        width,
-        fillWidth = width ? true : false, 
-        step = 1, 
-        number = numberLoc, 
-        setNumber = setNumberLoc, 
-        size, 
-        formLabel, 
-        tooltip } = 
-    props;
+    const [numberLoc, setNumberLoc] = useState<number>(10);
+    const { color = Colors.MEDIUM_BLUE, type, formLabelPlacement, showPlusMinus, min, max, unit = '', width, fillWidth = width ? true : false, step = 1, number = numberLoc, setNumber = setNumberLoc, size, formLabel } = props;
+
+    let input = (
+        <EditableText
+            color={color}
+            type={type}
+            size={size}
+            val={number.toString() + unit}
+            // width={getHeight(undefined, size)}
+            textAlign={'center'}
+            fillWidth={fillWidth}
+            width={width && width - (showPlusMinus ? +getHeight(undefined, size) * 4 : 0)}
+            setVal={val => setNumber(!isNaN(Number(val)) ? Number(val) : number)}
+        />
+    );
 
-    let input = <EditableText
-        color={color}
-        type={type}
-        size={size}
-        val={number.toString() + unit}
-        // width={getHeight(undefined, size)}
-        textAlign={'center'}
-        fillWidth={fillWidth}
-        width={width && width - (showPlusMinus ? getHeight(undefined, size) * 4 : 0)}
-        setVal={val => setNumber(!isNaN(Number(val)) ? Number(val) : number)}
-    />;
-    
     if (showPlusMinus) {
-        input = <Group columnGap={0} style={{overflow: 'hidden'}}>
-            {input}
-            <IconButton 
-                size={size} 
-                icon={<fa.FaMinus/>} 
-                color={color}
-                onClick={(e) => {
-                    e.stopPropagation();
-                    setNumber(number - step);
-                }}
-                inactive={number - step < min}
-                tooltip={`Subtract ${step}${unit}`}
-            />
-            <IconButton 
-                size={size} 
-                icon={<fa.FaPlus/>} 
-                color={color}
-                onClick={(e) => {
-                    e.stopPropagation();
-                    setNumber(number + step);
-                }}
-                inactive={number + step > max}
-                tooltip={`Add ${step}${unit}`}
-            />
-        </Group>
+        input = (
+            <Group columnGap={0} style={{ overflow: 'hidden' }}>
+                {input}
+                <IconButton
+                    size={size}
+                    icon={<fa.FaMinus />}
+                    color={color}
+                    onClick={e => {
+                        e.stopPropagation();
+                        setNumber(number - step);
+                    }}
+                    inactive={number - step < min}
+                    tooltip={`Subtract ${step}${unit}`}
+                />
+                <IconButton
+                    size={size}
+                    icon={<fa.FaPlus />}
+                    color={color}
+                    onClick={e => {
+                        e.stopPropagation();
+                        setNumber(number + step);
+                    }}
+                    inactive={number + step > max}
+                    tooltip={`Add ${step}${unit}`}
+                />
+            </Group>
+        );
     }
 
-
-    return (
-        formLabel ? 
-        <div className={`form-wrapper ${formLabelPlacement}`} style={{ width: fillWidth ? '100%' : undefined}}>
-            <div className={'formLabel'} style={{fontSize: getFormLabelSize(size)}}>{formLabel}</div>
-            <div className={`numberInput-container`} style={{width: fillWidth ? '100%' : 'fit-content'}}>
+    return formLabel ? (
+        <div className={`form-wrapper ${formLabelPlacement}`} style={{ width: fillWidth ? '100%' : undefined }}>
+            <div className={'formLabel'} style={{ fontSize: getFormLabelSize(size) }}>
+                {formLabel}
+            </div>
+            <div className={`numberInput-container`} style={{ width: fillWidth ? '100%' : 'fit-content' }}>
                 {input}
             </div>
         </div>
-        :
-        <div className={`numberInput-container`} style={{width: fillWidth ? '100%' : 'fit-content'}}>
+    ) : (
+        <div className={`numberInput-container`} style={{ width: fillWidth ? '100%' : 'fit-content' }}>
             {input}
         </div>
-    )
-}
\ No newline at end of file
+    );
+};
diff --git a/packages/components/src/components/Popup/Popup.tsx b/packages/components/src/components/Popup/Popup.tsx
index 5a58fee29..82e60f343 100644
--- a/packages/components/src/components/Popup/Popup.tsx
+++ b/packages/components/src/components/Popup/Popup.tsx
@@ -1,5 +1,5 @@
 import React, { useEffect, useRef, useState } from 'react';
-import { Colors, IGlobalProps, Placement, Size, isDark } from '../../global';
+import { IGlobalProps, Placement, Size } from '../../global';
 import { Toggle, ToggleType } from '../Toggle';
 import './Popup.scss';
 import { Popper } from '@mui/material';
@@ -57,7 +57,7 @@ export const Popup = (props: IPopupProps) => {
         height,
         fillWidth,
         iconPlacement = 'left',
-        background = isDark(color) ? Colors.LIGHT_GRAY : Colors.DARK_GRAY,
+        background,
         popupContainsPt,
     } = props;
 
@@ -116,7 +116,7 @@ export const Popup = (props: IPopupProps) => {
                             size={size}
                             type={type}
                             color={color}
-                            background={props.isToggle ? undefined : background}
+                            background={background}
                             toggleType={ToggleType.BUTTON}
                             icon={icon}
                             iconPlacement={iconPlacement}
@@ -138,7 +138,7 @@ export const Popup = (props: IPopupProps) => {
             </div>
             <Popper open={isOpen} style={{ zIndex: 20000 }} anchorEl={triggerRef.current} placement={placement} modifiers={[]}>
                 <div
-                    className={`popup-container`}
+                    className="popup-container"
                     ref={popperRef}
                     style={{ width, height, background }}
                     tabIndex={-1}
diff --git a/packages/components/src/components/Slider/Slider.tsx b/packages/components/src/components/Slider/Slider.tsx
index 5af945383..fefc14832 100644
--- a/packages/components/src/components/Slider/Slider.tsx
+++ b/packages/components/src/components/Slider/Slider.tsx
@@ -52,7 +52,7 @@ export const Slider = (props: ISliderProps) => {
     const toDecimal = (num: number) => (decimals !== undefined ? Math.round(num * Math.pow(10, decimals)) / Math.pow(10, decimals) : num);
 
     const getLeftPos = (locVal: number) => {
-        const dragger = getHeight(+(height || 0), size);
+        const dragger = +getHeight(height, size);
         return ((locVal - min) / (max - min)) * (width - dragger);
     };
 
@@ -65,8 +65,8 @@ export const Slider = (props: ISliderProps) => {
                     background: color,
                     color: isDark(color) ? Colors.LIGHT_GRAY : Colors.DARK_GRAY,
                     fontSize: getFontSize(size),
-                    height: getHeight(+(height || 0), size),
-                    width: getHeight(+(height || 0), size),
+                    height: getHeight(height, size),
+                    width: getHeight(height, size),
                     top: 0,
                 }}>
                 <span className="rs-label">{toDecimal(locVal)}</span>
@@ -132,7 +132,7 @@ export const Slider = (props: ISliderProps) => {
                 lastEndVal = endNumberLoc;
             }}
             style={{
-                padding: `5px 0px ${getHeight(+(height || 0), size)}px 0px`,
+                padding: `5px 0px ${getHeight(height, size)}px 0px`,
                 width: fillWidth ? '100%' : 'fit-content',
             }}>
             <div
@@ -141,22 +141,22 @@ export const Slider = (props: ISliderProps) => {
                     r && new ResizeObserver(() => setWidth(+(r?.clientWidth ?? 100))).observe(r);
                     setWidth(+(r?.clientWidth ?? 100));
                 }}
-                style={{ height: getHeight(+(height || 0), size) }}
+                style={{ height: getHeight(height, size) }}
                 onPointerDown={onPointerDown}>
                 {ValSlider}
                 <div
                     className="selected-range"
                     style={{
-                        height: getHeight(+(height || 0), size) / 10,
+                        height: +getHeight(height, size) / 10,
                         background: multithumb ? Colors.LIGHT_GRAY : color,
                     }}
                 />
                 <div
                     className="range"
                     style={{
-                        height: getHeight(+(height || 0), size) / 10,
+                        height: +getHeight(height, size) / 10,
                         width: getLeftPos(endNumber) - getLeftPos(number),
-                        left: getLeftPos(number) + getHeight(+(height || 0), size),
+                        left: getLeftPos(number) + +getHeight(height, size),
                         display: multithumb ? undefined : 'none',
                         background: color,
                     }}
diff --git a/packages/components/src/components/Toggle/Toggle.tsx b/packages/components/src/components/Toggle/Toggle.tsx
index 5cc2ae339..371d00cc1 100644
--- a/packages/components/src/components/Toggle/Toggle.tsx
+++ b/packages/components/src/components/Toggle/Toggle.tsx
@@ -1,169 +1,170 @@
-import { Tooltip } from '@mui/material'
-import React, { useState } from 'react'
-import * as bi from 'react-icons/bi'
-import { IGlobalProps, Placement, Type , getFormLabelSize } from '../../global'
-import { Size } from '../../global/globalEnums'
-import { getFontSize, getHeight } from '../../global/globalUtils'
-import { Button, IButtonProps } from '../Button'
-import { IconButton } from '../IconButton'
-import './Toggle.scss'
+import { Tooltip } from '@mui/material';
+import React, { useState } from 'react';
+import * as bi from 'react-icons/bi';
+import { Type, getFormLabelSize } from '../../global';
+import { Size } from '../../global/globalEnums';
+import { getFontSize, getHeight } from '../../global/globalUtils';
+import { Button, IButtonProps } from '../Button';
+import { IconButton } from '../IconButton';
+import './Toggle.scss';
 
 export enum ToggleType {
-  BUTTON = "button",
-  CHECKBOX = "checkbox",
-  SWITCH = "switch",
+    BUTTON = 'button',
+    CHECKBOX = 'checkbox',
+    SWITCH = 'switch',
 }
 
 export interface IToggleProps extends IButtonProps {
-  toggleStatus?: boolean // true -> selected, false -> unselected
-  toggleType?: ToggleType
-  iconFalse?: JSX.Element | string
+    toggleStatus?: boolean; // true -> selected, false -> unselected
+    toggleType?: ToggleType;
+    iconFalse?: JSX.Element | string;
+    triState?: boolean;
 }
 
 export const Toggle = (props: IToggleProps) => {
-  const [toggleStatusLoc, setToggleStatusLoc] = useState<boolean>(true);
-  const {
-    toggleStatus = toggleStatusLoc,
-    toggleType = ToggleType.CHECKBOX,
-    type = Type.SEC,
-    style,
-    color,
-    background,
-    text,
-    icon,
-    iconFalse = icon,
-    height,
-    inactive,
-    label,
-    iconPlacement,
-    onPointerDown,
-    onClick,
-    tooltip,
-    tooltipPlacement = 'top',
-    size = Size.SMALL,
-    formLabel,
-    formLabelPlacement,
-    fillWidth,
-    align
-  } = props
+    const [toggleStatusLoc, setToggleStatusLoc] = useState<boolean>(true);
+    const {
+        toggleStatus = toggleStatusLoc,
+        toggleType = ToggleType.CHECKBOX,
+        type = Type.SEC,
+        color,
+        background,
+        text,
+        icon,
+        iconFalse = icon,
+        height,
+        inactive,
+        label,
+        iconPlacement,
+        onPointerDown,
+        onClick,
+        triState,
+        tooltip,
+        tooltipPlacement = 'top',
+        size = Size.SMALL,
+        formLabel,
+        formLabelPlacement,
+        fillWidth,
+        align,
+    } = props;
 
-  /**
-   * Pointer down
-   * @param e
-   */
-  const handlePointerDown = (e: React.PointerEvent) => {
-    if (!inactive && onPointerDown){
-      e.stopPropagation();
-      e.preventDefault();
-      onPointerDown(e)
-    } 
-  }
+    /**
+     * Pointer down
+     * @param e
+     */
+    const handlePointerDown = (e: React.PointerEvent) => {
+        if (!inactive && onPointerDown) {
+            e.stopPropagation();
+            e.preventDefault();
+            onPointerDown(e);
+        }
+    };
 
-  /**
-   * Single click
-   * @param e
-   */
-  const handleClick = (e: React.MouseEvent) => {
-    if (toggleStatus === toggleStatusLoc) {
-      setToggleStatusLoc(!toggleStatus)
-    }
-    
-    if (!inactive && onClick) {
-      e.stopPropagation();
-      e.preventDefault();
-      onClick(e);
-    } 
-  }
+    /**
+     * Single click
+     * @param e
+     */
+    const handleClick = (e: React.MouseEvent) => {
+        if (toggleStatus === toggleStatusLoc) {
+            setToggleStatusLoc(!toggleStatus);
+        }
 
-  const defaultProperties = {
-    height: getHeight(height, size),
-    borderColor: color
-  }
+        if (!inactive && onClick) {
+            e.stopPropagation();
+            e.preventDefault();
+            onClick(e);
+        }
+    };
 
-  let toggleElement: JSX.Element;
+    const defaultProperties = {
+        height: getHeight(height, size),
+        borderColor: color,
+    };
 
-  switch(toggleType) {
-    case ToggleType.BUTTON:
-      toggleElement = (
-        <Button
-          text={text}
-          tooltip={tooltip}
-          icon={toggleStatus ? icon : iconFalse}
-          onPointerDown={handlePointerDown}
-          onClick={handleClick}
-          active={toggleStatus}
-          type={type}
-          size={size}
-          iconPlacement={iconPlacement}
-          color={color}
-          background={background}
-          label={label}
-          fillWidth={fillWidth}
-          align={align}
-        />
-      );
-      break;
-    case ToggleType.CHECKBOX:
-      toggleElement = (
-        <IconButton
-          icon={
-            toggleStatus ? <bi.BiCheck/> : undefined
-          }
-          tooltip={tooltip}
-          onPointerDown={handlePointerDown}
-          onClick={handleClick}
-          active={toggleStatus}
-          type={type}
-          size={size}
-          color={color}
-          background={background}
-          label={label}
-          fillWidth={fillWidth}
-          align={align}
-        />
-      );
-      break;
-    case ToggleType.SWITCH:
-    default:
-      toggleElement =  (
-        <Tooltip disableInteractive={true} arrow={true} placement={tooltipPlacement} title={tooltip}>
-          <div
-            className={`toggle-container ${toggleType}`}
-            onPointerDown={handlePointerDown}
-            onClick={handleClick}
-            style={{
-              width: 2*getHeight(height, size),
-              ...defaultProperties
-            }}
-          >
-            <div className="toggle-content" style={{
-              fontSize: getFontSize(size), 
-              borderColor: color, 
-              left: toggleStatus ? '0%' : `calc(100% - ${getHeight(height, size)}px)`
-            }}>
-              <div className="toggle-switch" style={{
-                width: getHeight(height, size), 
-                height: getHeight(height, size),
-                background: color
-              }}></div>  
-            </div>
-            <div className={`toggle-background ${toggleStatus && 'active'}`}
-              style={{ background: color}}
-            />
-          </div>
-        </Tooltip>
-      );
-      break;
-  }
+    let toggleElement: JSX.Element;
 
+    switch (toggleType) {
+        case ToggleType.BUTTON:
+            toggleElement = (
+                <Button
+                    text={text}
+                    tooltip={tooltip}
+                    icon={toggleStatus ? icon : iconFalse}
+                    onPointerDown={handlePointerDown}
+                    onClick={handleClick}
+                    active={toggleStatus}
+                    type={type}
+                    size={size}
+                    iconPlacement={iconPlacement}
+                    color={color}
+                    background={background}
+                    label={label}
+                    fillWidth={fillWidth}
+                    align={align}
+                    filter={triState ? 'opacity(0.2)' : undefined}
+                />
+            );
+            break;
+        case ToggleType.CHECKBOX:
+            toggleElement = (
+                <IconButton
+                    icon={toggleStatus ? <bi.BiCheck /> : undefined}
+                    tooltip={tooltip}
+                    onPointerDown={handlePointerDown}
+                    onClick={handleClick}
+                    active={toggleStatus}
+                    type={type}
+                    size={size}
+                    color={color}
+                    background={background}
+                    label={label}
+                    fillWidth={fillWidth}
+                    align={align}
+                />
+            );
+            break;
+        case ToggleType.SWITCH:
+        default:
+            toggleElement = (
+                <Tooltip disableInteractive={true} arrow={true} placement={tooltipPlacement} title={tooltip}>
+                    <div
+                        className={`toggle-container ${toggleType}`}
+                        onPointerDown={handlePointerDown}
+                        onClick={handleClick}
+                        style={{
+                            width: 2 * +getHeight(height, size),
+                            ...defaultProperties,
+                        }}>
+                        <div
+                            className="toggle-content"
+                            style={{
+                                fontSize: getFontSize(size),
+                                borderColor: color,
+                                left: toggleStatus ? '0%' : `calc(100% - ${getHeight(height, size)}px)`,
+                            }}>
+                            <div
+                                className="toggle-switch"
+                                style={{
+                                    width: getHeight(height, size),
+                                    height: getHeight(height, size),
+                                    background: color,
+                                }}></div>
+                        </div>
+                        <div className={`toggle-background ${toggleStatus && 'active'}`} style={{ background: color }} />
+                    </div>
+                </Tooltip>
+            );
+            break;
+    }
 
-  return (
-    formLabel ? 
-    <div className={`form-wrapper ${formLabelPlacement}`}>
-        <div className={'formLabel'} style={{fontSize: getFormLabelSize(size)}}>{formLabel}</div>
-        {toggleElement}
-    </div>
-    :
-    toggleElement
-  )
-}
+    return formLabel ? (
+        <div className={`form-wrapper ${formLabelPlacement}`}>
+            <div className={'formLabel'} style={{ fontSize: getFormLabelSize(size) }}>
+                {formLabel}
+            </div>
+            {toggleElement}
+        </div>
+    ) : (
+        toggleElement
+    );
+};
diff --git a/packages/components/src/global/globalEnums.tsx b/packages/components/src/global/globalEnums.tsx
index bdeacccdb..bd82e3c57 100644
--- a/packages/components/src/global/globalEnums.tsx
+++ b/packages/components/src/global/globalEnums.tsx
@@ -1,52 +1,53 @@
 export enum Colors {
-    BLACK = "#000000",
-    DARK_GRAY = "#323232",
-    MEDIUM_GRAY = "#9F9F9F",
-    LIGHT_GRAY = "#DFDFDF",
-    WHITE = "#FFFFFF",
-    MEDIUM_BLUE = "#4476F7",
-    MEDIUM_BLUE_ALT = "#4476f73d", // REDUCED OPACITY
-    LIGHT_BLUE = "#BDDDF5",
-    PINK = "#E0217D",
-    YELLOW = "#F5D747",
-    DROP_SHADOW = "#32323215",
-    ERROR_RED = "#FF9494",
-    SUCCESS_GREEN = "#4BB543",
-    TRANSPARENT = "transparent"
+    BLACK = '#000000',
+    DARK_GRAY = '#323232',
+    MEDIUM_GRAY = '#9F9F9F',
+    LIGHT_GRAY = '#DFDFDF',
+    WHITE = '#FFFFFF',
+    MEDIUM_BLUE = '#4476F7',
+    MEDIUM_BLUE_ALT = '#4476f73d', // REDUCED OPACITY
+    LIGHT_BLUE = '#BDDDF5',
+    PINK = '#E0217D',
+    YELLOW = '#F5D747',
+    DROP_SHADOW = '#32323215',
+    ERROR_RED = '#FF9494',
+    SUCCESS_GREEN = '#4BB543',
+    TRANSPARENT = 'transparent',
 }
 
 export enum FontSize {
-    JUMBO_ICON = "5rem",
-    ICON = "3rem",
-    HEADER = "1.6rem",
-    DEFAULT = "1rem",
-    SECONDARY = "1.3rem",
-    LABEL = "0.6rem"
+    JUMBO_ICON = '5rem',
+    ICON = '3rem',
+    HEADER = '1.6rem',
+    DEFAULT = '1rem',
+    SECONDARY = '1.3rem',
+    LABEL = '0.6rem',
 }
 
 export enum Padding {
-    MINIMUM_PADDING = "4px",
-    SMALL_PADDING = "8px",
-    MEDIUM_PADDING = "16px",
-    LARGE_PADDING = "32px",
+    MINIMUM_PADDING = '4px',
+    SMALL_PADDING = '8px',
+    MEDIUM_PADDING = '16px',
+    LARGE_PADDING = '32px',
 }
 
 export enum IconSizes {
-    ICON_SIZE = "28px",
+    ICON_SIZE = '28px',
 }
 
 export enum Borders {
-    STANDARD = "solid 1px #9F9F9F",
-    STANDARD_BORDER_RADIUS = '5px'
+    STANDARD = 'solid 1px #9F9F9F',
+    STANDARD_BORDER_RADIUS = '5px',
 }
 
 export enum Shadows {
-    STANDARD_SHADOW = "0px 3px 4px rgba(0, 0, 0, 0.3)"
+    STANDARD_SHADOW = '0px 3px 4px rgba(0, 0, 0, 0.3)',
 }
 
 export enum Size {
-    XSMALL = "xsmall",
-    SMALL = "small",
-    MEDIUM = "medium",
-    LARGE = "large"
-}
\ No newline at end of file
+    XXSMALL = 'xxsmall',
+    XSMALL = 'xsmall',
+    SMALL = 'small',
+    MEDIUM = 'medium',
+    LARGE = 'large',
+}
diff --git a/packages/components/src/global/globalUtils.tsx b/packages/components/src/global/globalUtils.tsx
index 0f1e0adbc..4a1c2cb66 100644
--- a/packages/components/src/global/globalUtils.tsx
+++ b/packages/components/src/global/globalUtils.tsx
@@ -1,93 +1,88 @@
-import { Size } from './globalEnums'
+import { Size } from './globalEnums';
 import Color from 'color';
 
 export interface ILocation {
-  top: number
-  left: number
-  width: number
-  height: number
-  override?: 'left' | 'bottom' | 'top' | 'right'
+    top: number;
+    left: number;
+    width: number;
+    height: number;
+    override?: 'left' | 'bottom' | 'top' | 'right';
 }
 
-export const getFormLabelSize = (
-  size: Size | undefined,
-) => {
-  switch (size) {
-    case Size.XSMALL:
-      return '7px'
-    case Size.SMALL:
-      return '10px'
-    case Size.MEDIUM:
-      return '13px'
-    case Size.LARGE:
-      return '14px'
-    default:
-      return '10px'
-  }
-}
+export const getFormLabelSize = (size: Size | undefined) => {
+    switch (size) {
+        case Size.XXSMALL:
+            return '6px';
+        case Size.XSMALL:
+            return '7px';
+        case Size.SMALL:
+            return '10px';
+        case Size.MEDIUM:
+            return '13px';
+        case Size.LARGE:
+            return '14px';
+        default:
+            return '10px';
+    }
+};
 
-export const getFontSize = (
-  size: Size | undefined,
-  icon?: boolean
-) => {
-  switch (size) {
-    case Size.XSMALL:
-      if (icon) return '11px'
-      return '9px'
-    case Size.SMALL:
-      if (icon) return '15px'
-      return '11px'
-    case Size.MEDIUM:
-      if (icon) return '17px'
-      return '14px'
-    case Size.LARGE:
-      if (icon) return '22px'
-      return '17px'
-    default:
-      if (icon) return '15px'
-      return '12px'
-  }
-}
+export const getFontSize = (size: Size | undefined, icon?: boolean) => {
+    switch (size) {
+        case Size.XXSMALL:
+            if (icon) return '10px';
+            return '7px';
+        case Size.XSMALL:
+            if (icon) return '11px';
+            return '9px';
+        case Size.SMALL:
+            if (icon) return '15px';
+            return '11px';
+        case Size.MEDIUM:
+            if (icon) return '17px';
+            return '14px';
+        case Size.LARGE:
+            if (icon) return '22px';
+            return '17px';
+        default:
+            if (icon) return '15px';
+            return '12px';
+    }
+};
 
-export const getHeight = (
-  height: number | undefined,
-  size: Size | undefined
-) => {
-  if (height) return height
-  switch (size) {
-    case Size.XSMALL:
-      return 20
-    case Size.SMALL:
-      return 30
-    case Size.MEDIUM:
-      return 40
-    case Size.LARGE:
-      return 50
-    default:
-      return 30
-  }
-}
+export const getHeight = (height: number | string | undefined, size: Size | undefined) => {
+    if (height) return height;
+    switch (size) {
+        case Size.XXSMALL:
+            return 15;
+        case Size.XSMALL:
+            return 20;
+        case Size.SMALL:
+            return 30;
+        case Size.MEDIUM:
+            return 40;
+        case Size.LARGE:
+            return 50;
+        default:
+            return 30;
+    }
+};
 
-export const colorConvert = (color: any) => {
-  try {
-    return color ? Color(color.toLowerCase()) : Color('transparent')
-  } catch (e) {
-    console.log('COLOR error:', e)
-    return Color('red')
-  }
-}
+export const colorConvert = (color: string) => {
+    try {
+        return color ? Color(color.toLowerCase()) : Color('transparent');
+    } catch (e) {
+        console.log('COLOR error:', e);
+        return Color('red');
+    }
+};
 
-export const isDark = (color: any): boolean => {
-  if (color === undefined) return false
-  if (color === 'transparent') return false
-  if (color.startsWith?.('linear')) return false
-  const nonAlphaColor = color.startsWith('#')
-    ? (color as string).substring(0, 7)
-    : color.startsWith('rgba')
-    ? color.replace(/,.[^,]*\)/, ')').replace('rgba', 'rgb')
-    : color
-  const col = colorConvert(nonAlphaColor).rgb()
-  const colsum = col.red() + col.green() + col.blue()
-  if (colsum / col.alpha() > 400 || col.alpha() < 0.25) return false
-  else return true
-}
+export const isDark = (color: string): boolean => {
+    if (color === undefined) return false;
+    if (color === 'transparent') return false;
+    if (color.startsWith?.('linear')) return false;
+    const nonAlphaColor = color.startsWith('#') ? (color as string).substring(0, 7) : color.startsWith('rgba') ? color.replace(/,.[^,]*\)/, ')').replace('rgba', 'rgb') : color;
+    const col = colorConvert(nonAlphaColor).rgb();
+    const colsum = col.red() + col.green() + col.blue();
+    if (colsum / col.alpha() > 400 || col.alpha() < 0.25) return false;
+    else return true;
+};
diff --git a/src/client/util/CalendarManager.tsx b/src/client/util/CalendarManager.tsx
index 1a5a5f889..4e321a893 100644
--- a/src/client/util/CalendarManager.tsx
+++ b/src/client/util/CalendarManager.tsx
@@ -236,7 +236,7 @@ export class CalendarManager extends ObservableReactComponent<object> {
                 className="calendar-interface"
                 style={{
                     background: SnappingManager.userBackgroundColor,
-                    color: StrCast(Doc.UserDoc().userColor),
+                    color: SnappingManager.userColor,
                 }}>
                 <p className="selected-doc-title" style={{ color: SnappingManager.userColor }}>
                     <b>{this.focusOn(docs.length < 2 ? StrCast(targetDoc?.title, 'this document') : '-multiple-')}</b>
diff --git a/src/client/util/GroupManager.tsx b/src/client/util/GroupManager.tsx
index 1ec85c9d9..79d009720 100644
--- a/src/client/util/GroupManager.tsx
+++ b/src/client/util/GroupManager.tsx
@@ -19,6 +19,7 @@ import './GroupManager.scss';
 import { GroupMemberView } from './GroupMemberView';
 import { SharingManager, User } from './SharingManager';
 import { SnappingManager } from './SnappingManager';
+import { SettingsManager } from './SettingsManager';
 
 /**
  * Interface for options for the react-select component
@@ -290,11 +291,12 @@ export class GroupManager extends ObservableReactComponent<object> {
                                 this.createGroupModalOpen = false;
                                 TaskCompletionBox.taskCompleted = false;
                             })}
-                            color={StrCast(Doc.UserDoc().userColor)}
+                            color={SettingsManager.userColor}
+                            background={SettingsManager.userBackgroundColor}
                         />
                     </div>
                 </div>
-                <div className="group-input" style={{ border: StrCast(Doc.UserDoc().userColor) }}>
+                <div className="group-input" style={{ border: SettingsManager.userColor }}>
                     <input
                         ref={this.inputRef}
                         onKeyDown={this.handleKeyDown}
@@ -306,7 +308,7 @@ export class GroupManager extends ObservableReactComponent<object> {
                         })}
                     />
                 </div>
-                <div style={{ border: StrCast(Doc.UserDoc().userColor) }}>
+                <div style={{ border: SettingsManager.userColor }}>
                     <Select
                         className="select-users"
                         isMulti
@@ -332,15 +334,15 @@ export class GroupManager extends ObservableReactComponent<object> {
                             }),
                             valueContainer: () => ({
                                 display: 'inline-flex',
-                                fontStyle: StrCast(Doc.UserDoc().userColor),
-                                color: StrCast(Doc.UserDoc().userColor),
+                                fontStyle: SettingsManager.userColor,
+                                color: SettingsManager.userColor,
                                 width: '100%',
                             }),
                         }}
                     />
                 </div>
                 <div className="create-button">
-                    <Button text="Create" type={Type.TERT} color={StrCast(Doc.UserDoc().userColor)} onClick={this.createGroup} />
+                    <Button text="Create" type={Type.TERT} color={SettingsManager.userColor} background={SettingsManager.userBackgroundColor} onClick={this.createGroup} />
                 </div>
             </div>
         );
diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx
index 6ea242fc3..89e3686b2 100644
--- a/src/client/util/SettingsManager.tsx
+++ b/src/client/util/SettingsManager.tsx
@@ -135,9 +135,9 @@ export class SettingsManager extends React.Component<object> {
         reaction(
             () => [SettingsManager.userBackgroundColor, SettingsManager.userColor, SettingsManager.userVariantColor],
             ([back, user, variant]) => {
-                SnappingManager.userBackgroundColor = back;
-                SnappingManager.userVariantColor = variant;
-                SnappingManager.userColor = user;
+                SnappingManager.SetUserBackgroundColor(back);
+                SnappingManager.SetUserVariantColor(variant);
+                SnappingManager.SetUserColor(user);
             },
             { fireImmediately: true }
         );
@@ -177,6 +177,7 @@ export class SettingsManager extends React.Component<object> {
                     }))}
                     dropdownType={DropdownType.SELECT}
                     color={SettingsManager.userColor}
+                    background={SettingsManager.userBackgroundColor}
                     fillWidth
                 />
                 <Toggle formLabel="Match System" toggleType={ToggleType.SWITCH} color={SettingsManager.userColor} toggleStatus={BoolCast(Doc.UserDoc().userThemeSystem)} onClick={this.userThemeSystemToggle} />
@@ -300,6 +301,7 @@ export class SettingsManager extends React.Component<object> {
                     <NumberDropdown
                         number={NumCast(Doc.UserDoc().headerHeight, 30)}
                         color={SettingsManager.userColor}
+                        background={SettingsManager.userBackgroundColor}
                         numberDropdownType="slider"
                         min={6}
                         max={60}
@@ -342,6 +344,7 @@ export class SettingsManager extends React.Component<object> {
                         <Group formLabel="Default Font">
                             <NumberDropdown
                                 color={SettingsManager.userColor}
+                                background={SettingsManager.userBackgroundColor}
                                 numberDropdownType="slider"
                                 min={0}
                                 max={50}
@@ -355,10 +358,10 @@ export class SettingsManager extends React.Component<object> {
                             />
                             <ColorPicker
                                 color={SettingsManager.userColor}
+                                background={SettingsManager.userBackgroundColor}
                                 type={Type.PRIM}
                                 defaultPickerType="Classic"
                                 selectedColor={StrCast(Doc.UserDoc().textBackgroundColor, Colors.LIGHT_GRAY)}
-                                background={SnappingManager.userBackgroundColor}
                                 icon={<FontAwesomeIcon icon="palette" size="lg" />}
                                 tooltip="default text background color"
                                 label="background"
@@ -390,6 +393,7 @@ export class SettingsManager extends React.Component<object> {
                                     this.changeFontFamily(val as string);
                                 }}
                                 color={SettingsManager.userColor}
+                                background={SettingsManager.userBackgroundColor}
                                 fillWidth
                             />
                         </Group>
@@ -402,12 +406,12 @@ export class SettingsManager extends React.Component<object> {
     @computed get passwordContent() {
         return (
             <div className="password-content">
-                <EditableText placeholder="Current password" type={Type.SEC} color={SettingsManager.userColor} val="" setVal={val => this.changeVal(val as string, 'curr')} fillWidth password />
-                <EditableText placeholder="New password" type={Type.SEC} color={SettingsManager.userColor} val="" setVal={val => this.changeVal(val as string, 'new')} fillWidth password />
-                <EditableText placeholder="Confirm new password" type={Type.SEC} color={SettingsManager.userColor} val="" setVal={val => this.changeVal(val as string, 'conf')} fillWidth password />
+                <EditableText placeholder="Current password" type={Type.SEC} color={SettingsManager.userColor} background={SettingsManager.userBackgroundColor} val="" setVal={val => this.changeVal(val as string, 'curr')} fillWidth password />
+                <EditableText placeholder="New password" type={Type.SEC} color={SettingsManager.userColor} background={SettingsManager.userBackgroundColor} val="" setVal={val => this.changeVal(val as string, 'new')} fillWidth password />
+                <EditableText placeholder="Confirm new password" type={Type.SEC} color={SettingsManager.userColor} background={SettingsManager.userBackgroundColor} val="" setVal={val => this.changeVal(val as string, 'conf')} fillWidth password />
                 {!this._passwordResultText ? null : <div className={`${this._passwordResultText.startsWith('Error') ? 'error' : 'success'}-text`}>{this._passwordResultText}</div>}
-                <Button type={Type.SEC} text="Forgot Password" color={SettingsManager.userColor} />
-                <Button type={Type.TERT} text="Submit" onClick={this.changePassword} color={SettingsManager.userColor} />
+                <Button type={Type.SEC} text="Forgot Password" color={SettingsManager.userColor} background={SettingsManager.userBackgroundColor} />
+                <Button type={Type.TERT} text="Submit" onClick={this.changePassword} color={SettingsManager.userColor} background={SettingsManager.userBackgroundColor} />
             </div>
         );
     }
@@ -415,7 +419,7 @@ export class SettingsManager extends React.Component<object> {
     @computed get accountOthersContent() {
         return (
             <div className="account-others-content">
-                <Button type={Type.TERT} text="Connect to Google" iconPlacement="left" icon={<BsGoogle />} onClick={() => this.googleAuthorize()} />
+                <Button type={Type.TERT} text="Connect to Google" color={SnappingManager.userColor} background={SnappingManager.userBackgroundColor} iconPlacement="left" icon={<BsGoogle />} onClick={() => this.googleAuthorize()} />
             </div>
         );
     }
@@ -465,6 +469,7 @@ export class SettingsManager extends React.Component<object> {
                             type={Type.TERT}
                             placement="bottom-start"
                             color={SettingsManager.userColor}
+                            background={SettingsManager.userBackgroundColor}
                             fillWidth
                         />
                         <Toggle formLabel="Playground Mode" toggleType={ToggleType.SWITCH} toggleStatus={this._playgroundMode} onClick={this.playgroundModeToggle} color={SettingsManager.userColor} />
@@ -494,13 +499,14 @@ export class SettingsManager extends React.Component<object> {
                             type={Type.TERT}
                             placement="bottom-start"
                             color={SettingsManager.userColor}
+                            background={SettingsManager.userBackgroundColor}
                         />
                     </div>
                 </div>
                 <div className="tab-column">
                     <div className="tab-column-title">Permissions</div>
                     <div className="tab-column-content">
-                        <Button text="Manage Groups" type={Type.TERT} onClick={() => GroupManager.Instance?.open()} color={SettingsManager.userColor} />
+                        <Button text="Manage Groups" type={Type.TERT} color={SnappingManager.userColor} background={SnappingManager.userBackgroundColor} onClick={() => GroupManager.Instance?.open()} />
                         <Toggle
                             toggleType={ToggleType.SWITCH}
                             formLabel="Default access private"
diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx
index 962f51cd4..db8c6c5cb 100644
--- a/src/client/util/SharingManager.tsx
+++ b/src/client/util/SharingManager.tsx
@@ -286,7 +286,7 @@ export class SharingManager extends React.Component<object> {
                         {this.focusOn(docs.length < 2 ? StrCast(targetDoc?.title, 'this document') : '-multiple-')}
                     </p>
                     <div className="share-copy-link">
-                        <Button type={Type.TERT} color={SnappingManager.userColor} icon={<FontAwesomeIcon icon="copy" size="sm" />} iconPlacement="left" text="Copy Guest URL" onClick={this.copyURL} />
+                        <Button type={Type.TERT} color={SnappingManager.userColor} background={SnappingManager.userBackgroundColor} icon={<FontAwesomeIcon icon="copy" size="sm" />} iconPlacement="left" text="Copy Guest URL" onClick={this.copyURL} />
                     </div>
                     <div className="close-button">
                         <Button icon={<FontAwesomeIcon icon="times" size="lg" />} onClick={this.close} color={SnappingManager.userColor} />
@@ -331,7 +331,7 @@ export class SharingManager extends React.Component<object> {
                                     </select>
                                 </div>
                                 <div className="share-button">
-                                    <Button text="SHARE" type={Type.TERT} color={SnappingManager.userColor} onClick={this.share} />
+                                    <Button text="SHARE" type={Type.TERT} color={SnappingManager.userColor} background={SnappingManager.userBackgroundColor} onClick={this.share} />
                                 </div>
                             </div>
                             <div className="sort-checkboxes">
diff --git a/src/client/util/SnappingManager.ts b/src/client/util/SnappingManager.ts
index 3bbc297b8..54c91087f 100644
--- a/src/client/util/SnappingManager.ts
+++ b/src/client/util/SnappingManager.ts
@@ -1,4 +1,4 @@
-import { observable, action, runInAction, makeObservable } from 'mobx';
+import { observable, action, makeObservable } from 'mobx';
 import { Gestures } from '../../pen-gestures/GestureTypes';
 
 export enum freeformScrollMode {
@@ -34,6 +34,9 @@ export class SnappingManager {
     @observable _keepGestureMode: boolean = false; // for whether primitive selection enters a one-shot or persistent mode
     @observable _inkShape: Gestures | undefined = undefined;
     @observable _chatVisible: boolean = false;
+    @observable _userBackgroundColor: string | undefined = undefined;
+    @observable _userVariantColor: string | undefined = undefined;
+    @observable _userColor: string | undefined = undefined;
 
     private constructor() {
         SnappingManager._manager = this;
@@ -48,6 +51,9 @@ export class SnappingManager {
         this.Instance._vertSnapLines.push(...vertLines);
     };
 
+    public static get userBackgroundColor() { return this.Instance._userBackgroundColor; } // prettier-ignore
+    public static get userVariantColor() { return this.Instance._userVariantColor; } // prettier-ignore
+    public static get userColor()      { return this.Instance._userColor; } // prettier-ignore
     public static get HorizSnapLines() { return this.Instance._horizSnapLines; } // prettier-ignore
     public static get VertSnapLines()  { return this.Instance._vertSnapLines; } // prettier-ignore
     public static get LongPress()      { return this.Instance._longPress; } // prettier-ignore
@@ -71,29 +77,29 @@ export class SnappingManager {
     public static get InkShape()       { return this.Instance._inkShape; } // prettier-ignore
     public static get ChatVisible()    { return this.Instance._chatVisible; } // prettier-ignore
 
-    public static SetLongPress      = (press: boolean) => runInAction(() => {this.Instance._longPress = press}); // prettier-ignore
-    public static SetShiftKey       = (down: boolean) => runInAction(() => {this.Instance._shiftKey = down}); // prettier-ignore
-    public static SetCtrlKey        = (down: boolean) => runInAction(() => {this.Instance._ctrlKey = down}); // prettier-ignore
-    public static SetMetaKey        = (down: boolean) => runInAction(() => {this.Instance._metaKey = down}); // prettier-ignore
-    public static SetHideUI         = (vis: boolean) => runInAction(() => {this.Instance._hideUI = vis}); // prettier-ignore
-    public static SetShowPresPaths  = (paths:boolean) => runInAction(() => {this.Instance._showPresPaths = paths}); // prettier-ignore
-    public static SetIsLinkFollowing= (follow:boolean)=> runInAction(() => {this.Instance._isLinkFollowing = follow}); // prettier-ignore
-    public static SetIsDragging     = (drag: boolean) => runInAction(() => {this.Instance._isDragging = drag}); // prettier-ignore
-    public static SetIsResizing     = (docid?:string) => runInAction(() => {this.Instance._isResizing = docid}); // prettier-ignore
-    public static SetCanEmbed       = (embed:boolean) => runInAction(() => {this.Instance._canEmbed = embed}); // prettier-ignore
-    public static SetExploreMode    = (state:boolean) => runInAction(() => {this.Instance._exploreMode = state}); // prettier-ignore
-    public static TriggerUserPanned = ()              => runInAction(() => {this.Instance._userPanned = !this.Instance._userPanned}); // prettier-ignore
-    public static SetServerVersion  = (version:string) =>runInAction(() => {this.Instance._serverVersion = version}); // prettier-ignore
-    public static SetLastPressedBtn = (id:string)      =>runInAction(() => {this.Instance._lastBtnId = id}); // prettier-ignore
-    public static SetPropertiesWidth= (wid:number)     =>runInAction(() => {this.Instance._propertyWid = wid}); // prettier-ignore
-    public static SetPrintToConsole = (state:boolean)  =>runInAction(() => {this.Instance._printToConsole = state}); // prettier-ignore
-    public static SetHideDecorations= (state:boolean)  =>runInAction(() => {this.Instance._hideDecorations = state}); // prettier-ignore
-    public static SetKeepGestureMode= (state:boolean)  =>runInAction(() => {this.Instance._keepGestureMode = state}); // prettier-ignore
-    public static SetInkShape       = (shape?:Gestures)=>runInAction(() => {this.Instance._inkShape = shape}); // prettier-ignore
-    public static SetChatVisible    = (vis:boolean)    =>runInAction(() => {this.Instance._chatVisible = vis}); // prettier-ignore
+    public static SetUserBackgroundColor = action((color: string) => (this.Instance._userBackgroundColor = color)); // prettier-ignore
+    public static SetUserVariantColor    = action((color: string) => (this.Instance._userVariantColor = color)); // prettier-ignore
+    public static SetUserColor           = action((color: string) => (this.Instance._userColor = color)); // prettier-ignore
+    public static SetLongPress           = action((press: boolean)=> (this.Instance._longPress = press)); // prettier-ignore
+    public static SetShiftKey            = action((down: boolean) => (this.Instance._shiftKey = down)); // prettier-ignore
+    public static SetCtrlKey             = action((down: boolean) => (this.Instance._ctrlKey = down)); // prettier-ignore
+    public static SetMetaKey             = action((down: boolean) => (this.Instance._metaKey = down)); // prettier-ignore
+    public static SetHideUI              = action((vis: boolean)  => (this.Instance._hideUI = vis)); // prettier-ignore
+    public static SetShowPresPaths       = action((paths:boolean) => (this.Instance._showPresPaths = paths)); // prettier-ignore
+    public static SetIsLinkFollowing     = action((follow:boolean)=> (this.Instance._isLinkFollowing = follow)); // prettier-ignore
+    public static SetIsDragging          = action((drag: boolean) => (this.Instance._isDragging = drag)); // prettier-ignore
+    public static SetIsResizing          = action((docid?:string) => (this.Instance._isResizing = docid)); // prettier-ignore
+    public static SetCanEmbed            = action((embed:boolean) => (this.Instance._canEmbed = embed)); // prettier-ignore
+    public static SetExploreMode         = action((state:boolean) => (this.Instance._exploreMode = state)); // prettier-ignore
+    public static TriggerUserPanned      = action(()              => (this.Instance._userPanned = !this.Instance._userPanned)); // prettier-ignore
+    public static SetServerVersion       = action((version:string)=> (this.Instance._serverVersion = version)); // prettier-ignore
+    public static SetLastPressedBtn      = action((id:string)     => (this.Instance._lastBtnId = id)); // prettier-ignore
+    public static SetPropertiesWidth     = action((wid:number)    => (this.Instance._propertyWid = wid)); // prettier-ignore
+    public static SetPrintToConsole      = action((state:boolean) => (this.Instance._printToConsole = state)); // prettier-ignore
+    public static SetHideDecorations     = action((state:boolean) => (this.Instance._hideDecorations = state)); // prettier-ignore
+    public static SetKeepGestureMode     = action((state:boolean) => (this.Instance._keepGestureMode = state)); // prettier-ignore
+    public static SetInkShape            = action((shape?:Gestures)=>(this.Instance._inkShape = shape)); // prettier-ignore
+    public static SetChatVisible         = action((vis:boolean)   => (this.Instance._chatVisible = vis)); // prettier-ignore
 
-    public static userColor: string | undefined;
-    public static userVariantColor: string | undefined;
-    public static userBackgroundColor: string | undefined;
     public static SettingsStyle: CSSStyleSheet | null;
 }
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index 331ee1707..e25227c00 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -108,8 +108,6 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
         LayoutTemplateString,
         disableBrushing,
         NativeDimScaling,
-        PanelWidth,
-        PanelHeight,
         isSelected,
         isHovering,
     } = props || {}; // extract props that are not shared between fieldView and documentView props.
@@ -259,7 +257,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
             switch (layoutDoc?.type) {
                 case DocumentType.PRESELEMENT: docColor = docColor || ""; break;
                 case DocumentType.PRES:        docColor = docColor || 'transparent'; break;
-                case DocumentType.FONTICON:    docColor = boxBackground ? undefined : docColor || Colors.DARK_GRAY; break;
+                case DocumentType.FONTICON:    docColor = boxBackground ? undefined : docColor || SnappingManager.userBackgroundColor; break;
                 case DocumentType.RTF:         docColor = docColor || StrCast(Doc.UserDoc().textBackgroundColor, Colors.LIGHT_GRAY); break;
                 case DocumentType.LINK:        docColor = (isAnchor ? docColor : undefined); break;
                 case DocumentType.INK:         docColor = doc?.stroke_isInkMask ? 'rgba(0,0,0,0.7)' : undefined; break;
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index c79610595..1576a8e4a 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -23,6 +23,7 @@ import { DefaultStyleProvider, returnEmptyDocViewList } from '../StyleProvider';
 import { DocumentView, DocumentViewInternal } from '../nodes/DocumentView';
 import './CollectionMenu.scss';
 import { CollectionLinearView } from './collectionLinear';
+import { SettingsManager } from '../../util/SettingsManager';
 
 interface CollectionMenuProps {
     panelHeight: () => number;
@@ -118,7 +119,7 @@ export class CollectionMenu extends AntimodeMenu<CollectionMenuProps> {
             <div className="hardCodedButtons">
                 <Toggle
                     toggleType={ToggleType.BUTTON}
-                    type={Type.PRIM}
+                    type={Type.TERT}
                     color={SnappingManager.userColor}
                     onClick={this.props.toggleTopBar}
                     toggleStatus={this.props.topBarHeight() > 0}
@@ -127,7 +128,7 @@ export class CollectionMenu extends AntimodeMenu<CollectionMenuProps> {
                 />
                 <Toggle
                     toggleType={ToggleType.BUTTON}
-                    type={Type.PRIM}
+                    type={Type.TERT}
                     color={SnappingManager.userColor}
                     onClick={this._props.togglePropertiesFlyout}
                     toggleStatus={SnappingManager.PropertiesWidth > 0}
@@ -138,19 +139,17 @@ export class CollectionMenu extends AntimodeMenu<CollectionMenuProps> {
         );
 
         // dash col linear view buttons
-        const contMenuButtons = (
+        return (
             <div
                 className="collectionMenu-container"
                 style={{
-                    background: SnappingManager.userBackgroundColor,
+                    background: SettingsManager.userBackgroundColor,
                     // borderColor: SettingsManager.userColor
                 }}>
                 {this.contMenuButtons}
                 {hardCodedButtons}
             </div>
         );
-
-        return contMenuButtons;
     }
 }
 
diff --git a/src/client/views/nodes/FontIconBox/FontIconBox.tsx b/src/client/views/nodes/FontIconBox/FontIconBox.tsx
index f699568f1..966d8d7a0 100644
--- a/src/client/views/nodes/FontIconBox/FontIconBox.tsx
+++ b/src/client/views/nodes/FontIconBox/FontIconBox.tsx
@@ -4,7 +4,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, computed, makeObservable, observable } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
-import { ClientUtils, DashColor, returnFalse, returnTrue, setupMoveUpEvents } from '../../../../ClientUtils';
+import { ClientUtils, returnFalse, returnTrue, setupMoveUpEvents } from '../../../../ClientUtils';
 import { Doc, DocListCast, StrListCast } from '../../../../fields/Doc';
 import { InkTool } from '../../../../fields/InkField';
 import { ScriptField } from '../../../../fields/ScriptField';
@@ -134,7 +134,7 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
                 min={NumCast(this.dataDoc.numBtnMin, 0)}
                 max={NumCast(this.dataDoc.numBtnMax, 100)}
                 number={checkResult}
-                size={Size.XSMALL}
+                size={Size.XXSMALL}
                 setNumber={undoable(value => numScript(value), `${this.Document.title} button set from list`)}
                 fillWidth
             />
@@ -252,7 +252,9 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
      * Color button
      */
     @computed get colorButton() {
-        const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) as string;
+        const color = SnappingManager.userColor;
+        const pickedColor = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) as string;
+        const background = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor) as string;
         const curColor = (this.colorScript?.script.run({ this: this.Document, value: undefined, _readOnly_: true }).result as string) ?? 'transparent';
         const tooltip: string = StrCast(this.Document.toolTip);
 
@@ -270,10 +272,10 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
                     }}
                     defaultPickerType="Classic"
                     selectedColor={curColor}
-                    type={Type.PRIM}
+                    type={Type.TERT}
                     color={color}
-                    background={SnappingManager.userBackgroundColor}
-                    icon={this.Icon(color) ?? undefined}
+                    background={background}
+                    icon={this.Icon(pickedColor) ?? undefined}
                     tooltip={tooltip}
                     label={this.label}
                 />
@@ -287,15 +289,16 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
         const toggleStatus = script?.run({ this: this.Document, value: undefined, _readOnly_: true }).result as boolean;
 
         const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) as string;
+        const background = this._props.styleProvider?.(this.Document, this._props, StyleProp.BackgroundColor) as string;
         const items = DocListCast(this.dataDoc.data);
         const selectedItems = items.filter(itemDoc => ScriptCast(itemDoc.onClick).script.run({ this: itemDoc, value: undefined, _readOnly_: true }).result).map(item => StrCast(item.toolType));
 
         return (
             <MultiToggle
                 tooltip={`Click to Toggle ${tooltip} or select new option`}
-                type={Type.PRIM}
+                type={Type.TERT}
                 color={color}
-                background={undefined}
+                background={background}
                 multiSelect={true}
                 onPointerDown={e => script && !toggleStatus && setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => script.run({ this: this.Document, value: undefined, _readOnly_: false }))}
                 isToggle={false}
@@ -339,11 +342,12 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
             <Toggle
                 tooltip={`Toggle ${tooltip}`}
                 toggleType={ToggleType.BUTTON}
-                type={inkShapeHack ? Type.TERT : Type.PRIM}
+                type={Type.TERT}
                 toggleStatus={toggleStatus}
                 text={buttonText}
                 color={color}
-                background={inkShapeHack ? DashColor(SnappingManager.userBackgroundColor).darken(0.05).toString() : undefined}
+                triState={inkShapeHack}
+                background={color}
                 icon={this.Icon(color)!}
                 label={this.label}
                 onPointerDown={e =>
@@ -404,12 +408,12 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
             case ButtonType.ColorButton:        return this.colorButton; 
             case ButtonType.MultiToggleButton:  return this.multiToggleButton;
             case ButtonType.ToggleButton:       return this.toggleButton;
-            case ButtonType.ClickButton:return <IconButton {...btnProps} size={Size.MEDIUM} color={color} />;
-            case ButtonType.ToolButton: return <IconButton {...btnProps} size={Size.LARGE} color={color} />;
-            case ButtonType.TextButton: return <Button     {...btnProps} color={color} 
-                        background={SnappingManager.userBackgroundColor} text={StrCast(this.dataDoc.buttonText)}/>;
-            case ButtonType.MenuButton: return <IconButton {...btnProps} color={color} 
-                        background={SnappingManager.userBackgroundColor} size={Size.LARGE} tooltipPlacement='right' onPointerDown={scriptFunc} />; 
+            case ButtonType.ClickButton:        return <IconButton {...btnProps} size={Size.MEDIUM} color={color} background={color} />;
+            case ButtonType.ToolButton:         return <IconButton {...btnProps} size={Size.LARGE}  color={color} background={color} />;
+            case ButtonType.TextButton:         return <Button     {...btnProps}                    color={color} background={color} 
+                                                                   text={StrCast(this.dataDoc.buttonText)}/>;
+            case ButtonType.MenuButton:         return <IconButton size={Size.LARGE}  {...btnProps} color={color} background={color} 
+                                                                   tooltipPlacement='right' onPointerDown={scriptFunc} />; 
             default: 
         }
         return this.defaultButton;
diff --git a/src/client/views/pdf/GPTPopup/GPTPopup.scss b/src/client/views/pdf/GPTPopup/GPTPopup.scss
index 18441f76e..bb43291ee 100644
--- a/src/client/views/pdf/GPTPopup/GPTPopup.scss
+++ b/src/client/views/pdf/GPTPopup/GPTPopup.scss
@@ -9,6 +9,8 @@ $headingHeight: 32px;
 
 .gptPopup-summary-box {
     position: fixed;
+    padding-left: 10px;
+    padding-right: 10px;
     top: 115px;
     left: 75px;
     width: 100%;
@@ -48,7 +50,6 @@ $headingHeight: 32px;
     }
 
     label {
-        color: $textgrey;
         font-size: 12px;
         font-weight: 400;
         letter-spacing: 1px;
@@ -73,7 +74,6 @@ $headingHeight: 32px;
         justify-content: center;
         align-items: center;
         height: $inputHeight;
-        background-color: white;
         width: 100%;
         pointer-events: all;
 
diff --git a/src/client/views/pdf/GPTPopup/GPTPopup.tsx b/src/client/views/pdf/GPTPopup/GPTPopup.tsx
index 67213382d..e3ee51424 100644
--- a/src/client/views/pdf/GPTPopup/GPTPopup.tsx
+++ b/src/client/views/pdf/GPTPopup/GPTPopup.tsx
@@ -411,7 +411,8 @@ export class GPTPopup extends ObservableReactComponent<object> {
                 tooltip="Ask Firefly to create images"
                 text="Ask Firefly"
                 onClick={() => this.setMode(GPTPopupMode.FIREFLY)}
-                color={StrCast(Doc.UserDoc().userVariantColor)}
+                color={SettingsManager.userColor}
+                background={SettingsManager.userVariantColor}
                 type={Type.TERT}
                 style={{
                     width: '100%',
@@ -426,7 +427,8 @@ export class GPTPopup extends ObservableReactComponent<object> {
                 tooltip="Ask GPT to sort, tag, define, or filter your Docs!"
                 text="Ask GPT"
                 onClick={() => this.setMode(GPTPopupMode.USER_PROMPT)}
-                color={StrCast(Doc.UserDoc().userVariantColor)}
+                color={SettingsManager.userColor}
+                background={SettingsManager.userVariantColor}
                 type={Type.TERT}
                 style={{
                     width: '100%',
@@ -445,7 +447,8 @@ export class GPTPopup extends ObservableReactComponent<object> {
                     this.setMode(GPTPopupMode.QUIZ_RESPONSE);
                     this.onQuizRandom?.();
                 }}
-                color={StrCast(Doc.UserDoc().userVariantColor)}
+                color={SettingsManager.userColor}
+                background={SettingsManager.userVariantColor}
                 type={Type.TERT}
                 style={{
                     width: '100%',
@@ -517,6 +520,7 @@ export class GPTPopup extends ObservableReactComponent<object> {
                     onChange={e => onChange(e.target.value)}
                     onKeyDown={e => this.handleKeyPress(e, this._mode)}
                     type="text"
+                    style={{ color: SnappingManager.userColor }}
                     placeholder={placeholder}
                 />
                 <Button //
@@ -524,7 +528,8 @@ export class GPTPopup extends ObservableReactComponent<object> {
                     type={Type.TERT}
                     icon={<AiOutlineSend />}
                     iconPlacement="right"
-                    color={SnappingManager.userVariantColor}
+                    color={SettingsManager.userColor}
+                    background={SettingsManager.userVariantColor}
                     onClick={() => this.callGpt(this._mode)}
                 />
                 <DictationButton ref={r => (this._askDictation = r)} setInput={onChange} />
@@ -551,7 +556,7 @@ export class GPTPopup extends ObservableReactComponent<object> {
                             </div>
                         </div>
                         <div key={rawSrc[0] + i + 'btn'} className="btn-container">
-                            <Button text="Save Image" onClick={() => this.transferToImage(rawSrc[1])} color={StrCast(Doc.UserDoc().userColor)} type={Type.TERT} />
+                            <Button text="Save Image" onClick={() => this.transferToImage(rawSrc[1])} color={SettingsManager.userColor} background={SettingsManager.userVariantColor} type={Type.TERT} />
                         </div>
                     </>
                 ))}
@@ -561,7 +566,8 @@ export class GPTPopup extends ObservableReactComponent<object> {
                     tooltip="Generate Again"
                     onClick={() => this._imgTargetDoc && this.generateImage(this._imageDescription, this._imgTargetDoc, this._addToCollection)}
                     icon={<FontAwesomeIcon icon="redo-alt" size="lg" />}
-                    color={StrCast(Doc.UserDoc().userVariantColor)}
+                    color={SettingsManager.userColor}
+                    background={SettingsManager.userVariantColor}
                 />
             )}
         </div>
@@ -603,14 +609,16 @@ export class GPTPopup extends ObservableReactComponent<object> {
                                         tooltip="Show originally selected text" //
                                         text="Selection"
                                         onClick={action(() => (this._showOriginal = true))}
-                                        color={StrCast(SettingsManager.userVariantColor)}
+                                        color={SettingsManager.userColor}
+                                        background={SettingsManager.userVariantColor}
                                         type={Type.TERT}
                                     />
                                     <Button
                                         tooltip="Create a text Doc with this text and link to the text selection" //
                                         text="Transfer To Text"
                                         onClick={this.transferToText}
-                                        color={StrCast(SettingsManager.userVariantColor)}
+                                        color={SettingsManager.userColor}
+                                        background={SettingsManager.userVariantColor}
                                         type={Type.TERT}
                                     />
                                 </>
@@ -627,14 +635,16 @@ export class GPTPopup extends ObservableReactComponent<object> {
                                             }
                                             this.generateSummary(this._aiReferenceText);
                                         })}
-                                        color={StrCast(SettingsManager.userVariantColor)}
+                                        color={SettingsManager.userColor}
+                                        background={SettingsManager.userVariantColor}
                                         type={Type.TERT}
                                     />
                                     <Button
                                         tooltip="Create Flashcards" //
                                         text="Create Flashcards"
                                         onClick={this.createFlashcards}
-                                        color={StrCast(SettingsManager.userVariantColor)}
+                                        color={SettingsManager.userColor}
+                                        background={SettingsManager.userVariantColor}
                                         type={Type.TERT}
                                     />
                                 </>
@@ -644,7 +654,7 @@ export class GPTPopup extends ObservableReactComponent<object> {
                         <div className="summarizing">
                             <span>{this._showOriginal ? 'Creating Cards...' : 'Summarizing'}</span>
                             <ReactLoading type="bubbles" color="#bcbcbc" width={20} height={20} />
-                            <Button text="Stop Animation" onClick={() => this.setStopAnimatingResponse(true)} color={StrCast(SettingsManager.userVariantColor)} type={Type.TERT} />
+                            <Button text="Stop Animation" onClick={() => this.setStopAnimatingResponse(true)} color={SettingsManager.userColor} background={SettingsManager.userVariantColor} type={Type.TERT} />
                         </div>
                     )}
                 </div>
@@ -689,19 +699,19 @@ export class GPTPopup extends ObservableReactComponent<object> {
                                 placeholder="Ask GPT a question about the data..."
                                 id="search-input"
                                 className="searchBox-input"
-                                style={{ width: '100%' }}
+                                style={{ width: '100%', color: SnappingManager.userColor }}
                             />
                         ) : (
                             <>
-                                <Button tooltip="Transfer to text" text="Transfer To Text" onClick={this.transferToText} color={StrCast(SnappingManager.userVariantColor)} type={Type.TERT} />
-                                <Button tooltip="Chat with AI" text="Chat with AI" onClick={() => this.setChatEnabled(true)} color={StrCast(SnappingManager.userVariantColor)} type={Type.TERT} />
+                                <Button tooltip="Transfer to text" text="Transfer To Text" onClick={this.transferToText} color={SettingsManager.userColor} background={SettingsManager.userVariantColor} type={Type.TERT} />
+                                <Button tooltip="Chat with AI" text="Chat with AI" onClick={() => this.setChatEnabled(true)} color={SettingsManager.userColor} background={SettingsManager.userVariantColor} type={Type.TERT} />
                             </>
                         )
                     ) : (
                         <div className="summarizing">
                             <span>Summarizing</span>
                             <ReactLoading type="bubbles" color="#bcbcbc" width={20} height={20} />
-                            <Button text="Stop Animation" onClick={() => this.setStopAnimatingResponse(true)} color={StrCast(SnappingManager.userVariantColor)} type={Type.TERT} />
+                            <Button text="Stop Animation" onClick={() => this.setStopAnimatingResponse(true)} color={SettingsManager.userColor} background={SettingsManager.userVariantColor} type={Type.TERT} />
                         </div>
                     )}
                 </div>
@@ -718,7 +728,7 @@ export class GPTPopup extends ObservableReactComponent<object> {
         );
 
     heading = (headingText: string) => (
-        <div className="summary-heading">
+        <div className="summary-heading" style={{ color: SnappingManager.userBackgroundColor }}>
             <label className="summary-text">{headingText}</label>
             {this._gptProcessing ? (
                 <ReactLoading type="spin" color="#bcbcbc" width={14} height={14} />
@@ -734,7 +744,7 @@ export class GPTPopup extends ObservableReactComponent<object> {
                         onClick={() => this._collectionContext && Doc.setDocFilter(this._collectionContext, 'tags', GPTPopup.ChatTag, 'remove')}
                     />
                     {[GPTPopupMode.USER_PROMPT, GPTPopupMode.QUIZ_RESPONSE, GPTPopupMode.FIREFLY].includes(this._mode) && (
-                        <IconButton color={StrCast(SettingsManager.userVariantColor)} tooltip="back" icon={<CgCornerUpLeft size="16px" />} onClick={() => (this._mode = GPTPopupMode.GPT_MENU)} />
+                        <IconButton color={SettingsManager.userVariantColor} background={SettingsManager.userColor} tooltip="back" icon={<CgCornerUpLeft size="16px" />} onClick={() => (this._mode = GPTPopupMode.GPT_MENU)} />
                     )}
                 </>
             )}
@@ -743,7 +753,7 @@ export class GPTPopup extends ObservableReactComponent<object> {
 
     render() {
         return (
-            <div className="gptPopup-summary-box" style={{ display: SnappingManager.ChatVisible ? 'flex' : 'none', overflow: 'auto' }}>
+            <div className="gptPopup-summary-box" style={{ background: SnappingManager.userColor, color: SnappingManager.userBackgroundColor, display: SnappingManager.ChatVisible ? 'flex' : 'none', overflow: 'auto' }}>
                 {(() => {
                     //prettier-ignore
                     switch (this._mode) {
diff --git a/src/client/views/topbar/TopBar.tsx b/src/client/views/topbar/TopBar.tsx
index 00114a3f9..18e30b3c2 100644
--- a/src/client/views/topbar/TopBar.tsx
+++ b/src/client/views/topbar/TopBar.tsx
@@ -59,7 +59,7 @@ export class TopBar extends ObservableReactComponent<object> {
         return SettingsManager.userVariantColor;
     }
     @computed get backgroundColor() {
-        return PingManager.Instance.IsBeating ? SettingsManager.userBackgroundColor : Colors.MEDIUM_GRAY;
+        return SettingsManager.userBackgroundColor;
     }
 
     @observable happyHeart: boolean = PingManager.Instance.IsBeating;
@@ -86,6 +86,7 @@ export class TopBar extends ObservableReactComponent<object> {
                         onClick={this.navigateToHome}
                         icon={<FontAwesomeIcon icon={DocListCast(Doc.MySharedDocs.data_dashboards).some(dash => !DocListCast(Doc.MySharedDocs.viewed).includes(dash)) ? 'portrait' : 'home'} />}
                         color={this.color}
+                        background={this.backgroundColor}
                     />
                 ) : (
                     <div className="logo-container">
@@ -166,6 +167,7 @@ export class TopBar extends ObservableReactComponent<object> {
                     tooltip="Open Dashboards"
                     size={Size.SMALL}
                     color={this.color}
+                    background={this.backgroundColor}
                     style={{ fontWeight: 700, fontSize: '1rem' }}
                     onClick={(e: React.MouseEvent) => {
                         const dashView = Doc.ActiveDashboard && DocumentView.getDocumentView(Doc.ActiveDashboard);
@@ -191,22 +193,27 @@ export class TopBar extends ObservableReactComponent<object> {
                         type={Type.TERT}
                         color={SettingsManager.userColor}
                         background={this.variantColor}
-                        onClick={() => {
-                            SharingManager.Instance.open(undefined, Doc.ActiveDashboard);
-                        }}
+                        onClick={() => SharingManager.Instance.open(undefined, Doc.ActiveDashboard)}
                     />
                 ) : null}
-                <IconButton tooltip="Issue Reporter ⌘I" size={Size.SMALL} color={this.color} onClick={ReportManager.Instance.open} icon={<FaBug />} />
+                <IconButton tooltip="Issue Reporter ⌘I" size={Size.SMALL} color={this.color} background={this.backgroundColor} onClick={ReportManager.Instance.open} icon={<FaBug />} />
                 <Flip key={this._flipDocumentation}>
-                    <IconButton tooltip="Documentation ⌘D" size={Size.SMALL} color={this.color} onClick={() => window.open('https://brown-dash.github.io/Dash-Documentation/', '_blank')} icon={<FontAwesomeIcon icon="question-circle" />} />
+                    <IconButton
+                        tooltip="Documentation ⌘D"
+                        size={Size.SMALL}
+                        color={this.color}
+                        background={this.backgroundColor}
+                        onClick={() => window.open('https://brown-dash.github.io/Dash-Documentation/', '_blank')}
+                        icon={<FontAwesomeIcon icon="question-circle" />}
+                    />
                 </Flip>
-                <IconButton tooltip="Settings ⌘⇧S" size={Size.SMALL} color={this.color} onClick={SettingsManager.Instance.openMgr} icon={<FontAwesomeIcon icon="cog" />} />
+                <IconButton tooltip="Settings ⌘⇧S" size={Size.SMALL} color={this.color} background={this.backgroundColor} onClick={SettingsManager.Instance.openMgr} icon={<FontAwesomeIcon icon="cog" />} />
                 <IconButton
                     size={Size.SMALL}
                     onClick={ServerStats.Instance.open}
-                    type={Type.TERT}
                     tooltip={'Server is ' + (PingManager.Instance.IsBeating ? '' : 'NOT ') + 'running ' + (upToDate ? DashVersion : 'out of date version:' + DashVersion)}
                     color={this.happyHeart ? (upToDate ? Colors.LIGHT_BLUE : Colors.YELLOW) : Colors.ERROR_RED}
+                    background={PingManager.Instance.IsBeating ? SettingsManager.userBackgroundColor : Colors.MEDIUM_GRAY}
                     icon={<FontAwesomeIcon icon={this.happyHeart ? 'heart' : 'heart-broken'} />}
                 />
                 {/* <Button text={'Logout'} borderRadius={5} hoverStyle={'gray'} backgroundColor={Colors.DARK_GRAY} color={this.color} fontSize={FontSize.SECONDARY} onClick={() => window.location.assign(Utils.prepend('/logout'))} /> */}
-- 
cgit v1.2.3-70-g09d2


From 78ac87b8acf63079071e5e8805692ed8c30042ce Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 23 Apr 2025 22:02:36 -0400
Subject: lots of typechecking fixes.

---
 .../apis/google_docs/GooglePhotosClientUtils.ts    |  2 +-
 src/client/util/CalendarManager.tsx                |  2 +-
 src/client/util/DocumentManager.ts                 |  8 +++---
 src/client/util/LinkManager.ts                     |  3 +-
 src/client/util/ReplayMovements.ts                 |  6 ++--
 src/client/util/ScriptManager.ts                   |  9 ++----
 src/client/util/SearchUtil.ts                      |  5 ++--
 .../util/reportManager/ReportManagerComponents.tsx |  4 +--
 src/client/views/DashboardView.tsx                 | 28 +++++++++----------
 src/client/views/InkStrokeProperties.ts            |  8 +++---
 src/client/views/InkingStroke.tsx                  | 12 ++++----
 src/client/views/PropertiesButtons.tsx             | 23 ++++++++--------
 .../views/PropertiesDocBacklinksSelector.tsx       |  8 ++----
 src/client/views/PropertiesDocContextSelector.tsx  |  4 +--
 src/client/views/UndoStack.tsx                     |  5 +---
 src/client/views/animationtimeline/Region.tsx      | 32 ++++++++++------------
 src/client/views/animationtimeline/Track.tsx       | 24 ++++++++--------
 src/client/views/collections/CollectionMenu.tsx    |  4 +--
 .../collections/CollectionNoteTakingViewColumn.tsx |  2 +-
 .../views/collections/CollectionPileView.tsx       |  1 -
 .../collections/CollectionStackedTimeline.tsx      |  2 +-
 .../views/collections/CollectionTreeView.tsx       |  8 +++---
 .../views/collections/FlashcardPracticeUI.tsx      |  2 +-
 src/client/views/collections/TreeView.tsx          |  4 +--
 .../CollectionFreeFormLayoutEngines.tsx            |  2 +-
 .../collectionFreeForm/FaceCollectionBox.tsx       | 13 +++++----
 .../collectionSchema/SchemaColumnHeader.tsx        |  2 +-
 .../collectionSchema/SchemaTableCell.tsx           | 18 ++++++------
 src/client/views/linking/LinkMenuGroup.tsx         |  5 ++--
 src/client/views/linking/LinkMenuItem.tsx          |  4 +--
 .../views/newlightbox/ExploreView/ExploreView.tsx  |  4 +--
 src/client/views/newlightbox/NewLightboxView.tsx   |  7 ++---
 src/client/views/nodes/DataVizBox/DataVizBox.tsx   | 16 +++++------
 .../views/nodes/DataVizBox/SchemaCSVPopUp.tsx      |  6 ++--
 .../nodes/DataVizBox/components/Histogram.tsx      | 17 ++++++------
 .../nodes/DataVizBox/components/LineChart.tsx      | 25 +++++++++++------
 .../views/nodes/DataVizBox/components/TableBox.tsx |  2 +-
 src/client/views/nodes/EquationBox.tsx             |  1 -
 src/client/views/nodes/FieldView.tsx               |  7 +++--
 src/client/views/nodes/FunctionPlotBox.tsx         | 11 ++++----
 src/client/views/nodes/ImageBox.tsx                |  2 +-
 .../views/nodes/MapBox/DirectionsAnchorMenu.tsx    |  2 +-
 src/client/views/nodes/calendarBox/CalendarBox.tsx |  3 +-
 .../nodes/chatbot/chatboxcomponents/ChatBox.tsx    | 20 ++++++++------
 .../views/nodes/chatbot/tools/GetDocsTool.ts       |  5 +++-
 .../views/nodes/chatbot/vectorstore/Vectorstore.ts | 15 +++++-----
 .../views/nodes/formattedText/DailyJournal.tsx     |  2 +-
 src/client/views/nodes/scrapbook/ScrapbookBox.tsx  |  2 +-
 src/client/views/pdf/Annotation.tsx                |  7 +++--
 src/client/views/search/FaceRecognitionHandler.tsx |  6 ++--
 src/fields/Doc.ts                                  |  2 +-
 src/fields/Types.ts                                |  2 ++
 52 files changed, 207 insertions(+), 207 deletions(-)

(limited to 'src/client/views/collections/CollectionMenu.tsx')

diff --git a/src/client/apis/google_docs/GooglePhotosClientUtils.ts b/src/client/apis/google_docs/GooglePhotosClientUtils.ts
index 4b86a8341..15fd6313a 100644
--- a/src/client/apis/google_docs/GooglePhotosClientUtils.ts
+++ b/src/client/apis/google_docs/GooglePhotosClientUtils.ts
@@ -311,7 +311,7 @@ export namespace GooglePhotos {
             sources
                 .filter(source => ImageCast(Doc.GetProto(source).data))
                 .forEach(async source => {
-                    const data = ImageCast(Doc.GetProto(source).data);
+                    const data = ImageCast(Doc.GetProto(source).data)!;
                     const url = data.url.href;
                     const target = Doc.MakeEmbedding(source);
                     const description = parseDescription(target, descriptionKey);
diff --git a/src/client/util/CalendarManager.tsx b/src/client/util/CalendarManager.tsx
index 4e321a893..b50e39c02 100644
--- a/src/client/util/CalendarManager.tsx
+++ b/src/client/util/CalendarManager.tsx
@@ -162,7 +162,7 @@ export class CalendarManager extends ObservableReactComponent<object> {
 
             console.log('my calendars: ', Doc.MyCalendars);
             if (this.creationType === 'new-calendar') {
-                Doc.AddDocToList(Doc.MyCalendars, 'data', calendar); // add to new calendar to dashboard calendars
+                Doc.MyCalendars && Doc.AddDocToList(Doc.MyCalendars, 'data', calendar); // add to new calendar to dashboard calendars
             }
         }
     };
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index ad57c2a62..3bae2881e 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -173,10 +173,10 @@ export class DocumentManager {
         while (
             containerDocContext.length &&
             DocCast(containerDocContext[0]?.embedContainer) &&
-            DocCast(containerDocContext[0].embedContainer)?._type_collection !== CollectionViewType.Docking &&
+            DocCast(containerDocContext[0].embedContainer)!._type_collection !== CollectionViewType.Docking &&
             (includeExistingViews || !DocumentManager.Instance.getDocumentView(containerDocContext[0]))
         ) {
-            containerDocContext = [Cast(containerDocContext[0].embedContainer, Doc, null), ...containerDocContext];
+            containerDocContext = [DocCast(containerDocContext[0].embedContainer)!, ...containerDocContext];
         }
         return containerDocContext;
     }
@@ -248,7 +248,7 @@ export class DocumentManager {
         finished?: (changed: boolean) => void // func called after focusing on target with flag indicating whether anything needed to be done.
     ) => {
         const options = optionsIn;
-        Doc.RemoveDocFromList(Doc.MyRecentlyClosed, undefined, targetDoc);
+        Doc.MyRecentlyClosed && Doc.RemoveDocFromList(Doc.MyRecentlyClosed, undefined, targetDoc);
         const docContextPath = DocumentManager.GetContextPath(targetDoc, true);
         if (docContextPath.some(doc => doc.hidden)) options.toggleTarget = false;
         let activatedTab = false;
@@ -272,7 +272,7 @@ export class DocumentManager {
             }));
         if (options.openLocation?.includes(OpenWhere.lightbox)) {
             // even if we found the document view, if the target is a lightbox, we try to open it in the lightbox to preserve lightbox semantics (eg, there's only one active doc in the lightbox)
-            const target = DocCast(targetDoc.annotationOn, targetDoc);
+            const target = DocCast(targetDoc.annotationOn, targetDoc)!;
             const compView = this.getDocumentView(DocCast(target.embedContainer))?.ComponentView;
             if ((compView?.addDocTab ?? compView?._props.addDocTab)?.(target, options.openLocation)) {
                 await new Promise<void>(waitres => {
diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts
index 344e2e4c0..d8e0c4cbe 100644
--- a/src/client/util/LinkManager.ts
+++ b/src/client/util/LinkManager.ts
@@ -217,7 +217,8 @@ export class LinkManager {
     }
 
     // finds the opposite anchor of a given anchor in a link
-    public static getOppositeAnchor(linkDoc: Doc, anchor: Doc): Doc | undefined {
+    public static getOppositeAnchor(linkDoc: Doc | undefined, anchor: Doc | undefined): Doc | undefined {
+        if (!linkDoc || !anchor) return undefined;
         const id = LinkManager.anchorIndex(linkDoc, anchor);
         const a1 = DocCast(linkDoc.link_anchor_1);
         const a2 = DocCast(linkDoc.link_anchor_2);
diff --git a/src/client/util/ReplayMovements.ts b/src/client/util/ReplayMovements.ts
index 62a09a8bc..4f0423342 100644
--- a/src/client/util/ReplayMovements.ts
+++ b/src/client/util/ReplayMovements.ts
@@ -108,9 +108,11 @@ export class ReplayMovements {
 
         movements.forEach((movement, i) => {
             if (typeof movement.doc === 'string') {
-                movements[i].doc = IdToDoc(movement.doc);
-                if (!movements[i].doc) {
+                const doc = IdToDoc(movement.doc);
+                if (!doc) {
                     console.log('ERROR: tracked doc not found');
+                } else {
+                    movements[i].doc = doc;
                 }
             }
         });
diff --git a/src/client/util/ScriptManager.ts b/src/client/util/ScriptManager.ts
index 9158f6c0b..8c7f88bf6 100644
--- a/src/client/util/ScriptManager.ts
+++ b/src/client/util/ScriptManager.ts
@@ -1,7 +1,6 @@
-import { Doc, DocListCast } from '../../fields/Doc';
+import { Doc, DocListCast, StrListCast } from '../../fields/Doc';
 import { List } from '../../fields/List';
-import { listSpec } from '../../fields/Schema';
-import { Cast, StrCast } from '../../fields/Types';
+import { StrCast } from '../../fields/Types';
 import { Docs } from '../documents/Documents';
 import { ScriptingGlobals } from './ScriptingGlobals';
 
@@ -10,7 +9,6 @@ export class ScriptManager {
     // eslint-disable-next-line no-use-before-define
     private static _instance: ScriptManager;
     public static get Instance(): ScriptManager {
-        // eslint-disable-next-line no-return-assign
         return this._instance || (this._instance = new this());
     }
     private constructor() {
@@ -58,7 +56,7 @@ export class ScriptManager {
     public static addScriptToGlobals(scriptDoc: Doc): void {
         ScriptingGlobals.removeGlobal(StrCast(scriptDoc.name));
 
-        const params = Cast(scriptDoc['data-params'], listSpec('string'), []);
+        const params = StrListCast(scriptDoc['data-params']);
         const paramNames = params.reduce((o: string, p: string) => {
             let out = o;
             if (params.indexOf(p) === params.length - 1) {
@@ -69,7 +67,6 @@ export class ScriptManager {
             return out;
         }, '' as string);
 
-        // eslint-disable-next-line no-new-func
         const f = new Function(paramNames, StrCast(scriptDoc.script));
 
         Object.defineProperty(f, 'name', { value: StrCast(scriptDoc.name), writable: false });
diff --git a/src/client/util/SearchUtil.ts b/src/client/util/SearchUtil.ts
index e4adcaa7e..fc3bb99ab 100644
--- a/src/client/util/SearchUtil.ts
+++ b/src/client/util/SearchUtil.ts
@@ -13,7 +13,7 @@ export namespace SearchUtil {
         const blockedKeys = matchKeyNames
             ? []
             : Object.entries(DocOptions)
-                  .filter(([, info]: [string, FInfo]) => !info?.searchable())
+                  .filter(([, info]: [string, FieldType | FInfo | undefined]) => (info instanceof FInfo ? !info.searchable() : true))
                   .map(([key]) => key);
 
         const exact = queryIn.startsWith('=');
@@ -22,8 +22,7 @@ export namespace SearchUtil {
         const results = new ObservableMap<Doc, string[]>();
         if (collectionDoc) {
             const docs = DocListCast(collectionDoc[Doc.LayoutDataKey(collectionDoc)]);
-            // eslint-disable-next-line @typescript-eslint/ban-types
-            const docIDs: String[] = [];
+            const docIDs: string[] = [];
             SearchUtil.foreachRecursiveDoc(docs, (depth: number, doc: Doc) => {
                 const dtype = StrCast(doc.type) as DocumentType;
                 if (dtype && !blockedTypes.includes(dtype) && !docIDs.includes(doc[Id]) && depth >= 0) {
diff --git a/src/client/util/reportManager/ReportManagerComponents.tsx b/src/client/util/reportManager/ReportManagerComponents.tsx
index 92f877859..80653779e 100644
--- a/src/client/util/reportManager/ReportManagerComponents.tsx
+++ b/src/client/util/reportManager/ReportManagerComponents.tsx
@@ -1,5 +1,3 @@
-/* eslint-disable react/require-default-props */
-/* eslint-disable prefer-destructuring */
 /* eslint-disable no-use-before-define */
 import * as React from 'react';
 import ReactMarkdown from 'react-markdown';
@@ -299,7 +297,7 @@ export function IssueView({ issue }: IssueViewProps) {
                     </div>
                 </div>
             )}
-            <ReactMarkdown className="issue-content" remarkPlugins={[remarkGfm]} rehypePlugins={[rehypeRaw]}>
+            <ReactMarkdown remarkPlugins={[remarkGfm]} rehypePlugins={[rehypeRaw]}>
                 {issueBody}
             </ReactMarkdown>
         </div>
diff --git a/src/client/views/DashboardView.tsx b/src/client/views/DashboardView.tsx
index f61f6db18..3ceb23ffd 100644
--- a/src/client/views/DashboardView.tsx
+++ b/src/client/views/DashboardView.tsx
@@ -113,12 +113,12 @@ export class DashboardView extends ObservableReactComponent<object> {
 
     getDashboards = (whichGroup: DashboardGroup) => {
         if (whichGroup === DashboardGroup.MyDashboards) {
-            return DocListCast(Doc.MyDashboards.data).filter(dashboard => dashboard.$author === ClientUtils.CurrentUserEmail());
+            return DocListCast(Doc.MyDashboards?.data).filter(dashboard => dashboard.$author === ClientUtils.CurrentUserEmail());
         }
-        return DocListCast(Doc.MySharedDocs.data_dashboards).filter(doc => doc.dockingConfig);
+        return DocListCast(Doc.MySharedDocs?.data_dashboards).filter(doc => doc.dockingConfig);
     };
 
-    isUnviewedSharedDashboard = (dashboard: Doc) => !DocListCast(Doc.MySharedDocs.viewed).includes(dashboard);
+    isUnviewedSharedDashboard = (dashboard: Doc) => !DocListCast(Doc.MySharedDocs?.viewed).includes(dashboard);
 
     @undoBatch
     createNewDashboard = (name: string, background?: string) => {
@@ -155,7 +155,7 @@ export class DashboardView extends ObservableReactComponent<object> {
     @action
     openNewDashboardModal = () => {
         this.openModal = true;
-        this.setNewDashboardName(`Dashboard ${DocListCast(Doc.MyDashboards.data).length + 1}`);
+        this.setNewDashboardName(`Dashboard ${DocListCast(Doc.MyDashboards?.data).length + 1}`);
     };
 
     _downX: number = 0;
@@ -191,7 +191,7 @@ export class DashboardView extends ObservableReactComponent<object> {
                         <Button
                             text={'Shared Dashboards (' + this.getDashboards(DashboardGroup.SharedDashboards).length + ')'}
                             active={this.selectedDashboardGroup === DashboardGroup.SharedDashboards}
-                            color={this.getDashboards(DashboardGroup.SharedDashboards).some(dash => !DocListCast(Doc.MySharedDocs.viewed).includes(dash)) ? 'green' : color}
+                            color={this.getDashboards(DashboardGroup.SharedDashboards).some(dash => !DocListCast(Doc.MySharedDocs?.viewed).includes(dash)) ? 'green' : color}
                             align="flex-start"
                             onClick={() => this.selectDashboardGroup(DashboardGroup.SharedDashboards)}
                             fillWidth
@@ -275,7 +275,7 @@ export class DashboardView extends ObservableReactComponent<object> {
     }
 
     public static openSharedDashboard = (dashboard: Doc) => {
-        Doc.AddDocToList(Doc.MySharedDocs, 'viewed', dashboard);
+        Doc.MySharedDocs && Doc.AddDocToList(Doc.MySharedDocs, 'viewed', dashboard);
         DashboardView.openDashboard(Doc.BestEmbedding(dashboard));
     };
 
@@ -283,8 +283,8 @@ export class DashboardView extends ObservableReactComponent<object> {
     /// this also sets the readonly state of the dashboard based on the current mode of dash (from its url)
     public static openDashboard = (doc: Doc | undefined, fromHistory = false) => {
         if (!doc) return false;
-        Doc.AddDocToList(Doc.MyDashboards, 'data', doc);
-        Doc.RemoveDocFromList(Doc.MyRecentlyClosed, 'data', doc);
+        Doc.MyDashboards && Doc.AddDocToList(Doc.MyDashboards, 'data', doc);
+        Doc.MyRecentlyClosed && Doc.RemoveDocFromList(Doc.MyRecentlyClosed, 'data', doc);
 
         // this has the side-effect of setting the main container since we're assigning the active/guest dashboard
         Doc.UserDoc() ? (Doc.ActiveDashboard = doc) : (Doc.GuestDashboard = doc);
@@ -316,11 +316,11 @@ export class DashboardView extends ObservableReactComponent<object> {
     };
 
     public static removeDashboard = (dashboard: Doc) => {
-        const dashboards = DocListCast(Doc.MyDashboards.data).filter(dash => dash !== dashboard);
+        const dashboards = DocListCast(Doc.MyDashboards?.data).filter(dash => dash !== dashboard);
         undoable(() => {
             if (dashboard === Doc.ActiveDashboard) DashboardView.openDashboard(dashboards.lastElement());
-            Doc.RemoveDocFromList(Doc.MyDashboards, 'data', dashboard);
-            Doc.AddDocToList(Doc.MyRecentlyClosed, 'data', dashboard, undefined, true, true);
+            Doc.MyDashboards && Doc.RemoveDocFromList(Doc.MyDashboards, 'data', dashboard);
+            Doc.MyRecentlyClosed && Doc.AddDocToList(Doc.MyRecentlyClosed, 'data', dashboard, undefined, true, true);
             if (!dashboards.length) Doc.ActivePage = 'home';
         }, 'remove dashboard')();
     };
@@ -409,7 +409,7 @@ export class DashboardView extends ObservableReactComponent<object> {
     };
 
     public static createNewDashboard = (id?: string, name?: string, background?: string) => {
-        const dashboardCount = DocListCast(Doc.MyDashboards.data).length + 1;
+        const dashboardCount = DocListCast(Doc.MyDashboards?.data).length + 1;
         const freeformOptions: DocumentOptions = {
             x: 0,
             y: 400,
@@ -425,8 +425,8 @@ export class DashboardView extends ObservableReactComponent<object> {
         const freeformDoc = Doc.GuestTarget || Docs.Create.FreeformDocument([], freeformOptions);
         const dashboardDoc = DashboardView.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600 }], { title: title }, id, 'row');
 
-        Doc.AddDocToList(Doc.MyHeaderBar, 'data', freeformDoc, undefined, undefined, true);
-        Doc.AddDocToList(Doc.MyDashboards, 'data', dashboardDoc);
+        Doc.MyHeaderBar && Doc.AddDocToList(Doc.MyHeaderBar, 'data', freeformDoc, undefined, undefined, true);
+        Doc.MyDashboards && Doc.AddDocToList(Doc.MyDashboards, 'data', dashboardDoc);
         freeformDoc._embedContainer = dashboardDoc;
         dashboardDoc.$myPaneCount = 1;
         dashboardDoc.$myOverlayDocs = new List<Doc>();
diff --git a/src/client/views/InkStrokeProperties.ts b/src/client/views/InkStrokeProperties.ts
index 425f5b6bb..41f38c008 100644
--- a/src/client/views/InkStrokeProperties.ts
+++ b/src/client/views/InkStrokeProperties.ts
@@ -99,7 +99,7 @@ export class InkStrokeProperties {
             controls.splice(i, 4, ...splicepts.map(p => ({ X: p.x, Y: p.y })));
 
             // Updating the indices of the control points whose handle tangency has been broken.
-            doc.brokenInkIndices = new List(Cast(doc.brokenInkIndices, listSpec('number'), []).map(control => (control > i ? control + 4 : control)));
+            doc.brokenInkIndices = new List(NumListCast(doc.brokenInkIndices).map(control => (control > i ? control + 4 : control)));
             runInAction(() => {
                 this._currentPoint = -1;
             });
@@ -252,7 +252,7 @@ export class InkStrokeProperties {
             this.applyFunction(inkView, (view: DocumentView, ink: InkData) => {
                 const order = controlIndex % 4;
                 const closed = InkingStroke.IsClosed(ink);
-                const brokenIndices = Cast(inkView.Document.brokenInkIndices, listSpec('number'), []);
+                const brokenIndices = NumListCast(inkView.Document.brokenInkIndices);
                 if (origInk && this._currentPoint > 0 && this._currentPoint < ink.length - 1 && brokenIndices.findIndex(value => value === controlIndex) === -1) {
                     const cptBefore = ink[controlIndex];
                     const cpt = { X: cptBefore.X + deltaX, Y: cptBefore.Y + deltaY };
@@ -405,9 +405,9 @@ export class InkStrokeProperties {
         this.applyFunction(inkView, (view: DocumentView, ink: InkData) => {
             const doc = view.Document;
             const brokenIndices = Cast(doc.brokenInkIndices, listSpec('number'), []);
-            const ind = brokenIndices.findIndex(value => value === controlIndex);
+            const ind = brokenIndices?.findIndex(value => value === controlIndex) ?? -1;
             if (ind !== -1) {
-                brokenIndices.splice(ind, 1);
+                brokenIndices!.splice(ind, 1);
                 const [controlPoint, handleA, handleB] = [ink[controlIndex], ink[handleIndexA], ink[handleIndexB]];
                 const oppositeHandleA = this.rotatePoint(handleA, controlPoint, Math.PI);
                 const angleDifference = InkStrokeProperties.angleChange(handleB, oppositeHandleA, controlPoint);
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index 0a49ea28e..0136f6abe 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -26,8 +26,8 @@ import { observer } from 'mobx-react';
 import * as React from 'react';
 import { DashColor, returnFalse, setupMoveUpEvents } from '../../ClientUtils';
 import { Doc } from '../../fields/Doc';
-import { InkData, InkField } from '../../fields/InkField';
-import { BoolCast, Cast, NumCast, RTFCast, StrCast } from '../../fields/Types';
+import { InkData } from '../../fields/InkField';
+import { BoolCast, InkCast, NumCast, RTFCast, StrCast } from '../../fields/Types';
 import { TraceMobx } from '../../fields/util';
 import { Gestures } from '../../pen-gestures/GestureTypes';
 import { Docs } from '../documents/Documents';
@@ -35,6 +35,7 @@ import { DocumentType } from '../documents/DocumentTypes';
 import { InteractionUtils } from '../util/InteractionUtils';
 import { SnappingManager } from '../util/SnappingManager';
 import { UndoManager } from '../util/UndoManager';
+import { CollectionFreeFormView } from './collections/collectionFreeForm';
 import { ContextMenu } from './ContextMenu';
 import { ViewBoxAnnotatableComponent } from './DocComponent';
 import { Colors } from './global/globalEnums';
@@ -42,14 +43,13 @@ import { InkControlPtHandles, InkEndPtHandles } from './InkControlPtHandles';
 import './InkStroke.scss';
 import { InkStrokeProperties } from './InkStrokeProperties';
 import { InkTangentHandles } from './InkTangentHandles';
+import { InkTranscription } from './InkTranscription';
+import { DocumentView } from './nodes/DocumentView';
 import { FieldView, FieldViewProps } from './nodes/FieldView';
 import { FormattedTextBox, FormattedTextBoxProps } from './nodes/formattedText/FormattedTextBox';
 import { PinDocView, PinProps } from './PinFuncs';
 import { StyleProp } from './StyleProp';
 import { ViewBoxInterface } from './ViewBoxInterface';
-import { InkTranscription } from './InkTranscription';
-import { CollectionFreeFormView } from './collections/collectionFreeForm';
-import { DocumentView } from './nodes/DocumentView';
 
 // eslint-disable-next-line @typescript-eslint/no-require-imports
 const { INK_MASK_SIZE } = require('./global/globalCssVariables.module.scss'); // prettier-ignore
@@ -245,7 +245,7 @@ export class InkingStroke extends ViewBoxAnnotatableComponent<FieldViewProps>()
      * factor for converting between ink and screen space.
      */
     inkScaledData = () => {
-        const inkData = Cast(this.dataDoc[this.fieldKey], InkField, Cast(this.layoutDoc[this.fieldKey], InkField, null) ?? null)?.inkData ?? [];
+        const inkData = InkCast(this.dataDoc[this.fieldKey], InkCast(this.layoutDoc[this.fieldKey]) ?? null)?.inkData ?? [];
         const inkStrokeWidth = NumCast(this.layoutDoc.stroke_width, 1);
         const inkTop = Math.min(...inkData.map(p => p.Y)) - inkStrokeWidth / 2;
         const inkBottom = Math.max(...inkData.map(p => p.Y)) + inkStrokeWidth / 2;
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
index 66936c64c..28566ba1d 100644
--- a/src/client/views/PropertiesButtons.tsx
+++ b/src/client/views/PropertiesButtons.tsx
@@ -385,18 +385,19 @@ export class PropertiesButtons extends React.Component {
             const followLoc = this.selectedDoc._followLinkLocation;
             const linkedToLightboxView = () => Doc.Links(this.selectedDoc).some(link => Doc.getOppositeAnchor(link, this.selectedDoc)?._isLightbox);
 
-            let active = false;
-            // prettier-ignore
-            switch (value[0]) {
-                case 'linkInPlace': active = linkButton && followLoc === OpenWhere.lightbox && !linkedToLightboxView();  break;
-                case 'linkOnRight': active = linkButton && followLoc === OpenWhere.addRight; break;
-                case 'enterPortal': active = linkButton && this.selectedDoc._followLinkLocation === OpenWhere.lightbox && linkedToLightboxView(); break;
-                case 'toggleDetail':active = ScriptCast(this.selectedDoc.onClick)?.script.originalScript.includes('toggleDetail'); break;
-                case 'nothing':     active = !linkButton && this.selectedDoc.onClick === undefined;break;
-                default:
-            }
+            const active = () => {
+                // prettier-ignore
+                switch (value[0]) {
+                    case 'linkInPlace': return linkButton && followLoc === OpenWhere.lightbox && !linkedToLightboxView();  break;
+                    case 'linkOnRight': return linkButton && followLoc === OpenWhere.addRight; break;
+                    case 'enterPortal': return linkButton && this.selectedDoc._followLinkLocation === OpenWhere.lightbox && linkedToLightboxView(); break;
+                    case 'toggleDetail':return ScriptCast(this.selectedDoc.onClick)?.script.originalScript.includes('toggleDetail'); break;
+                    case 'nothing':    return !linkButton && this.selectedDoc.onClick === undefined;break;
+                    default: return false;
+                }
+            };
             return (
-                <div className="list-item" key={`${value}`} style={{ backgroundColor: active ? Colors.LIGHT_BLUE : undefined }} onClick={click}>
+                <div className="list-item" key={`${value}`} style={{ backgroundColor: active() ? Colors.LIGHT_BLUE : undefined }} onClick={click}>
                     {value[1]}
                 </div>
             );
diff --git a/src/client/views/PropertiesDocBacklinksSelector.tsx b/src/client/views/PropertiesDocBacklinksSelector.tsx
index e30d14eae..5a00e6a89 100644
--- a/src/client/views/PropertiesDocBacklinksSelector.tsx
+++ b/src/client/views/PropertiesDocBacklinksSelector.tsx
@@ -1,18 +1,16 @@
-/* eslint-disable react/require-default-props */
-/* eslint-disable react/no-unused-prop-types */
 import { action } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import { Doc } from '../../fields/Doc';
-import { Cast } from '../../fields/Types';
+import { DocCast } from '../../fields/Types';
 import { DocumentType } from '../documents/DocumentTypes';
 import { LinkManager } from '../util/LinkManager';
 import { SettingsManager } from '../util/SettingsManager';
 import './PropertiesDocBacklinksSelector.scss';
 import { CollectionDockingView } from './collections/CollectionDockingView';
 import { LinkMenu } from './linking/LinkMenu';
-import { OpenWhere } from './nodes/OpenWhere';
 import { DocumentView } from './nodes/DocumentView';
+import { OpenWhere } from './nodes/OpenWhere';
 
 type PropertiesDocBacklinksSelectorProps = {
     Document: Doc;
@@ -26,7 +24,7 @@ export class PropertiesDocBacklinksSelector extends React.Component<PropertiesDo
     getOnClick = action((link: Doc) => {
         const linkAnchor = this.props.Document;
         const other = Doc.getOppositeAnchor(link, linkAnchor);
-        const otherdoc = !other ? undefined : other.annotationOn && other.type !== DocumentType.RTF ? Cast(other.annotationOn, Doc, null) : other;
+        const otherdoc = !other ? undefined : other.annotationOn && other.type !== DocumentType.RTF ? DocCast(other.annotationOn) : other;
         LinkManager.Instance.currentLink = link;
         if (otherdoc) {
             otherdoc.hidden = false;
diff --git a/src/client/views/PropertiesDocContextSelector.tsx b/src/client/views/PropertiesDocContextSelector.tsx
index ee6486a9c..1aa956e16 100644
--- a/src/client/views/PropertiesDocContextSelector.tsx
+++ b/src/client/views/PropertiesDocContextSelector.tsx
@@ -3,7 +3,7 @@ import { observer } from 'mobx-react';
 import * as React from 'react';
 import { Doc } from '../../fields/Doc';
 import { Id } from '../../fields/FieldSymbols';
-import { Cast, StrCast } from '../../fields/Types';
+import { DocCast, StrCast } from '../../fields/Types';
 import { ObservableReactComponent } from './ObservableReactComponent';
 import './PropertiesDocContextSelector.scss';
 import { CollectionDockingView } from './collections/CollectionDockingView';
@@ -29,7 +29,7 @@ export class PropertiesDocContextSelector extends ObservableReactComponent<Prope
         const target = this._props.DocView.Document;
         const targetContext = this._props.DocView.containerViewPath?.().lastElement()?.Document;
         const embeddings = Doc.GetEmbeddings(target);
-        const containerProtos = embeddings.filter(embedding => embedding.embedContainer && embedding.embedContainer instanceof Doc).reduce((set, embedding) => set.add(Cast(embedding.embedContainer, Doc, null)), new Set<Doc>());
+        const containerProtos = embeddings.filter(embedding => DocCast(embedding.embedContainer)).reduce((set, embedding) => set.add(DocCast(embedding.embedContainer)!), new Set<Doc>());
         const containerSets = Array.from(containerProtos.keys()).map(container => (Doc.GetEmbeddings(container).length ? Doc.GetEmbeddings(container) : [container]));
         const containers = containerSets.reduce((p, set) => {
             set.map(s => p.add(s));
diff --git a/src/client/views/UndoStack.tsx b/src/client/views/UndoStack.tsx
index 32b97b31a..067020a62 100644
--- a/src/client/views/UndoStack.tsx
+++ b/src/client/views/UndoStack.tsx
@@ -7,9 +7,8 @@ import { SettingsManager } from '../util/SettingsManager';
 import { UndoManager } from '../util/UndoManager';
 import './UndoStack.scss';
 
-interface UndoStackProps {}
 @observer
-export class UndoStack extends React.Component<UndoStackProps> {
+export class UndoStack extends React.Component<object> {
     render() {
         const background = UndoManager.batchCounter.get() ? 'yellow' : SettingsManager.userVariantColor;
         const color = UndoManager.batchCounter.get() ? 'black' : SettingsManager.userColor;
@@ -34,7 +33,6 @@ export class UndoStack extends React.Component<UndoStackProps> {
                                     {Array.from(UndoManager.undoStackNames).map((name, i) => (
                                         <div
                                             className="undoStack-resultContainer"
-                                            // eslint-disable-next-line react/no-array-index-key
                                             key={i}
                                             onClick={() => {
                                                 const size = UndoManager.undoStackNames.length;
@@ -48,7 +46,6 @@ export class UndoStack extends React.Component<UndoStackProps> {
                                         .map((name, i) => (
                                             <div
                                                 className="undoStack-resultContainer"
-                                                // eslint-disable-next-line react/no-array-index-key
                                                 key={i}
                                                 onClick={() => {
                                                     for (let n = 0; n <= i; n++) UndoManager.Redo();
diff --git a/src/client/views/animationtimeline/Region.tsx b/src/client/views/animationtimeline/Region.tsx
index 99163f6c6..40fcb2bf6 100644
--- a/src/client/views/animationtimeline/Region.tsx
+++ b/src/client/views/animationtimeline/Region.tsx
@@ -12,6 +12,18 @@ import './Region.scss';
 import './Timeline.scss';
 import { TimelineMenu } from './TimelineMenu';
 
+export const RegionDataSchema = createSchema({
+    position: defaultSpec('number', 0),
+    duration: defaultSpec('number', 0),
+    keyframes: listSpec(Doc),
+    fadeIn: defaultSpec('number', 0),
+    fadeOut: defaultSpec('number', 0),
+    functions: listSpec(Doc),
+    hasData: defaultSpec('boolean', false),
+});
+export type RegionData = makeInterface<[typeof RegionDataSchema]>;
+export const RegionData = makeInterface(RegionDataSchema);
+
 /**
  * Useful static functions that you can use. Mostly for logic, but you can also add UI logic here also
  */
@@ -108,18 +120,6 @@ export namespace RegionHelpers {
     };
 }
 
-export const RegionDataSchema = createSchema({
-    position: defaultSpec('number', 0),
-    duration: defaultSpec('number', 0),
-    keyframes: listSpec(Doc),
-    fadeIn: defaultSpec('number', 0),
-    fadeOut: defaultSpec('number', 0),
-    functions: listSpec(Doc),
-    hasData: defaultSpec('boolean', false),
-});
-export type RegionData = makeInterface<[typeof RegionDataSchema]>;
-export const RegionData = makeInterface(RegionDataSchema);
-
 interface IProps {
     animatedDoc: Doc;
     RegionData: Doc;
@@ -184,7 +184,7 @@ export class Region extends ObservableReactComponent<IProps> {
         return RegionHelpers.convertPixelTime(this.regiondata.fadeOut, 'mili', 'pixel', this._props.tickSpacing, this._props.tickIncrement);
     }
 
-    constructor(props: any) {
+    constructor(props: IProps) {
         super(props);
         makeObservable(this);
     }
@@ -220,9 +220,7 @@ export class Region extends ObservableReactComponent<IProps> {
             }, 200);
             this._doubleClickEnabled = true;
             document.addEventListener('pointermove', this.onBarPointerMove);
-            document.addEventListener('pointerup', (e: PointerEvent) => {
-                document.removeEventListener('pointermove', this.onBarPointerMove);
-            });
+            document.addEventListener('pointerup', () => document.removeEventListener('pointermove', this.onBarPointerMove));
         }
     };
 
@@ -426,6 +424,7 @@ export class Region extends ObservableReactComponent<IProps> {
                         .map(region => ({ pos: NumCast(region.position), dur: NumCast(region.duration) }))
                         .forEach(({ pos, dur }) => {
                             if (pos !== this.regiondata.position) {
+                                // eslint-disable-next-line no-param-reassign
                                 val += this.regiondata.position;
                                 if (val < 0 || (val > pos && val < pos + dur)) {
                                     cannotMove = true;
@@ -483,7 +482,6 @@ export class Region extends ObservableReactComponent<IProps> {
      * this probably needs biggest change, since everyone expected all keyframes to have a circle (and draggable)
      */
     drawKeyframes = () => {
-        const keyframeDivs: JSX.Element[] = [];
         return DocListCast(this.regiondata.keyframes).map(kf => {
             return (
                 <>
diff --git a/src/client/views/animationtimeline/Track.tsx b/src/client/views/animationtimeline/Track.tsx
index 1e4ed74be..dea7b6aae 100644
--- a/src/client/views/animationtimeline/Track.tsx
+++ b/src/client/views/animationtimeline/Track.tsx
@@ -1,4 +1,4 @@
-import { action, computed, intercept, makeObservable, observable, reaction, runInAction } from 'mobx';
+import { action, computed, intercept, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import { Doc, DocListCast, DocListCastAsync, Opt } from '../../../fields/Doc';
@@ -6,7 +6,7 @@ import { Copy } from '../../../fields/FieldSymbols';
 import { List } from '../../../fields/List';
 import { ObjectField } from '../../../fields/ObjectField';
 import { listSpec } from '../../../fields/Schema';
-import { Cast, NumCast } from '../../../fields/Types';
+import { Cast, DocCast, NumCast } from '../../../fields/Types';
 import { Transform } from '../../util/Transform';
 import { ObservableReactComponent } from '../ObservableReactComponent';
 import { Region, RegionData, RegionHelpers } from './Region';
@@ -29,16 +29,16 @@ interface IProps {
 @observer
 export class Track extends ObservableReactComponent<IProps> {
     @observable private _inner = React.createRef<HTMLDivElement>();
-    @observable private _currentBarXReaction: any = undefined;
-    @observable private _timelineVisibleReaction: any = undefined;
-    @observable private _autoKfReaction: any = undefined;
+    @observable private _currentBarXReaction: IReactionDisposer | undefined = undefined;
+    @observable private _timelineVisibleReaction: IReactionDisposer | undefined = undefined;
+    @observable private _autoKfReaction: IReactionDisposer | undefined = undefined;
     @observable private _newKeyframe: boolean = false;
     private readonly MAX_TITLE_HEIGHT = 75;
     @observable private _trackHeight = 0;
     private primitiveWhitelist = ['x', 'y', '_freeform_panX', '_freeform_panY', '_width', '_height', '_rotation', 'opacity', '_layout_scrollTop'];
     private objectWhitelist = ['data'];
 
-    constructor(props: any) {
+    constructor(props: IProps) {
         super(props);
         makeObservable(this);
     }
@@ -101,11 +101,11 @@ export class Track extends ObservableReactComponent<IProps> {
         }
         const keyframes = Cast(this.saveStateRegion.keyframes, listSpec(Doc)) as List<Doc>;
         const kfIndex = keyframes.indexOf(this.saveStateKf);
-        const kf = keyframes[kfIndex] as Doc; //index in the keyframe
+        const kf = DocCast(keyframes[kfIndex]); //index in the keyframe
         if (this._newKeyframe) {
-            DocListCast(this.saveStateRegion.keyframes).forEach((kf, index) => {
-                this.copyDocDataToKeyFrame(kf);
-                kf.opacity = index === 0 || index === 3 ? 0.1 : 1;
+            DocListCast(this.saveStateRegion.keyframes).forEach((keyF, index) => {
+                this.copyDocDataToKeyFrame(keyF);
+                keyF.opacity = index === 0 || index === 3 ? 0.1 : 1;
             });
             this._newKeyframe = false;
         }
@@ -144,7 +144,7 @@ export class Track extends ObservableReactComponent<IProps> {
             () => {
                 return [...this.primitiveWhitelist.map(key => this._props.animatedDoc[key]), ...objects];
             },
-            (changed, reaction) => {
+            (/* changed, reaction */) => {
                 //check for region
                 const region = this.findRegion(this.time);
                 if (region !== undefined) {
@@ -374,7 +374,7 @@ export class Track extends ObservableReactComponent<IProps> {
 
     @action
     copyDocDataToKeyFrame = (doc: Doc) => {
-        var somethingChanged = false;
+        let somethingChanged = false;
         this.primitiveWhitelist.map(key => {
             const originalVal = this._props.animatedDoc[key];
             somethingChanged = somethingChanged || originalVal !== doc[key];
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 1576a8e4a..7f835938b 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -46,7 +46,7 @@ export class CollectionMenu extends AntimodeMenu<CollectionMenuProps> {
         makeObservable(this);
         CollectionMenu.Instance = this;
         this._canFade = false; // don't let the inking menu fade away
-        this.Pinned = Cast(Doc.UserDoc().menuCollections_pinned, 'boolean', true);
+        this.Pinned = BoolCast(Doc.UserDoc().menuCollections_pinned, true);
         this.jumpTo(300, 300);
     }
 
@@ -269,7 +269,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu
         initialize: (button: Doc) => {
             const activeDash = Doc.ActiveDashboard;
             if (activeDash) {
-                button.target_childFilters = (Doc.MySearcher._childFilters || activeDash._childFilters) instanceof ObjectField ? ObjectField.MakeCopy((Doc.MySearcher._childFilters || activeDash._childFilters) as ObjectField) : undefined;
+                button.target_childFilters = (Doc.MySearcher?._childFilters || activeDash._childFilters) instanceof ObjectField ? ObjectField.MakeCopy((Doc.MySearcher?._childFilters || activeDash._childFilters) as ObjectField) : undefined;
                 button.target_searchFilterDocs = activeDash._searchFilterDocs instanceof ObjectField ? ObjectField.MakeCopy(activeDash._searchFilterDocs) : undefined;
             }
         },
diff --git a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx
index f283b0abe..461689a70 100644
--- a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx
+++ b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx
@@ -155,7 +155,7 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent<CSV
     // all docs are added to the column directly to the left.
     @undoBatch
     deleteColumn = () => {
-        const colHdrData = Array.from(Cast(this._props.Doc[this._props.fieldKey + '_columnHeaders'], listSpec(SchemaHeaderField), null));
+        const colHdrData = Array.from(Cast(this._props.Doc[this._props.fieldKey + '_columnHeaders'], listSpec(SchemaHeaderField), [])!);
         if (this._props.headingObject) {
             //          this._props.docList.forEach(d => (d['$'+this._props.pivotField] = undefined));
             colHdrData.splice(colHdrData.indexOf(this._props.headingObject), 1);
diff --git a/src/client/views/collections/CollectionPileView.tsx b/src/client/views/collections/CollectionPileView.tsx
index eea128803..5a85c8ee3 100644
--- a/src/client/views/collections/CollectionPileView.tsx
+++ b/src/client/views/collections/CollectionPileView.tsx
@@ -67,7 +67,6 @@ export class CollectionPileView extends CollectionSubView() {
         return (
             <div className="collectionPileView-innards" style={{ pointerEvents: this.contentEvents }}>
                 <CollectionFreeFormView
-                    // eslint-disable-next-line react/jsx-props-no-spreading
                     {...this._props} //
                     layoutEngine={this.layoutEngine}
                     addDocument={this.addPileDoc}
diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx
index fd4bdf364..4e7e19548 100644
--- a/src/client/views/collections/CollectionStackedTimeline.tsx
+++ b/src/client/views/collections/CollectionStackedTimeline.tsx
@@ -435,7 +435,7 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
         anchor['$' + endTag] = anchorEndTime;
         if (addAsAnnotation) {
             if (Cast(dataDoc[fieldKey], listSpec(Doc), null)) {
-                Cast(dataDoc[fieldKey], listSpec(Doc), []).push(anchor);
+                Cast(dataDoc[fieldKey], listSpec(Doc), [])!.push(anchor);
             } else {
                 dataDoc[fieldKey] = new List<Doc>([anchor]);
             }
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 3497a62cb..bee5d016d 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -137,7 +137,7 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
         if (res && de.complete.docDragData) {
             if (this.Document !== Doc.MyRecentlyClosed)
                 de.complete.docDragData.droppedDocuments.forEach(doc => {
-                    if (this.Document !== Doc.MyRecentlyClosed) Doc.RemoveDocFromList(Doc.MyRecentlyClosed, undefined, doc);
+                    if (this.Document !== Doc.MyRecentlyClosed) Doc.MyRecentlyClosed && Doc.RemoveDocFromList(Doc.MyRecentlyClosed, undefined, doc);
                 });
         }
         return res;
@@ -193,7 +193,7 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
         res &&
             doclist.forEach(doc => {
                 Doc.SetContainer(doc, this.Document);
-                if (this.Document !== Doc.MyRecentlyClosed) Doc.RemoveDocFromList(Doc.MyRecentlyClosed, undefined, doc);
+                if (this.Document !== Doc.MyRecentlyClosed) Doc.MyRecentlyClosed && Doc.RemoveDocFromList(Doc.MyRecentlyClosed, undefined, doc);
             });
         return res;
     };
@@ -273,8 +273,8 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
         );
     }
     childContextMenuItems = () => {
-        const customScripts = Cast(this.Document.childContextMenuScripts, listSpec(ScriptField), []);
-        const customFilters = Cast(this.Document.childContextMenuFilters, listSpec(ScriptField), []);
+        const customScripts = Cast(this.Document.childContextMenuScripts, listSpec(ScriptField), [])!;
+        const customFilters = Cast(this.Document.childContextMenuFilters, listSpec(ScriptField), [])!;
         const icons = StrListCast(this.Document.childContextMenuIcons);
         return StrListCast(this.Document.childContextMenuLabels).map((label, i) => ({ script: customScripts[i], filter: customFilters[i], icon: icons[i], label }));
     };
diff --git a/src/client/views/collections/FlashcardPracticeUI.tsx b/src/client/views/collections/FlashcardPracticeUI.tsx
index f24a8acb7..2f46c00bd 100644
--- a/src/client/views/collections/FlashcardPracticeUI.tsx
+++ b/src/client/views/collections/FlashcardPracticeUI.tsx
@@ -60,7 +60,7 @@ export class FlashcardPracticeUI extends ObservableReactComponent<PracticeUIProp
 
     get practiceField() { return this._props.fieldKey + "_practice"; } // prettier-ignore
 
-    @computed get filterDoc() { return DocListCast(Doc.MyContextMenuBtns.data).find(doc => doc.title === 'Filter'); } // prettier-ignore
+    @computed get filterDoc() { return DocListCast(Doc.MyContextMenuBtns?.data).find(doc => doc.title === 'Filter'); } // prettier-ignore
     @computed get practiceMode() {  return this._props.allChildDocs().some(doc => doc._layout_flashcardType) ? StrCast(this._props.layoutDoc.practiceMode) : ''; } // prettier-ignore
 
     btnHeight = () => NumCast(this.filterDoc?.height);
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index 4beb75074..fb2d0955f 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -70,7 +70,7 @@ export interface TreeViewProps {
     treeViewHideHeaderFields: () => boolean;
     renderedIds: string[]; // list of document ids rendered used to avoid unending expansion of items in a cycle
     onCheckedClick?: () => ScriptField;
-    onChildClick?: () => ScriptField;
+    onChildClick?: () => ScriptField | undefined;
     skipFields?: string[];
     firstLevel: boolean;
     // TODO: [AL] add these
@@ -1268,7 +1268,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
         treeViewHideHeaderFields: () => boolean,
         renderedIds: string[],
         onCheckedClick: undefined | (() => ScriptField),
-        onChildClick: undefined | (() => ScriptField),
+        onChildClick: undefined | (() => ScriptField | undefined),
         skipFields: string[] | undefined,
         firstLevel: boolean,
         whenChildContentsActiveChanged: (isActive: boolean) => void,
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
index 158bac7ba..4d17dedfb 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
@@ -108,7 +108,7 @@ export function computePassLayout(poolData: Map<string, PoolData>, pivotDoc: Doc
 }
 
 function toNumber(val: FieldResult<FieldType>) {
-    return val === undefined ? undefined : DateCast(val) ? DateCast(val).date.getTime() : NumCast(val, Number(StrCast(val)));
+    return val === undefined ? undefined : DateCast(val) ? DateCast(val)!.date.getTime() : NumCast(val, Number(StrCast(val)));
 }
 
 export function computeStarburstLayout(poolData: Map<string, PoolData>, pivotDoc: Doc, childPairs: { layout: Doc; data?: Doc }[], panelDim: number[], viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[] /* , engineProps: any */) {
diff --git a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx
index 72485aa86..ad05a798b 100644
--- a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx
+++ b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx
@@ -106,7 +106,7 @@ export class UniqueFaceBox extends ViewBoxBaseComponent<FieldViewProps>() {
 
                     // assign the face in the image that's closest to the face collection's face
                     if (faceAnno) {
-                        faceAnno.face && FaceRecognitionHandler.UniqueFaceRemoveFaceImage(faceAnno, DocCast(faceAnno.face));
+                        DocCast(faceAnno.face) && FaceRecognitionHandler.UniqueFaceRemoveFaceImage(faceAnno, DocCast(faceAnno.face)!);
                         FaceRecognitionHandler.UniqueFaceAddFaceImage(faceAnno, this.Document);
                         faceAnno.$face = this.Document[DocData];
                     }
@@ -116,7 +116,7 @@ export class UniqueFaceBox extends ViewBoxBaseComponent<FieldViewProps>() {
             ?.filter(doc => DocCast(doc.face)?.type === DocumentType.UFACE)
             .forEach(faceAnno => {
                 const imgDoc = faceAnno;
-                faceAnno.face && FaceRecognitionHandler.UniqueFaceRemoveFaceImage(imgDoc, DocCast(faceAnno.face));
+                DocCast(faceAnno.face) && FaceRecognitionHandler.UniqueFaceRemoveFaceImage(imgDoc, DocCast(faceAnno.face)!);
                 FaceRecognitionHandler.UniqueFaceAddFaceImage(faceAnno, this.Document);
                 faceAnno.$face = this.Document[DocData];
             });
@@ -187,7 +187,7 @@ export class UniqueFaceBox extends ViewBoxBaseComponent<FieldViewProps>() {
                             ele?.addEventListener('wheel', this.onPassiveWheel, { passive: false });
                         })}>
                         {FaceRecognitionHandler.UniqueFaceImages(this.Document).map((doc, i) => {
-                            const [name, type] = ImageCastToNameType(doc[Doc.LayoutDataKey(doc)]) ?? ['-missing-', '.png'];
+                            const [name, type] = ImageCastToNameType(doc?.[Doc.LayoutDataKey(doc)]) ?? ['-missing-', '.png'];
                             return (
                                 <div
                                     className="image-wrapper"
@@ -197,7 +197,7 @@ export class UniqueFaceBox extends ViewBoxBaseComponent<FieldViewProps>() {
                                             this,
                                             e,
                                             () => {
-                                                const dragDoc = DocListCast(doc.data_annotations).find(a => a.face === this.Document[DocData]) ?? this.Document;
+                                                const dragDoc = DocListCast(doc?.data_annotations).find(a => a.face === this.Document[DocData]) ?? this.Document;
                                                 DragManager.StartDocumentDrag([e.target as HTMLElement], new DragManager.DocumentDragData([dragDoc], dropActionType.embed), e.clientX, e.clientY);
                                                 return true;
                                             },
@@ -205,7 +205,7 @@ export class UniqueFaceBox extends ViewBoxBaseComponent<FieldViewProps>() {
                                             emptyFunction
                                         )
                                     }>
-                                    <img onClick={() => DocumentView.showDocument(doc, { willZoomCentered: true })} style={{ maxWidth: '60px', margin: '10px' }} src={`${name}_o.${type}`} />
+                                    <img onClick={() => doc && DocumentView.showDocument(doc, { willZoomCentered: true })} style={{ maxWidth: '60px', margin: '10px' }} src={`${name}_o.${type}`} />
                                     <div className="remove-item">
                                         <IconButton tooltip={'Remove Doc From Face Collection'} onPointerDown={() => this.removeFaceImageFromUniqueFace(doc)} icon={'x'} style={{ width: '4px' }} size={Size.XSMALL} />
                                     </div>
@@ -239,11 +239,12 @@ export class FaceCollectionBox extends ViewBoxBaseComponent<FieldViewProps>() {
     }
 
     moveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[]) => boolean): boolean => !!(this._props.removeDocument?.(doc) && addDocument?.(doc));
+    // eslint-disable-next-line @typescript-eslint/no-unused-vars
     addDocument = (doc: Doc | Doc[], annotationKey?: string) => {
         const uniqueFaceDoc = doc instanceof Doc ? doc : doc[0];
         const added = uniqueFaceDoc.type === DocumentType.UFACE;
         if (added) {
-            Doc.SetContainer(uniqueFaceDoc, Doc.MyFaceCollection);
+            Doc.MyFaceCollection && Doc.SetContainer(uniqueFaceDoc, Doc.MyFaceCollection);
             Doc.ActiveDashboard && Doc.AddDocToList(Doc.ActiveDashboard[DocData], 'myUniqueFaces', uniqueFaceDoc);
         }
         return added;
diff --git a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx
index 81a2d8e64..16d33eb93 100644
--- a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx
@@ -107,7 +107,7 @@ export class SchemaColumnHeader extends ObservableReactComponent<SchemaColumnHea
             focus: emptyFunction,
             addDocTab: SchemaTableCell.addFieldDoc,
             pinToPres: returnZero,
-            Document: DocCast(Document.rootDocument, Document),
+            Document: DocCast(Document.rootDocument, Document)!,
             fieldKey: fieldKey,
             PanelWidth: columnWidth,
             PanelHeight: props.rowHeight,
diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
index 8e1edc1ee..8b34b4139 100644
--- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
@@ -106,7 +106,7 @@ export class SchemaTableCell extends ObservableReactComponent<SchemaTableCellPro
         const { Doc: Document, fieldKey, /* getFinfo,*/ columnWidth, isRowActive } = props;
         let protoCount = 0;
         const layoutDoc = fieldKey.startsWith('_') ? Document[DocLayout] : Document;
-        let doc = Document;
+        let doc: Doc | undefined = Document;
         while (doc) {
             if (Object.keys(doc).includes(fieldKey.replace(/^_/, ''))) break;
             protoCount++;
@@ -168,9 +168,11 @@ export class SchemaTableCell extends ObservableReactComponent<SchemaTableCellPro
         while ((matches = idPattern.exec(field)) !== null) {
             results.push([matches[0], matches[1].replace(/"/g, '')]);
         }
-        results.forEach(idFuncPair => {
-            modField = modField.replace(idFuncPair[0], 'd' + DocumentView.getDocViewIndex(IdToDoc(idFuncPair[1])).toString());
-        });
+        results
+            .filter(idFuncPair => IdToDoc(idFuncPair[1]))
+            .forEach(idFuncPair => {
+                modField = modField.replace(idFuncPair[0], 'd' + DocumentView.getDocViewIndex(IdToDoc(idFuncPair[1])!).toString());
+            });
 
         if (modField.endsWith(';')) modField = modField.substring(0, modField.length - 1);
 
@@ -328,7 +330,7 @@ export class SchemaImageCell extends ObservableReactComponent<SchemaTableCellPro
         const altpaths = alts
             .map(doc => Cast(doc[Doc.LayoutDataKey(doc)], ImageField, null)?.url)
             .filter(url => url)
-            .map(url => this.choosePath(url)); // access the primary layout data of the alternate documents
+            .map(url => this.choosePath(url!)); // access the primary layout data of the alternate documents
         const paths = field ? [this.choosePath(field.url), ...altpaths] : altpaths;
         // If there is a path, follow it; otherwise, follow a link to a default image icon
         const url = paths.length ? paths : [ClientUtils.CorsProxy('http://www.cs.brown.edu/~bcz/noImage.png')];
@@ -379,7 +381,7 @@ export class SchemaDateCell extends ObservableReactComponent<SchemaTableCellProp
     }
 
     @observable _pickingDate: boolean = false;
-    @computed get date(): DateField {
+    @computed get date(): DateField | undefined {
         // if the cell is a date field, cast then contents to a date. Otherrwwise, make the contents undefined.
         return DateCast(this._props.Doc[this._props.fieldKey]);
     }
@@ -399,7 +401,7 @@ export class SchemaDateCell extends ObservableReactComponent<SchemaTableCellProp
         return (
             <>
                 <div style={{ pointerEvents: 'none' }} tabIndex={1}>
-                    <DatePicker dateFormat="Pp" selected={this.date?.date ?? Date.now()} onChange={emptyFunction} />
+                    <DatePicker dateFormat="Pp" selected={this.date?.date ?? new Date()} onChange={emptyFunction} />
                 </div>
                 {pointerEvents === 'none' || !selectedCell(this._props) ? null : (
                     <Popup
@@ -410,7 +412,7 @@ export class SchemaDateCell extends ObservableReactComponent<SchemaTableCellProp
                         background={SnappingManager.userBackgroundColor}
                         popup={
                             <div style={{ width: 'fit-content', height: '200px' }}>
-                                <DatePicker open dateFormat="Pp" selected={this.date?.date ?? Date.now()} onChange={this.handleChange} />
+                                <DatePicker open dateFormat="Pp" selected={this.date?.date ?? new Date()} onChange={this.handleChange} />
                             </div>
                         }
                     />
diff --git a/src/client/views/linking/LinkMenuGroup.tsx b/src/client/views/linking/LinkMenuGroup.tsx
index c15508669..9eaf0e491 100644
--- a/src/client/views/linking/LinkMenuGroup.tsx
+++ b/src/client/views/linking/LinkMenuGroup.tsx
@@ -1,10 +1,9 @@
-/* eslint-disable react/require-default-props */
 import { action, observable } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import { Doc, StrListCast } from '../../../fields/Doc';
 import { Id } from '../../../fields/FieldSymbols';
-import { Cast, DocCast } from '../../../fields/Types';
+import { DocCast } from '../../../fields/Types';
 import { DocumentType } from '../../documents/DocumentTypes';
 import { DocumentView } from '../nodes/DocumentView';
 import './LinkMenu.scss';
@@ -56,7 +55,7 @@ export class LinkMenuGroup extends React.Component<LinkMenuGroupProps> {
                   ? this.props.docView._props.LayoutTemplateString?.includes('link_anchor_1')
                       ? DocCast(linkDoc.link_anchor_2)
                       : DocCast(linkDoc.link_anchor_1)
-                  : Doc.getOppositeAnchor(linkDoc, sourceDoc) || Doc.getOppositeAnchor(linkDoc, Cast(linkDoc.link_anchor_2, Doc, null)?.annotationOn === sourceDoc ? Cast(linkDoc.link_anchor_2, Doc, null) : Cast(linkDoc.link_anchor_1, Doc, null));
+                  : Doc.getOppositeAnchor(linkDoc, sourceDoc) || Doc.getOppositeAnchor(linkDoc, DocCast(linkDoc.link_anchor_2)?.annotationOn === sourceDoc ? DocCast(linkDoc.link_anchor_2) : DocCast(linkDoc.link_anchor_1));
             return !destDoc || !sourceDoc ? null : (
                 <LinkMenuItem
                     key={linkDoc[Id]}
diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx
index 1c92c3b0d..c984a7053 100644
--- a/src/client/views/linking/LinkMenuItem.tsx
+++ b/src/client/views/linking/LinkMenuItem.tsx
@@ -68,8 +68,8 @@ export class LinkMenuItem extends ObservableReactComponent<LinkMenuItemProps> {
     @computed get sourceAnchor() {
         const ldoc = this._props.linkDoc;
         if (this._props.sourceDoc !== ldoc.link_anchor_1 && this._props.sourceDoc !== ldoc.link_anchor_2) {
-            if (Doc.AreProtosEqual(DocCast(DocCast(ldoc.link_anchor_1).annotationOn), this._props.sourceDoc)) return DocCast(ldoc.link_anchor_1);
-            if (Doc.AreProtosEqual(DocCast(DocCast(ldoc.link_anchor_2).annotationOn), this._props.sourceDoc)) return DocCast(ldoc.link_anchor_2);
+            if (Doc.AreProtosEqual(DocCast(DocCast(ldoc.link_anchor_1)?.annotationOn), this._props.sourceDoc)) return DocCast(ldoc.link_anchor_1);
+            if (Doc.AreProtosEqual(DocCast(DocCast(ldoc.link_anchor_2)?.annotationOn), this._props.sourceDoc)) return DocCast(ldoc.link_anchor_2);
         }
         return this._props.sourceDoc;
     }
diff --git a/src/client/views/newlightbox/ExploreView/ExploreView.tsx b/src/client/views/newlightbox/ExploreView/ExploreView.tsx
index f8c07cc43..7f9a13549 100644
--- a/src/client/views/newlightbox/ExploreView/ExploreView.tsx
+++ b/src/client/views/newlightbox/ExploreView/ExploreView.tsx
@@ -1,5 +1,3 @@
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
 import * as React from 'react';
 import { StrCast } from '../../../../fields/Types';
 import { NewLightboxView } from '../NewLightboxView';
@@ -19,7 +17,7 @@ export function ExploreView(props: IExploreView) {
                         const x = (rec.embedding.x / xBound) * 50;
                         const y = (rec.embedding.y / yBound) * 50;
                         return (
-                            <div className="exploreView-doc" onClick={() => {}} style={{ top: `calc(50% + ${y}%)`, left: `calc(50% + ${x}%)` }}>
+                            <div key={'' + x + ' ' + y} className="exploreView-doc" onClick={() => {}} style={{ top: `calc(50% + ${y}%)`, left: `calc(50% + ${x}%)` }}>
                                 {rec.title}
                             </div>
                         );
diff --git a/src/client/views/newlightbox/NewLightboxView.tsx b/src/client/views/newlightbox/NewLightboxView.tsx
index 87cef01d2..7ec45d0dd 100644
--- a/src/client/views/newlightbox/NewLightboxView.tsx
+++ b/src/client/views/newlightbox/NewLightboxView.tsx
@@ -5,7 +5,7 @@ import { returnEmptyFilter, returnTrue } from '../../../ClientUtils';
 import { emptyFunction } from '../../../Utils';
 import { CreateLinkToActiveAudio, Doc, DocListCast, Opt, returnEmptyDoclist } from '../../../fields/Doc';
 import { InkTool } from '../../../fields/InkField';
-import { Cast, NumCast, StrCast, toList } from '../../../fields/Types';
+import { Cast, DocCast, NumCast, StrCast, toList } from '../../../fields/Types';
 import { SnappingManager } from '../../util/SnappingManager';
 import { Transform } from '../../util/Transform';
 import { GestureOverlay } from '../GestureOverlay';
@@ -100,7 +100,7 @@ export class NewLightboxView extends React.Component<LightboxViewProps> {
             SnappingManager.SetExploreMode(false);
         } else {
             const l = CreateLinkToActiveAudio(() => doc).lastElement();
-            l && (Cast(l.link_anchor_2, Doc, null).backgroundColor = 'lightgreen');
+            DocCast(l?.link_anchor_2) && (DocCast(l!.link_anchor_2)!.backgroundColor = 'lightgreen');
             DocumentView.CurrentlyPlaying?.forEach(dv => dv.ComponentView?.Pause?.());
             // DocumentView.PinDoc(doc, { hidePresBox: true });
             this._history ? this._history.push({ doc, target }) : (this._history = [{ doc, target }]);
@@ -142,7 +142,7 @@ export class NewLightboxView extends React.Component<LightboxViewProps> {
         const targetDocView = target && DocumentView.getLightboxDocumentView(target);
         if (targetDocView && target) {
             const l = CreateLinkToActiveAudio(() => targetDocView.ComponentView?.getAnchor?.(true) || target).lastElement();
-            l && (Cast(l.link_anchor_2, Doc, null).backgroundColor = 'lightgreen');
+            DocCast(l?.link_anchor_2) && (DocCast(l!.link_anchor_2)!.backgroundColor = 'lightgreen');
             DocumentView.showDocument(target, { willZoomCentered: true, zoomScale: 0.9 });
             if (NewLightboxView._history?.lastElement().target !== target) NewLightboxView._history?.push({ doc, target });
         } else if (!target && NewLightboxView.path.length) {
@@ -326,7 +326,6 @@ export class NewLightboxView extends React.Component<LightboxViewProps> {
 }
 interface NewLightboxTourBtnProps {
     navBtn: (left: Opt<string | number>, bottom: Opt<number>, top: number, icon: string, display: () => string, click: (e: React.MouseEvent) => void, color?: string) => JSX.Element;
-    // eslint-disable-next-line react/no-unused-prop-types
     future: () => Opt<Doc[]>;
     stepInto: () => void;
 }
diff --git a/src/client/views/nodes/DataVizBox/DataVizBox.tsx b/src/client/views/nodes/DataVizBox/DataVizBox.tsx
index c80e8ebc1..9369ff98a 100644
--- a/src/client/views/nodes/DataVizBox/DataVizBox.tsx
+++ b/src/client/views/nodes/DataVizBox/DataVizBox.tsx
@@ -108,7 +108,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
     // all CSV records in the dataset (that aren't an empty row)
     @computed.struct get records() {
         try {
-            const records = DataVizBox.dataset.get(CsvCast(this.dataDoc[this.fieldKey]).url.href);
+            const records = DataVizBox.dataset.get(CsvCast(this.dataDoc[this.fieldKey])?.url.href ?? '');
             this._urlError = false;
             return records?.filter(record => Object.keys(record).some(key => record[key])) ?? [];
         } catch {
@@ -344,7 +344,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
     componentDidMount() {
         this._props.setContentViewBox?.(this);
         if (!this._urlError) {
-            if (!DataVizBox.dataset.has(CsvCast(this.dataDoc[this.fieldKey]).url.href)) this.fetchData();
+            if (!DataVizBox.dataset.has(CsvCast(this.dataDoc[this.fieldKey])?.url.href ?? '')) this.fetchData();
         }
         this._disposers.datavis = reaction(
             () => {
@@ -386,8 +386,8 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
                     this.layoutDoc._dataViz_schemaOG = loading;
                 }
                 const ogDoc = this.layoutDoc._dataViz_schemaOG as Doc;
-                const ogHref = CsvCast(ogDoc[this.fieldKey]) ? CsvCast(ogDoc[this.fieldKey]).url.href : undefined;
-                const { href } = CsvCast(this.Document[this.fieldKey]).url;
+                const ogHref = CsvCast(ogDoc[this.fieldKey]) ? CsvCast(ogDoc[this.fieldKey])!.url.href : undefined;
+                const { href } = CsvCast(this.Document[this.fieldKey])?.url ?? { href: '' };
                 if (ogHref && !DataVizBox.datasetSchemaOG.has(href)) {
                     // sets original dataset to the var
                     const lastRow = current.pop();
@@ -399,7 +399,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
             },
             current => {
                 if (current) {
-                    const { href } = CsvCast(this.Document[this.fieldKey]).url;
+                    const { href } = CsvCast(this.Document[this.fieldKey])?.url ?? { href: '' };
                     if (this.layoutDoc.dataViz_schemaLive) DataVizBox.dataset.set(href, current);
                     else DataVizBox.dataset.set(href, DataVizBox.datasetSchemaOG.get(href)!);
                 }
@@ -414,9 +414,9 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
 
     fetchData = () => {
         if (!this.Document.dataViz_asSchema) {
-            DataVizBox.dataset.set(CsvCast(this.dataDoc[this.fieldKey]).url.href, []); // assign temporary dataset as a lock to prevent duplicate server requests
+            DataVizBox.dataset.set(CsvCast(this.dataDoc[this.fieldKey])?.url.href ?? '', []); // assign temporary dataset as a lock to prevent duplicate server requests
             fetch('/csvData?uri=' + (this.dataUrl?.url.href ?? '')) //
-                .then(res => res.json().then(action(jsonRes => !jsonRes.errno && DataVizBox.dataset.set(CsvCast(this.dataDoc[this.fieldKey]).url.href, jsonRes))));
+                .then(res => res.json().then(action(jsonRes => !jsonRes.errno && DataVizBox.dataset.set(CsvCast(this.dataDoc[this.fieldKey])?.url.href ?? '', jsonRes))));
         }
     };
 
@@ -523,7 +523,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
         GPTPopup.Instance.createFilteredDoc = this.createFilteredDoc;
         GPTPopup.Instance.setDataJson('');
         GPTPopup.Instance.setMode(GPTPopupMode.DATA);
-        const csvdata = DataVizBox.dataset.get(CsvCast(this.dataDoc[this.fieldKey]).url.href);
+        const csvdata = DataVizBox.dataset.get(CsvCast(this.dataDoc[this.fieldKey])?.url.href ?? '');
         GPTPopup.Instance.setDataJson(JSON.stringify(csvdata));
         GPTPopup.Instance.generateDataAnalysis();
     });
diff --git a/src/client/views/nodes/DataVizBox/SchemaCSVPopUp.tsx b/src/client/views/nodes/DataVizBox/SchemaCSVPopUp.tsx
index 8ae29a88c..1e2a95d31 100644
--- a/src/client/views/nodes/DataVizBox/SchemaCSVPopUp.tsx
+++ b/src/client/views/nodes/DataVizBox/SchemaCSVPopUp.tsx
@@ -11,10 +11,8 @@ import { DragManager } from '../../../util/DragManager';
 import { DocumentView } from '../DocumentView';
 import './SchemaCSVPopUp.scss';
 
-interface SchemaCSVPopUpProps {}
-
 @observer
-export class SchemaCSVPopUp extends React.Component<SchemaCSVPopUpProps> {
+export class SchemaCSVPopUp extends React.Component<object> {
     // eslint-disable-next-line no-use-before-define
     static Instance: SchemaCSVPopUp;
 
@@ -23,7 +21,7 @@ export class SchemaCSVPopUp extends React.Component<SchemaCSVPopUpProps> {
     @observable public target: Doc | undefined = undefined;
     @observable public visible: boolean = false;
 
-    constructor(props: SchemaCSVPopUpProps) {
+    constructor(props: object) {
         super(props);
         makeObservable(this);
         SchemaCSVPopUp.Instance = this;
diff --git a/src/client/views/nodes/DataVizBox/components/Histogram.tsx b/src/client/views/nodes/DataVizBox/components/Histogram.tsx
index 5450d03b1..a7c4a00b0 100644
--- a/src/client/views/nodes/DataVizBox/components/Histogram.tsx
+++ b/src/client/views/nodes/DataVizBox/components/Histogram.tsx
@@ -5,10 +5,9 @@ import { IReactionDisposer, action, computed, makeObservable, observable, reacti
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import { FaFillDrip } from 'react-icons/fa';
-import { Doc, NumListCast } from '../../../../../fields/Doc';
+import { Doc, NumListCast, StrListCast } from '../../../../../fields/Doc';
 import { List } from '../../../../../fields/List';
-import { listSpec } from '../../../../../fields/Schema';
-import { Cast, DocCast, StrCast } from '../../../../../fields/Types';
+import { DocCast, StrCast } from '../../../../../fields/Types';
 import { Docs } from '../../../../documents/Documents';
 import { undoable } from '../../../../util/UndoManager';
 import { ObservableReactComponent } from '../../../ObservableReactComponent';
@@ -108,13 +107,13 @@ export class Histogram extends ObservableReactComponent<HistogramProps> {
     }
 
     @computed get defaultBarColor() {
-        return Cast(this.layoutDoc.dataViz_histogram_defaultColor, 'string', '#69b3a2');
+        return StrCast(this.layoutDoc.dataViz_histogram_defaultColor, '#69b3a2')!;
     }
     @computed get barColors() {
-        return Cast(this.layoutDoc.dataViz_histogram_barColors, listSpec('string'), null);
+        return StrListCast(this.layoutDoc.dataViz_histogram_barColors);
     }
     @computed get selectedBins() {
-        return Cast(this.layoutDoc.dataViz_histogram_selectedBins, listSpec('number'), null);
+        return NumListCast(this.layoutDoc.dataViz_histogram_selectedBins);
     }
 
     @computed get rangeVals(): { xMin?: number; xMax?: number; yMin?: number; yMax?: number } {
@@ -129,7 +128,7 @@ export class Histogram extends ObservableReactComponent<HistogramProps> {
         // restore selected bars
         this._histogramSvg?.selectAll('rect').attr('class', dIn => {
             const d = dIn as HistogramData;
-            if (this.selectedBins.some(selBin => d[0] === selBin)) {
+            if (this.selectedBins?.some(selBin => d[0] === selBin)) {
                 this._selectedBars.push(d);
                 return 'histogram-bar hover';
             }
@@ -199,10 +198,10 @@ export class Histogram extends ObservableReactComponent<HistogramProps> {
                     const alreadySelected = this._selectedBars.findIndex(eachData => !Object.keys(d).some(key => d[key] !== eachData[key]));
                     if (alreadySelected !== -1) {
                         this._selectedBars.splice(alreadySelected, 1);
-                        this.selectedBins.splice(alreadySelected, 1);
+                        this.selectedBins?.splice(alreadySelected, 1);
                     } else {
                         this._selectedBars.push(d);
-                        this.selectedBins.push(d[0] as number);
+                        this.selectedBins?.push(d[0] as number);
                     }
                     const showSelectedLabel = (dataset: HistogramData[]) => {
                         const datum = dataset.lastElement();
diff --git a/src/client/views/nodes/DataVizBox/components/LineChart.tsx b/src/client/views/nodes/DataVizBox/components/LineChart.tsx
index 6b047546c..80fadf178 100644
--- a/src/client/views/nodes/DataVizBox/components/LineChart.tsx
+++ b/src/client/views/nodes/DataVizBox/components/LineChart.tsx
@@ -26,7 +26,7 @@ export interface LineChartProps {
     layoutDoc: Doc;
     axes: string[];
     titleCol: string;
-    records: { [key: string]: any }[];
+    records: { [key: string]: string }[];
     width: number;
     height: number;
     dataDoc: Doc;
@@ -47,7 +47,7 @@ export class LineChart extends ObservableReactComponent<LineChartProps> {
     @observable _currSelected: DataPoint | undefined = undefined;
 
     // TODO: nda - some sort of mapping that keeps track of the annotated points so we can easily remove when annotations list updates
-    constructor(props: any) {
+    constructor(props: LineChartProps) {
         super(props);
         makeObservable(this);
     }
@@ -79,7 +79,7 @@ export class LineChart extends ObservableReactComponent<LineChartProps> {
     @computed get incomingHighlited() {
         // return selected x and y axes
         // otherwise, use the selection of whatever is linked to us
-        const incomingVizBox = DocumentView.getFirstDocumentView(this.parentViz)?.ComponentView as DataVizBox;
+        const incomingVizBox = this.parentViz && (DocumentView.getFirstDocumentView(this.parentViz)?.ComponentView as DataVizBox);
         const highlitedRowIds = NumListCast(incomingVizBox?.layoutDoc?.dataViz_highlitedRows);
         return this._tableData.filter((record, i) => highlitedRowIds.includes(this._tableDataIds[i])); // get all the datapoints they have selected field set by incoming anchor
     }
@@ -170,8 +170,8 @@ export class LineChart extends ObservableReactComponent<LineChartProps> {
             }
         });
         if (!ptWasSelected) {
-            selectedDatapoints.push(d.x + ',' + d.y);
-            this._currSelected = selectedDatapoints.length > 1 ? undefined : d;
+            selectedDatapoints?.push(d.x + ',' + d.y);
+            this._currSelected = (selectedDatapoints?.length ?? 0 > 1) ? undefined : d;
         }
 
         // for filtering child dataviz docs
@@ -190,7 +190,14 @@ export class LineChart extends ObservableReactComponent<LineChartProps> {
         }
     }
 
-    drawDataPoints(data: DataPoint[], idx: number, xScale: d3.ScaleLinear<number, number, never>, yScale: d3.ScaleLinear<number, number, never>, higlightFocusPt: any, tooltip: any) {
+    drawDataPoints(
+        data: DataPoint[], //
+        idx: number,
+        xScale: d3.ScaleLinear<number, number, never>,
+        yScale: d3.ScaleLinear<number, number, never>,
+        higlightFocusPt: d3.Selection<SVGGElement, unknown, null, undefined>,
+        tooltip: d3.Selection<HTMLDivElement, unknown, null, undefined>
+    ) {
         if (this._lineChartSvg) {
             const circleClass = '.circle-' + idx;
             this._lineChartSvg
@@ -211,7 +218,7 @@ export class LineChart extends ObservableReactComponent<LineChartProps> {
                 .on('mouseleave', () => {
                     tooltip?.transition().duration(300).style('opacity', 0);
                 })
-                .on('click', (e: any) => {
+                .on('click', e => {
                     const d0 = { x: Number(e.target.getAttribute('data-x')), y: Number(e.target.getAttribute('data-y')) };
                     // find .circle-d1 with data-x = d0.x and data-y = d0.y
                     this.setCurrSelected(d0);
@@ -220,7 +227,7 @@ export class LineChart extends ObservableReactComponent<LineChartProps> {
         }
     }
 
-    drawChart = (dataSet: any[][], rangeVals: { xMin?: number; xMax?: number; yMin?: number; yMax?: number }, width: number, height: number) => {
+    drawChart = (dataSet: { x: number; y: number }[][], rangeVals: { xMin?: number; xMax?: number; yMin?: number; yMax?: number }, width: number, height: number) => {
         // clearing tooltip and the current chart
         d3.select(this._lineChartRef).select('svg').remove();
         d3.select(this._lineChartRef).select('.tooltip').remove();
@@ -277,7 +284,7 @@ export class LineChart extends ObservableReactComponent<LineChartProps> {
             svg.append('path').attr('stroke', 'red');
 
             // legend
-            const color: any = d3.scaleOrdinal().range(['black', 'blue']).domain([this._props.axes[1], this._props.axes[2]]);
+            const color = d3.scaleOrdinal().range(['black', 'blue']).domain([this._props.axes[1], this._props.axes[2]]);
             svg.selectAll('mydots')
                 .data([this._props.axes[1], this._props.axes[2]])
                 .enter()
diff --git a/src/client/views/nodes/DataVizBox/components/TableBox.tsx b/src/client/views/nodes/DataVizBox/components/TableBox.tsx
index b73123691..ad2731109 100644
--- a/src/client/views/nodes/DataVizBox/components/TableBox.tsx
+++ b/src/client/views/nodes/DataVizBox/components/TableBox.tsx
@@ -128,7 +128,7 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> {
             selected.splice(selected.indexOf(rowId), 1);
         } else selected?.push(rowId);
         e.stopPropagation();
-        this.hasRowsToFilter = selected.length > 0;
+        this.hasRowsToFilter = (selected?.length ?? 0) > 0;
     };
 
     columnPointerDown = (e: React.PointerEvent, col: string) => {
diff --git a/src/client/views/nodes/EquationBox.tsx b/src/client/views/nodes/EquationBox.tsx
index dcc6e27ed..3cacb6692 100644
--- a/src/client/views/nodes/EquationBox.tsx
+++ b/src/client/views/nodes/EquationBox.tsx
@@ -1,7 +1,6 @@
 import { action, computed, makeObservable, reaction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
-import { Doc } from '../../../fields/Doc';
 import { NumCast, StrCast } from '../../../fields/Types';
 import { TraceMobx } from '../../../fields/util';
 import { DocUtils } from '../../documents/DocUtils';
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index 34e3a5d76..a6872f8dc 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -6,16 +6,17 @@ import { DateField } from '../../../fields/DateField';
 import { Doc, Field, FieldType, Opt } from '../../../fields/Doc';
 import { List } from '../../../fields/List';
 import { ScriptField } from '../../../fields/ScriptField';
+import { WebField } from '../../../fields/URLField';
+import { DragManager } from '../../util/DragManager';
 import { dropActionType } from '../../util/DropActionTypes';
 import { Transform } from '../../util/Transform';
+import { ContextMenuProps } from '../ContextMenuItem';
 import { PinProps } from '../PinFuncs';
 import { ViewBoxInterface } from '../ViewBoxInterface';
 import { DocumentView } from './DocumentView';
 import { FocusViewOptions } from './FocusViewOptions';
-import { OpenWhere } from './OpenWhere';
-import { WebField } from '../../../fields/URLField';
-import { ContextMenuProps } from '../ContextMenuItem';
 import { FormattedTextBox } from './formattedText/FormattedTextBox';
+import { OpenWhere } from './OpenWhere';
 
 export type FocusFuncType = (doc: Doc, options: FocusViewOptions) => Opt<number>;
 export type StyleProviderFuncType = (
diff --git a/src/client/views/nodes/FunctionPlotBox.tsx b/src/client/views/nodes/FunctionPlotBox.tsx
index 91c351895..8e4b64851 100644
--- a/src/client/views/nodes/FunctionPlotBox.tsx
+++ b/src/client/views/nodes/FunctionPlotBox.tsx
@@ -2,10 +2,11 @@ import functionPlot, { Chart } from 'function-plot';
 import { action, computed, makeObservable, reaction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
-import { Doc, DocListCast } from '../../../fields/Doc';
+import { returnFalse, setupMoveUpEvents } from '../../../ClientUtils';
+import { emptyFunction } from '../../../Utils';
+import { Doc, DocListCast, NumListCast } from '../../../fields/Doc';
 import { List } from '../../../fields/List';
-import { listSpec } from '../../../fields/Schema';
-import { Cast, StrCast } from '../../../fields/Types';
+import { StrCast } from '../../../fields/Types';
 import { TraceMobx } from '../../../fields/util';
 import { DocUtils } from '../../documents/DocUtils';
 import { DocumentType } from '../../documents/DocumentTypes';
@@ -15,8 +16,6 @@ import { undoBatch } from '../../util/UndoManager';
 import { ViewBoxAnnotatableComponent } from '../DocComponent';
 import { PinDocView, PinProps } from '../PinFuncs';
 import { FieldView, FieldViewProps } from './FieldView';
-import { returnFalse, setupMoveUpEvents } from '../../../ClientUtils';
-import { emptyFunction } from '../../../Utils';
 
 @observer
 export class FunctionPlotBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
@@ -76,7 +75,7 @@ export class FunctionPlotBox extends ViewBoxAnnotatableComponent<FieldViewProps>
         this._plotEle = ele || this._plotEle;
         const width = this._props.PanelWidth();
         const height = this._props.PanelHeight();
-        const xrange = Cast(this.layoutDoc.xRange, listSpec('number'), [-10, 10]);
+        const xrange = NumListCast(this.layoutDoc.xRange, [-10, 10])!;
         try {
             this._plotEle?.children.length && this._plotEle.removeChild(this._plotEle.children[0]);
             this._plot = functionPlot({
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 9c6b8e99c..999d7089b 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -212,7 +212,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
 
     drop = undoable(
         action((e: Event, de: DragManager.DropEvent) => {
-            if (de.complete.docDragData && this._props.rejectDrop?.(de.complete.docDragData?.draggedDocuments, this.DocumentView?.())) {
+            if (de.complete.docDragData && this._props.rejectDrop?.(de, this.DocumentView?.())) {
                 let added: boolean | undefined;
                 const hitDropTarget = (ele: HTMLElement, dropTarget: HTMLDivElement | null): boolean => {
                     if (!ele) return false;
diff --git a/src/client/views/nodes/MapBox/DirectionsAnchorMenu.tsx b/src/client/views/nodes/MapBox/DirectionsAnchorMenu.tsx
index 8784a709a..8bb7ddd9f 100644
--- a/src/client/views/nodes/MapBox/DirectionsAnchorMenu.tsx
+++ b/src/client/views/nodes/MapBox/DirectionsAnchorMenu.tsx
@@ -43,7 +43,7 @@ export class DirectionsAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
         return this._left > 0;
     }
 
-    constructor(props: Readonly<{}>) {
+    constructor(props: AntimodeMenuProps) {
         super(props);
 
         DirectionsAnchorMenu.Instance = this;
diff --git a/src/client/views/nodes/calendarBox/CalendarBox.tsx b/src/client/views/nodes/calendarBox/CalendarBox.tsx
index 6f1f58a4c..fa863e123 100644
--- a/src/client/views/nodes/calendarBox/CalendarBox.tsx
+++ b/src/client/views/nodes/calendarBox/CalendarBox.tsx
@@ -105,9 +105,10 @@ export class CalendarBox extends CollectionSubView() {
 
     // TODO: Return a different color based on the event type
     eventToColor = (event: Doc): string => {
-        return 'red';
+        return 'red' + event;
     };
 
+    // eslint-disable-next-line @typescript-eslint/no-unused-vars
     internalDocDrop = (e: Event, de: DragManager.DropEvent, docDragData: DragManager.DocumentDragData) => {
         if (!super.onInternalDrop(e, de)) return false;
         de.complete.docDragData?.droppedDocuments.forEach(doc => {
diff --git a/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx b/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx
index 528bcd05a..6c3da8977 100644
--- a/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx
+++ b/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx
@@ -196,7 +196,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
 
             // Add CSV details to linked files
             this._linked_csv_files.push({
-                filename: CsvCast(newLinkedDoc.data).url.pathname,
+                filename: CsvCast(newLinkedDoc.data)?.url.pathname ?? '',
                 id: csvId,
                 text: csvData,
             });
@@ -634,6 +634,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
     };
 
     getDirectMatchingSegmentStart = (doc: Doc, citationText: string, indexesOfSegments: string[]): number => {
+        // eslint-disable-next-line @typescript-eslint/no-explicit-any
         const originalSegments = JSON.parse(StrCast(doc.original_segments!)).map((segment: any, index: number) => ({
             index: index.toString(),
             text: segment.text,
@@ -877,7 +878,8 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
         return LinkManager.Instance.getAllRelatedLinks(this.Document)
             .map(d => DocCast(LinkManager.getOppositeAnchor(d, this.Document)))
             .map(d => DocCast(d?.annotationOn, d))
-            .filter(d => d);
+            .filter(d => d)
+            .map(d => d!);
     }
 
     /**
@@ -889,6 +891,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
             .map(d => DocCast(LinkManager.getOppositeAnchor(d, this.Document)))
             .map(d => DocCast(d?.annotationOn, d))
             .filter(d => d)
+            .map(d => d!)
             .filter(d => {
                 console.log(d.ai_doc_id);
                 return d.ai_doc_id;
@@ -905,15 +908,14 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
             LinkManager.Instance.getAllRelatedLinks(this.Document)
                 .map(d => DocCast(LinkManager.getOppositeAnchor(d, this.Document)))
                 .map(d => DocCast(d?.annotationOn, d))
-                .filter(d => d)
-                .filter(d => d.summary)
+                .filter(d => d?.summary)
                 .map((doc, index) => {
-                    if (PDFCast(doc.data)) {
-                        return `<summary file_name="${PDFCast(doc.data).url.pathname}" applicable_tools=["rag"]>${doc.summary}</summary>`;
-                    } else if (CsvCast(doc.data)) {
-                        return `<summary file_name="${CsvCast(doc.data).url.pathname}" applicable_tools=["dataAnalysis"]>${doc.summary}</summary>`;
+                    if (PDFCast(doc?.data)) {
+                        return `<summary file_name="${PDFCast(doc!.data)!.url.pathname}" applicable_tools=["rag"]>${doc!.summary}</summary>`;
+                    } else if (CsvCast(doc?.data)) {
+                        return `<summary file_name="${CsvCast(doc!.data)!.url.pathname}" applicable_tools=["dataAnalysis"]>${doc!.summary}</summary>`;
                     } else {
-                        return `${index + 1}) ${doc.summary}`;
+                        return `${index + 1}) ${doc?.summary}`;
                     }
                 })
                 .join('\n') + '\n'
diff --git a/src/client/views/nodes/chatbot/tools/GetDocsTool.ts b/src/client/views/nodes/chatbot/tools/GetDocsTool.ts
index 05482a66e..42a7747d3 100644
--- a/src/client/views/nodes/chatbot/tools/GetDocsTool.ts
+++ b/src/client/views/nodes/chatbot/tools/GetDocsTool.ts
@@ -40,7 +40,10 @@ export class GetDocsTool extends BaseTool<GetDocsToolParamsType> {
     }
 
     async execute(args: ParametersType<GetDocsToolParamsType>): Promise<Observation[]> {
-        const docs = args.document_ids.map(doc_id => DocCast(DocServer.GetCachedRefField(doc_id)));
+        const docs = args.document_ids
+            .map(doc_id => DocCast(DocServer.GetCachedRefField(doc_id)))
+            .filter(d => d)
+            .map(d => d!);
         const collection = Docs.Create.FreeformDocument(docs, { title: args.title });
         this._docView._props.addDocTab(collection, OpenWhere.addRight);
         return [{ type: 'text', text: `Collection created in Dash called ${args.title}` }];
diff --git a/src/client/views/nodes/chatbot/vectorstore/Vectorstore.ts b/src/client/views/nodes/chatbot/vectorstore/Vectorstore.ts
index c1915a398..6d524e40f 100644
--- a/src/client/views/nodes/chatbot/vectorstore/Vectorstore.ts
+++ b/src/client/views/nodes/chatbot/vectorstore/Vectorstore.ts
@@ -15,7 +15,6 @@ import { Networking } from '../../../../Network';
 import { AI_Document, CHUNK_TYPE, RAGChunk } from '../types/types';
 import OpenAI from 'openai';
 import { Embedding } from 'openai/resources';
-import { PineconeEnvironmentVarsNotSupportedError } from '@pinecone-database/pinecone/dist/errors';
 
 dotenv.config();
 
@@ -101,7 +100,7 @@ export class Vectorstore {
         } else {
             // Start processing the document.
             doc.ai_document_status = 'PROGRESS';
-            const local_file_path: string = CsvCast(doc.data)?.url?.pathname ?? PDFCast(doc.data)?.url?.pathname ?? VideoCast(doc.data)?.url?.pathname ?? AudioCast(doc.data)?.url?.pathname;
+            const local_file_path = CsvCast(doc.data)?.url?.pathname ?? PDFCast(doc.data)?.url?.pathname ?? VideoCast(doc.data)?.url?.pathname ?? AudioCast(doc.data)?.url?.pathname;
 
             if (!local_file_path) {
                 console.log('Invalid file path.');
@@ -112,13 +111,13 @@ export class Vectorstore {
             let result: AI_Document & { doc_id: string };
             if (isAudioOrVideo) {
                 console.log('Processing media file...');
-                const response = await Networking.PostToServer('/processMediaFile', { fileName: path.basename(local_file_path) });
+                const response = (await Networking.PostToServer('/processMediaFile', { fileName: path.basename(local_file_path) })) as { [key: string]: unknown };
                 const segmentedTranscript = response.condensed;
                 console.log(segmentedTranscript);
-                const summary = response.summary;
+                const summary = response.summary as string;
                 doc.summary = summary;
                 // Generate embeddings for each chunk
-                const texts = segmentedTranscript.map((chunk: any) => chunk.text);
+                const texts = (segmentedTranscript as { text: string }[])?.map(chunk => chunk.text);
 
                 try {
                     const embeddingsResponse = await this.openai.embeddings.create({
@@ -138,7 +137,7 @@ export class Vectorstore {
                         file_name: local_file_path,
                         num_pages: 0,
                         summary: '',
-                        chunks: segmentedTranscript.map((chunk: any, index: number) => ({
+                        chunks: (segmentedTranscript as { text: string; start: number; end: number; indexes: string[] }[]).map((chunk, index) => ({
                             id: uuidv4(),
                             values: (embeddingsResponse.data as Embedding[])[index].embedding, // Assign embedding
                             metadata: {
@@ -173,7 +172,7 @@ export class Vectorstore {
             } else {
                 // Existing document processing logic remains unchanged
                 console.log('Processing regular document...');
-                const { jobId } = await Networking.PostToServer('/createDocument', { file_path: local_file_path });
+                const { jobId } = (await Networking.PostToServer('/createDocument', { file_path: local_file_path })) as { jobId: string };
 
                 while (true) {
                     await new Promise(resolve => setTimeout(resolve, 2000));
@@ -297,7 +296,7 @@ export class Vectorstore {
                 encoding_format: 'float',
             });
 
-            let queryEmbedding = queryEmbeddingResponse.data[0].embedding;
+            const queryEmbedding = queryEmbeddingResponse.data[0].embedding;
 
             // Extract the embedding from the response.
 
diff --git a/src/client/views/nodes/formattedText/DailyJournal.tsx b/src/client/views/nodes/formattedText/DailyJournal.tsx
index 797a9b812..871c556e6 100644
--- a/src/client/views/nodes/formattedText/DailyJournal.tsx
+++ b/src/client/views/nodes/formattedText/DailyJournal.tsx
@@ -161,7 +161,7 @@ export class DailyJournal extends ViewBoxAnnotatableComponent<FieldViewProps>()
 
                         // Check if doc or selection changed
                         if (!prevState.doc.eq(state.doc) || !prevState.selection.eq(state.selection)) {
-                            let found = false;
+                            const found = false;
                             const textToRemove = this.predictiveText;
 
                             state.doc.descendants((node, pos) => {
diff --git a/src/client/views/nodes/scrapbook/ScrapbookBox.tsx b/src/client/views/nodes/scrapbook/ScrapbookBox.tsx
index b241b27d7..6cfe9a62c 100644
--- a/src/client/views/nodes/scrapbook/ScrapbookBox.tsx
+++ b/src/client/views/nodes/scrapbook/ScrapbookBox.tsx
@@ -1,6 +1,6 @@
 import { action, makeObservable, observable } from 'mobx';
 import * as React from 'react';
-import { Doc, DocListCast, StrListCast } from '../../../../fields/Doc';
+import { Doc, DocListCast } from '../../../../fields/Doc';
 import { List } from '../../../../fields/List';
 import { emptyFunction } from '../../../../Utils';
 import { Docs } from '../../../documents/Documents';
diff --git a/src/client/views/pdf/Annotation.tsx b/src/client/views/pdf/Annotation.tsx
index 1891cfd4c..e8a5235c9 100644
--- a/src/client/views/pdf/Annotation.tsx
+++ b/src/client/views/pdf/Annotation.tsx
@@ -50,7 +50,7 @@ interface IAnnotationProps extends FieldViewProps {
 }
 @observer
 export class Annotation extends ObservableReactComponent<IAnnotationProps> {
-    constructor(props: any) {
+    constructor(props: IAnnotationProps) {
         super(props);
         makeObservable(this);
     }
@@ -58,7 +58,7 @@ export class Annotation extends ObservableReactComponent<IAnnotationProps> {
     @computed get linkHighlighted() {
         const found = LinkManager.Instance.getAllDirectLinks(this._props.annoDoc).find(link => {
             const a1 = Doc.getOppositeAnchor(link, this._props.annoDoc);
-            return a1 && Doc.GetBrushStatus(DocCast(a1.annotationOn, a1));
+            return a1 && Doc.GetBrushStatus(DocCast(a1.annotationOn, a1)!);
         });
         return found;
     }
@@ -112,6 +112,7 @@ export class Annotation extends ObservableReactComponent<IAnnotationProps> {
     outline = () => (this.linkHighlighted ? 'solid 1px lightBlue' : undefined);
     background = () => (this._props.annoDoc[Highlight] ? 'orange' : StrCast(this._props.annoDoc.backgroundColor));
     render() {
+        // eslint-disable-next-line @typescript-eslint/no-unused-vars
         const forceRenderHack = [this.background(), this.outline(), this.opacity()]; // forces a re-render when these change -- because RegionAnnotation doesn't do this internally..
         return (
             <div style={{ display: this._props.annoDoc.textCopied && !Doc.GetBrushHighlightStatus(this._props.annoDoc) ? 'none' : undefined }}>
@@ -121,7 +122,7 @@ export class Annotation extends ObservableReactComponent<IAnnotationProps> {
                     .map(([x, y, width, height]) => (
                         <div
                             key={'' + x + y + width + height}
-                            style={{ pointerEvents: this._props.pointerEvents?.() as any }}
+                            style={{ pointerEvents: this._props.pointerEvents?.() as Property.PointerEvents }}
                             onPointerDown={this.onPointerDown}
                             onContextMenu={this.onContextMenu}
                             onPointerEnter={() => {
diff --git a/src/client/views/search/FaceRecognitionHandler.tsx b/src/client/views/search/FaceRecognitionHandler.tsx
index f60eb486e..cb837e3ab 100644
--- a/src/client/views/search/FaceRecognitionHandler.tsx
+++ b/src/client/views/search/FaceRecognitionHandler.tsx
@@ -162,7 +162,7 @@ export class FaceRecognitionHandler {
         });
         uniqueFaceDoc.$face = `Face${faceDocNum}`;
         uniqueFaceDoc.$face_annos = new List<Doc>();
-        Doc.SetContainer(uniqueFaceDoc, Doc.MyFaceCollection);
+        Doc.MyFaceCollection && Doc.SetContainer(uniqueFaceDoc, Doc.MyFaceCollection);
 
         Doc.ActiveDashboard && Doc.AddDocToList(Doc.ActiveDashboard[DocData], 'myUniqueFaces', uniqueFaceDoc);
         return uniqueFaceDoc;
@@ -208,9 +208,9 @@ export class FaceRecognitionHandler {
             setTimeout(() => this.classifyFacesInImage(imgDoc), 1000);
         } else {
             const imgUrl = ImageCast(imgDoc[Doc.LayoutDataKey(imgDoc)]);
-            if (imgUrl && !DocListCast(Doc.MyFaceCollection.examinedFaceDocs).includes(imgDoc[DocData])) {
+            if (imgUrl && !DocListCast(Doc.MyFaceCollection?.examinedFaceDocs).includes(imgDoc[DocData])) {
                 // only examine Docs that have an image and that haven't already been examined.
-                Doc.AddDocToList(Doc.MyFaceCollection, 'examinedFaceDocs', imgDoc[DocData]);
+                Doc.MyFaceCollection && Doc.AddDocToList(Doc.MyFaceCollection, 'examinedFaceDocs', imgDoc[DocData]);
                 FaceRecognitionHandler.loadImage(imgUrl).then(
                     // load image and analyze faces
                     img => faceapi
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 1c17dd369..ba94f0504 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -231,7 +231,7 @@ export class Doc extends RefField {
     public static AddLink: (link: Doc, checkExists?: boolean) => void;
     public static DeleteLink: (link: Doc) => void;
     public static Links: (link: Doc | undefined) => Doc[];
-    public static getOppositeAnchor: (linkDoc: Doc, anchor: Doc) => Doc | undefined;
+    public static getOppositeAnchor: (linkDoc: Doc | undefined, anchor: Doc | undefined) => Doc | undefined;
     // KeyValueBox SetField (defined there)
     public static SetField: (doc: Doc, key: string, value: string, forceOnDelegate?: boolean, setResult?: (value: FieldResult) => void) => boolean;
     // UserDoc "API"
diff --git a/src/fields/Types.ts b/src/fields/Types.ts
index e6755f828..ba2e9bb6f 100644
--- a/src/fields/Types.ts
+++ b/src/fields/Types.ts
@@ -1,5 +1,6 @@
 import { DateField } from './DateField';
 import { Doc, FieldType, FieldResult, Opt } from './Doc';
+import { InkField } from './InkField';
 import { List } from './List';
 import { ProxyField } from './Proxy';
 import { RefField } from './RefField';
@@ -99,6 +100,7 @@ export function VideoCast (field: FieldResult, defaultVal: VideoField | null = n
 export function AudioCast (field: FieldResult, defaultVal: AudioField | null = null)   { return Cast(field, AudioField, defaultVal); } // prettier-ignore
 export function PDFCast   (field: FieldResult, defaultVal: PdfField | null = null)     { return Cast(field, PdfField, defaultVal); } // prettier-ignore
 export function ImageCast (field: FieldResult, defaultVal: ImageField | null = null)   { return Cast(field, ImageField, defaultVal); } // prettier-ignore
+export function InkCast   (field: FieldResult, defaultVal: InkField | null = null)     { return Cast(field, InkField, defaultVal); } // prettier-ignore
 
 export function ImageCastToNameType(field: FieldResult, defaultVal: ImageField | null = null) {
     const href = ImageCast(field, defaultVal)?.url.href;
-- 
cgit v1.2.3-70-g09d2

