@functionalcms/svelte-components 5.8.6 → 5.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/form/Editor.svelte +103 -0
- package/dist/components/form/Editor.svelte.d.ts +14 -0
- package/dist/components/form/SmartForm.svelte +28 -1
- package/dist/components/form/form.d.ts +15 -2
- package/dist/components/form/form.js +9 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +3 -1
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import {
|
|
3
|
+
Editor,
|
|
4
|
+
rootCtx,
|
|
5
|
+
commandsCtx,
|
|
6
|
+
defaultValueCtx,
|
|
7
|
+
editorViewCtx,
|
|
8
|
+
} from "@milkdown/kit/core";
|
|
9
|
+
import { commonmark } from "@milkdown/kit/preset/commonmark";
|
|
10
|
+
import { history } from "@milkdown/kit/plugin/history";
|
|
11
|
+
import { nord } from "@milkdown/theme-nord";
|
|
12
|
+
import {
|
|
13
|
+
wrapInHeadingCommand,
|
|
14
|
+
toggleStrongCommand,
|
|
15
|
+
toggleEmphasisCommand,
|
|
16
|
+
wrapInBulletListCommand,
|
|
17
|
+
turnIntoTextCommand,
|
|
18
|
+
} from "@milkdown/kit/preset/commonmark";
|
|
19
|
+
import { getMarkdown, getHTML } from "@milkdown/kit/utils";
|
|
20
|
+
import { listener, listenerCtx } from "@milkdown/kit/plugin/listener";
|
|
21
|
+
import { Button, ButtonGroup } from "@functionalcms/svelte-components";
|
|
22
|
+
|
|
23
|
+
interface Props {
|
|
24
|
+
initialValue: string;
|
|
25
|
+
markdown: string;
|
|
26
|
+
html: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
let { initialValue = "", markdown = $bindable(initialValue), html = $bindable(initialValue) }: Partial<Props> = $props();
|
|
30
|
+
|
|
31
|
+
let editorInstance: Editor | null = null;
|
|
32
|
+
|
|
33
|
+
const applyCommand = (command: any, params?: any) => {
|
|
34
|
+
if (!editorInstance) return;
|
|
35
|
+
|
|
36
|
+
try {
|
|
37
|
+
editorInstance.action((ctx) => {
|
|
38
|
+
const commandManager = ctx.get(commandsCtx);
|
|
39
|
+
commandManager.call(command, params);
|
|
40
|
+
});
|
|
41
|
+
} catch (e) {
|
|
42
|
+
console.error("Command error:", e);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const setHeadingCommand = (level: 1 | 2 | 3 | 4 | 5 | 6) =>
|
|
47
|
+
applyCommand(wrapInHeadingCommand.key, level);
|
|
48
|
+
const makeBold = () => applyCommand(toggleStrongCommand.key);
|
|
49
|
+
const makeItalic = () => applyCommand(toggleEmphasisCommand.key);
|
|
50
|
+
const makeList = () => applyCommand(wrapInBulletListCommand.key);
|
|
51
|
+
const clearFormatting = () => applyCommand(turnIntoTextCommand.key);
|
|
52
|
+
|
|
53
|
+
function editor(dom) {
|
|
54
|
+
const MakeEditor = Editor.make()
|
|
55
|
+
.config((ctx) => {
|
|
56
|
+
ctx.set(rootCtx, dom);
|
|
57
|
+
ctx.set(defaultValueCtx, initialValue);
|
|
58
|
+
ctx.get(listenerCtx).markdownUpdated((ctx, markdownContent) => {
|
|
59
|
+
markdown = markdownContent;
|
|
60
|
+
html = getHTML()(ctx);
|
|
61
|
+
});
|
|
62
|
+
})
|
|
63
|
+
.config(nord)
|
|
64
|
+
.use(commonmark)
|
|
65
|
+
.use(listener)
|
|
66
|
+
.use(history)
|
|
67
|
+
.create();
|
|
68
|
+
MakeEditor.then((editor) => {
|
|
69
|
+
editorInstance = editor;
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
</script>
|
|
73
|
+
|
|
74
|
+
<div class="editor-container">
|
|
75
|
+
<ButtonGroup>
|
|
76
|
+
<Button onclick={() => setHeadingCommand(1)}>H1</Button>
|
|
77
|
+
<Button onclick={() => setHeadingCommand(2)}>H2</Button>
|
|
78
|
+
<Button onclick={() => setHeadingCommand(3)}>H3</Button>
|
|
79
|
+
<Button onclick={() => setHeadingCommand(4)}>H4</Button>
|
|
80
|
+
<Button onclick={() => setHeadingCommand(5)}>H5</Button>
|
|
81
|
+
<Button onclick={() => setHeadingCommand(6)}>H6</Button>
|
|
82
|
+
<Button onclick={() => makeBold()}><strong>B</strong></Button>
|
|
83
|
+
<Button onclick={() => makeItalic()}><em>I</em></Button>
|
|
84
|
+
<Button onclick={() => makeList()}>List</Button>
|
|
85
|
+
<Button onclick={() => clearFormatting()}>Clear</Button>
|
|
86
|
+
</ButtonGroup>
|
|
87
|
+
<div class="editor-body" use:editor></div>
|
|
88
|
+
</div>
|
|
89
|
+
|
|
90
|
+
<style>
|
|
91
|
+
.editor-container {
|
|
92
|
+
display: flex;
|
|
93
|
+
flex-direction: column;
|
|
94
|
+
gap: 0.5rem;
|
|
95
|
+
border: 2px solid black;
|
|
96
|
+
border-radius: 5px;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.editor-body {
|
|
100
|
+
background: white;
|
|
101
|
+
height: 100%;
|
|
102
|
+
}
|
|
103
|
+
</style>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
declare const __propDef: {
|
|
3
|
+
props: Record<string, never>;
|
|
4
|
+
events: {
|
|
5
|
+
[evt: string]: CustomEvent<any>;
|
|
6
|
+
};
|
|
7
|
+
slots: {};
|
|
8
|
+
};
|
|
9
|
+
export type EditorProps = typeof __propDef.props;
|
|
10
|
+
export type EditorEvents = typeof __propDef.events;
|
|
11
|
+
export type EditorSlots = typeof __propDef.slots;
|
|
12
|
+
export default class Editor extends SvelteComponentTyped<EditorProps, EditorEvents, EditorSlots> {
|
|
13
|
+
}
|
|
14
|
+
export {};
|
|
@@ -11,7 +11,13 @@
|
|
|
11
11
|
type ButtonConfig,
|
|
12
12
|
type HiddenField,
|
|
13
13
|
type DatePickerField,
|
|
14
|
-
SubmitResult
|
|
14
|
+
SubmitResult,
|
|
15
|
+
|
|
16
|
+
type MarkdownEditorField,
|
|
17
|
+
|
|
18
|
+
type HtmlEditorField
|
|
19
|
+
|
|
20
|
+
|
|
15
21
|
} from './form.js';
|
|
16
22
|
import {
|
|
17
23
|
Button,
|
|
@@ -28,6 +34,8 @@
|
|
|
28
34
|
Datepicker
|
|
29
35
|
} from 'flowbite-svelte';
|
|
30
36
|
import { fade } from 'svelte/transition';
|
|
37
|
+
import Editor from './Editor.svelte';
|
|
38
|
+
import Markdown from '../content/Markdown.svelte';
|
|
31
39
|
|
|
32
40
|
interface Props {
|
|
33
41
|
action: string;
|
|
@@ -223,6 +231,21 @@
|
|
|
223
231
|
<input type="hidden" id={field.id} name={field.id} bind:value={field.value} />
|
|
224
232
|
{/snippet}
|
|
225
233
|
|
|
234
|
+
{#snippet renderMdEditory(field: MarkdownEditorField)}
|
|
235
|
+
<Label for={field.id} class={field.class}>{field.label}</Label>
|
|
236
|
+
{#key field.id}
|
|
237
|
+
<Editor initialValue={field.value} bind:markdown={field.value} />
|
|
238
|
+
<input type="hidden" name={field.id} bind:value={field.value} />
|
|
239
|
+
{/key}
|
|
240
|
+
{/snippet}
|
|
241
|
+
{#snippet renderHtmlEditory(field: HtmlEditorField)}
|
|
242
|
+
<Label for={field.id} class={field.class}>{field.label}</Label>
|
|
243
|
+
{#key field.id}
|
|
244
|
+
<Editor initialValue={field.value} bind:html={field.value} />
|
|
245
|
+
<input type="hidden" name={field.id} bind:value={field.value} />
|
|
246
|
+
{/key}
|
|
247
|
+
{/snippet}
|
|
248
|
+
|
|
226
249
|
{#if showMessage}
|
|
227
250
|
<div class="alert alert-success" transition:fade={{ duration: 2000 }}>
|
|
228
251
|
{successMessage}
|
|
@@ -249,6 +272,10 @@
|
|
|
249
272
|
{@render renderHidden(field)}
|
|
250
273
|
{:else if field.typeOfField === 'date'}
|
|
251
274
|
{@render renderDatePicker(field)}
|
|
275
|
+
{:else if field.typeOfField === 'markdown'}
|
|
276
|
+
{@render renderMdEditory(field)}
|
|
277
|
+
{:else if field.typeOfField === 'html'}
|
|
278
|
+
{@render renderHtmlEditory(field)}
|
|
252
279
|
{/if}
|
|
253
280
|
{/each}
|
|
254
281
|
|
|
@@ -12,7 +12,9 @@ export declare enum InputType {
|
|
|
12
12
|
Date = "date",
|
|
13
13
|
DateTimeLocal = "datetime-local",
|
|
14
14
|
Color = "color",
|
|
15
|
-
Textarea = "textarea"
|
|
15
|
+
Textarea = "textarea",
|
|
16
|
+
Markdown = "markdown",
|
|
17
|
+
Html = "html"
|
|
16
18
|
}
|
|
17
19
|
export type FieldDef = {
|
|
18
20
|
id: string;
|
|
@@ -82,7 +84,13 @@ export type PhoneInputField = FieldDef & {
|
|
|
82
84
|
size: "md" | "sm" | "lg";
|
|
83
85
|
placeholder?: string;
|
|
84
86
|
};
|
|
85
|
-
export type
|
|
87
|
+
export type MarkdownEditorField = FieldDef & {
|
|
88
|
+
typeOfField: "markdown";
|
|
89
|
+
};
|
|
90
|
+
export type HtmlEditorField = FieldDef & {
|
|
91
|
+
typeOfField: "html";
|
|
92
|
+
};
|
|
93
|
+
export type Field = InputField | TextareaField | CollectionField | SelectField | FilePickerField | DatePickerField | DropzoneField | TimePickerField | PhoneInputField | HiddenField | MarkdownEditorField | HtmlEditorField;
|
|
86
94
|
export declare enum SubmitResult {
|
|
87
95
|
Success = "success",
|
|
88
96
|
Error = "error"
|
|
@@ -107,6 +115,11 @@ export declare function createSelectField(id: string, label: string, selectOptio
|
|
|
107
115
|
export declare function createTimePickerField(id: string, label: string, value?: any, options?: Partial<Omit<TimePickerField, "id" | "label" | "typeOfField">>): TimePickerField;
|
|
108
116
|
export declare function createPhoneInputField(id: string, label: string, value?: any, options?: Partial<Omit<PhoneInputField, "id" | "label" | "typeOfField">>): PhoneInputField;
|
|
109
117
|
export declare function createHiddenField(id: string, value: string): HiddenField;
|
|
118
|
+
export declare function createEditorField(id: string, value: string, type: "markdown" | "html"): {
|
|
119
|
+
id: string;
|
|
120
|
+
value: string;
|
|
121
|
+
typeOfField: "html" | "markdown";
|
|
122
|
+
};
|
|
110
123
|
export type ButtonConfig = {
|
|
111
124
|
label: string;
|
|
112
125
|
type: "submit" | "reset" | "button";
|
|
@@ -15,6 +15,8 @@ export var InputType;
|
|
|
15
15
|
InputType["DateTimeLocal"] = "datetime-local";
|
|
16
16
|
InputType["Color"] = "color";
|
|
17
17
|
InputType["Textarea"] = "textarea";
|
|
18
|
+
InputType["Markdown"] = "markdown";
|
|
19
|
+
InputType["Html"] = "html";
|
|
18
20
|
})(InputType || (InputType = {}));
|
|
19
21
|
export var SubmitResult;
|
|
20
22
|
(function (SubmitResult) {
|
|
@@ -114,3 +116,10 @@ export function createHiddenField(id, value) {
|
|
|
114
116
|
typeOfField: "hidden",
|
|
115
117
|
};
|
|
116
118
|
}
|
|
119
|
+
export function createEditorField(id, value, type) {
|
|
120
|
+
return {
|
|
121
|
+
id,
|
|
122
|
+
value,
|
|
123
|
+
typeOfField: type,
|
|
124
|
+
};
|
|
125
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ export { default as Well } from './components/presentation/Well.svelte';
|
|
|
10
10
|
export { default as FlexBox } from './components/presentation/FlexBox.svelte';
|
|
11
11
|
export { default as StyleBox } from './components/presentation/StyleBox.svelte';
|
|
12
12
|
export { default as ImageCompare } from './components/presentation/ImageCompare.svelte';
|
|
13
|
-
export { InputType, type Field, type InputField, type TextareaField, type CollectionField, type SelectField, type FilePickerField, type TimePickerField, type PhoneInputField, type DatePickerField, type DropzoneField, type HiddenField, type ButtonConfig, SubmitResult, createInputField, createTextareaField, createFilePickerField, createCollectionField, createSelectField, createTimePickerField, createPhoneInputField, createHiddenField, createDatePickerField, } from './components/form/form.js';
|
|
13
|
+
export { InputType, type Field, type InputField, type TextareaField, type CollectionField, type SelectField, type FilePickerField, type TimePickerField, type PhoneInputField, type DatePickerField, type DropzoneField, type HiddenField, type ButtonConfig, type MarkdownEditorField, type HtmlEditorField, SubmitResult, createInputField, createTextareaField, createFilePickerField, createCollectionField, createSelectField, createTimePickerField, createPhoneInputField, createHiddenField, createDatePickerField, createEditorField, } from './components/form/form.js';
|
|
14
14
|
export { default as AntiBot } from './components/form/AntiBot.svelte';
|
|
15
15
|
export { default as SmartForm } from './components/form/SmartForm.svelte';
|
|
16
16
|
export { default as EasyTools } from './components/integrations/EasyTools.svelte';
|
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ export { default as Well } from './components/presentation/Well.svelte';
|
|
|
9
9
|
export { default as FlexBox } from './components/presentation/FlexBox.svelte';
|
|
10
10
|
export { default as StyleBox } from './components/presentation/StyleBox.svelte';
|
|
11
11
|
export { default as ImageCompare } from './components/presentation/ImageCompare.svelte';
|
|
12
|
-
export { InputType, SubmitResult, createInputField, createTextareaField, createFilePickerField, createCollectionField, createSelectField, createTimePickerField, createPhoneInputField, createHiddenField, createDatePickerField, } from './components/form/form.js';
|
|
12
|
+
export { InputType, SubmitResult, createInputField, createTextareaField, createFilePickerField, createCollectionField, createSelectField, createTimePickerField, createPhoneInputField, createHiddenField, createDatePickerField, createEditorField, } from './components/form/form.js';
|
|
13
13
|
export { default as AntiBot } from './components/form/AntiBot.svelte';
|
|
14
14
|
export { default as SmartForm } from './components/form/SmartForm.svelte';
|
|
15
15
|
export { default as EasyTools } from './components/integrations/EasyTools.svelte';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@functionalcms/svelte-components",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.9.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"watch": {
|
|
6
6
|
"build": {
|
|
@@ -56,6 +56,8 @@
|
|
|
56
56
|
"vite": "^8.0.1"
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
|
+
"@milkdown/kit": "^7.21.2",
|
|
60
|
+
"@milkdown/theme-nord": "^7.21.2",
|
|
59
61
|
"@tailwindcss/vite": "^4.2.2",
|
|
60
62
|
"@upstash/redis": "^1.37.0",
|
|
61
63
|
"flowbite": "^4.0.1",
|