diff --git a/eslint.config.js b/eslint.config.js index c3b20b0..01d423c 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -22,6 +22,7 @@ export default [ { rules: { "react/react-in-jsx-scope": "off", + "react/no-unknown-property": "off", }, }, ] diff --git a/src/components/ContextMenuPortal.tsx b/src/components/ContextMenuPortal.tsx index e57278a..d0777bd 100644 --- a/src/components/ContextMenuPortal.tsx +++ b/src/components/ContextMenuPortal.tsx @@ -1,14 +1,12 @@ -import { useClickOutside, useKeyStroke, useMouse } from "@kaioken-core/hooks"; +import { useClickOutside, useMouse } from "@kaioken-core/hooks"; import { Portal, signal, useEffect, useRef } from "kaioken"; -namespace ContextMenuPortal { - export interface Props { - children: JSX.Children - open: boolean - closeAction: (() => void) | null | undefined - } +interface ContextMenuPortalProps { + children: JSX.Children + open: boolean + closeAction: (() => void) | null | undefined } -export function ContextMenuPortal({ children, open, closeAction }: ContextMenuPortal.Props) { +export function ContextMenuPortal({ children, open, closeAction }: ContextMenuPortalProps) { const { mouse } = useMouse() const pos = signal({ x: 0, y: 0 }) const ref = useRef(null) diff --git a/src/components/ImageCard.tsx b/src/components/ImageCard.tsx index a1fda18..35f127d 100644 --- a/src/components/ImageCard.tsx +++ b/src/components/ImageCard.tsx @@ -6,15 +6,14 @@ import images, { ImageCardType } from "../signals/images" import { updateLocalStorage } from "../utils/localStorage" import { useThemeDetector } from "../utils/useThemeDetector" import { ContextMenuPortal } from "./ContextMenuPortal" +import { CardTypes } from "../types" -namespace ImageCard { - export interface ImageCardProps { - key: ImageCardType['id'] - data: ImageCardType - } +interface ImageCardProps { + key: ImageCardType['id'] + data: ImageCardType } -export function ImageCard({ key: itemKey, data: item }: ImageCard.ImageCardProps) { +export function ImageCard({ key: itemKey, data: item }: ImageCardProps) { const { debounce } = useDebounce() const pressed = signal(false) const newX = useRef(0) @@ -27,7 +26,7 @@ export function ImageCard({ key: itemKey, data: item }: ImageCard.ImageCardProps function debounceLSUpdate(time?: number) { debounce(() => { - updateLocalStorage("images", images.images).notify() + updateLocalStorage(CardTypes.IMAGES, images.images).notify() }, time) } @@ -90,7 +89,7 @@ export function ImageCard({ key: itemKey, data: item }: ImageCard.ImageCardProps window.removeEventListener('mouseup', _handleResizeMouseUp) } - function _handleClose(_e: Event) { + function _handleClose() { ImagesSignal.default.removeImage(item.id) ImagesSignal.default.images.notify() debounceLSUpdate() @@ -161,7 +160,7 @@ export function ImageCard({ key: itemKey, data: item }: ImageCard.ImageCardProps function ExpandIcon({ cb }: { - cb: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null | undefined + cb: ((this: GlobalEventHandlers, ev: MouseEvent) => void) | null | undefined }) { const isDarkTheme = useThemeDetector() return ( diff --git a/src/components/InfinateCanvas.tsx b/src/components/InfinateCanvas.tsx index 39fef0b..e22d97c 100644 --- a/src/components/InfinateCanvas.tsx +++ b/src/components/InfinateCanvas.tsx @@ -110,7 +110,7 @@ function getInitialPosition(canvasDimensions: typeof canvasDimentsion): ScrollTo try { initPosition = JSON.parse(localStorage.getItem("pos") ?? "") } catch (e) { - console.error("no local storage for pos") + console.error("no local storage for pos " + e) } if (!initPosition) return defaultScroll diff --git a/src/components/MarkDownEditor/MarkDownEditor.tsx b/src/components/MarkDownEditor/MarkDownEditor.tsx index ddb4568..7d804e7 100644 --- a/src/components/MarkDownEditor/MarkDownEditor.tsx +++ b/src/components/MarkDownEditor/MarkDownEditor.tsx @@ -2,14 +2,12 @@ import { Editor, Listener } from 'tiny-markdown-editor' import './md.css' import { useEffect, useRef } from "kaioken" -namespace MarkDownEditor { - export interface Props { - initial: string - onChange: Listener<'change'> - } +interface MarkDownEditorProps { + initial: string + onChange: Listener<'change'> } -export function MarkDownEditor({ initial, onChange }: MarkDownEditor.Props) { +export function MarkDownEditor({ initial, onChange }: MarkDownEditorProps) { const elRef = useRef(null) useEffect(() => { diff --git a/src/components/MiniMap.tsx b/src/components/MiniMap.tsx index c9c60bc..535c489 100644 --- a/src/components/MiniMap.tsx +++ b/src/components/MiniMap.tsx @@ -24,7 +24,7 @@ export function MiniMap() { useEffect(() => { - function _handleScroll(_e: Event) { + function _handleScroll() { scrollX.value = window.scrollX scrollY.value = window.scrollY } @@ -47,7 +47,7 @@ export function MiniMap() { const image = images.images.value[imageKey] const el = useRef(null) - function _handleItemClick(_e: MouseEvent) { + function _handleItemClick() { const newLeft = image.position.x - ((viewportWidth / 2) - (image.dimensions.w / 2)) const newTop = image.position.y - ((viewportHeight / 2) - (image.dimensions.h / 2)) @@ -65,7 +65,7 @@ export function MiniMap() { const newZIndex = LayerEnum.MINIMAP + 1 return ( -
{ const note = notes.notes.value[noteKey] - function _handleItemClick(_e: MouseEvent) { + function _handleItemClick() { const newLeft = note.position.x - ((viewportWidth / 2) - (note.dimensions.w / 2)) const newTop = note.position.y - ((viewportHeight / 2) - (note.dimensions.h / 2)) window.scrollTo({ @@ -99,7 +99,7 @@ export function MiniMap() { const newZIndex = LayerEnum.MINIMAP + 1 return ( -
any) | null | undefined + cb: ((this: GlobalEventHandlers, ev: MouseEvent) => void) | null | undefined }) { const isDarkTheme = useThemeDetector() diff --git a/src/components/TextItem.tsx b/src/components/TextItem.tsx index a7078d4..f524347 100644 --- a/src/components/TextItem.tsx +++ b/src/components/TextItem.tsx @@ -3,17 +3,15 @@ import { TextSignal, focusedItem } from "../signals" import { useDebounce } from "../utils/useDebounce" import texts, { TextCardType } from "../signals/texts" import { LayerEnum } from "../utils/enums" -import { Card } from "../types" +import { Card, CardTypes } from "../types" import { useThemeDetector } from "../utils/useThemeDetector" -namespace TextItem { - export interface TextCardProps { - key: TextCardType['id'] - data: TextCardType - } +interface TextCardProps { + key: TextCardType['id'] + data: TextCardType } -export function TextItem({ key: itemKey, data: item }: TextItem.TextCardProps) { +export function TextItem({ key: itemKey, data: item }: TextCardProps) { const { debounce } = useDebounce() const pressed = signal(false) const newX = useRef(0) @@ -28,7 +26,7 @@ export function TextItem({ key: itemKey, data: item }: TextItem.TextCardProps) { const elDems = elRef.current?.getBoundingClientRect() const elW = elDems?.width ?? 100 const elH = elDems?.height ?? 100 - const newDems: Card<'texts'>['dimensions'] = { w: elW, h: elH } + const newDems: Card['dimensions'] = { w: elW, h: elH } TextSignal.default.updateTextProperty(itemKey, 'dimensions', newDems) TextSignal.default.texts.notify() }, [elRef.current, item.fontSize]) @@ -37,7 +35,7 @@ export function TextItem({ key: itemKey, data: item }: TextItem.TextCardProps) { function updateLocalStorage(time?: number) { debounce(() => { - localStorage.setItem("texts", JSON.stringify(texts.texts.value)) + localStorage.setItem(CardTypes.TEXTS, JSON.stringify(texts.texts.value)) }, time) } @@ -87,7 +85,7 @@ export function TextItem({ key: itemKey, data: item }: TextItem.TextCardProps) { window.addEventListener('mouseup', _handleResizeMouseUp) } - function _handleResizeMouseUp(_e: MouseEvent) { + function _handleResizeMouseUp() { pressed.value = false window.removeEventListener('mousemove', _handleResizeMove) window.removeEventListener('mouseup', _handleResizeMouseUp) @@ -157,7 +155,7 @@ export function TextItem({ key: itemKey, data: item }: TextItem.TextCardProps) { >

@@ -171,13 +169,12 @@ export function TextItem({ key: itemKey, data: item }: TextItem.TextCardProps) { ) } -namespace CloseIcon { - export interface Props { - cb: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null | undefined, - item: TextSignal.TextCardType - } +interface CloseIconProps { + cb: ((this: GlobalEventHandlers, ev: MouseEvent) => void) | null | undefined, + item: TextSignal.TextCardType } -function CloseIcon({ item, cb }: CloseIcon.Props) { + +function CloseIcon({ item, cb }: CloseIconProps) { const isDark = useThemeDetector() return ( any) | null | undefined, - item: TextSignal.TextCardType - } +interface ExpandIconProps { + cb: ((this: GlobalEventHandlers, ev: MouseEvent) => void) | null | undefined, + item: TextSignal.TextCardType } -function ExpandIcon({ cb, item }: ExpandIcon.Props) { + +function ExpandIcon({ cb, item }: ExpandIconProps) { const isDark = useThemeDetector() return ( void -}>(null as any) +}>({ showToast: noop }) export const useToast = () => useContext(ToastContext) -export const ToastContextProvider: Kaioken.FC = ({ children }) => { +interface ToastProviderProps { + children: JSX.Children +} + +export function ToastContextProvider({ children }: ToastProviderProps) { const [toasts, setToasts] = useState([]) useEffect(() => { diff --git a/src/components/cardSelector/ImageCardButton.tsx b/src/components/cardSelector/ImageCardButton.tsx index be6ae0a..300a887 100644 --- a/src/components/cardSelector/ImageCardButton.tsx +++ b/src/components/cardSelector/ImageCardButton.tsx @@ -1,5 +1,6 @@ import { ImagesSignal } from "../../signals" import images from "../../signals/images" +import { CardTypes } from "../../types" import { updateLocalStorage } from "../../utils/localStorage" import { useToast } from "../Toast" import { Tooltip } from "./Tooltip" @@ -13,12 +14,16 @@ export function ImageCardButton() { input.accept = "image/*" input.multiple = false - input.onchange = (e: any) => { - const file = e.target.files[0] + input.onchange = (e: Event) => { + const el = e.target as HTMLInputElement + if (!el.files?.length) return + if (!el.files.length) return + const file = el.files[0] + const reader = new FileReader() reader.readAsDataURL(file) reader.onload = function(readerEvent) { - let image = document.createElement('img') + const image = document.createElement('img') image.onload = function() { const { width, height } = image @@ -33,7 +38,7 @@ export function ImageCardButton() { if (!img) return const imgId = ImagesSignal.default.addImage({ - type: "image", + type: CardTypes.IMAGES, title: "New Image", contents: content as string, position: { @@ -47,7 +52,7 @@ export function ImageCardButton() { }) try { - updateLocalStorage("images", images.images).notify() + updateLocalStorage(CardTypes.IMAGES, images.images).notify() } catch (e: unknown) { if (e instanceof DOMException) { if (e.name !== 'QuotaExceededError') return diff --git a/src/components/cardSelector/ImportButton.tsx b/src/components/cardSelector/ImportButton.tsx index b2ab086..025a5f0 100644 --- a/src/components/cardSelector/ImportButton.tsx +++ b/src/components/cardSelector/ImportButton.tsx @@ -20,8 +20,12 @@ export function ImportButton() { input.type = 'file' input.accept = ".json" input.multiple = false - input.onchange = (e: any) => { - const file = e.target.files[0] + input.onchange = (e: Event) => { + if (e.target === null) return + const el = e.target as HTMLInputElement + if (!el.files?.length) return + const file = el.files[0] + const reader = new FileReader() reader.readAsDataURL(file) reader.onload = function(readerEvent) { @@ -30,19 +34,19 @@ export function ImportButton() { content = (content as string).split(',')[1] const data: Record> = convertBase64ToJson(content) console.log(data) - for (let key in data) { + for (const key in data) { const item = data[key] const { id, ...rest } = item console.log(id, rest) switch (item.type) { - case CardTypes: + case CardTypes.IMAGES: console.log("adding image: ", rest) images.addImage(rest as ImageCardType) break; - case 'notes': + case CardTypes.NOTES: notes.addNote(rest as NoteCardType) break; - case 'texts': + case CardTypes.TEXTS: texts.addText(rest as TextCardType) break; default: @@ -52,9 +56,9 @@ export function ImportButton() { console.log("images: ", images.images.value) - updateLocalStorage('notes', notes.notes).notify() - updateLocalStorage('images', images.images).notify() - updateLocalStorage('texts', texts.texts).notify() + updateLocalStorage(CardTypes.NOTES, notes.notes).notify() + updateLocalStorage(CardTypes.IMAGES, images.images).notify() + updateLocalStorage(CardTypes.TEXTS, texts.texts).notify() } } input.click() diff --git a/src/components/icons/ExportIcon.tsx b/src/components/icons/ExportIcon.tsx index 6766f5e..6efceea 100644 --- a/src/components/icons/ExportIcon.tsx +++ b/src/components/icons/ExportIcon.tsx @@ -1,9 +1,8 @@ -namespace ExportIcon { - export interface Props { - className?: string - } +interface ExportIconProps { + className?: string } -export function ExportIcon({ className }: ExportIcon.Props) { + +export function ExportIcon({ className }: ExportIconProps) { return ( void - onMouseOut?: () => void - } +interface HelpIconProps { + onMouseOver?: () => void + onMouseOut?: () => void } -export function HelpIcon({ onMouseOver, onMouseOut }: HelpIcon.Props) { + +export function HelpIcon({ onMouseOver, onMouseOut }: HelpIconProps) { return ( +export type ImageCardType = Card const images = signal>({}) diff --git a/src/signals/notes.ts b/src/signals/notes.ts index 71be04a..39099b6 100644 --- a/src/signals/notes.ts +++ b/src/signals/notes.ts @@ -1,8 +1,8 @@ import { signal } from "kaioken" -import { Card } from "../types" +import { Card, CardTypes } from "../types" import { focusedItem } from "." -export type NoteCardType = Card<"notes"> +export type NoteCardType = Card const notes = signal>({}) diff --git a/src/signals/texts.ts b/src/signals/texts.ts index e56eb60..7939891 100644 --- a/src/signals/texts.ts +++ b/src/signals/texts.ts @@ -1,8 +1,8 @@ import { signal } from "kaioken" -import { Card } from "../types" +import { Card, CardTypes } from "../types" import { focusedItem } from "." -export type TextCardType = Card<"texts"> & { +export type TextCardType = Card & { fontSize: number } diff --git a/src/types/Card.ts b/src/types/Card.ts index 660253a..189037f 100644 --- a/src/types/Card.ts +++ b/src/types/Card.ts @@ -9,11 +9,11 @@ export enum CardTypes { type Base64 = string -export interface Card { +export interface Card { id: string - type: Ttype + type: TCard title: string - contents: Ttype extends "image" ? Base64 : string + contents: TCard extends "image" ? Base64 : string position: positionCoords dimensions: dimensionCoords } diff --git a/src/utils/localStorage.ts b/src/utils/localStorage.ts index 26d064a..96fef02 100644 --- a/src/utils/localStorage.ts +++ b/src/utils/localStorage.ts @@ -8,9 +8,8 @@ export function updateLocalStorage( try { localStorage.setItem(location, JSON.stringify(collection.value)) } catch (e) { - // throw new Error("Could not update local storage") throw new DOMException( - "Could not update local storage", + "Could not update local storage " + e, "LocalStorageError" ) } diff --git a/src/utils/useDebounce.ts b/src/utils/useDebounce.ts index 35b6ec6..b7b3138 100644 --- a/src/utils/useDebounce.ts +++ b/src/utils/useDebounce.ts @@ -2,12 +2,12 @@ import { sideEffectsEnabled, useHook } from "kaioken" import { noop } from "kaioken/utils" type UseDebounceState = { - timer: number - debounce: (this: any, func: Function, timeout?: number) => void + timer: Timer | undefined + debounce: (func: (...args: unknown[]) => void, timeout?: number) => void } function createState(): UseDebounceState { - return { timer: 0, debounce: noop } + return { timer: undefined, debounce: noop } } export function useDebounce() { @@ -17,8 +17,7 @@ export function useDebounce() { if (!isInit) return { timer: hook.timer, debounce: hook.debounce } hook.debounce = function debounce( - this: any, - func: Function, + func: (...args: unknown[]) => void, timeout = 300 ) { clearTimeout(hook.timer)