generated from Klectr/KTemplate
abstract card selector components and add export functionality
This commit is contained in:
parent
2f185fcd60
commit
5c5740bc73
@ -1,11 +1,11 @@
|
||||
import { useRef, useEffect } from "kaioken"
|
||||
import { CardSelector } from "./CardSelector"
|
||||
import { ImagesSignal, NotesSigal, canvasDimentsion } from "../signals"
|
||||
import { NoteCard } from "./NoteCard"
|
||||
import notes from "../signals/notes"
|
||||
import { MiniMap } from "./MiniMap"
|
||||
import { ImageCard } from "./ImageCard"
|
||||
import images from "../signals/images"
|
||||
import { CardSelector } from "./cardSelector/CardSelector"
|
||||
|
||||
export default function InfiniteCanvas() {
|
||||
const containerRef = useRef<HTMLDivElement>(null)
|
||||
|
39
src/components/cardSelector/CardSelector.tsx
Normal file
39
src/components/cardSelector/CardSelector.tsx
Normal file
@ -0,0 +1,39 @@
|
||||
import { useRef } from "kaioken"
|
||||
import { StickyNoteButton } from "./StickyNoteButton"
|
||||
import { ImageCardButton } from "./ImageCardButton"
|
||||
import { ExportButton } from "./ExportButton"
|
||||
|
||||
export function CardSelector() {
|
||||
const containerRef = useRef<HTMLDivElement>(null)
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={containerRef}
|
||||
className="z-50 flex gap-1 border border-[#9c9c9c] rounded-full fixed px-4 bg-[#181818] top-2 py-1 shadow-xl"
|
||||
style={{
|
||||
left: `${window.innerWidth / 2 - (containerRef.current?.getBoundingClientRect().width ?? 1) / 2}px`
|
||||
}}>
|
||||
<StickyNoteButton />
|
||||
<ImageCardButton />
|
||||
<Divider />
|
||||
<ExportButton />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function Divider() {
|
||||
return (
|
||||
<div style={{
|
||||
margin: '2px 2px',
|
||||
border: "1px solid #9c9c9c",
|
||||
borderRight: 'none',
|
||||
borderLeft: 'none',
|
||||
}}></div>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
46
src/components/cardSelector/ExportButton.tsx
Normal file
46
src/components/cardSelector/ExportButton.tsx
Normal file
@ -0,0 +1,46 @@
|
||||
import { ImagesSignal, NotesSigal } from "../../signals"
|
||||
|
||||
export function ExportButton() {
|
||||
|
||||
function _handleExport() {
|
||||
const { notes } = NotesSigal.default
|
||||
const { images } = ImagesSignal.default
|
||||
|
||||
const mergeState = {
|
||||
...notes.value,
|
||||
...images.value
|
||||
}
|
||||
const date = new Date().toDateString().split(' ').join('_')
|
||||
const name = `Kslab_export_${date}.json`
|
||||
const jsonData = JSON.stringify(mergeState)
|
||||
const file = new File([jsonData], name, {
|
||||
type: 'text/json'
|
||||
})
|
||||
const url = URL.createObjectURL(file)
|
||||
const a = document.createElement('a')
|
||||
a.download = name
|
||||
a.href = url
|
||||
a.click()
|
||||
}
|
||||
|
||||
return (
|
||||
<svg
|
||||
onclick={_handleExport}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
className="cursor-pointer w-5 h-5 text-[#9c9c9c] hover:text-blue-500 transition-color duration-300"
|
||||
>
|
||||
<path
|
||||
d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
|
||||
<polyline points="7 10 12 15 17 10" />
|
||||
<line x1="12" x2="12" y1="15" y2="3" />
|
||||
</svg>
|
||||
)
|
||||
}
|
@ -1,67 +1,8 @@
|
||||
import { useRef } from "kaioken"
|
||||
import { ImagesSignal, NotesSigal } from "../signals"
|
||||
import { updateLocalStorage } from "../utils/localStorage"
|
||||
import notes from "../signals/notes"
|
||||
import images from "../signals/images"
|
||||
import { ImagesSignal } from "../../signals"
|
||||
import images from "../../signals/images"
|
||||
import { updateLocalStorage } from "../../utils/localStorage"
|
||||
|
||||
export function CardSelector() {
|
||||
const containerRef = useRef<HTMLDivElement>(null)
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={containerRef}
|
||||
className="z-50 flex gap-1 border border-[#9c9c9c] rounded-full fixed px-4 bg-[#181818] top-2 py-1 shadow-xl"
|
||||
style={{
|
||||
left: `${window.innerWidth / 2 - (containerRef.current?.getBoundingClientRect().width ?? 1) / 2}px`
|
||||
}}>
|
||||
<StickyNote />
|
||||
<Image />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function StickyNote() {
|
||||
function _handleClick(e: MouseEvent) {
|
||||
NotesSigal.default.addNote({
|
||||
type: "note",
|
||||
title: "New Note",
|
||||
contents: "",
|
||||
position: {
|
||||
x: e.pageX - 100,
|
||||
y: e.pageY + (window.innerHeight / 2) - 100
|
||||
},
|
||||
dimensions: {
|
||||
w: 200,
|
||||
h: 200
|
||||
}
|
||||
})
|
||||
updateLocalStorage("notes", notes.notes.value)
|
||||
}
|
||||
|
||||
return (
|
||||
<button onclick={_handleClick} className="cursor-pointer">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
className="w-5 h-5 text-[#9c9c9c] hover:text-[#ccc] transition-color duration-300">
|
||||
<path
|
||||
d="M16 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V8Z" />
|
||||
<path
|
||||
d="M15 3v4a2 2 0 0 0 2 2h4" />
|
||||
</svg>
|
||||
</button>
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
function Image() {
|
||||
export function ImageCardButton() {
|
||||
function _handleClick(mouseEvent: MouseEvent) {
|
||||
const input = document.createElement('input')
|
||||
input.type = 'file'
|
||||
@ -117,7 +58,7 @@ function Image() {
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
className="w-5 h-5 text-[#9c9c9c] hover:text-[#ccc] transition-color duration-300">
|
||||
className="w-5 h-5 text-[#9c9c9c] hover:text-blue-500 transition-color duration-300">
|
||||
<rect
|
||||
width="18"
|
||||
height="18"
|
||||
@ -135,5 +76,3 @@ function Image() {
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
|
44
src/components/cardSelector/StickyNoteButton.tsx
Normal file
44
src/components/cardSelector/StickyNoteButton.tsx
Normal file
@ -0,0 +1,44 @@
|
||||
import { NotesSigal } from "../../signals"
|
||||
import notes from "../../signals/notes"
|
||||
import { updateLocalStorage } from "../../utils/localStorage"
|
||||
|
||||
export function StickyNoteButton() {
|
||||
function _handleClick(e: MouseEvent) {
|
||||
NotesSigal.default.addNote({
|
||||
type: "note",
|
||||
title: "New Note",
|
||||
contents: "",
|
||||
position: {
|
||||
x: e.pageX - 100,
|
||||
y: e.pageY + (window.innerHeight / 2) - 100
|
||||
},
|
||||
dimensions: {
|
||||
w: 200,
|
||||
h: 200
|
||||
}
|
||||
})
|
||||
updateLocalStorage("notes", notes.notes.value)
|
||||
}
|
||||
|
||||
return (
|
||||
<button onclick={_handleClick} className="cursor-pointer">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
className="w-5 h-5 text-[#9c9c9c] hover:text-blue-500 transition-color duration-300">
|
||||
<path
|
||||
d="M16 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V8Z" />
|
||||
<path
|
||||
d="M15 3v4a2 2 0 0 0 2 2h4" />
|
||||
</svg>
|
||||
</button>
|
||||
)
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user