diff --git a/babel.config.js b/babel.config.js
new file mode 100644
index 000000000..e1c4074c4
--- /dev/null
+++ b/babel.config.js
@@ -0,0 +1,3 @@
+module.exports = {
+ babelrcRoots: ['.', './packages/*'],
+}
diff --git a/packages/desktop/.eslintrc b/packages/desktop/.eslintrc
index 2734a4925..7ae62d57f 100644
--- a/packages/desktop/.eslintrc
+++ b/packages/desktop/.eslintrc
@@ -11,7 +11,7 @@
"../../node_modules/@standardnotes/config/src/.eslintrc"
],
"parser": "@typescript-eslint/parser",
- "ignorePatterns": ["test", "scripts", ".eslintrc", "tsconfig.json", "node_modules"],
+ "ignorePatterns": ["test", "scripts", ".eslintrc", "tsconfig.json", "node_modules", "*.webpack.*.js"],
"rules": {
/** Style */
"quotes": ["error", "single", { "avoidEscape": true }],
diff --git a/packages/toast/.eslintignore b/packages/toast/.eslintignore
new file mode 100644
index 000000000..f06235c46
--- /dev/null
+++ b/packages/toast/.eslintignore
@@ -0,0 +1,2 @@
+node_modules
+dist
diff --git a/packages/toast/.eslintrc b/packages/toast/.eslintrc
new file mode 100644
index 000000000..7d6d24814
--- /dev/null
+++ b/packages/toast/.eslintrc
@@ -0,0 +1,3 @@
+{
+ "extends": ["../../node_modules/@standardnotes/config/src/.eslintrc"]
+}
diff --git a/packages/toast/.gitignore b/packages/toast/.gitignore
new file mode 100644
index 000000000..53c37a166
--- /dev/null
+++ b/packages/toast/.gitignore
@@ -0,0 +1 @@
+dist
\ No newline at end of file
diff --git a/packages/toast/linter.tsconfig.json b/packages/toast/linter.tsconfig.json
new file mode 100644
index 000000000..ab3d8c031
--- /dev/null
+++ b/packages/toast/linter.tsconfig.json
@@ -0,0 +1,3 @@
+{
+ "extends": "../../node_modules/@standardnotes/config/src/linter.tsconfig.json"
+}
diff --git a/packages/toast/package.json b/packages/toast/package.json
new file mode 100644
index 000000000..419d32ae0
--- /dev/null
+++ b/packages/toast/package.json
@@ -0,0 +1,32 @@
+{
+ "name": "@standardnotes/toast",
+ "version": "1.0.0",
+ "main": "dist/index.js",
+ "types": "dist/index.d.ts",
+ "publishConfig": {
+ "access": "public"
+ },
+ "scripts": {
+ "build": "yarn run tsc",
+ "clean": "rm -fr dist",
+ "prestart": "yarn clean",
+ "start": "tsc -p tsconfig.json --watch",
+ "prebuild": "yarn clean",
+ "lint": "eslint ./src"
+ },
+ "dependencies": {
+ "@nanostores/react": "^0.2.0",
+ "@standardnotes/config": "^2.4.3",
+ "@standardnotes/icons": "^1.1.7",
+ "nanoid": "^3.3.4",
+ "nanostores": "^0.5.12"
+ },
+ "devDependencies": {
+ "@babel/preset-env": "^7.18.0",
+ "@babel/preset-react": "^7.17.12",
+ "@babel/preset-typescript": "^7.17.12"
+ },
+ "peerDependencies": {
+ "react": "17"
+ }
+}
diff --git a/packages/toast/src/Toast.tsx b/packages/toast/src/Toast.tsx
new file mode 100644
index 000000000..7a4a9f340
--- /dev/null
+++ b/packages/toast/src/Toast.tsx
@@ -0,0 +1,133 @@
+import type { Toast as ToastPropType } from './types'
+import { CheckCircleFilledIcon, ClearCircleFilledIcon } from '@standardnotes/icons'
+import { dismissToast } from './toastStore'
+import { ToastType } from './enums'
+import { ForwardedRef, forwardRef, RefObject, useEffect } from 'react'
+
+const prefersReducedMotion = () => {
+ const mediaQuery = matchMedia('(prefers-reduced-motion: reduce)')
+ return mediaQuery.matches
+}
+
+const colorForToastType = (type: ToastType) => {
+ switch (type) {
+ case ToastType.Success:
+ return 'color-success'
+ case ToastType.Error:
+ return 'color-danger'
+ default:
+ return 'color-info'
+ }
+}
+
+const iconForToastType = (type: ToastType) => {
+ switch (type) {
+ case ToastType.Success:
+ return
+ case ToastType.Error:
+ return
+ case ToastType.Progress:
+ case ToastType.Loading:
+ return
+ default:
+ return null
+ }
+}
+
+type Props = {
+ toast: ToastPropType
+ index: number
+}
+
+export const Toast = forwardRef(({ toast, index }: Props, ref: ForwardedRef) => {
+ const icon = iconForToastType(toast.type)
+ const hasActions = toast.actions && toast.actions.length > 0
+ const hasProgress = toast.type === ToastType.Progress && toast.progress !== undefined && toast.progress > -1
+
+ const shouldReduceMotion = prefersReducedMotion()
+ const enterAnimation = shouldReduceMotion ? 'fade-in-animation' : 'slide-in-right-animation'
+ const exitAnimation = shouldReduceMotion ? 'fade-out-animation' : 'slide-out-left-animation'
+ const currentAnimation = toast.dismissed ? exitAnimation : enterAnimation
+
+ useEffect(() => {
+ if (!ref) {
+ return
+ }
+
+ const element = (ref as RefObject).current
+
+ if (element && toast.dismissed) {
+ const { scrollHeight, style } = element
+
+ requestAnimationFrame(() => {
+ style.minHeight = 'initial'
+ style.height = scrollHeight + 'px'
+ style.transition = 'all 200ms'
+
+ requestAnimationFrame(() => {
+ style.height = '0'
+ style.padding = '0'
+ style.margin = '0'
+ })
+ })
+ }
+ }, [ref, toast.dismissed])
+
+ return (
+ {
+ if (!hasActions && toast.type !== ToastType.Loading && toast.type !== ToastType.Progress) {
+ dismissToast(toast.id)
+ }
+ }}
+ ref={ref}
+ >
+
+ {icon ?
{icon}
: null}
+
{toast.message}
+ {hasActions && (
+
+ {toast.actions?.map((action, index) => (
+
+ ))}
+
+ )}
+
+ {hasProgress && (
+
+ )}
+
+ )
+})
diff --git a/packages/toast/src/ToastContainer.tsx b/packages/toast/src/ToastContainer.tsx
new file mode 100644
index 000000000..e460cab38
--- /dev/null
+++ b/packages/toast/src/ToastContainer.tsx
@@ -0,0 +1,20 @@
+import { FunctionComponent } from 'react'
+import { useStore } from '@nanostores/react'
+import { toastStore } from './toastStore'
+import { ToastTimer } from './ToastTimer'
+
+export const ToastContainer: FunctionComponent = () => {
+ const toasts = useStore(toastStore)
+
+ if (!toasts.length) {
+ return null
+ }
+
+ return (
+
+ {toasts.map((toast, index) => (
+
+ ))}
+
+ )
+}
diff --git a/packages/toast/src/ToastTimer.tsx b/packages/toast/src/ToastTimer.tsx
new file mode 100644
index 000000000..e92c7b92b
--- /dev/null
+++ b/packages/toast/src/ToastTimer.tsx
@@ -0,0 +1,115 @@
+import { useCallback, useEffect, useRef, FunctionComponent } from 'react'
+import { Toast } from './Toast'
+import { Toast as ToastPropType } from './types'
+import { ToastType } from './enums'
+import { dismissToast } from './toastStore'
+
+type Props = {
+ toast: ToastPropType
+ index: number
+}
+
+const getDefaultForAutoClose = (hasActions: boolean, type: ToastType) => {
+ return !hasActions && ![ToastType.Loading, ToastType.Progress].includes(type)
+}
+
+const getDefaultToastDuration = (type: ToastType) => (type === ToastType.Error ? 8000 : 4000)
+
+export const ToastTimer: FunctionComponent = ({ toast, index }) => {
+ const toastElementRef = useRef(null)
+ const toastTimerIdRef = useRef()
+
+ const hasActions = Boolean(toast.actions?.length)
+ const shouldAutoClose = toast.autoClose ?? getDefaultForAutoClose(hasActions, toast.type)
+ const duration = toast.duration ?? getDefaultToastDuration(toast.type)
+
+ const startTimeRef = useRef(duration)
+ const remainingTimeRef = useRef(duration)
+
+ const dismissToastOnEnd = useCallback(() => {
+ dismissToast(toast.id)
+ }, [toast.id])
+
+ const clearTimer = useCallback(() => {
+ if (toastTimerIdRef.current) {
+ clearTimeout(toastTimerIdRef.current)
+ }
+ }, [])
+
+ const pauseTimer = useCallback(() => {
+ clearTimer()
+ remainingTimeRef.current -= Date.now() - startTimeRef.current
+ }, [clearTimer])
+
+ const resumeTimer = useCallback(() => {
+ startTimeRef.current = Date.now()
+ clearTimer()
+ toastTimerIdRef.current = window.setTimeout(dismissToastOnEnd, remainingTimeRef.current)
+ }, [clearTimer, dismissToastOnEnd])
+
+ const handleMouseEnter = useCallback(() => {
+ pauseTimer()
+ }, [pauseTimer])
+
+ const handleMouseLeave = useCallback(() => {
+ resumeTimer()
+ }, [resumeTimer])
+
+ const handlePageVisibility = useCallback(() => {
+ if (document.visibilityState === 'hidden') {
+ pauseTimer()
+ } else {
+ resumeTimer()
+ }
+ }, [pauseTimer, resumeTimer])
+
+ const handlePageFocus = useCallback(() => {
+ resumeTimer()
+ }, [resumeTimer])
+
+ const handlePageBlur = useCallback(() => {
+ pauseTimer()
+ }, [pauseTimer])
+
+ useEffect(() => {
+ clearTimer()
+
+ if (shouldAutoClose) {
+ resumeTimer()
+ }
+
+ const toastElement = toastElementRef.current
+ if (toastElement) {
+ toastElement.addEventListener('mouseenter', handleMouseEnter)
+ toastElement.addEventListener('mouseleave', handleMouseLeave)
+ }
+ document.addEventListener('visibilitychange', handlePageVisibility)
+ window.addEventListener('focus', handlePageFocus)
+ window.addEventListener('blur', handlePageBlur)
+
+ return () => {
+ clearTimer()
+ if (toastElement) {
+ toastElement.removeEventListener('mouseenter', handleMouseEnter)
+ toastElement.removeEventListener('mouseleave', handleMouseLeave)
+ }
+ document.removeEventListener('visibilitychange', handlePageVisibility)
+ window.removeEventListener('focus', handlePageFocus)
+ window.removeEventListener('blur', handlePageBlur)
+ }
+ }, [
+ clearTimer,
+ dismissToastOnEnd,
+ duration,
+ handleMouseEnter,
+ handleMouseLeave,
+ handlePageBlur,
+ handlePageFocus,
+ handlePageVisibility,
+ resumeTimer,
+ shouldAutoClose,
+ toast.id,
+ ])
+
+ return
+}
diff --git a/packages/toast/src/addTimedToast.ts b/packages/toast/src/addTimedToast.ts
new file mode 100644
index 000000000..693f1bf5d
--- /dev/null
+++ b/packages/toast/src/addTimedToast.ts
@@ -0,0 +1,35 @@
+import { addToast, dismissToast, updateToast } from './toastStore'
+import { ToastOptions } from './types'
+
+type InitialToastOptions = Omit & {
+ message: (timeRemainingInSeconds: number) => string
+}
+
+export const addTimedToast = (
+ initialOptions: InitialToastOptions,
+ callback: () => void,
+ timeInSeconds: number,
+): [string, number] => {
+ let timeRemainingInSeconds = timeInSeconds
+
+ const intervalId = window.setInterval(() => {
+ timeRemainingInSeconds--
+ if (timeRemainingInSeconds > 0) {
+ updateToast(toastId, {
+ message: initialOptions.message(timeRemainingInSeconds),
+ })
+ } else {
+ dismissToast(toastId)
+ clearInterval(intervalId)
+ callback()
+ }
+ }, 1000)
+
+ const toastId = addToast({
+ ...initialOptions,
+ message: initialOptions.message(timeRemainingInSeconds),
+ autoClose: false,
+ })
+
+ return [toastId, intervalId]
+}
diff --git a/packages/toast/src/enums.ts b/packages/toast/src/enums.ts
new file mode 100644
index 000000000..eed528183
--- /dev/null
+++ b/packages/toast/src/enums.ts
@@ -0,0 +1,7 @@
+export enum ToastType {
+ Regular = 'regular',
+ Success = 'success',
+ Error = 'error',
+ Loading = 'loading',
+ Progress = 'progress',
+}
diff --git a/packages/toast/src/index.ts b/packages/toast/src/index.ts
new file mode 100644
index 000000000..b788bf614
--- /dev/null
+++ b/packages/toast/src/index.ts
@@ -0,0 +1,5 @@
+export { ToastContainer } from './ToastContainer'
+export { addToast, updateToast, dismissToast } from './toastStore'
+export { ToastType } from './enums'
+export { addTimedToast } from './addTimedToast'
+export type { Toast, ToastAction, ToastOptions } from './types'
diff --git a/packages/toast/src/toastStore.ts b/packages/toast/src/toastStore.ts
new file mode 100644
index 000000000..ba676842a
--- /dev/null
+++ b/packages/toast/src/toastStore.ts
@@ -0,0 +1,73 @@
+import { nanoid } from 'nanoid'
+import { action, atom, WritableAtom } from 'nanostores'
+import { Toast, ToastOptions, ToastUpdateOptions } from './types'
+
+export const toastStore = atom([])
+
+export const updateToast = action(
+ toastStore,
+ 'updateToast',
+ (store: WritableAtom, toastId: Toast['id'], options: ToastUpdateOptions) => {
+ const existingToasts = store.get()
+ store.set(
+ existingToasts.map((toast) => {
+ if (toast.id === toastId) {
+ return {
+ ...toast,
+ ...options,
+ }
+ } else {
+ return toast
+ }
+ }),
+ )
+ },
+)
+
+const removeToast = action(toastStore, 'removeToast', (store: WritableAtom, toastId: Toast['id']) => {
+ const existingToasts = store.get()
+ store.set(existingToasts.filter((toast) => toast.id !== toastId))
+})
+
+const DelayBeforeRemovingToast = 175
+
+export const dismissToast = action(toastStore, 'dismissToast', (store: WritableAtom, toastId: Toast['id']) => {
+ const existingToasts = store.get()
+ store.set(
+ existingToasts.map((toast) => {
+ if (toast.id === toastId) {
+ return {
+ ...toast,
+ dismissed: true,
+ }
+ } else {
+ return toast
+ }
+ }),
+ )
+ setTimeout(() => {
+ removeToast(toastId)
+ }, DelayBeforeRemovingToast)
+})
+
+export const addToast = action(toastStore, 'addToast', (store: WritableAtom, options: ToastOptions) => {
+ const existingToasts = store.get()
+ const isToastIdDuplicate = existingToasts.findIndex((toast) => toast.id === options.id) > -1
+
+ const id = options.id && !isToastIdDuplicate ? options.id : nanoid()
+
+ if (isToastIdDuplicate) {
+ console.warn(`Generated new ID for toast instead of overriding toast of ID "${options.id}".
+If you want to update an existing toast, use the \`updateToast()\` function instead.`)
+ }
+
+ const toast = {
+ ...options,
+ id,
+ dismissed: false,
+ }
+
+ store.set([...existingToasts, toast])
+
+ return id
+})
diff --git a/packages/toast/src/types.ts b/packages/toast/src/types.ts
new file mode 100644
index 000000000..363541a53
--- /dev/null
+++ b/packages/toast/src/types.ts
@@ -0,0 +1,30 @@
+import { ToastType } from './enums'
+
+export type ToastAction = {
+ label: string
+ handler: (toastId: Toast['id']) => void
+}
+
+type CommonToastProperties = {
+ type: ToastType
+ message: string
+ actions?: ToastAction[]
+ progress?: number
+ autoClose?: boolean
+ duration?: number
+}
+
+export type Toast = CommonToastProperties & {
+ id: string
+ dismissed: boolean
+}
+
+export type ToastOptions = CommonToastProperties & {
+ id?: string
+}
+
+export type ToastUpdateOptions = Omit, 'id'>
+
+export type ToastState = {
+ toasts: Toast[]
+}
diff --git a/packages/toast/tsconfig.json b/packages/toast/tsconfig.json
new file mode 100644
index 000000000..d45ccebf8
--- /dev/null
+++ b/packages/toast/tsconfig.json
@@ -0,0 +1,13 @@
+{
+ "extends": "../../node_modules/@standardnotes/config/src/tsconfig.json",
+ "compilerOptions": {
+ "baseUrl": ".",
+ "rootDir": "src",
+ "outDir": "dist",
+ "jsx": "react-jsx",
+ "skipLibCheck": true,
+ "module": "es2022"
+ },
+ "include": ["src"],
+ "exclude": ["dist", "node_modules"]
+}
diff --git a/packages/web/.babelrc b/packages/web/.babelrc.json
similarity index 100%
rename from packages/web/.babelrc
rename to packages/web/.babelrc.json
diff --git a/packages/web/.eslintrc b/packages/web/.eslintrc
index 7344f0a1b..0691e2ada 100644
--- a/packages/web/.eslintrc
+++ b/packages/web/.eslintrc
@@ -9,7 +9,7 @@
"../../node_modules/@standardnotes/config/src/.eslintrc"
],
"plugins": ["@typescript-eslint", "react", "react-hooks"],
- "ignorePatterns": [".eslintrc.js", "webpack.*.js", "webpack-defaults.js", "jest.config.js", "__mocks__"],
+ "ignorePatterns": [".eslintrc.js", "*.webpack.*.js", "webpack-defaults.js", "jest.config.js", "__mocks__"],
"rules": {
"standard/no-callback-literal": 0, // Disable this as we have too many callbacks relying on literals
"no-throw-literal": 0,
diff --git a/packages/web/jest.config.js b/packages/web/jest.config.js
index 53a2735e4..786b3ea5d 100644
--- a/packages/web/jest.config.js
+++ b/packages/web/jest.config.js
@@ -1,4 +1,4 @@
-const pathsToModuleNameMapper = require('ts-jest/utils').pathsToModuleNameMapper
+const pathsToModuleNameMapper = require('ts-jest').pathsToModuleNameMapper
const tsConfig = require('./tsconfig.json')
const pathsFromTsconfig = tsConfig.compilerOptions.paths
@@ -12,23 +12,14 @@ module.exports = {
prefix: '',
}),
'\\.(css|less|scss|sass)$': 'identity-obj-proxy',
+ '@standardnotes/toast': 'identity-obj-proxy',
},
globals: {
__WEB_VERSION__: '1.0.0',
- __DESKTOP__: false,
- __WEB__: true,
self: {}, // fixes error happening on `import { SKAlert } from 'sn-stylekit'`
},
transform: {
'^.+\\.(ts|tsx)?$': 'ts-jest',
'\\.svg$': 'svg-jest',
},
- coverageThreshold: {
- global: {
- branches: 3,
- functions: 5,
- lines: 21,
- statements: 22,
- },
- },
}
diff --git a/packages/web/package.json b/packages/web/package.json
index 219a906b4..b343409bb 100644
--- a/packages/web/package.json
+++ b/packages/web/package.json
@@ -73,6 +73,7 @@
"@standardnotes/sncrypto-web": "1.10.1",
"@standardnotes/snjs": "^2.115.6",
"@standardnotes/stylekit": "5.29.3",
+ "@standardnotes/toast": "1.0.0",
"@zip.js/zip.js": "^2.4.10",
"mobx": "^6.5.0",
"mobx-react-lite": "^3.3.0",
diff --git a/packages/web/src/javascripts/Components/ApplicationView/ApplicationView.tsx b/packages/web/src/javascripts/Components/ApplicationView/ApplicationView.tsx
index 558b6bd77..92fc97980 100644
--- a/packages/web/src/javascripts/Components/ApplicationView/ApplicationView.tsx
+++ b/packages/web/src/javascripts/Components/ApplicationView/ApplicationView.tsx
@@ -18,7 +18,7 @@ import RevisionHistoryModalWrapper from '@/Components/RevisionHistoryModal/Revis
import PremiumModalProvider from '@/Hooks/usePremiumModal'
import ConfirmSignoutContainer from '@/Components/ConfirmSignoutModal/ConfirmSignoutModal'
import TagsContextMenuWrapper from '@/Components/Tags/TagContextMenu'
-import { ToastContainer } from '@standardnotes/stylekit'
+import { ToastContainer } from '@standardnotes/toast'
import FilePreviewModalWrapper from '@/Components/FilePreview/FilePreviewModal'
import ContentListView from '@/Components/ContentListView/ContentListView'
import FileContextMenuWrapper from '@/Components/FileContextMenu/FileContextMenu'
diff --git a/packages/web/src/javascripts/Components/AttachedFilesPopover/AttachedFilesButton.tsx b/packages/web/src/javascripts/Components/AttachedFilesPopover/AttachedFilesButton.tsx
index f4a4823f8..533a07cb9 100644
--- a/packages/web/src/javascripts/Components/AttachedFilesPopover/AttachedFilesButton.tsx
+++ b/packages/web/src/javascripts/Components/AttachedFilesPopover/AttachedFilesButton.tsx
@@ -7,7 +7,7 @@ import { FunctionComponent, useCallback, useEffect, useRef, useState } from 'rea
import Icon from '@/Components/Icon/Icon'
import { useCloseOnBlur } from '@/Hooks/useCloseOnBlur'
import { FileItem, SNNote } from '@standardnotes/snjs'
-import { addToast, ToastType } from '@standardnotes/stylekit'
+import { addToast, ToastType } from '@standardnotes/toast'
import { StreamingFileReader } from '@standardnotes/filepicker'
import AttachedFilesPopover from './AttachedFilesPopover'
import { usePremiumModal } from '@/Hooks/usePremiumModal'
diff --git a/packages/web/src/javascripts/Components/NotesOptions/NotesOptions.tsx b/packages/web/src/javascripts/Components/NotesOptions/NotesOptions.tsx
index 5d3de8c5d..a1a7c8b1d 100644
--- a/packages/web/src/javascripts/Components/NotesOptions/NotesOptions.tsx
+++ b/packages/web/src/javascripts/Components/NotesOptions/NotesOptions.tsx
@@ -8,7 +8,7 @@ import ChangeEditorOption from './ChangeEditorOption'
import { BYTES_IN_ONE_MEGABYTE } from '@/Constants/Constants'
import ListedActionsOption from './ListedActionsOption'
import AddTagOption from './AddTagOption'
-import { addToast, dismissToast, ToastType } from '@standardnotes/stylekit'
+import { addToast, dismissToast, ToastType } from '@standardnotes/toast'
import { NotesOptionsProps } from './NotesOptionsProps'
import { NotesController } from '@/Controllers/NotesController'
diff --git a/packages/web/src/javascripts/Controllers/FilesController.ts b/packages/web/src/javascripts/Controllers/FilesController.ts
index 777c0762f..7b19e2951 100644
--- a/packages/web/src/javascripts/Controllers/FilesController.ts
+++ b/packages/web/src/javascripts/Controllers/FilesController.ts
@@ -15,7 +15,7 @@ import {
parseFileName,
} from '@standardnotes/filepicker'
import { ChallengeReason, ClientDisplayableError, ContentType, FileItem, InternalEventBus } from '@standardnotes/snjs'
-import { addToast, dismissToast, ToastType, updateToast } from '@standardnotes/stylekit'
+import { addToast, dismissToast, ToastType, updateToast } from '@standardnotes/toast'
import { action, makeObservable, observable, reaction } from 'mobx'
import { WebApplication } from '../Application/Application'
import { AbstractViewController } from './Abstract/AbstractViewController'
diff --git a/packages/web/src/javascripts/Services/ThemeManager.ts b/packages/web/src/javascripts/Services/ThemeManager.ts
index 204da4f85..4002b64d0 100644
--- a/packages/web/src/javascripts/Services/ThemeManager.ts
+++ b/packages/web/src/javascripts/Services/ThemeManager.ts
@@ -14,7 +14,7 @@ import {
PayloadEmitSource,
LocalStorageDecryptedContextualPayload,
} from '@standardnotes/snjs'
-import { dismissToast, ToastType, addTimedToast } from '@standardnotes/stylekit'
+import { dismissToast, ToastType, addTimedToast } from '@standardnotes/toast'
const CachedThemesKey = 'cachedThemes'
const TimeBeforeApplyingColorScheme = 5
diff --git a/packages/web/web.webpack.dev.js b/packages/web/web.webpack.dev.js
index 7e967390e..870025128 100644
--- a/packages/web/web.webpack.dev.js
+++ b/packages/web/web.webpack.dev.js
@@ -22,7 +22,7 @@ module.exports = (env, argv) => {
],
devServer: {
hot: 'only',
- static: '../../web-server/public',
+ static: '../web-server/public',
port,
devMiddleware: {
writeToDisk: argv.writeToDisk,
diff --git a/yarn.lock b/yarn.lock
index 9c1da3563..50a688c5e 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -731,7 +731,21 @@
dependencies:
"@babel/helper-plugin-utils" "^7.16.7"
-"@babel/plugin-transform-react-jsx@^7.17.3":
+"@babel/plugin-transform-react-display-name@^7.16.7":
+ version "7.16.7"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.16.7.tgz#7b6d40d232f4c0f550ea348593db3b21e2404340"
+ integrity sha512-qgIg8BcZgd0G/Cz916D5+9kqX0c7nPZyXaP8R2tLNN5tkyIZdG5fEwBrxwplzSnjC1jvQmyMNVwUCZPcbGY7Pg==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.16.7"
+
+"@babel/plugin-transform-react-jsx-development@^7.16.7":
+ version "7.16.7"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.16.7.tgz#43a00724a3ed2557ed3f276a01a929e6686ac7b8"
+ integrity sha512-RMvQWvpla+xy6MlBpPlrKZCMRs2AGiHOGHY3xRwl0pEeim348dDyxeH4xBsMPbIMhujeq7ihE702eM2Ew0Wo+A==
+ dependencies:
+ "@babel/plugin-transform-react-jsx" "^7.16.7"
+
+"@babel/plugin-transform-react-jsx@^7.16.7", "@babel/plugin-transform-react-jsx@^7.17.12", "@babel/plugin-transform-react-jsx@^7.17.3":
version "7.17.12"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.17.12.tgz#2aa20022709cd6a3f40b45d60603d5f269586dba"
integrity sha512-Lcaw8bxd1DKht3thfD4A12dqo1X16he1Lm8rIv8sTwjAYNInRS1qHa9aJoqvzpscItXvftKDCfaEQzwoVyXpEQ==
@@ -742,6 +756,14 @@
"@babel/plugin-syntax-jsx" "^7.17.12"
"@babel/types" "^7.17.12"
+"@babel/plugin-transform-react-pure-annotations@^7.16.7":
+ version "7.18.0"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.18.0.tgz#ef82c8e310913f3522462c9ac967d395092f1954"
+ integrity sha512-6+0IK6ouvqDn9bmEG7mEyF/pwlJXVj5lwydybpyyH3D0A7Hftk+NCTdYjnLNZksn261xaOV5ksmp20pQEmc2RQ==
+ dependencies:
+ "@babel/helper-annotate-as-pure" "^7.16.7"
+ "@babel/helper-plugin-utils" "^7.17.12"
+
"@babel/plugin-transform-regenerator@^7.18.0":
version "7.18.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.0.tgz#44274d655eb3f1af3f3a574ba819d3f48caf99d5"
@@ -817,7 +839,7 @@
"@babel/helper-create-regexp-features-plugin" "^7.16.7"
"@babel/helper-plugin-utils" "^7.16.7"
-"@babel/preset-env@^7.16.11", "@babel/preset-env@^7.17.10":
+"@babel/preset-env@^7.16.11", "@babel/preset-env@^7.17.10", "@babel/preset-env@^7.18.0":
version "7.18.2"
resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.18.2.tgz#f47d3000a098617926e674c945d95a28cb90977a"
integrity sha512-PfpdxotV6afmXMU47S08F9ZKIm2bJIQ0YbAAtDfIENX7G1NUAXigLREh69CWDjtgUy7dYn7bsMzkgdtAlmS68Q==
@@ -909,7 +931,19 @@
"@babel/types" "^7.4.4"
esutils "^2.0.2"
-"@babel/preset-typescript@^7.16.7":
+"@babel/preset-react@^7.17.12":
+ version "7.17.12"
+ resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.17.12.tgz#62adbd2d1870c0de3893095757ed5b00b492ab3d"
+ integrity sha512-h5U+rwreXtZaRBEQhW1hOJLMq8XNJBQ/9oymXiCXTuT/0uOwpbT0gUt+sXeOqoXBgNuUKI7TaObVwoEyWkpFgA==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.17.12"
+ "@babel/helper-validator-option" "^7.16.7"
+ "@babel/plugin-transform-react-display-name" "^7.16.7"
+ "@babel/plugin-transform-react-jsx" "^7.17.12"
+ "@babel/plugin-transform-react-jsx-development" "^7.16.7"
+ "@babel/plugin-transform-react-pure-annotations" "^7.16.7"
+
+"@babel/preset-typescript@^7.16.7", "@babel/preset-typescript@^7.17.12":
version "7.17.12"
resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.17.12.tgz#40269e0a0084d56fc5731b6c40febe1c9a4a3e8c"
integrity sha512-S1ViF8W2QwAKUGJXxP9NAfNaqGDdEBJKpYkxHf5Yy2C4NPPzXGeR3Lhk7G8xJaaLcFTRfNjVbtbVtm8Gb0mqvg==
@@ -2837,7 +2871,7 @@
"@standardnotes/services" "^1.13.11"
"@standardnotes/utils" "^1.6.10"
-"@standardnotes/icons@^1.1.8":
+"@standardnotes/icons@^1.1.7", "@standardnotes/icons@^1.1.8":
version "1.1.8"
resolved "https://registry.yarnpkg.com/@standardnotes/icons/-/icons-1.1.8.tgz#958b73cc3dd68c7fe31dcceb8ee48627093ab468"
integrity sha512-RhNzHEbSYFVwVz5+BqDAC5wJZ8DkQlboofwPxuTLSrmezjBeNi9kOw9metoC1Sf82u3bXJr5fgXAC8DEYXYKTg==