Comparing version 0.1.3 to 0.1.6
@@ -8,2 +8,4 @@ import { SvelteComponentTyped } from "svelte"; | ||
value?: string | undefined; | ||
mode?: "tab" | "split" | "auto" | undefined; | ||
disableToolbar?: boolean | undefined; | ||
}; | ||
@@ -15,7 +17,7 @@ events: { | ||
}; | ||
export type CartaEditorProps = typeof __propDef.props; | ||
export type CartaEditorEvents = typeof __propDef.events; | ||
export type CartaEditorSlots = typeof __propDef.slots; | ||
export declare type CartaEditorProps = typeof __propDef.props; | ||
export declare type CartaEditorEvents = typeof __propDef.events; | ||
export declare type CartaEditorSlots = typeof __propDef.slots; | ||
export default class CartaEditor extends SvelteComponentTyped<CartaEditorProps, CartaEditorEvents, CartaEditorSlots> { | ||
} | ||
export {}; |
@@ -14,7 +14,7 @@ import { SvelteComponentTyped } from "svelte"; | ||
}; | ||
export type CartaViewerProps = typeof __propDef.props; | ||
export type CartaViewerEvents = typeof __propDef.events; | ||
export type CartaViewerSlots = typeof __propDef.slots; | ||
export declare type CartaViewerProps = typeof __propDef.props; | ||
export declare type CartaViewerEvents = typeof __propDef.events; | ||
export declare type CartaViewerSlots = typeof __propDef.slots; | ||
export default class CartaViewer extends SvelteComponentTyped<CartaViewerProps, CartaViewerEvents, CartaViewerSlots> { | ||
} | ||
export {}; |
export { default as CartaEditor } from './CartaEditor.svelte'; | ||
export { default as CartaViewer } from './CartaViewer.svelte'; | ||
export { Carta, type CartaExtension, type CartaOptions } from './internal/carta'; | ||
export type { CartaInput, KeyboardShortcut, TextSelection } from './internal/input'; | ||
export * from './internal/carta'; | ||
export type { CartaInput, TextSelection } from './internal/input'; | ||
export type { CartaIcon } from './internal/icons'; | ||
export type { KeyboardShortcut } from './internal/shortcuts'; | ||
export type { Prefix } from './internal/prefixes'; |
export { default as CartaEditor } from './CartaEditor.svelte'; | ||
export { default as CartaViewer } from './CartaViewer.svelte'; | ||
export { Carta } from './internal/carta'; | ||
export * from './internal/carta'; |
import { marked } from 'marked'; | ||
import type { CartaHistoryOptions } from './history'; | ||
import { CartaInput, type KeyboardShortcut } from './input'; | ||
import { CartaInput } from './input'; | ||
import { type DefaultShortcutId, type KeyboardShortcut } from './shortcuts'; | ||
import { type CartaIcon, type DefaultIconId } from './icons'; | ||
import { type DefaultPrefixId, type Prefix } from './prefixes'; | ||
/** | ||
* Carta editor options. | ||
*/ | ||
export interface CartaOptions { | ||
@@ -15,6 +21,14 @@ /** | ||
/** | ||
* Remove default shortcuts. | ||
* Remove default shortcuts by ids. | ||
*/ | ||
disableDefaultShortcuts?: boolean; | ||
disableShortcuts?: DefaultShortcutId[]; | ||
/** | ||
* Remove default icons by ids. | ||
*/ | ||
disableIcons?: DefaultIconId[]; | ||
/** | ||
* Remove default prefixes by ids. | ||
*/ | ||
disablePrefixes?: DefaultPrefixId[]; | ||
/** | ||
* History options. | ||
@@ -24,2 +38,5 @@ */ | ||
} | ||
/** | ||
* Carta editor extensions. | ||
*/ | ||
export interface CartaExtension { | ||
@@ -34,6 +51,16 @@ /** | ||
shortcuts?: KeyboardShortcut[]; | ||
/** | ||
* Additional icons. | ||
*/ | ||
icons?: CartaIcon[]; | ||
/** | ||
* Additional prefixes. | ||
*/ | ||
prefixes?: Prefix[]; | ||
} | ||
export declare class Carta { | ||
readonly options?: CartaOptions | undefined; | ||
private readonly keyboardShortcuts; | ||
readonly keyboardShortcuts: KeyboardShortcut[]; | ||
readonly icons: CartaIcon[]; | ||
readonly prefixes: Prefix[]; | ||
input: CartaInput | undefined; | ||
@@ -48,7 +75,2 @@ constructor(options?: CartaOptions | undefined); | ||
/** | ||
* Get all the registered keyboard shortcuts. | ||
* @returns Registered keyboard shortcuts. | ||
*/ | ||
getKeyboardShortcuts(): KeyboardShortcut[]; | ||
/** | ||
* Set the input element. | ||
@@ -55,0 +77,0 @@ * @param textarea The input textarea element. |
import { marked } from 'marked'; | ||
import { CartaInput } from './input'; | ||
import { DefaultKeyboardShortcuts } from './shortcuts'; | ||
import { defaultKeyboardShortcuts } from './shortcuts'; | ||
import { defaultIcons } from './icons'; | ||
import { defaultPrefixes } from './prefixes'; | ||
export class Carta { | ||
options; | ||
keyboardShortcuts; | ||
icons; | ||
prefixes; | ||
input; | ||
@@ -11,15 +15,19 @@ constructor(options) { | ||
this.keyboardShortcuts = []; | ||
// Load keyboard shortcuts | ||
const extensionKeyboardShortcuts = this.options?.extensions | ||
?.flatMap((ext) => ext.shortcuts) | ||
.filter((shortcut) => shortcut != null) ?? []; | ||
if (extensionKeyboardShortcuts) | ||
this.keyboardShortcuts = this.keyboardShortcuts.concat(extensionKeyboardShortcuts); | ||
this.icons = []; | ||
this.prefixes = []; | ||
for (const ext of options?.extensions ?? []) { | ||
this.keyboardShortcuts = this.keyboardShortcuts.concat(this.keyboardShortcuts, ext.shortcuts ?? []); | ||
this.icons = this.icons.concat(this.icons, ext.icons ?? []); | ||
this.prefixes = this.prefixes.concat(this.prefixes, ext.prefixes ?? []); | ||
} | ||
// Load default keyboard shortcuts | ||
if (!options?.disableDefaultShortcuts) | ||
this.keyboardShortcuts = this.keyboardShortcuts.concat(DefaultKeyboardShortcuts); | ||
this.keyboardShortcuts = this.keyboardShortcuts.concat(defaultKeyboardShortcuts.filter((shortcut) => !options?.disableShortcuts?.includes(shortcut.id))); | ||
// Load default icons | ||
this.icons = this.icons.concat(defaultIcons.filter((icon) => !options?.disableIcons?.includes(icon.id))); | ||
// Load default prefixes | ||
this.prefixes = this.prefixes.concat(defaultPrefixes.filter((prefix) => !options?.disablePrefixes?.includes(prefix.id))); | ||
// Load marked extensions | ||
const markedExtensions = this.options?.extensions | ||
?.flatMap((ext) => ext.markedExtensions) | ||
.filter((ext) => ext != null); | ||
// Load marked extensions | ||
if (markedExtensions) | ||
@@ -37,9 +45,2 @@ marked.use(...markedExtensions); | ||
/** | ||
* Get all the registered keyboard shortcuts. | ||
* @returns Registered keyboard shortcuts. | ||
*/ | ||
getKeyboardShortcuts() { | ||
return this.keyboardShortcuts; | ||
} | ||
/** | ||
* Set the input element. | ||
@@ -50,4 +51,4 @@ * @param textarea The input textarea element. | ||
setInput(textarea, onUpdate) { | ||
this.input = new CartaInput(textarea, this.getKeyboardShortcuts(), onUpdate, this.options?.historyOptions); | ||
this.input = new CartaInput(textarea, this.keyboardShortcuts, this.prefixes, onUpdate, this.options?.historyOptions); | ||
} | ||
} |
@@ -7,3 +7,2 @@ import { SvelteComponentTyped } from "svelte"; | ||
value: string; | ||
theme: string; | ||
}; | ||
@@ -15,7 +14,7 @@ events: { | ||
}; | ||
export type CartaRendererProps = typeof __propDef.props; | ||
export type CartaRendererEvents = typeof __propDef.events; | ||
export type CartaRendererSlots = typeof __propDef.slots; | ||
export declare type CartaRendererProps = typeof __propDef.props; | ||
export declare type CartaRendererEvents = typeof __propDef.events; | ||
export declare type CartaRendererSlots = typeof __propDef.slots; | ||
export default class CartaRenderer extends SvelteComponentTyped<CartaRendererProps, CartaRendererEvents, CartaRendererSlots> { | ||
} | ||
export {}; |
@@ -8,3 +8,2 @@ import { SvelteComponentTyped } from "svelte"; | ||
value?: string | undefined; | ||
theme: string; | ||
}; | ||
@@ -16,7 +15,7 @@ events: { | ||
}; | ||
export type MarkdownInputProps = typeof __propDef.props; | ||
export type MarkdownInputEvents = typeof __propDef.events; | ||
export type MarkdownInputSlots = typeof __propDef.slots; | ||
export declare type MarkdownInputProps = typeof __propDef.props; | ||
export declare type MarkdownInputEvents = typeof __propDef.events; | ||
export declare type MarkdownInputSlots = typeof __propDef.slots; | ||
export default class MarkdownInput extends SvelteComponentTyped<MarkdownInputProps, MarkdownInputEvents, MarkdownInputSlots> { | ||
} | ||
export {}; |
@@ -0,0 +0,0 @@ export interface CartaHistoryOptions { |
@@ -0,0 +0,0 @@ import { mergeDefaultInterface } from './utils'; |
import { CartaHistory, type CartaHistoryOptions } from './history'; | ||
import type { Prefix } from './prefixes'; | ||
import type { KeyboardShortcut } from './shortcuts'; | ||
/** | ||
@@ -11,23 +13,6 @@ * Text selection information. | ||
} | ||
/** | ||
* Keyboard shortcut data. | ||
*/ | ||
export interface KeyboardShortcut { | ||
/** | ||
* Set of keys, corresponding to the `e.key` of `KeyboardEvent`s, but lowercase. | ||
*/ | ||
combination: Set<string>; | ||
/** | ||
* Callback action. | ||
* @param input Input helper. | ||
*/ | ||
action: (input: CartaInput) => void; | ||
/** | ||
* Prevent saving the current state in history. | ||
*/ | ||
preventSave?: boolean; | ||
} | ||
export declare class CartaInput { | ||
readonly textarea: HTMLTextAreaElement; | ||
private readonly shortcuts; | ||
private readonly prefixes; | ||
private readonly onUpdate; | ||
@@ -37,3 +22,3 @@ private pressedKeys; | ||
private onKeyDownValue; | ||
constructor(textarea: HTMLTextAreaElement, shortcuts: KeyboardShortcut[], onUpdate: () => void, historyOptions?: Partial<CartaHistoryOptions>); | ||
constructor(textarea: HTMLTextAreaElement, shortcuts: KeyboardShortcut[], prefixes: Prefix[], onUpdate: () => void, historyOptions?: Partial<CartaHistoryOptions>); | ||
private isWordCharacter; | ||
@@ -43,2 +28,3 @@ private handleMouseDown; | ||
private handleKeyUp; | ||
private handleNewLine; | ||
/** | ||
@@ -66,2 +52,7 @@ * Get the selected text data. | ||
toggleSelectionSurrounding(delimiter: string | [string, string]): void; | ||
toggleLinePrefix(prefix: string, whitespace?: 'attach' | 'detach'): void; | ||
/** | ||
* Update the textarea. | ||
*/ | ||
update: () => void; | ||
} |
@@ -6,2 +6,3 @@ import { CartaHistory } from './history'; | ||
shortcuts; | ||
prefixes; | ||
onUpdate; | ||
@@ -12,5 +13,6 @@ pressedKeys; | ||
onKeyDownValue; | ||
constructor(textarea, shortcuts, onUpdate, historyOptions) { | ||
constructor(textarea, shortcuts, prefixes, onUpdate, historyOptions) { | ||
this.textarea = textarea; | ||
this.shortcuts = shortcuts; | ||
this.prefixes = prefixes; | ||
this.onUpdate = onUpdate; | ||
@@ -75,2 +77,7 @@ this.pressedKeys = new Set(); | ||
else { | ||
// On newline | ||
if (key === 'enter') { | ||
// Check prefixes | ||
this.handleNewLine(e); | ||
} | ||
this.onKeyDownValue = this.textarea.value; | ||
@@ -86,2 +93,23 @@ } | ||
} | ||
handleNewLine(e) { | ||
const cursor = this.textarea.selectionStart; | ||
// Get all the line | ||
let lineStartingIndex; | ||
for (lineStartingIndex = cursor; lineStartingIndex > 0 && this.textarea.value.at(lineStartingIndex - 1) !== '\n'; lineStartingIndex--) | ||
; | ||
const line = this.textarea.value.slice(lineStartingIndex, cursor); | ||
for (const prefix of this.prefixes) { | ||
const match = prefix.match(line); | ||
if (match) { | ||
e.preventDefault(); | ||
const newPrefix = prefix.maker(match, line); | ||
this.insertAt(cursor, '\n' + newPrefix); | ||
this.onUpdate(); | ||
// Update cursor position | ||
const newCursorPosition = cursor + newPrefix.length + 1; | ||
this.textarea.setSelectionRange(newCursorPosition, newCursorPosition); | ||
break; | ||
} | ||
} | ||
} | ||
/** | ||
@@ -140,2 +168,35 @@ * Get the selected text data. | ||
} | ||
toggleLinePrefix(prefix, whitespace = 'attach') { | ||
const selection = this.getSelection(); | ||
let index = selection.start; | ||
while (index > 0 && this.textarea.value.at(index - 1) !== '\n') | ||
index--; | ||
let newPosition = selection.start; | ||
const currentPrefix = this.textarea.value.slice(index, prefix.length); | ||
if (currentPrefix === prefix) { | ||
if (whitespace === 'attach' && this.textarea.value.at(index + prefix.length) === ' ') { | ||
this.removeAt(index, prefix.length + 1); | ||
newPosition -= prefix.length + 1; | ||
} | ||
else { | ||
this.removeAt(index, prefix.length); | ||
newPosition -= prefix.length; | ||
} | ||
} | ||
else { | ||
if (whitespace === 'attach') { | ||
this.insertAt(index, prefix + ' '); | ||
newPosition += prefix.length + 1; | ||
} | ||
else { | ||
this.insertAt(index, prefix); | ||
newPosition += prefix.length; | ||
} | ||
} | ||
this.textarea.setSelectionRange(newPosition, newPosition + selection.slice.length); | ||
} | ||
/** | ||
* Update the textarea. | ||
*/ | ||
update = () => this.onUpdate(); | ||
} |
@@ -1,6 +0,60 @@ | ||
import type { KeyboardShortcut } from './input'; | ||
import type { CartaInput } from './input'; | ||
/** | ||
* Keyboard shortcut data. | ||
*/ | ||
export interface KeyboardShortcut { | ||
id: string; | ||
/** | ||
* Set of keys, corresponding to the `e.key` of `KeyboardEvent`s, but lowercase. | ||
*/ | ||
combination: Set<string>; | ||
/** | ||
* Callback action. | ||
* @param input Input helper. | ||
*/ | ||
action: (input: CartaInput) => void; | ||
/** | ||
* Prevent saving the current state in history. | ||
*/ | ||
preventSave?: boolean; | ||
} | ||
/** | ||
* Default keyboard shortcuts. Can be disabled in `Carta` by | ||
* passing the `disableDefaultShortcuts` option. | ||
*/ | ||
export declare const DefaultKeyboardShortcuts: KeyboardShortcut[]; | ||
export declare const defaultKeyboardShortcuts: readonly [{ | ||
readonly id: "bold"; | ||
readonly combination: Set<string>; | ||
readonly action: (input: any) => any; | ||
}, { | ||
readonly id: "italic"; | ||
readonly combination: Set<string>; | ||
readonly action: (input: any) => any; | ||
}, { | ||
readonly id: "quote"; | ||
readonly combination: Set<string>; | ||
readonly action: (input: any) => any; | ||
}, { | ||
readonly id: "link"; | ||
readonly combination: Set<string>; | ||
readonly action: (input: any) => void; | ||
}, { | ||
readonly id: "strikethrough"; | ||
readonly combination: Set<string>; | ||
readonly action: (input: any) => any; | ||
}, { | ||
readonly id: "code"; | ||
readonly combination: Set<string>; | ||
readonly action: (input: any) => any; | ||
}, { | ||
readonly id: "undo"; | ||
readonly combination: Set<string>; | ||
readonly preventSave: true; | ||
readonly action: (input: any) => void; | ||
}, { | ||
readonly id: "redo"; | ||
readonly combination: Set<string>; | ||
readonly preventSave: true; | ||
readonly action: (input: any) => void; | ||
}], satisfies: any, readonly: any, KeyboardShortcut: any; | ||
export declare type DefaultShortcutId = (typeof defaultKeyboardShortcuts)[number]['id']; |
@@ -5,5 +5,6 @@ /** | ||
*/ | ||
export const DefaultKeyboardShortcuts = [ | ||
export const defaultKeyboardShortcuts = [ | ||
// Bold text | ||
{ | ||
id: 'bold', | ||
combination: new Set(['control', 'b']), | ||
@@ -14,7 +15,15 @@ action: (input) => input.toggleSelectionSurrounding('**') | ||
{ | ||
id: 'italic', | ||
combination: new Set(['control', 'i']), | ||
action: (input) => input.toggleSelectionSurrounding('*') | ||
action: (input) => input.toggleSelectionSurrounding('_') | ||
}, | ||
// Quote | ||
{ | ||
id: 'quote', | ||
combination: new Set(['control', 'shift', ',']), | ||
action: (input) => input.toggleLinePrefix('>') | ||
}, | ||
// Link | ||
{ | ||
id: 'link', | ||
combination: new Set(['control', 'k']), | ||
@@ -28,5 +37,12 @@ action: (input) => { | ||
}, | ||
// Strikethrough | ||
{ | ||
id: 'strikethrough', | ||
combination: new Set(['control', 'shift', 'x']), | ||
action: (input) => input.toggleSelectionSurrounding('~~') | ||
}, | ||
// Code | ||
{ | ||
combination: new Set(['control', 'shift', 'k']), | ||
id: 'code', | ||
combination: new Set(['control', 'e']), | ||
action: (input) => input.toggleSelectionSurrounding('`') | ||
@@ -36,2 +52,3 @@ }, | ||
{ | ||
id: 'undo', | ||
combination: new Set(['control', 'z']), | ||
@@ -47,2 +64,3 @@ preventSave: true, | ||
{ | ||
id: 'redo', | ||
combination: new Set(['control', 'y']), | ||
@@ -56,2 +74,2 @@ preventSave: true, | ||
} | ||
]; | ||
], satisfies, readonly, KeyboardShortcut, []; |
@@ -0,0 +0,0 @@ /** |
@@ -0,0 +0,0 @@ /** |
@@ -16,5 +16,16 @@ { | ||
"./internal/components/CartaRenderer.svelte": "./internal/components/CartaRenderer.svelte", | ||
"./internal/components/icons/BoldIcon.svelte": "./internal/components/icons/BoldIcon.svelte", | ||
"./internal/components/icons/CodeIcon.svelte": "./internal/components/icons/CodeIcon.svelte", | ||
"./internal/components/icons/HeadingIcon.svelte": "./internal/components/icons/HeadingIcon.svelte", | ||
"./internal/components/icons/ItalicIcon.svelte": "./internal/components/icons/ItalicIcon.svelte", | ||
"./internal/components/icons/LinkIcon.svelte": "./internal/components/icons/LinkIcon.svelte", | ||
"./internal/components/icons/ListBulletedIcon.svelte": "./internal/components/icons/ListBulletedIcon.svelte", | ||
"./internal/components/icons/ListNumberedIcon.svelte": "./internal/components/icons/ListNumberedIcon.svelte", | ||
"./internal/components/icons/ListTaskIcon.svelte": "./internal/components/icons/ListTaskIcon.svelte", | ||
"./internal/components/icons/QuoteIcon.svelte": "./internal/components/icons/QuoteIcon.svelte", | ||
"./internal/components/MarkdownInput.svelte": "./internal/components/MarkdownInput.svelte", | ||
"./internal/history": "./internal/history.js", | ||
"./internal/icons": "./internal/icons.js", | ||
"./internal/input": "./internal/input.js", | ||
"./internal/prefixes": "./internal/prefixes.js", | ||
"./internal/shortcuts": "./internal/shortcuts.js", | ||
@@ -24,3 +35,3 @@ "./internal/utils": "./internal/utils.js", | ||
}, | ||
"version": "0.1.3", | ||
"version": "0.1.6", | ||
"devDependencies": { | ||
@@ -34,3 +45,3 @@ "@sveltejs/adapter-auto": "^1.0.0-next.90", | ||
"tslib": "^2.4.1", | ||
"typescript": "^5.0.4", | ||
"typescript": "^4.8.4", | ||
"vite": "^4.0.0" | ||
@@ -37,0 +48,0 @@ }, |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
64525
45
1581
0