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 { useRef, useEffect } from "kaioken"
|
||||||
import { CardSelector } from "./CardSelector"
|
|
||||||
import { ImagesSignal, NotesSigal, canvasDimentsion } from "../signals"
|
import { ImagesSignal, NotesSigal, canvasDimentsion } from "../signals"
|
||||||
import { NoteCard } from "./NoteCard"
|
import { NoteCard } from "./NoteCard"
|
||||||
import notes from "../signals/notes"
|
import notes from "../signals/notes"
|
||||||
import { MiniMap } from "./MiniMap"
|
import { MiniMap } from "./MiniMap"
|
||||||
import { ImageCard } from "./ImageCard"
|
import { ImageCard } from "./ImageCard"
|
||||||
import images from "../signals/images"
|
import images from "../signals/images"
|
||||||
|
import { CardSelector } from "./cardSelector/CardSelector"
|
||||||
|
|
||||||
export default function InfiniteCanvas() {
|
export default function InfiniteCanvas() {
|
||||||
const containerRef = useRef<HTMLDivElement>(null)
|
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 } from "../../signals"
|
||||||
import { ImagesSignal, NotesSigal } from "../signals"
|
import images from "../../signals/images"
|
||||||
import { updateLocalStorage } from "../utils/localStorage"
|
import { updateLocalStorage } from "../../utils/localStorage"
|
||||||
import notes from "../signals/notes"
|
|
||||||
import images from "../signals/images"
|
|
||||||
|
|
||||||
export function CardSelector() {
|
export function ImageCardButton() {
|
||||||
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() {
|
|
||||||
function _handleClick(mouseEvent: MouseEvent) {
|
function _handleClick(mouseEvent: MouseEvent) {
|
||||||
const input = document.createElement('input')
|
const input = document.createElement('input')
|
||||||
input.type = 'file'
|
input.type = 'file'
|
||||||
@ -117,7 +58,7 @@ function Image() {
|
|||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="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
|
<rect
|
||||||
width="18"
|
width="18"
|
||||||
height="18"
|
height="18"
|
||||||
@ -135,5 +76,3 @@ function Image() {
|
|||||||
</button>
|
</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