@humandialog/forms.svelte 0.5.11 → 0.5.13
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/components/combo/combo.d.ts +2 -0
- package/components/combo/combo.item.svelte +2 -0
- package/components/combo/combo.item.svelte.d.ts +1 -0
- package/components/combo/combo.js +2 -0
- package/components/combo/combo.source.svelte +2 -0
- package/components/combo/combo.source.svelte.d.ts +1 -0
- package/components/combo/combo.svelte +19 -0
- package/components/document/internal/palette.row.svelte +4 -1
- package/components/document/internal/palette.row.svelte.d.ts +1 -0
- package/components/document/internal/palette.svelte +99 -19
- package/components/document/internal/palette.svelte.d.ts +6 -1
- package/components/document/rich.edit.svelte +69 -25
- package/components/document/rich.edit.svelte.d.ts +2 -0
- package/components/kanban/Kanban.d.ts +2 -0
- package/components/kanban/Kanban.js +3 -1
- package/components/kanban/internal/kanban.card.svelte +60 -21
- package/components/kanban/internal/kanban.column.svelte +25 -6
- package/components/kanban/kanban.column.svelte +1 -1
- package/components/kanban/kanban.title.svelte +4 -0
- package/components/kanban/kanban.title.svelte.d.ts +2 -0
- package/components/list/internal/list.element.svelte +64 -32
- package/index.d.ts +2 -2
- package/index.js +2 -2
- package/package.json +2 -2
- package/stores.d.ts +2 -2
- package/stores.js +4 -4
- package/utils.d.ts +2 -0
- package/utils.js +23 -0
|
@@ -3,6 +3,7 @@ export declare class rCombo_item {
|
|
|
3
3
|
Name: string | undefined;
|
|
4
4
|
Avatar: string | undefined;
|
|
5
5
|
Color: string | undefined;
|
|
6
|
+
Icon: any | undefined;
|
|
6
7
|
}
|
|
7
8
|
export declare class rCombo_definition {
|
|
8
9
|
source: rCombo_item[];
|
|
@@ -13,5 +14,6 @@ export declare class rCombo_definition {
|
|
|
13
14
|
element_key: string | undefined;
|
|
14
15
|
element_name: string | undefined;
|
|
15
16
|
element_avatar: string | undefined;
|
|
17
|
+
element_icon: string | undefined;
|
|
16
18
|
}
|
|
17
19
|
export declare const cached_sources: Map<string, Promise<object>>;
|
|
@@ -4,11 +4,13 @@ export let key = void 0;
|
|
|
4
4
|
export let name = void 0;
|
|
5
5
|
export let avatar = void 0;
|
|
6
6
|
export let color = void 0;
|
|
7
|
+
export let icon = void 0;
|
|
7
8
|
let definition = getContext("rCombo-definition");
|
|
8
9
|
let item = new rCombo_item();
|
|
9
10
|
item.Name = name;
|
|
10
11
|
item.Key = key;
|
|
11
12
|
item.Avatar = avatar;
|
|
12
13
|
item.Color = color;
|
|
14
|
+
item.Icon = icon;
|
|
13
15
|
definition.source.push(item);
|
|
14
16
|
</script>
|
|
@@ -3,6 +3,7 @@ export class rCombo_item {
|
|
|
3
3
|
Name;
|
|
4
4
|
Avatar; //url to avatar
|
|
5
5
|
Color;
|
|
6
|
+
Icon = undefined;
|
|
6
7
|
}
|
|
7
8
|
export class rCombo_definition {
|
|
8
9
|
source = [];
|
|
@@ -13,5 +14,6 @@ export class rCombo_definition {
|
|
|
13
14
|
element_key;
|
|
14
15
|
element_name;
|
|
15
16
|
element_avatar;
|
|
17
|
+
element_icon;
|
|
16
18
|
}
|
|
17
19
|
export const cached_sources = new Map();
|
|
@@ -6,6 +6,7 @@ export let onCollect = void 0;
|
|
|
6
6
|
export let key = "";
|
|
7
7
|
export let name = "";
|
|
8
8
|
export let avatar = "";
|
|
9
|
+
export let icon = "";
|
|
9
10
|
let definition = getContext("rCombo-definition");
|
|
10
11
|
definition.collection_expr = association;
|
|
11
12
|
definition.collection_path = path;
|
|
@@ -14,4 +15,5 @@ definition.onCollect = onCollect;
|
|
|
14
15
|
definition.element_key = key;
|
|
15
16
|
definition.element_name = name;
|
|
16
17
|
definition.element_avatar = avatar;
|
|
18
|
+
definition.element_icon = icon;
|
|
17
19
|
</script>
|
|
@@ -84,6 +84,14 @@ function setup(...args) {
|
|
|
84
84
|
item = self ?? $contextItemsStore[ctx];
|
|
85
85
|
if (!typename)
|
|
86
86
|
typename = $contextTypesStore[ctx];
|
|
87
|
+
if (!typename) {
|
|
88
|
+
if (item.$type)
|
|
89
|
+
typename = item.$type;
|
|
90
|
+
else if (item.$ref) {
|
|
91
|
+
let s2 = item.$ref.split("/");
|
|
92
|
+
typename = s2[1];
|
|
93
|
+
}
|
|
94
|
+
}
|
|
87
95
|
if (!label)
|
|
88
96
|
label = a;
|
|
89
97
|
tick_request_internal = tick_request_internal + 1;
|
|
@@ -236,6 +244,7 @@ function selected_item(itm, a2) {
|
|
|
236
244
|
let found = definition.source.find((e) => e.Key == choosed_value);
|
|
237
245
|
if (!found)
|
|
238
246
|
found = definition.source.find((e) => e.Name == choosed_value);
|
|
247
|
+
console.log("found: ", found);
|
|
239
248
|
if (found)
|
|
240
249
|
return found;
|
|
241
250
|
else
|
|
@@ -493,6 +502,8 @@ function source_fetched(source) {
|
|
|
493
502
|
if (icon) {
|
|
494
503
|
if (definition.element_avatar)
|
|
495
504
|
el.Avatar = e[definition.element_avatar];
|
|
505
|
+
else if (definition.element_icon)
|
|
506
|
+
el.Icon = e[definition.element_icon];
|
|
496
507
|
else
|
|
497
508
|
el.Avatar = e.$icon;
|
|
498
509
|
}
|
|
@@ -541,6 +552,10 @@ function on_focus_out(e) {
|
|
|
541
552
|
{#if icon && sel_item}
|
|
542
553
|
{#if sel_item.Color}
|
|
543
554
|
<Icon size={5} circle={true} color={sel_item.Color}/>
|
|
555
|
+
{:else if sel_item.Icon}
|
|
556
|
+
<Icon size={4} component={sel_item.Icon}/>
|
|
557
|
+
{:else if sel_item.Icon == null}
|
|
558
|
+
<div class="w-4 h-4"></div>
|
|
544
559
|
{:else}
|
|
545
560
|
<Icon size={5} circle={true} symbol={sel_item.Avatar} label={sel_item.Name}/>
|
|
546
561
|
{/if}
|
|
@@ -591,6 +606,10 @@ function on_focus_out(e) {
|
|
|
591
606
|
<Icon size={5} circle={true} color={item.Color}/>
|
|
592
607
|
{:else if item.Avatar}
|
|
593
608
|
<Icon size={5} circle={true} symbol={item.Avatar}/>
|
|
609
|
+
{:else if item.Icon}
|
|
610
|
+
<Icon size={4} component={item.Icon}/>
|
|
611
|
+
{:else if item.Icon == null}
|
|
612
|
+
<div class="w-4 h-4"></div>
|
|
594
613
|
{:else if item.Name}
|
|
595
614
|
<Icon size={5} circle={true} label={item.Name}/>
|
|
596
615
|
{:else}
|
|
@@ -12,7 +12,10 @@ $:
|
|
|
12
12
|
</script>
|
|
13
13
|
|
|
14
14
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
15
|
-
<div id={id} class="font-medium m-0 p-0 text-sm w-full text-left flex flew-row cursor-context-menu {active_class} {cl}"
|
|
15
|
+
<div id={id} class="font-medium m-0 p-0 text-sm w-full text-left flex flew-row cursor-context-menu {active_class} {cl}"
|
|
16
|
+
on:click
|
|
17
|
+
on:mousemove
|
|
18
|
+
on:mousedown>
|
|
16
19
|
<div class="flex items-center justify-center" style:width={`${icon_placeholder_size*0.25}rem`}>
|
|
17
20
|
{#if cmd.icon}
|
|
18
21
|
<Icon size={icon_size} component={cmd.icon}/>
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
<script>import { tick } from "svelte";
|
|
3
3
|
import Pallete_row from "./palette.row.svelte";
|
|
4
4
|
import { createEventDispatcher } from "svelte";
|
|
5
|
+
import Icon from "../../icon.svelte";
|
|
6
|
+
import { isDeviceSmallerThan } from "../../../utils.js";
|
|
5
7
|
export let commands;
|
|
6
8
|
export let width_px = 400;
|
|
7
9
|
export let max_height_px = 500;
|
|
@@ -9,8 +11,22 @@ let visible = false;
|
|
|
9
11
|
let css_style = "";
|
|
10
12
|
let filtered_commands = [...commands];
|
|
11
13
|
let current_command = filtered_commands.length ? filtered_commands[0] : null;
|
|
14
|
+
let isToolbox = false;
|
|
12
15
|
const dispatch = createEventDispatcher();
|
|
16
|
+
let toolboxX;
|
|
17
|
+
let toolboxY;
|
|
18
|
+
export function showAsToolbox(rect) {
|
|
19
|
+
isToolbox = true;
|
|
20
|
+
visible = true;
|
|
21
|
+
const margin = 15;
|
|
22
|
+
const windowWidth = window.innerWidth - 2 * margin;
|
|
23
|
+
toolboxX = margin;
|
|
24
|
+
toolboxY = rect.bottom + margin;
|
|
25
|
+
css_style = `position: absolute; left:${toolboxX}px; top:${toolboxY}px;`;
|
|
26
|
+
dispatch("palette_shown");
|
|
27
|
+
}
|
|
13
28
|
export function show(x, y, up = false) {
|
|
29
|
+
isToolbox = false;
|
|
14
30
|
css_style = `width: ${width_px}px; max-height:${max_height_px}px; position: fixed; left:${x}px; top:${y}px;`;
|
|
15
31
|
if (up)
|
|
16
32
|
css_style += " transform: translate(0, -100%);";
|
|
@@ -18,6 +34,7 @@ export function show(x, y, up = false) {
|
|
|
18
34
|
dispatch("palette_shown");
|
|
19
35
|
}
|
|
20
36
|
export function show_fullscreen(_width_px, _height_px) {
|
|
37
|
+
isToolbox = false;
|
|
21
38
|
width_px = _width_px;
|
|
22
39
|
max_height_px = _height_px;
|
|
23
40
|
css_style = `position: fixed; left: 0px; top: 0px; width: ${_width_px}px; height: ${_height_px}px; z-index: 1055;`;
|
|
@@ -26,6 +43,7 @@ export function show_fullscreen(_width_px, _height_px) {
|
|
|
26
43
|
}
|
|
27
44
|
export function hide() {
|
|
28
45
|
visible = false;
|
|
46
|
+
isToolbox = false;
|
|
29
47
|
dispatch("palette_hidden");
|
|
30
48
|
}
|
|
31
49
|
export function execute_selected_command() {
|
|
@@ -84,7 +102,6 @@ async function execute_mouse_click(on_choice) {
|
|
|
84
102
|
if (!visible)
|
|
85
103
|
return;
|
|
86
104
|
dispatch("palette_mouse_click");
|
|
87
|
-
await tick();
|
|
88
105
|
hide();
|
|
89
106
|
on_choice();
|
|
90
107
|
}
|
|
@@ -100,24 +117,87 @@ function update_current_command(cmd) {
|
|
|
100
117
|
rows.find((r) => r.cmd == cmd).is_highlighted = true;
|
|
101
118
|
current_command = cmd;
|
|
102
119
|
}
|
|
120
|
+
function buttonMousedown(e) {
|
|
121
|
+
e.preventDefault();
|
|
122
|
+
}
|
|
123
|
+
let isMoving = false;
|
|
124
|
+
let beforeTrackingClient = null;
|
|
125
|
+
let beforeTrackingPos = null;
|
|
126
|
+
function mousedown(e) {
|
|
127
|
+
if (e.touches.length != 1)
|
|
128
|
+
return;
|
|
129
|
+
const touch = e.touches.item(0);
|
|
130
|
+
beforeTrackingClient = new DOMPoint(touch.clientX, touch.clientY);
|
|
131
|
+
beforeTrackingPos = new DOMPoint(toolboxX, toolboxY);
|
|
132
|
+
isMoving = true;
|
|
133
|
+
}
|
|
134
|
+
function mousemove(e) {
|
|
135
|
+
if (isMoving && beforeTrackingClient && beforeTrackingPos) {
|
|
136
|
+
if (e.touches.length != 1)
|
|
137
|
+
return;
|
|
138
|
+
const touch = e.touches.item(0);
|
|
139
|
+
const trackDelta = new DOMPoint(touch.clientX - beforeTrackingClient.x, touch.clientY - beforeTrackingClient.y);
|
|
140
|
+
toolboxX = beforeTrackingPos.x + trackDelta.x;
|
|
141
|
+
css_style = `position: fixed; left:${toolboxX}px; top:${toolboxY}px;`;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
function mouseup(e) {
|
|
145
|
+
isMoving = false;
|
|
146
|
+
beforeTrackingClient = null;
|
|
147
|
+
beforeTrackingPos = null;
|
|
148
|
+
}
|
|
103
149
|
</script>
|
|
104
150
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
{
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
151
|
+
{#if isToolbox}
|
|
152
|
+
<menu class=" not-prose bg-white dark:bg-stone-800 text-stone-500 dark:text-stone-400 rounded-lg border border-stone-200 dark:border-stone-700 shadow-md
|
|
153
|
+
z-30
|
|
154
|
+
flex flex-row flex-nowrap"
|
|
155
|
+
style={css_style}
|
|
156
|
+
hidden={!visible}
|
|
157
|
+
on:touchstart={mousedown}
|
|
158
|
+
on:touchmove={mousemove}
|
|
159
|
+
on:touchend={mouseup}>
|
|
160
|
+
{#if filtered_commands && filtered_commands.length}
|
|
161
|
+
{#each filtered_commands as cmd, idx (cmd.caption)}
|
|
162
|
+
{@const id = "cpi_" + idx}
|
|
163
|
+
{@const mobile = isDeviceSmallerThan("sm")}
|
|
164
|
+
{@const icon_placeholder_size = mobile ? 12 : 10}
|
|
165
|
+
<button class="font-medium m-0 py-2 pr-4 text-lg sm:text-sm w-full text-left flex flex-row cursor-context-menu focus:outline-none"
|
|
166
|
+
{id}
|
|
167
|
+
bind:this={rows[idx]}
|
|
168
|
+
on:click={ () => { execute_mouse_click(cmd.on_choice); }}
|
|
169
|
+
on:mousedown={buttonMousedown}>
|
|
170
|
+
|
|
171
|
+
<div class="flex items-center justify-center mt-1 sm:mt-0.5" style:width={`${icon_placeholder_size*0.25}rem`}>
|
|
172
|
+
{#if cmd.icon}
|
|
173
|
+
{@const cc = mobile ? 7 : 6}
|
|
174
|
+
{@const icon_size = icon_placeholder_size - cc}
|
|
175
|
+
<Icon size={icon_size} component={cmd.icon}/>
|
|
176
|
+
{/if}
|
|
177
|
+
</div>
|
|
178
|
+
</button>
|
|
179
|
+
{/each}
|
|
180
|
+
{/if}
|
|
181
|
+
</menu>
|
|
182
|
+
{:else}
|
|
183
|
+
<div class="not-prose bg-white dark:bg-stone-800 text-stone-500 dark:text-stone-400 rounded-lg border border-stone-200 dark:border-stone-700 shadow-md z-30"
|
|
184
|
+
hidden={!visible}
|
|
185
|
+
style={css_style}>
|
|
186
|
+
{#if filtered_commands && filtered_commands.length}
|
|
187
|
+
{#each filtered_commands as cmd, idx (cmd.caption)}
|
|
188
|
+
{@const id = "cpi_" + idx}
|
|
189
|
+
<Pallete_row {id}
|
|
190
|
+
cmd={cmd}
|
|
191
|
+
is_highlighted={cmd == current_command}
|
|
192
|
+
on:click={ () => { execute_mouse_click(cmd.on_choice); }}
|
|
193
|
+
on:mousemove={ () => { on_mouse_over(cmd); }}
|
|
194
|
+
on:mousedown={buttonMousedown}
|
|
195
|
+
bind:this={rows[idx]}
|
|
196
|
+
/>
|
|
197
|
+
{/each}
|
|
198
|
+
{:else}
|
|
199
|
+
<p class="text-sm text-stone-500">No results</p>
|
|
200
|
+
{/if}
|
|
122
201
|
|
|
123
|
-
</div>
|
|
202
|
+
</div>
|
|
203
|
+
{/if}
|
|
@@ -5,6 +5,7 @@ declare const __propDef: {
|
|
|
5
5
|
commands: Document_command[];
|
|
6
6
|
width_px?: number | undefined;
|
|
7
7
|
max_height_px?: number | undefined;
|
|
8
|
+
showAsToolbox?: ((rect: DOMRect) => void) | undefined;
|
|
8
9
|
show?: ((x: number, y: number, up?: boolean) => void) | undefined;
|
|
9
10
|
show_fullscreen?: ((_width_px: number, _height_px: number) => void) | undefined;
|
|
10
11
|
hide?: (() => void) | undefined;
|
|
@@ -20,12 +21,13 @@ declare const __propDef: {
|
|
|
20
21
|
} & {
|
|
21
22
|
[evt: string]: CustomEvent<any>;
|
|
22
23
|
};
|
|
23
|
-
slots: {};
|
|
24
|
+
slots: {};
|
|
24
25
|
};
|
|
25
26
|
export type PaletteProps = typeof __propDef.props;
|
|
26
27
|
export type PaletteEvents = typeof __propDef.events;
|
|
27
28
|
export type PaletteSlots = typeof __propDef.slots;
|
|
28
29
|
export default class Palette extends SvelteComponentTyped<PaletteProps, PaletteEvents, PaletteSlots> {
|
|
30
|
+
get showAsToolbox(): (rect: DOMRect) => void;
|
|
29
31
|
get show(): (x: number, y: number, up?: boolean) => void;
|
|
30
32
|
get show_fullscreen(): (_width_px: number, _height_px: number) => void;
|
|
31
33
|
get hide(): () => void;
|
|
@@ -63,5 +65,8 @@ export default class Palette extends SvelteComponentTyped<PaletteProps, PaletteE
|
|
|
63
65
|
get undefined(): any;
|
|
64
66
|
/**accessor*/
|
|
65
67
|
set undefined(_: any);
|
|
68
|
+
get undefined(): any;
|
|
69
|
+
/**accessor*/
|
|
70
|
+
set undefined(_: any);
|
|
66
71
|
}
|
|
67
72
|
export {};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<script>import { Selection_helper } from "./internal/Selection_helper";
|
|
2
|
-
import { getContext, onDestroy, onMount } from "svelte";
|
|
2
|
+
import { afterUpdate, getContext, onDestroy, onMount } from "svelte";
|
|
3
3
|
import { Selection_range, Selection_edge } from "./internal/Selection_range";
|
|
4
4
|
import { data_tick_store, contextItemsStore, contextTypesStore } from "../../stores.js";
|
|
5
5
|
import { informModification, pushChanges } from "../../updates.js";
|
|
6
|
-
import { parseWidthDirective } from "../../utils.js";
|
|
6
|
+
import { isDeviceSmallerThan, parseWidthDirective } from "../../utils.js";
|
|
7
7
|
import Palette from "./internal/palette.svelte";
|
|
8
8
|
import FaFont from "svelte-icons/fa/FaFont.svelte";
|
|
9
9
|
import FaRemoveFormat from "svelte-icons/fa/FaRemoveFormat.svelte";
|
|
@@ -13,6 +13,7 @@ import FaComments from "svelte-icons/fa/FaComment.svelte";
|
|
|
13
13
|
import FaQuote from "svelte-icons/fa/FaQuoteRight.svelte";
|
|
14
14
|
import FaWarn from "svelte-icons/fa/FaExclamationTriangle.svelte";
|
|
15
15
|
import FaInfo from "svelte-icons/fa/FaInfo.svelte";
|
|
16
|
+
import { showMenu } from "../menu";
|
|
16
17
|
export let value = "";
|
|
17
18
|
export let placeholder = "";
|
|
18
19
|
export let self = null;
|
|
@@ -62,8 +63,12 @@ else
|
|
|
62
63
|
px-2.5`;
|
|
63
64
|
let last_tick = -1;
|
|
64
65
|
$: {
|
|
65
|
-
if (last_tick < $data_tick_store)
|
|
66
|
-
|
|
66
|
+
if (last_tick < $data_tick_store) {
|
|
67
|
+
if (has_changed_value)
|
|
68
|
+
saveData();
|
|
69
|
+
else
|
|
70
|
+
setup_source();
|
|
71
|
+
}
|
|
67
72
|
}
|
|
68
73
|
function setup_source() {
|
|
69
74
|
last_tick = $data_tick_store;
|
|
@@ -80,6 +85,8 @@ function setup_source() {
|
|
|
80
85
|
if (!value)
|
|
81
86
|
value = "<p>\u200B</p>";
|
|
82
87
|
has_changed_value = false;
|
|
88
|
+
if (stored_selection)
|
|
89
|
+
set_selection(stored_selection);
|
|
83
90
|
}
|
|
84
91
|
onMount(() => {
|
|
85
92
|
if (!editable_div)
|
|
@@ -95,6 +102,9 @@ onMount(() => {
|
|
|
95
102
|
subtree: true
|
|
96
103
|
});
|
|
97
104
|
}
|
|
105
|
+
return () => {
|
|
106
|
+
on_blur();
|
|
107
|
+
};
|
|
98
108
|
});
|
|
99
109
|
onDestroy(() => {
|
|
100
110
|
if (!editable_div)
|
|
@@ -166,9 +176,12 @@ const on_keydown = (event) => {
|
|
|
166
176
|
} else {
|
|
167
177
|
event.cancelBubble = true;
|
|
168
178
|
event.preventDefault();
|
|
169
|
-
if (is_multiline())
|
|
170
|
-
|
|
171
|
-
|
|
179
|
+
if (is_multiline()) {
|
|
180
|
+
if (event.shiftKey)
|
|
181
|
+
insert_character_at_caret_position("\n");
|
|
182
|
+
else
|
|
183
|
+
insert_new_line();
|
|
184
|
+
} else
|
|
172
185
|
move_cursor_to_next_editable_element();
|
|
173
186
|
}
|
|
174
187
|
break;
|
|
@@ -176,6 +189,11 @@ const on_keydown = (event) => {
|
|
|
176
189
|
store_node_text_and_position();
|
|
177
190
|
show_command_palette();
|
|
178
191
|
break;
|
|
192
|
+
case "Tab":
|
|
193
|
+
event.cancelBubble = true;
|
|
194
|
+
event.preventDefault();
|
|
195
|
+
insert_character_at_caret_position(" ");
|
|
196
|
+
break;
|
|
179
197
|
case "Backspace":
|
|
180
198
|
if (is_range_selected()) {
|
|
181
199
|
if (is_multi_range_selection()) {
|
|
@@ -715,7 +733,7 @@ function set_tag_and_class_for_paragraph(node, tag, css_class) {
|
|
|
715
733
|
while (node && node.nodeType !== Node.ELEMENT_NODE)
|
|
716
734
|
node = node.parentNode;
|
|
717
735
|
if (!node)
|
|
718
|
-
return;
|
|
736
|
+
return false;
|
|
719
737
|
let element = node;
|
|
720
738
|
if (element.tagName == tag.toUpperCase()) {
|
|
721
739
|
element.className = css_class;
|
|
@@ -737,7 +755,7 @@ function set_tag_and_class_for_paragraph(node, tag, css_class) {
|
|
|
737
755
|
function do_format(tag, css_class) {
|
|
738
756
|
const elem = editable_div;
|
|
739
757
|
const editableElem = editable_div;
|
|
740
|
-
let
|
|
758
|
+
let stored_selection2 = Selection_helper.get_selection(elem);
|
|
741
759
|
let sel = window.getSelection();
|
|
742
760
|
let should_restore_selection = false;
|
|
743
761
|
if (sel.isCollapsed || sel.focusNode === sel.anchorNode) {
|
|
@@ -766,7 +784,28 @@ function do_format(tag, css_class) {
|
|
|
766
784
|
} while (node);
|
|
767
785
|
}
|
|
768
786
|
if (should_restore_selection) {
|
|
769
|
-
const range = Selection_helper.create_range(editableElem,
|
|
787
|
+
const range = Selection_helper.create_range(editableElem, stored_selection2.begin.absolute_index, stored_selection2.end.absolute_index);
|
|
788
|
+
set_selection(range);
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
function insert_character_at_caret_position(what_to_insert) {
|
|
792
|
+
if (is_range_selected()) {
|
|
793
|
+
console.log("Unsupported");
|
|
794
|
+
return false;
|
|
795
|
+
} else {
|
|
796
|
+
let sel;
|
|
797
|
+
sel = window.getSelection();
|
|
798
|
+
const focusNode = sel.focusNode;
|
|
799
|
+
const wholeText = focusNode.textContent;
|
|
800
|
+
const carretPos = sel.focusOffset;
|
|
801
|
+
let leftPart = wholeText.substring(0, carretPos);
|
|
802
|
+
let rightPart = wholeText.substring(carretPos);
|
|
803
|
+
focusNode.textContent = leftPart + what_to_insert + rightPart;
|
|
804
|
+
let pos = carretPos + 1;
|
|
805
|
+
let range = new Range();
|
|
806
|
+
range.collapse(true);
|
|
807
|
+
range.setStart(focusNode, pos);
|
|
808
|
+
range.setEnd(focusNode, pos);
|
|
770
809
|
set_selection(range);
|
|
771
810
|
}
|
|
772
811
|
}
|
|
@@ -879,7 +918,10 @@ function show_command_palette() {
|
|
|
879
918
|
y = rect.y - (preferred_palette_height - bottom_space);
|
|
880
919
|
} else
|
|
881
920
|
show_fullscreen = true;
|
|
882
|
-
|
|
921
|
+
const isSmallDevice = isDeviceSmallerThan("sm");
|
|
922
|
+
if (isSmallDevice) {
|
|
923
|
+
palette.showAsToolbox(rect);
|
|
924
|
+
} else if (show_fullscreen)
|
|
883
925
|
palette.show_fullscreen(client_rect.width, client_rect.height);
|
|
884
926
|
else
|
|
885
927
|
palette.show(x, y, show_above);
|
|
@@ -899,25 +941,18 @@ function navigate_command_palette(key) {
|
|
|
899
941
|
else if (key == "ArrowUp")
|
|
900
942
|
palette.navigate_up();
|
|
901
943
|
}
|
|
944
|
+
let stored_selection = void 0;
|
|
902
945
|
function on_selection_changed() {
|
|
946
|
+
let active_range = Selection_helper.get_selection(editable_div);
|
|
947
|
+
stored_selection = window.getSelection()?.getRangeAt(0);
|
|
903
948
|
}
|
|
904
949
|
let intervalId = 0;
|
|
905
950
|
function on_focus() {
|
|
906
|
-
if (pushChangesImmediately) {
|
|
907
|
-
intervalId = setInterval(
|
|
908
|
-
() => {
|
|
909
|
-
saveData();
|
|
910
|
-
},
|
|
911
|
-
2e3
|
|
912
|
-
);
|
|
913
|
-
}
|
|
914
951
|
}
|
|
915
952
|
function on_blur() {
|
|
916
953
|
let active_range = Selection_helper.get_selection(editable_div);
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
intervalId = 0;
|
|
920
|
-
}
|
|
954
|
+
console.log("rich.edit: on_blur", active_range?.begin?.absolute_index);
|
|
955
|
+
stored_selection = void 0;
|
|
921
956
|
if (onBlur) {
|
|
922
957
|
onBlur();
|
|
923
958
|
onBlur = void 0;
|
|
@@ -927,6 +962,12 @@ function on_blur() {
|
|
|
927
962
|
$data_tick_store = last_tick;
|
|
928
963
|
}
|
|
929
964
|
}
|
|
965
|
+
export function save() {
|
|
966
|
+
if (saveData()) {
|
|
967
|
+
last_tick = $data_tick_store + 1;
|
|
968
|
+
$data_tick_store = last_tick;
|
|
969
|
+
}
|
|
970
|
+
}
|
|
930
971
|
function saveData() {
|
|
931
972
|
if (item && a && has_changed_value) {
|
|
932
973
|
item[a] = changed_value;
|
|
@@ -948,7 +989,10 @@ let commands = [
|
|
|
948
989
|
// { caption: 'Heading 1', description: 'Big section heading', tags: 'h1', icon: FaHead, icon_size: 6, on_choice: () => { do_format('h2', '') } } ,
|
|
949
990
|
// { caption: 'Heading 2', description: 'Medium section heading', tags: 'h2', icon: FaHead, icon_size: 5, on_choice: () => { do_format('h3', '') } } ,
|
|
950
991
|
// { caption: 'Heading 3', description: 'Small section heading', tags: 'h3', icon: FaHead, icon_size: 4, on_choice: () => { do_format('h4', '') } } ,
|
|
951
|
-
{ caption: "Heading", description: "Description heading", tags: "
|
|
992
|
+
{ caption: "Heading 1", description: "Description heading", tags: "h1", icon: FaHead, icon_size: 6, on_choice: () => {
|
|
993
|
+
do_format("h1", "");
|
|
994
|
+
} },
|
|
995
|
+
{ caption: "Heading 2", description: "Description heading", tags: "h2", icon: FaHead, icon_size: 6, on_choice: () => {
|
|
952
996
|
do_format("h2", "");
|
|
953
997
|
} },
|
|
954
998
|
// { caption: 'Heading 2', description: 'Medium description heading', tags: 'h3', icon: FaHead, icon_size: 5, on_choice: () => { do_format('h3', '') } } ,
|
|
@@ -977,7 +1021,7 @@ let commands = [
|
|
|
977
1021
|
on:keydown={on_keydown}
|
|
978
1022
|
on:mouseup={on_mouseup}
|
|
979
1023
|
class="{cs} {appearance_class}
|
|
980
|
-
prose prose-base sm:prose-base dark:prose-invert {additional_class} overflow-y-auto"
|
|
1024
|
+
prose prose-base sm:prose-base dark:prose-invert {additional_class} overflow-y-auto whitespace-pre-wrap"
|
|
981
1025
|
on:blur={on_blur}
|
|
982
1026
|
on:focus={on_focus}
|
|
983
1027
|
on:focus
|
|
@@ -13,6 +13,7 @@ declare const __propDef: {
|
|
|
13
13
|
pushChangesImmediately?: boolean | undefined;
|
|
14
14
|
run?: ((onStop?: undefined) => void) | undefined;
|
|
15
15
|
getFormattingOperations?: ((withCaptions?: boolean) => any[]) | undefined;
|
|
16
|
+
save?: (() => void) | undefined;
|
|
16
17
|
};
|
|
17
18
|
events: {
|
|
18
19
|
focus: FocusEvent;
|
|
@@ -28,5 +29,6 @@ export type RichSlots = typeof __propDef.slots;
|
|
|
28
29
|
export default class Rich extends SvelteComponentTyped<RichProps, RichEvents, RichSlots> {
|
|
29
30
|
get run(): (onStop?: undefined) => void;
|
|
30
31
|
get getFormattingOperations(): (withCaptions?: boolean) => any[];
|
|
32
|
+
get save(): () => void;
|
|
31
33
|
}
|
|
32
34
|
export {};
|
|
@@ -16,6 +16,8 @@ export declare class rKanban_definition {
|
|
|
16
16
|
titleAttrib: string;
|
|
17
17
|
titleOnChange: Function | undefined;
|
|
18
18
|
titleReadOnly: boolean;
|
|
19
|
+
titleHref: string | undefined;
|
|
20
|
+
titleHrefFunc: Function | undefined;
|
|
19
21
|
summaryAttrib: string;
|
|
20
22
|
summaryOnChange: Function | undefined;
|
|
21
23
|
summaryReadOnly: boolean;
|
|
@@ -4,7 +4,7 @@ export const KanbanCardBottom = 3;
|
|
|
4
4
|
export class rKanban_column {
|
|
5
5
|
id;
|
|
6
6
|
title = '';
|
|
7
|
-
width = '
|
|
7
|
+
width = '';
|
|
8
8
|
state = '';
|
|
9
9
|
finishing = false;
|
|
10
10
|
operations = undefined;
|
|
@@ -15,6 +15,8 @@ export class rKanban_definition {
|
|
|
15
15
|
titleAttrib = '';
|
|
16
16
|
titleOnChange = undefined;
|
|
17
17
|
titleReadOnly = false;
|
|
18
|
+
titleHref = undefined;
|
|
19
|
+
titleHrefFunc = undefined;
|
|
18
20
|
summaryAttrib = '';
|
|
19
21
|
summaryOnChange = undefined;
|
|
20
22
|
summaryReadOnly = false;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script>import { getContext, tick } from "svelte";
|
|
2
|
+
import { push } from "svelte-spa-router";
|
|
2
3
|
import {
|
|
3
4
|
contextItemsStore,
|
|
4
5
|
isActive,
|
|
@@ -8,7 +9,8 @@ import {
|
|
|
8
9
|
editable,
|
|
9
10
|
showFloatingToolbar,
|
|
10
11
|
informModification,
|
|
11
|
-
pushChanges
|
|
12
|
+
pushChanges,
|
|
13
|
+
startEditing
|
|
12
14
|
} from "../../..";
|
|
13
15
|
import { FaArrowsAlt, FaTrash, FaPlus, FaExternalLinkAlt } from "svelte-icons/fa";
|
|
14
16
|
import MoveOperations from "./kanban.move.menu.svelte";
|
|
@@ -24,6 +26,8 @@ $:
|
|
|
24
26
|
selectedClass = isCardSelected ? "!border-blue-300" : "";
|
|
25
27
|
$:
|
|
26
28
|
focusedClass = isCardActive ? "bg-stone-100 dark:bg-stone-700" : "";
|
|
29
|
+
$:
|
|
30
|
+
isLinkLike = isCardActive && (!!definition.titleHref || !!definition.titleHrefFunc);
|
|
27
31
|
function calculate_active(...args) {
|
|
28
32
|
return isActive("props", item);
|
|
29
33
|
}
|
|
@@ -96,9 +100,13 @@ let summaryElement;
|
|
|
96
100
|
let summaryPlaceholder = false;
|
|
97
101
|
export async function editProperty(field) {
|
|
98
102
|
if (field == "Title") {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
103
|
+
if (isLinkLike) {
|
|
104
|
+
startEditing(titleElement);
|
|
105
|
+
} else {
|
|
106
|
+
titleElement.focus();
|
|
107
|
+
await tick();
|
|
108
|
+
setSelectionAtEnd(titleElement);
|
|
109
|
+
}
|
|
102
110
|
} else if (field == "Summary") {
|
|
103
111
|
if (!!summaryElement) {
|
|
104
112
|
summaryElement.focus();
|
|
@@ -127,6 +135,19 @@ export async function editProperty(field) {
|
|
|
127
135
|
}
|
|
128
136
|
}
|
|
129
137
|
}
|
|
138
|
+
function followDefinedHRef() {
|
|
139
|
+
let link = getHRef();
|
|
140
|
+
if (link)
|
|
141
|
+
push(link);
|
|
142
|
+
}
|
|
143
|
+
function getHRef() {
|
|
144
|
+
if (definition.titleHref)
|
|
145
|
+
return definition.titleHref;
|
|
146
|
+
else if (definition.titleHrefFunc)
|
|
147
|
+
return definition.titleHrefFunc(item);
|
|
148
|
+
else
|
|
149
|
+
return "";
|
|
150
|
+
}
|
|
130
151
|
</script>
|
|
131
152
|
|
|
132
153
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
@@ -162,25 +183,43 @@ export async function editProperty(field) {
|
|
|
162
183
|
|
|
163
184
|
|
|
164
185
|
{#if isCardActive}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
186
|
+
{#if isLinkLike}
|
|
187
|
+
<h3 class=" text-lg font-semibold min-h-[1.75rem]
|
|
188
|
+
sm:text-sm sm:font-semibold sm:min-h-[1.25rem]
|
|
189
|
+
whitespace-nowrap overflow-clip truncate w-full sm:flex-none
|
|
190
|
+
relative
|
|
191
|
+
sm:hover:cursor-pointer underline"
|
|
192
|
+
on:click|stopPropagation={followDefinedHRef}
|
|
193
|
+
use:editable={{
|
|
194
|
+
action: (text) => onTitleChanged(text),
|
|
195
|
+
active: false,
|
|
196
|
+
readonly: definition.titleReadOnly,
|
|
197
|
+
onFinish: (d) => {titleElement.blur()}}}
|
|
198
|
+
bind:this={titleElement}>
|
|
199
|
+
{item[definition.titleAttrib]}
|
|
200
|
+
</h3>
|
|
201
|
+
{:else}
|
|
202
|
+
<h3 class=" text-lg font-semibold min-h-[1.75rem]
|
|
203
|
+
sm:text-sm sm:font-semibold sm:min-h-[1.25rem]
|
|
204
|
+
whitespace-nowrap overflow-clip truncate w-full sm:flex-none
|
|
205
|
+
relative"
|
|
206
|
+
use:editable={{
|
|
207
|
+
action: (text) => onTitleChanged(text),
|
|
208
|
+
active: true,
|
|
209
|
+
readonly: definition.titleReadOnly,
|
|
210
|
+
onFinish: (d) => {titleElement.blur()}}}
|
|
211
|
+
bind:this={titleElement}>
|
|
212
|
+
{item[definition.titleAttrib]}
|
|
176
213
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
214
|
+
{#if definition.onOpen}
|
|
215
|
+
<button class="absolute top-1 right-0 w-5 h-5 sm:w-3 sm:h-3"
|
|
216
|
+
on:click={(e) => definition.onOpen(item)}>
|
|
217
|
+
<FaExternalLinkAlt/>
|
|
218
|
+
</button>
|
|
219
|
+
{/if}
|
|
220
|
+
</h3>
|
|
182
221
|
{/if}
|
|
183
|
-
|
|
222
|
+
|
|
184
223
|
{:else}
|
|
185
224
|
<h3 class=" text-lg font-semibold min-h-[1.75rem]
|
|
186
225
|
sm:text-sm sm:font-semibold sm:min-h-[1.25rem]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
<script>import { getContext, afterUpdate, tick } from "svelte";
|
|
1
|
+
<script>import { getContext, afterUpdate, tick, onMount } from "svelte";
|
|
2
2
|
import { data_tick_store, contextItemsStore, contextTypesStore } from "../../../stores";
|
|
3
|
-
import { getActive, activateItem, editable, isActive, isSelected, selectable, startEditing } from "../../../utils.js";
|
|
3
|
+
import { getActive, activateItem, editable, isActive, isSelected, selectable, startEditing, isDeviceSmallerThan } from "../../../utils.js";
|
|
4
4
|
import Card from "./kanban.card.svelte";
|
|
5
5
|
import { KanbanColumnTop, KanbanColumnBottom } from "../Kanban";
|
|
6
6
|
import Inserter from "./kanban.inserter.svelte";
|
|
@@ -38,7 +38,6 @@ export function setBorder(what_to_do) {
|
|
|
38
38
|
let definition = getContext("rKanban-definition");
|
|
39
39
|
let columnDef = definition.columns[currentColumnIdx];
|
|
40
40
|
let column_items = void 0;
|
|
41
|
-
let width_class = columnDef.width ? `w-11/12 sm:${columnDef.width}` : "w-11/12 sm:w-[240px]";
|
|
42
41
|
$:
|
|
43
42
|
setup_data();
|
|
44
43
|
$:
|
|
@@ -165,6 +164,25 @@ export function activate(e) {
|
|
|
165
164
|
}
|
|
166
165
|
);
|
|
167
166
|
}
|
|
167
|
+
onMount(() => {
|
|
168
|
+
window.addEventListener("resize", onResizeWindow);
|
|
169
|
+
return () => {
|
|
170
|
+
window.removeEventListener("resize", onResizeWindow);
|
|
171
|
+
};
|
|
172
|
+
});
|
|
173
|
+
let styleWidth = getWidthStyle();
|
|
174
|
+
function onResizeWindow() {
|
|
175
|
+
styleWidth = getWidthStyle();
|
|
176
|
+
}
|
|
177
|
+
function getWidthStyle() {
|
|
178
|
+
const assumed_space = 800;
|
|
179
|
+
const default_column_width = Math.floor(assumed_space / definition.columns.length);
|
|
180
|
+
const column_width = columnDef.width ? columnDef.width : default_column_width;
|
|
181
|
+
if (window.innerWidth >= 640)
|
|
182
|
+
return `width: ${column_width}px; min-width: 180px; max-width: ${column_width}px;`;
|
|
183
|
+
else
|
|
184
|
+
return "width: 92%;";
|
|
185
|
+
}
|
|
168
186
|
</script>
|
|
169
187
|
|
|
170
188
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
@@ -172,11 +190,11 @@ export function activate(e) {
|
|
|
172
190
|
<section class=" snap-center
|
|
173
191
|
sm:snap-align-none
|
|
174
192
|
flex-none sm:flex-1
|
|
175
|
-
sm:min-w-[180px] sm:max-w-[240px]
|
|
176
193
|
sm:min-h-[calc(100vh-8rem)]
|
|
177
194
|
min-h-[calc(100vh-5rem)]
|
|
178
195
|
rounded-md border border-transparent
|
|
179
|
-
{
|
|
196
|
+
{selected_class} {focused_class}"
|
|
197
|
+
style={styleWidth}
|
|
180
198
|
use:selectable={columnDef}
|
|
181
199
|
on:click={activate}>
|
|
182
200
|
<header class:cursor-pointer={!is_row_active && columnDef.operations} bind:this={headerElement}>
|
|
@@ -237,4 +255,5 @@ export function activate(e) {
|
|
|
237
255
|
{/if}
|
|
238
256
|
|
|
239
257
|
</ul>
|
|
240
|
-
</section>
|
|
258
|
+
</section>
|
|
259
|
+
|
|
@@ -2,9 +2,13 @@
|
|
|
2
2
|
export let a;
|
|
3
3
|
export let onChange = void 0;
|
|
4
4
|
export let readOnly = false;
|
|
5
|
+
export let href = void 0;
|
|
6
|
+
export let hrefFunc = void 0;
|
|
5
7
|
let definition = getContext("rKanban-definition");
|
|
6
8
|
definition.titleAttrib = a;
|
|
7
9
|
definition.titleOnChange = onChange;
|
|
8
10
|
definition.titleReadOnly = readOnly;
|
|
11
|
+
definition.titleHref = href;
|
|
12
|
+
definition.titleHrefFunc = hrefFunc;
|
|
9
13
|
</script>
|
|
10
14
|
|
|
@@ -36,7 +36,7 @@ $:
|
|
|
36
36
|
$:
|
|
37
37
|
focused_class = is_row_active ? "bg-stone-200 dark:bg-stone-700" : "";
|
|
38
38
|
$:
|
|
39
|
-
is_link_like =
|
|
39
|
+
is_link_like = is_row_active && (!!definition.title_href || !!definition.title_href_func);
|
|
40
40
|
if (!typename) {
|
|
41
41
|
if (item.$type)
|
|
42
42
|
typename = item.$type;
|
|
@@ -117,18 +117,24 @@ function on_active_row_clicked(e, part) {
|
|
|
117
117
|
}
|
|
118
118
|
} else if (click_on_empty_space) {
|
|
119
119
|
if (definition.title_href || definition.title_href_func) {
|
|
120
|
-
let link = "";
|
|
121
|
-
if (definition.title_href)
|
|
122
|
-
link = definition.title_href;
|
|
123
|
-
else if (definition.title_href_func)
|
|
124
|
-
link = definition.title_href_func(item);
|
|
125
|
-
if (link)
|
|
126
|
-
push(link);
|
|
127
120
|
} else {
|
|
128
121
|
}
|
|
129
122
|
} else {
|
|
130
123
|
}
|
|
131
124
|
}
|
|
125
|
+
function followDefinedHRef() {
|
|
126
|
+
let link = getHRef();
|
|
127
|
+
if (link)
|
|
128
|
+
push(link);
|
|
129
|
+
}
|
|
130
|
+
function getHRef() {
|
|
131
|
+
if (definition.title_href)
|
|
132
|
+
return definition.title_href;
|
|
133
|
+
else if (definition.title_href_func)
|
|
134
|
+
return definition.title_href_func(item);
|
|
135
|
+
else
|
|
136
|
+
return "";
|
|
137
|
+
}
|
|
132
138
|
function activate_row(e, item2) {
|
|
133
139
|
activateItem("props", item2, toolbarOperations(item2));
|
|
134
140
|
if (e)
|
|
@@ -174,8 +180,19 @@ async function force_editing(field) {
|
|
|
174
180
|
if (!element_node.classList.contains("editable")) {
|
|
175
181
|
return;
|
|
176
182
|
}
|
|
177
|
-
|
|
178
|
-
|
|
183
|
+
if (field == "Title") {
|
|
184
|
+
if (is_link_like) {
|
|
185
|
+
startEditing(element_node, () => {
|
|
186
|
+
placeholder = "";
|
|
187
|
+
});
|
|
188
|
+
} else {
|
|
189
|
+
element_node.focus();
|
|
190
|
+
setSelectionAtEnd(element_node);
|
|
191
|
+
}
|
|
192
|
+
} else {
|
|
193
|
+
element_node.focus();
|
|
194
|
+
setSelectionAtEnd(element_node);
|
|
195
|
+
}
|
|
179
196
|
}
|
|
180
197
|
function setSelectionAtEnd(element) {
|
|
181
198
|
const textNode = element.childNodes[0];
|
|
@@ -214,43 +231,58 @@ export function scrollToView() {
|
|
|
214
231
|
<slot name="left" element={item}/>
|
|
215
232
|
|
|
216
233
|
<div class="ml-3 w-full py-1"
|
|
217
|
-
class:sm:hover:cursor-pointer={is_link_like}
|
|
218
234
|
use:selectable={item}
|
|
219
235
|
on:click={(e) => {activate_row(e, item)}}
|
|
220
236
|
role="row"
|
|
221
237
|
tabindex="0">
|
|
222
238
|
<div class="block sm:flex sm:flex-row" on:click={(e) => on_active_row_clicked(e, 'top')}>
|
|
223
239
|
|
|
224
|
-
|
|
225
|
-
{#key item[title]}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
240
|
+
{#if is_row_active}
|
|
241
|
+
{#key item[title]} <!-- Wymusza pełne wyrenderowanie zwłasza po zmiane z pustego na tekst -->
|
|
242
|
+
{#if is_link_like}
|
|
243
|
+
<p class=" text-lg font-semibold min-h-[1.75rem]
|
|
244
|
+
sm:text-sm sm:font-semibold sm:min-h-[1.25rem]
|
|
245
|
+
whitespace-nowrap overflow-clip w-full sm:flex-none sm:w-2/3
|
|
246
|
+
sm:hover:cursor-pointer underline"
|
|
247
|
+
id="__hd_list_ctrl_{item[item_key]}_Title"
|
|
248
|
+
on:click|stopPropagation={followDefinedHRef}
|
|
249
|
+
use:editable={{
|
|
250
|
+
action: (text) => {change_name(text)},
|
|
251
|
+
active: false,
|
|
252
|
+
readonly: definition.title_readonly,
|
|
253
|
+
}}
|
|
254
|
+
>
|
|
235
255
|
{element_title}
|
|
256
|
+
</p>
|
|
257
|
+
{:else}
|
|
258
|
+
<p class=" text-lg font-semibold min-h-[1.75rem]
|
|
259
|
+
sm:text-sm sm:font-semibold sm:min-h-[1.25rem]
|
|
260
|
+
whitespace-nowrap overflow-clip w-full sm:flex-none sm:w-2/3"
|
|
261
|
+
id="__hd_list_ctrl_{item[item_key]}_Title"
|
|
262
|
+
use:editable={{
|
|
263
|
+
action: (text) => {change_name(text)},
|
|
264
|
+
active: true,
|
|
265
|
+
readonly: definition.title_readonly,
|
|
266
|
+
}}>
|
|
267
|
+
{element_title}
|
|
236
268
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
269
|
+
{#if definition.onOpen}
|
|
270
|
+
<button class="ml-3 w-5 h-5 sm:w-3 sm:h-3"
|
|
271
|
+
on:click={(e) => definition.onOpen(item)}>
|
|
272
|
+
<FaExternalLinkAlt/>
|
|
273
|
+
</button>
|
|
274
|
+
{/if}
|
|
275
|
+
</p>
|
|
276
|
+
{/if}
|
|
244
277
|
{/key}
|
|
245
|
-
|
|
278
|
+
{:else}
|
|
246
279
|
<p class=" text-lg font-semibold min-h-[1.75rem]
|
|
247
280
|
sm:text-sm sm:font-semibold sm:min-h-[1.25rem]
|
|
248
281
|
whitespace-nowrap overflow-clip w-full sm:flex-none sm:w-2/3"
|
|
249
282
|
id="__hd_list_ctrl_{item[item_key]}_Title">
|
|
250
283
|
{element_title}
|
|
251
284
|
</p>
|
|
252
|
-
|
|
253
|
-
|
|
285
|
+
{/if}
|
|
254
286
|
|
|
255
287
|
|
|
256
288
|
<section class="hidden sm:block w-full sm:flex-none sm:w-1/3">
|
package/index.d.ts
CHANGED
|
@@ -51,8 +51,8 @@ export { default as KanbanComboProperty } from './components/kanban/kanban.combo
|
|
|
51
51
|
export { default as KanbanTagsProperty } from './components/kanban/kanban.tags.svelte';
|
|
52
52
|
export { default as KanbanCallbacks } from './components/kanban/kanban.callbacks.svelte';
|
|
53
53
|
export { KanbanColumnTop, KanbanColumnBottom } from './components/kanban/Kanban';
|
|
54
|
-
export { selectItem, activateItem, clearActiveItem, isActive, isSelected, getActive, editable, startEditing, selectable, handleSelect, isDeviceSmallerThan } from './utils';
|
|
55
|
-
export {
|
|
54
|
+
export { selectItem, activateItem, clearActiveItem, isActive, isSelected, getActive, editable, startEditing, saveCurrentEditable, selectable, handleSelect, isDeviceSmallerThan } from './utils';
|
|
55
|
+
export { mainContentPageReloader, reloadMainContentPage } from './stores.js';
|
|
56
56
|
export { data_tick_store, // tmp
|
|
57
57
|
hasSelectedItem, hasDataItem, setNavigatorTitle } from "./stores";
|
|
58
58
|
export { contextToolbarOperations, pageToolbarOperations, contextItemsStore, contextTypesStore } from './stores';
|
package/index.js
CHANGED
|
@@ -57,8 +57,8 @@ export { default as KanbanComboProperty } from './components/kanban/kanban.combo
|
|
|
57
57
|
export { default as KanbanTagsProperty } from './components/kanban/kanban.tags.svelte';
|
|
58
58
|
export { default as KanbanCallbacks } from './components/kanban/kanban.callbacks.svelte';
|
|
59
59
|
export { KanbanColumnTop, KanbanColumnBottom } from './components/kanban/Kanban';
|
|
60
|
-
export { selectItem, activateItem, clearActiveItem, isActive, isSelected, getActive, editable, startEditing, selectable, handleSelect, isDeviceSmallerThan } from './utils';
|
|
61
|
-
export {
|
|
60
|
+
export { selectItem, activateItem, clearActiveItem, isActive, isSelected, getActive, editable, startEditing, saveCurrentEditable, selectable, handleSelect, isDeviceSmallerThan } from './utils';
|
|
61
|
+
export { mainContentPageReloader, reloadMainContentPage } from './stores.js';
|
|
62
62
|
export { data_tick_store, // tmp
|
|
63
63
|
hasSelectedItem, hasDataItem, setNavigatorTitle } from "./stores";
|
|
64
64
|
export { contextToolbarOperations, pageToolbarOperations, contextItemsStore, contextTypesStore } from './stores'; // tmp
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@humandialog/forms.svelte",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.13",
|
|
4
4
|
"description": "Basic Svelte UI components for Object Reef applications",
|
|
5
5
|
"devDependencies": {
|
|
6
6
|
"@playwright/test": "^1.28.1",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
},
|
|
27
27
|
"type": "module",
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@humandialog/auth.svelte": "^1.5.
|
|
29
|
+
"@humandialog/auth.svelte": "^1.5.3",
|
|
30
30
|
"flowbite-svelte": "^0.29.13",
|
|
31
31
|
"svelte-icons": "^2.1.0",
|
|
32
32
|
"svelte-spa-router": "^3.3.0"
|
package/stores.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export function setNavigatorTitle(key: any, title: any): void;
|
|
2
2
|
export function hasSelectedItem(): boolean;
|
|
3
3
|
export function hasDataItem(): boolean;
|
|
4
|
-
export function
|
|
4
|
+
export function reloadMainContentPage(): void;
|
|
5
5
|
export function set_dark_mode_default(value: any): void;
|
|
6
6
|
export function set_default_tools_visible(value: any): void;
|
|
7
7
|
export function restore_defults(): void;
|
|
@@ -28,7 +28,7 @@ export const contextToolbarOperations: import("svelte/store").Writable<never[]>;
|
|
|
28
28
|
export const pageToolbarOperations: import("svelte/store").Writable<never[]>;
|
|
29
29
|
export const page_title: import("svelte/store").Writable<string>;
|
|
30
30
|
export const nav_titles: import("svelte/store").Writable<{}>;
|
|
31
|
-
export const
|
|
31
|
+
export const mainContentPageReloader: import("svelte/store").Writable<number>;
|
|
32
32
|
export const dark_mode_store: import("svelte/store").Writable<any>;
|
|
33
33
|
export const main_sidebar_visible_store: import("svelte/store").Writable<any>;
|
|
34
34
|
export let previously_visible_sidebar: string;
|
package/stores.js
CHANGED
|
@@ -10,7 +10,7 @@ export const contextToolbarOperations = writable([]);
|
|
|
10
10
|
export const pageToolbarOperations = writable([]);
|
|
11
11
|
export const page_title = writable('');
|
|
12
12
|
export const nav_titles = writable({});
|
|
13
|
-
export const
|
|
13
|
+
export const mainContentPageReloader = writable(1);
|
|
14
14
|
|
|
15
15
|
export function setNavigatorTitle(key, title)
|
|
16
16
|
{
|
|
@@ -31,11 +31,11 @@ export function hasDataItem()
|
|
|
31
31
|
return itm !== null && itm !== undefined;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
export function
|
|
34
|
+
export function reloadMainContentPage()
|
|
35
35
|
{
|
|
36
|
-
let val = get(
|
|
36
|
+
let val = get(mainContentPageReloader);
|
|
37
37
|
val += 1;
|
|
38
|
-
|
|
38
|
+
mainContentPageReloader.set(val);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
|
package/utils.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export function editable(node: any, params: any): {
|
|
|
9
9
|
destroy(): void;
|
|
10
10
|
} | undefined;
|
|
11
11
|
export function startEditing(element: any, finish_callback: any): void;
|
|
12
|
+
export function saveCurrentEditable(): void;
|
|
12
13
|
export function selectable(node: any, itm: any): {
|
|
13
14
|
destroy(): void;
|
|
14
15
|
};
|
|
@@ -33,3 +34,4 @@ export namespace SCREEN_SIZES {
|
|
|
33
34
|
const lg: number;
|
|
34
35
|
const xl: number;
|
|
35
36
|
}
|
|
37
|
+
export let currentEditable: null;
|
package/utils.js
CHANGED
|
@@ -97,6 +97,8 @@ export function getActive(context_level)
|
|
|
97
97
|
return null;
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
+
export let currentEditable = null;
|
|
101
|
+
|
|
100
102
|
export function editable(node, params)
|
|
101
103
|
{
|
|
102
104
|
let action;
|
|
@@ -122,6 +124,9 @@ export function editable(node, params)
|
|
|
122
124
|
const org_text = node.textContent;
|
|
123
125
|
const blur_listener = async (e) =>
|
|
124
126
|
{
|
|
127
|
+
if(currentEditable == node)
|
|
128
|
+
currentEditable = null;
|
|
129
|
+
|
|
125
130
|
let cancel = !node.textContent
|
|
126
131
|
if(observer)
|
|
127
132
|
observer.disconnect();
|
|
@@ -170,6 +175,7 @@ export function editable(node, params)
|
|
|
170
175
|
{
|
|
171
176
|
node.removeEventListener("blur", blur_listener);
|
|
172
177
|
node.removeEventListener("keydown", key_listener);
|
|
178
|
+
node.removeEventListener("save", save_listener);
|
|
173
179
|
node.contentEditable = "false"
|
|
174
180
|
|
|
175
181
|
let sel = window.getSelection();
|
|
@@ -206,11 +212,20 @@ export function editable(node, params)
|
|
|
206
212
|
node.removeEventListener("finish", (e) => {});
|
|
207
213
|
}
|
|
208
214
|
|
|
215
|
+
const save_listener = async (e) =>
|
|
216
|
+
{
|
|
217
|
+
if(has_changed)
|
|
218
|
+
await action(node.textContent)
|
|
219
|
+
}
|
|
220
|
+
|
|
209
221
|
const edit_listener = async (e) =>
|
|
210
222
|
{
|
|
211
223
|
node.contentEditable = "true"
|
|
212
224
|
node.addEventListener("blur", blur_listener);
|
|
213
225
|
node.addEventListener("keydown", key_listener);
|
|
226
|
+
|
|
227
|
+
currentEditable = node;
|
|
228
|
+
node.addEventListener("save", save_listener)
|
|
214
229
|
|
|
215
230
|
node.focus();
|
|
216
231
|
|
|
@@ -235,6 +250,8 @@ export function editable(node, params)
|
|
|
235
250
|
node.addEventListener("blur", blur_listener);
|
|
236
251
|
node.addEventListener("keydown", key_listener);
|
|
237
252
|
has_changed = false;
|
|
253
|
+
currentEditable = node;
|
|
254
|
+
node.addEventListener("save", save_listener)
|
|
238
255
|
|
|
239
256
|
observer = new MutationObserver(() => { has_changed = true; });
|
|
240
257
|
observer.observe( node, {
|
|
@@ -298,6 +315,12 @@ export function startEditing(element, finish_callback)
|
|
|
298
315
|
}
|
|
299
316
|
}
|
|
300
317
|
|
|
318
|
+
export function saveCurrentEditable()
|
|
319
|
+
{
|
|
320
|
+
if(currentEditable)
|
|
321
|
+
currentEditable.dispatchEvent(new Event("save"))
|
|
322
|
+
}
|
|
323
|
+
|
|
301
324
|
export function selectable(node, itm)
|
|
302
325
|
{
|
|
303
326
|
const select_listener = (e) =>
|