generated from Klectr/KTemplate
Compare commits
2 Commits
f659a38026
...
261eb8348e
Author | SHA1 | Date | |
---|---|---|---|
261eb8348e | |||
77624aae8c |
7
src/components/Divider.tsx
Normal file
7
src/components/Divider.tsx
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
export function Divider() {
|
||||||
|
return (
|
||||||
|
<div className="border-l-[1px] border-l-[#9c9c9c]"></div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
import { signal, useRef } from "kaioken"
|
import { signal, useRef } from "kaioken"
|
||||||
import { NotesSigal, focusedItem } from "../signals"
|
import { NotesSigal, focusedItem } from "../signals"
|
||||||
import { useDebounce } from "../utils/useDebounce"
|
import { useDebounce } from "../utils/useDebounce"
|
||||||
@ -7,6 +6,9 @@ import { LayerEnum } from "../utils/enums"
|
|||||||
import { useThemeDetector } from "../utils/useThemeDetector"
|
import { useThemeDetector } from "../utils/useThemeDetector"
|
||||||
import { MarkDownEditor } from "./MarkDownEditor/MarkDownEditor"
|
import { MarkDownEditor } from "./MarkDownEditor/MarkDownEditor"
|
||||||
import { ChangeEvent } from "tiny-markdown-editor"
|
import { ChangeEvent } from "tiny-markdown-editor"
|
||||||
|
import { Divider } from "./Divider"
|
||||||
|
import { ExportIcon } from "./icons/ExportIcon"
|
||||||
|
import { createFileAndExport } from "../utils/createFileAndExport"
|
||||||
|
|
||||||
namespace NoteCard {
|
namespace NoteCard {
|
||||||
export interface NoteCardProps {
|
export interface NoteCardProps {
|
||||||
@ -107,6 +109,10 @@ export function NoteCard({ key: itemKey, data: item }: NoteCard.NoteCardProps) {
|
|||||||
focusedItem.value = itemKey
|
focusedItem.value = itemKey
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _handleExportClick(e) {
|
||||||
|
createFileAndExport("Note", item.contents, "text/markdown")
|
||||||
|
}
|
||||||
|
|
||||||
const cardPositionStyle = {
|
const cardPositionStyle = {
|
||||||
zIndex: `${focusedItem.value == itemKey ? LayerEnum.CARD_ELEVATED : LayerEnum.CARD}`,
|
zIndex: `${focusedItem.value == itemKey ? LayerEnum.CARD_ELEVATED : LayerEnum.CARD}`,
|
||||||
width: `${item.dimensions.w}px`,
|
width: `${item.dimensions.w}px`,
|
||||||
@ -128,7 +134,19 @@ export function NoteCard({ key: itemKey, data: item }: NoteCard.NoteCardProps) {
|
|||||||
<div className="overflow-hidden flex-1 flex flex-col gap-1">
|
<div className="overflow-hidden flex-1 flex flex-col gap-1">
|
||||||
<div className="px-2 flex justify-between items-center cursor-move" onmousedown={_handleMouseDown}>
|
<div className="px-2 flex justify-between items-center cursor-move" onmousedown={_handleMouseDown}>
|
||||||
<div style={saveIndicatorStyle} className="rounded-full w-1 h-1 dark:bg-white bg-green-500"></div>
|
<div style={saveIndicatorStyle} className="rounded-full w-1 h-1 dark:bg-white bg-green-500"></div>
|
||||||
|
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<div
|
||||||
|
onclick={_handleExportClick}
|
||||||
|
className="flex items-center">
|
||||||
|
<ExportIcon
|
||||||
|
className="cursor-pointer w-4 h-4 text-[#9c9c9c] hover:text-blue-500 transition-color duration-300"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<Divider />
|
||||||
<button className="text-md dark:text-[#777] text-black" onclick={_handleClose}>x</button>
|
<button className="text-md dark:text-[#777] text-black" onclick={_handleClose}>x</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr className="border dark:border-[#1c1c1c] border-[#ddd]" />
|
<hr className="border dark:border-[#1c1c1c] border-[#ddd]" />
|
||||||
|
@ -4,6 +4,7 @@ import { ImageCardButton } from "./ImageCardButton"
|
|||||||
import { ExportButton } from "./ExportButton"
|
import { ExportButton } from "./ExportButton"
|
||||||
import { TextButton } from "./TextButton"
|
import { TextButton } from "./TextButton"
|
||||||
import { ImportButton } from "./ImportButton"
|
import { ImportButton } from "./ImportButton"
|
||||||
|
import { Divider } from "../Divider"
|
||||||
|
|
||||||
export function CardSelector() {
|
export function CardSelector() {
|
||||||
const containerRef = useRef<HTMLDivElement>(null)
|
const containerRef = useRef<HTMLDivElement>(null)
|
||||||
@ -27,16 +28,6 @@ export function CardSelector() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function Divider() {
|
|
||||||
return (
|
|
||||||
<div style={{
|
|
||||||
margin: '2px 2px',
|
|
||||||
border: "1px solid #9c9c9c",
|
|
||||||
borderRight: 'none',
|
|
||||||
}}></div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { ImagesSignal, NotesSigal } from "../../signals"
|
import { ImagesSignal, NotesSigal } from "../../signals"
|
||||||
|
import { createFileAndExport } from "../../utils/createFileAndExport"
|
||||||
import { Tooltip } from "./Tooltip"
|
import { Tooltip } from "./Tooltip"
|
||||||
import { defaultClassName } from "./utils"
|
import { defaultClassName } from "./utils"
|
||||||
|
|
||||||
@ -12,17 +13,9 @@ export function ExportButton() {
|
|||||||
...notes.value,
|
...notes.value,
|
||||||
...images.value
|
...images.value
|
||||||
}
|
}
|
||||||
const date = new Date().toDateString().split(' ').join('_')
|
const name = `Kslab_export`
|
||||||
const name = `Kslab_export_${date}.json`
|
|
||||||
const jsonData = JSON.stringify(mergeState)
|
const jsonData = JSON.stringify(mergeState)
|
||||||
const file = new File([jsonData], name, {
|
createFileAndExport(name, jsonData, "text/json")
|
||||||
type: 'text/json'
|
|
||||||
})
|
|
||||||
const url = URL.createObjectURL(file)
|
|
||||||
const a = document.createElement('a')
|
|
||||||
a.download = name
|
|
||||||
a.href = url
|
|
||||||
a.click()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
26
src/components/icons/ExportIcon.tsx
Normal file
26
src/components/icons/ExportIcon.tsx
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
namespace ExportIcon {
|
||||||
|
export interface Props {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export function ExportIcon({ className }: ExportIcon.Props) {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<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={className ?? ""}
|
||||||
|
>
|
||||||
|
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
|
||||||
|
<polyline points="17 8 12 3 7 8" />
|
||||||
|
<line x1="12" x2="12" y1="3" y2="15" />
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
}
|
23
src/utils/createFileAndExport.ts
Normal file
23
src/utils/createFileAndExport.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import { createFileCompliantDateString } from "./createFileCompliantDateString"
|
||||||
|
import { createFileFromData } from "./createFileFromData"
|
||||||
|
|
||||||
|
export type acceptableFileTypes = "text/json" | "text/markdown"
|
||||||
|
export function createFileAndExport(
|
||||||
|
name: string,
|
||||||
|
data: string,
|
||||||
|
type: acceptableFileTypes
|
||||||
|
) {
|
||||||
|
const date = createFileCompliantDateString()
|
||||||
|
const fileName = `${name}_${date}.${_getFileType(type)}`
|
||||||
|
const file = createFileFromData(data, fileName, "text/json")
|
||||||
|
const url = URL.createObjectURL(file)
|
||||||
|
const a = document.createElement("a")
|
||||||
|
a.download = fileName
|
||||||
|
a.href = url
|
||||||
|
a.click()
|
||||||
|
}
|
||||||
|
|
||||||
|
function _getFileType(type: acceptableFileTypes): "json" | "md" {
|
||||||
|
if (type === "text/markdown") return "md"
|
||||||
|
return "json"
|
||||||
|
}
|
3
src/utils/createFileCompliantDateString.ts
Normal file
3
src/utils/createFileCompliantDateString.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export function createFileCompliantDateString() {
|
||||||
|
return new Date().toDateString().split(" ").join("_")
|
||||||
|
}
|
9
src/utils/createFileFromData.ts
Normal file
9
src/utils/createFileFromData.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
export function createFileFromData(
|
||||||
|
data: string,
|
||||||
|
name: string,
|
||||||
|
type: BlobPropertyBag["type"]
|
||||||
|
) {
|
||||||
|
return new File(Array.from(data), name, {
|
||||||
|
type: type,
|
||||||
|
})
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user