@humandialog/forms.svelte 0.5.21 → 0.5.22

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.
@@ -81,7 +81,6 @@ function getSelectionPos() {
81
81
  rect = range.getBoundingClientRect();
82
82
  let result = window.innerHeight - rect.top;
83
83
  result = Math.floor(result);
84
- console.log("selection box", result);
85
84
  return result;
86
85
  } else
87
86
  return 0;
@@ -28,7 +28,6 @@ afterUpdate(() => {
28
28
  const sel = window.getSelection();
29
29
  if (sel && sel.rangeCount > 0 && sel.focusNode && sel.focusNode.nodeType == sel.focusNode.TEXT_NODE) {
30
30
  container_rect.height -= 300;
31
- console.log("shirnked: ", container_rect);
32
31
  }
33
32
  }
34
33
  let xShifted = false;
@@ -963,7 +963,6 @@ function on_focus() {
963
963
  }
964
964
  function on_blur() {
965
965
  let active_range = Selection_helper.get_selection(editable_div);
966
- console.log("rich.edit: on_blur", active_range?.begin?.absolute_index);
967
966
  storedSelection = null;
968
967
  if (onBlur) {
969
968
  onBlur();
@@ -40,6 +40,7 @@ export declare class rKanban_definition {
40
40
  getCardOperations: Function | undefined;
41
41
  private items;
42
42
  getItems(): object[];
43
+ visibleColumnsNo(): number;
43
44
  clear(): void;
44
45
  }
45
46
  export declare const KanbanColumnTop = -1;
@@ -51,6 +51,29 @@ export class rKanban_definition {
51
51
  }
52
52
  return this.items;
53
53
  }
54
+ visibleColumnsNo() {
55
+ // has <Other> column
56
+ if (this.columns.find((c) => c.state < 0)) {
57
+ const allItems = this.getItems();
58
+ const isExplicitState = (e) => {
59
+ const elementState = e[this.stateAttrib];
60
+ const colsNo = this.columns.length;
61
+ for (let i = 0; i < colsNo; i++) {
62
+ const def = this.columns[i];
63
+ if ((def.state >= 0) && (def.state == elementState))
64
+ return true;
65
+ }
66
+ return false;
67
+ };
68
+ const unknownStateItems = allItems.filter(e => !isExplicitState(e));
69
+ if (unknownStateItems && (unknownStateItems.length > 0))
70
+ return this.columns.length;
71
+ else
72
+ return this.columns.length - 1;
73
+ }
74
+ else
75
+ return this.columns.length;
76
+ }
54
77
  clear() {
55
78
  this.columns = [];
56
79
  this.titleAttrib = '';
@@ -216,7 +216,9 @@ function showAttachementIcon() {
216
216
  action: (text) => onTitleChanged(text),
217
217
  active: false,
218
218
  readonly: definition.titleReadOnly,
219
- onFinish: (d) => {titleElement.blur()}}}
219
+ onFinish: (d) => {titleElement.blur()},
220
+ onSoftEnter: async (text) => { onTitleChanged(text); await editProperty('Summary') }
221
+ }}
220
222
  use:conditionalClick={{
221
223
  condition: canOpen,
222
224
  callback: performOpen}}
@@ -138,6 +138,8 @@ export async function add(after = KanbanColumnTop) {
138
138
  if (!inserter)
139
139
  return;
140
140
  inserter.run(async (detail) => {
141
+ if (detail.softEnter)
142
+ return;
141
143
  showInserterAfterId = None;
142
144
  if (detail.cancel)
143
145
  activateAfterDomUpdate = lastActivatedElement;
@@ -202,11 +204,14 @@ function onResizeWindow() {
202
204
  styleWidth = getWidthStyle();
203
205
  }
204
206
  function getWidthStyle() {
205
- const assumed_space = 800;
206
- const default_column_width = Math.floor(assumed_space / definition.columns.length);
207
- const column_width = columnDef.width ? columnDef.width : default_column_width;
207
+ const container = document.getElementById("__hd_svelte_main_content_container");
208
+ const containerRect = container?.getBoundingClientRect();
209
+ const assumed_space = containerRect.width;
210
+ const columns_no = definition.visibleColumnsNo();
211
+ const default_column_width = Math.floor(assumed_space / columns_no);
212
+ const column_width = Math.min(columnDef.width ? columnDef.width : default_column_width, 640);
208
213
  if (window.innerWidth >= 640)
209
- return `width: ${column_width}px; min-width: 180px; max-width: ${column_width}px;`;
214
+ return `width: ${column_width}px; min-width: 200px; max-width: ${column_width}px;`;
210
215
  else
211
216
  return "width: 92%;";
212
217
  }
@@ -252,7 +257,7 @@ function getWidthStyle() {
252
257
  </header>
253
258
  <ul class="w-full border-stone-700 pb-20" bind:this={column_element}>
254
259
  {#if showInserterAfterId === KanbanColumnTop}
255
- <Inserter onInsert={async (text) => {await onInsert(currentColumnIdx, text, KanbanColumnTop)}}
260
+ <Inserter onInsert={async (title, summary) => {await onInsert(currentColumnIdx, title, summary, KanbanColumnTop)}}
256
261
  bind:this={inserter} />
257
262
  {/if}
258
263
 
@@ -274,14 +279,14 @@ function getWidthStyle() {
274
279
  </Card>
275
280
 
276
281
  {#if showInserterAfterId == element.Id}
277
- <Inserter onInsert={async (text) => {await onInsert(currentColumnIdx, text, showInserterAfterId)}}
282
+ <Inserter onInsert={async (title, summary) => {await onInsert(currentColumnIdx, title, summary, showInserterAfterId)}}
278
283
  bind:this={inserter} />
279
284
  {/if}
280
285
  {/each}
281
286
  {/if}
282
287
 
283
288
  {#if showInserterAfterId === KanbanColumnBottom}
284
- <Inserter onInsert={async (text) => {await onInsert(currentColumnIdx, text, KanbanColumnBottom)}}
289
+ <Inserter onInsert={async (title, summary) => {await onInsert(currentColumnIdx, title, summary, KanbanColumnBottom)}}
285
290
  bind:this={inserter} />
286
291
  {/if}
287
292
 
@@ -1,12 +1,29 @@
1
- <script>import {
1
+ <script>import { tick } from "svelte";
2
+ import {
2
3
  startEditing,
3
4
  editable
4
5
  } from "../../..";
5
6
  export let onInsert;
7
+ let onClose;
6
8
  export function run(onclose) {
7
- startEditing(insertion_paragraph, onclose);
9
+ onClose = onclose;
10
+ startEditing(titleElement, onclose);
11
+ }
12
+ let titleElement;
13
+ let title = "";
14
+ let summary = "";
15
+ let editSummary = false;
16
+ let summaryElement;
17
+ async function softEnter(t) {
18
+ title = t;
19
+ editSummary = true;
20
+ await tick();
21
+ startEditing(summaryElement, onClose);
22
+ }
23
+ async function onSummaryChanged(text) {
24
+ summary = text;
25
+ await onInsert(title, summary);
8
26
  }
9
- let insertion_paragraph;
10
27
  </script>
11
28
 
12
29
  <!-- svelte-ignore a11y-click-events-have-key-events -->
@@ -17,8 +34,29 @@ let insertion_paragraph;
17
34
  <h3 class=" text-lg font-semibold min-h-[1.75rem]
18
35
  sm:text-sm sm:font-semibold sm:min-h-[1.25rem]
19
36
  whitespace-nowrap overflow-clip w-full sm:flex-none "
20
- use:editable={onInsert}
21
- bind:this={insertion_paragraph}>
22
-
37
+ use:editable={{
38
+ action: (text) => onInsert(text, ''),
39
+ active: false,
40
+ onSoftEnter: softEnter
41
+ }}
42
+ bind:this={titleElement}>
23
43
  </h3>
44
+
45
+ {#if editSummary}
46
+ <p class=" sm:text-xs sm:min-h-[1rem]
47
+ text-base min-h-[1.5rem]
48
+ text-stone-400
49
+ max-h-[75px] sm:max-h-[64px]
50
+ overflow-hidden"
51
+ use:editable={{
52
+ action: (text) => onSummaryChanged(text),
53
+ active: false,
54
+ onFinish: (d) => {editSummary = false}}}
55
+ bind:this={summaryElement}>
56
+ {summary}
57
+ </p>
58
+ {/if}
59
+
60
+
61
+
24
62
  </li>
@@ -304,7 +304,7 @@ export function replace(item, toColumnIdx, afterElement) {
304
304
  return;
305
305
  }
306
306
  }
307
- async function onInsert(columnIdx, title2, afterId) {
307
+ async function onInsert(columnIdx, title2, summary, afterId) {
308
308
  const columnState = definition.columns[columnIdx].state;
309
309
  const oa = definition.orderAttrib;
310
310
  const sa = definition.stateAttrib;
@@ -313,6 +313,7 @@ async function onInsert(columnIdx, title2, afterId) {
313
313
  const columnBottom = allItems.findLast((e) => e[sa] == columnState);
314
314
  let newElement = {
315
315
  [definition.titleAttrib]: title2,
316
+ [definition.summaryAttrib]: summary,
316
317
  [sa]: columnState
317
318
  };
318
319
  if (afterId == KanbanColumnTop) {
@@ -432,9 +433,10 @@ export function add(item, columnIdx = -1) {
432
433
  <!--hr class="hidden sm:block w-full"-->
433
434
  {/if}
434
435
 
435
- <section class="h-full mt-5 flex flex-row no-wrap sm:justify-center
436
+ <section id="__hd_svelte_kanban_columns_container"
437
+ class="h-full mt-5 flex flex-row no-wrap
436
438
  overflow-x-auto snap-x snap-mandatory sm:snap-none
437
- {user_class}">
439
+ {user_class}"> <!--sm:justify-center -->
438
440
  {#each definition.columns as column, idx (column.id)}
439
441
  <Column currentColumnIdx={idx}
440
442
  {onInsert}
@@ -250,6 +250,7 @@ export function scrollToView() {
250
250
  action: (text) => {change_name(text)},
251
251
  active: false,
252
252
  readonly: definition.title_readonly,
253
+ onSoftEnter: (text) => {change_name(text); editProperty('Summary')}
253
254
  }}
254
255
  >
255
256
  {element_title}
@@ -1,27 +1,65 @@
1
- <script>import { editable, startEditing } from "../../../utils";
1
+ <script>import { tick } from "svelte";
2
+ import { editable, startEditing } from "../../../utils";
2
3
  import Icon from "../../icon.svelte";
3
4
  import { FaPlus } from "svelte-icons/fa";
4
5
  export let onInsert;
5
6
  export let icon = false;
7
+ let onClose;
6
8
  export function run(onclose) {
7
- startEditing(insertion_paragraph, onclose);
9
+ onClose = onclose;
10
+ startEditing(titleElement, onclose);
11
+ }
12
+ let titleElement;
13
+ let summaryElement;
14
+ let title = "";
15
+ let summary = "";
16
+ let editSummary = false;
17
+ async function softEnter(text) {
18
+ title = text;
19
+ editSummary = true;
20
+ await tick();
21
+ startEditing(summaryElement, onClose);
22
+ }
23
+ async function onSummaryChanged(text) {
24
+ summary = text;
25
+ await onInsert(title, summary);
8
26
  }
9
- let insertion_paragraph;
10
27
  </script>
11
28
 
12
- <section class="mt-3 flex flex-row my-0 w-full text-lg sm:text-sm text-stone-700 dark:text-stone-400 cursor-default rounded-md border border-transparent bg-stone-200 dark:bg-stone-700">
13
- {#if icon}
14
- <!--Icon size={3}
15
- component={FaPlus}
16
- class="mt-1.5 ml-2 "/-->
17
- <div class="h-5 w-5 sm:h-4 sm:w-4 mt-2 sm:mt-1.5 ml-2"></div>
18
- {/if}
29
+ <section class="mt-3 my-0 w-full text-lg sm:text-sm text-stone-700 dark:text-stone-400 cursor-default rounded-md border border-transparent bg-stone-200 dark:bg-stone-700">
30
+ <div class="flex flex-row">
31
+ {#if icon}
32
+ <!--Icon size={3}
33
+ component={FaPlus}
34
+ class="mt-1.5 ml-2 "/-->
35
+ <div class="h-5 w-5 sm:h-4 sm:w-4 mt-2 sm:mt-1.5 ml-2"></div>
36
+ {/if}
19
37
 
20
- <p class=" ml-3 py-1
21
- text-lg font-semibold min-h-[1.75rem]
22
- sm:text-sm sm:font-semibold sm:min-h-[1.25rem]
23
- whitespace-nowrap overflow-clip flex-none w-1/2 sm:w-1/3" tabindex="0"
24
- bind:this={insertion_paragraph}
25
- use:editable={onInsert} >
26
- </p>
38
+ <p class=" ml-3 py-1
39
+ text-lg font-semibold min-h-[1.75rem]
40
+ sm:text-sm sm:font-semibold sm:min-h-[1.25rem]
41
+ whitespace-nowrap overflow-clip flex-none w-1/2 sm:w-1/3" tabindex="0"
42
+ bind:this={titleElement}
43
+ use:editable={{
44
+ action: (text) => onInsert(text, ''),
45
+ active: false,
46
+ onSoftEnter: softEnter
47
+ }} >
48
+ </p>
49
+ </div>
50
+
51
+ {#if editSummary}
52
+ <p bind:this={summaryElement}
53
+ class=" ml-10 sm:ml-9
54
+ sm:text-xs sm:min-h-[1rem]
55
+ text-base min-h-[1.5rem]
56
+ text-stone-400"
57
+ use:editable={{
58
+ action: onSummaryChanged,
59
+ active: false,
60
+ onFinish: (d) => {editSummary=false}
61
+ }}>
62
+ {summary}
63
+ </p>
64
+ {/if}
27
65
  </section>
@@ -175,6 +175,8 @@ export async function addRowAfter(after = null) {
175
175
  if (!inserter)
176
176
  return;
177
177
  inserter.run(async (detail) => {
178
+ if (detail.softEnter)
179
+ return;
178
180
  show_insertion_row_after_element = null;
179
181
  if (detail.cancel)
180
182
  activate_after_dom_update = last_activated_element;
@@ -233,9 +235,10 @@ function reorderElements(items2, from = null) {
233
235
  }
234
236
  pushChanges();
235
237
  }
236
- async function insert(title2, after) {
238
+ async function insert(title2, summary, after) {
237
239
  let newElement = {
238
- [definition.title]: title2
240
+ [definition.title]: title2,
241
+ [definition.summary]: summary
239
242
  };
240
243
  if (after && orderAttrib) {
241
244
  const leftElement = after;
@@ -298,7 +301,7 @@ async function insert(title2, after) {
298
301
  </List_element>
299
302
 
300
303
  {#if show_insertion_row_after_element == element}
301
- <Inserter onInsert={async (text) => {await insert(text, show_insertion_row_after_element)}}
304
+ <Inserter onInsert={async (title, summary) => {await insert(title, summary, show_insertion_row_after_element)}}
302
305
  icon={definition.inserter_icon}
303
306
  bind:this={inserter} />
304
307
  {/if}
@@ -306,7 +309,7 @@ async function insert(title2, after) {
306
309
  {/if}
307
310
 
308
311
  {#if show_insertion_row_after_element == END_OF_LIST}
309
- <Inserter onInsert={async (text) => {await insert(text, null)}}
312
+ <Inserter onInsert={async (title, summary) => {await insert(text, summary, null)}}
310
313
  icon={definition.inserter_icon}
311
314
  bind:this={inserter} />
312
315
  {/if}
@@ -1,7 +1,7 @@
1
1
  <script>import Icon from "../icon.svelte";
2
2
  import Edit from "../edit.field.svelte";
3
3
  import { FaPlus } from "svelte-icons/fa";
4
- import { getPrev, getNext, swapElements, getLast } from "../../utils";
4
+ import { getPrev, getNext, swapElements, getLast, getFirst, remove, insertAt } from "../../utils";
5
5
  import { informModification, pushChanges } from "../../updates";
6
6
  import { tick } from "svelte";
7
7
  export let objects;
@@ -28,6 +28,26 @@ export function moveUp(element) {
28
28
  pushChanges();
29
29
  }
30
30
  }
31
+ export function moveTop(element) {
32
+ if (!orderAttrib)
33
+ return;
34
+ let current = getFirst(objects);
35
+ if (current == element)
36
+ return;
37
+ const firstOrder = current[orderAttrib];
38
+ while (current != element) {
39
+ const next = getNext(objects, current);
40
+ const nextOrder = next[orderAttrib];
41
+ current[orderAttrib] = nextOrder;
42
+ informModification(current, orderAttrib);
43
+ current = next;
44
+ }
45
+ element[orderAttrib] = firstOrder;
46
+ informModification(element, orderAttrib);
47
+ objects = remove(objects, element);
48
+ objects = insertAt(objects, 0, element);
49
+ pushChanges();
50
+ }
31
51
  export function moveDown(element) {
32
52
  if (!orderAttrib)
33
53
  return;
@@ -9,6 +9,7 @@ declare const __propDef: {
9
9
  MIN_ORDER?: 0 | undefined;
10
10
  reload?: ((_objects: object[]) => void) | undefined;
11
11
  moveUp?: ((element: object) => void) | undefined;
12
+ moveTop?: ((element: object) => void) | undefined;
12
13
  moveDown?: ((element: object) => void) | undefined;
13
14
  add?: ((onAddHandler: Function) => Promise<void>) | undefined;
14
15
  };
@@ -30,6 +31,7 @@ export default class Sidebar extends SvelteComponentTyped<SidebarProps, SidebarE
30
31
  get MIN_ORDER(): 0;
31
32
  get reload(): (_objects: object[]) => void;
32
33
  get moveUp(): (element: object) => void;
34
+ get moveTop(): (element: object) => void;
33
35
  get moveDown(): (element: object) => void;
34
36
  get add(): (onAddHandler: Function) => Promise<void>;
35
37
  }
@@ -75,7 +75,6 @@ function override_items_from_slot(...args) {
75
75
  last_tick_internal = definition.items_ticket;
76
76
  if (definition.items)
77
77
  items = definition.items;
78
- console.log("override_items_from_slot", definition.items, definition.items_ticket);
79
78
  }
80
79
  return 0;
81
80
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@humandialog/forms.svelte",
3
- "version": "0.5.21",
3
+ "version": "0.5.22",
4
4
  "description": "Basic Svelte UI components for Object Reef applications",
5
5
  "devDependencies": {
6
6
  "@playwright/test": "^1.28.1",
package/utils.js CHANGED
@@ -105,13 +105,15 @@ export function editable(node, params)
105
105
  let active = false;
106
106
  let onRemove = undefined;
107
107
  let onFinish = undefined;
108
+ let onSoftEnter = undefined;
108
109
  if(params instanceof Object)
109
110
  {
110
111
  action = params.action ?? params;
111
112
  active = params.active ?? false;
112
113
  onRemove = params.remove ?? undefined
113
114
  onFinish = params.onFinish ?? undefined
114
-
115
+ onSoftEnter = params.onSoftEnter ?? undefined;
116
+
115
117
  if(params.readonly)
116
118
  return;
117
119
  }
@@ -131,7 +133,7 @@ export function editable(node, params)
131
133
  if(observer)
132
134
  observer.disconnect();
133
135
 
134
- await finish_editing(cancel, false);
136
+ await finish_editing({cancel: cancel});
135
137
  }
136
138
 
137
139
  const key_listener = async (e) =>
@@ -146,7 +148,7 @@ export function editable(node, params)
146
148
  e.stopPropagation();
147
149
  e.preventDefault();
148
150
 
149
- await finish_editing(true, false);
151
+ await finish_editing({ cancel: true });
150
152
  }
151
153
  break;
152
154
 
@@ -154,7 +156,10 @@ export function editable(node, params)
154
156
  e.stopPropagation();
155
157
  e.preventDefault();
156
158
 
157
- await finish_editing(false, true);
159
+ if(e.shiftKey && onSoftEnter)
160
+ await finish_editing({ softEnter: true});
161
+ else
162
+ await finish_editing({ incremental: true});
158
163
  break;
159
164
 
160
165
  case 'Backspace':
@@ -162,15 +167,19 @@ export function editable(node, params)
162
167
  {
163
168
  e.stopPropagation();
164
169
  e.preventDefault();
165
- //await finish_editing(false, false);
166
170
  onRemove();
167
171
  }
168
172
  break;
169
173
  }
170
174
  }
171
175
 
172
- const finish_editing = async (cancel, incremental) =>
176
+ //const finish_editing = async (softEnter, cancel, incremental) =>
177
+ const finish_editing = async (params) =>
173
178
  {
179
+ const softEnter = params.softEnter ?? false;
180
+ const cancel = params.cancel ?? false;
181
+ const incremental = params.incremental ?? false;
182
+
174
183
  if(!active)
175
184
  {
176
185
  node.removeEventListener("blur", blur_listener);
@@ -186,6 +195,10 @@ export function editable(node, params)
186
195
  {
187
196
  node.innerHTML = org_text;
188
197
  }
198
+ else if(softEnter)
199
+ {
200
+ onSoftEnter(node.textContent)
201
+ }
189
202
  else if(action)
190
203
  {
191
204
  if(active)
@@ -202,7 +215,8 @@ export function editable(node, params)
202
215
  detail:
203
216
  {
204
217
  cancel: cancel,
205
- incremental: incremental
218
+ incremental: incremental,
219
+ softEnter: softEnter
206
220
  }
207
221
  });
208
222