@humandialog/forms.svelte 1.6.6 → 1.6.8

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 ObjectReef
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -68,6 +68,7 @@ export function hide() {
68
68
  if (false)
69
69
  popToolsActionsOperations();
70
70
  visible = false;
71
+ toolbar = null;
71
72
  cssPosition = calculatePosition(x, y, around_rect, false, false);
72
73
  window.removeEventListener("click", on_before_window_click, true);
73
74
  rootElement?.removeEventListener("click", on_before_container_click, true);
@@ -76,6 +77,8 @@ export function isSameToolbar(_toolbar) {
76
77
  return _toolbar == toolbar;
77
78
  }
78
79
  async function onSizeChanged() {
80
+ if (!visible)
81
+ return;
79
82
  cssPosition = calculatePosition(x, y, around_rect, true, true);
80
83
  await tick();
81
84
  cssPosition = calculatePosition(x, y, around_rect, true, false);
@@ -169,6 +172,8 @@ function calculatePosition(x2, y2, around, visible2, fresh) {
169
172
  </button>
170
173
  {/if}
171
174
 
172
- <svelte:component this={toolbar} {...props} bind:this={internalElement} />
175
+ {#if toolbar}
176
+ <svelte:component this={toolbar} {...props} bind:this={internalElement} />
177
+ {/if}
173
178
  </div>
174
179
 
@@ -1,29 +1,44 @@
1
1
  <script>
2
2
  import {location, link, querystring} from 'svelte-spa-router'
3
- import { breadcrumbParse, breadcrumbStringify } from './breadcrumb_utils';
3
+ import {randomString, isDeviceSmallerThan, ext} from '../utils'
4
4
 
5
5
  export let path;
6
6
  export let collapseLonger = false
7
7
 
8
8
  let segments = []
9
9
  let userClass = $$props.class ?? ''
10
-
10
+
11
11
  $: init($location, $querystring)
12
12
 
13
13
  function init(...args)
14
14
  {
15
- segments = breadcrumbParse(path);
15
+ if(path && Array.isArray(path) && path.length > 0)
16
+ {
17
+ path.forEach(el =>
18
+ segments.push({
19
+ name: el.Name,
20
+ href: el.href ?? '',
21
+ uniqueKey: randomString(5)
22
+ })
23
+ )
24
+ }
25
+ else
26
+ segments = []
27
+
16
28
  }
17
29
 
18
- function getSegmentHRef(href, idx)
30
+
31
+ function shouldBeCollapsed(idx)
19
32
  {
20
- let prevSegments = []
21
- if(idx > 0)
22
- prevSegments = segments.slice(0, idx)
23
-
24
- const prevPath = breadcrumbStringify(prevSegments)
25
- return `${href}?path=${prevPath}`
33
+ const isSmall = isDeviceSmallerThan("sm")
34
+ const entriesNo = segments.length
35
+ const maxEntriesNo = isSmall ? 2 : 5 //todo: depending on elements real widths
36
+ const isCollaspable = collapseLonger && entriesNo > maxEntriesNo
37
+
38
+ if(!isCollaspable)
39
+ return false
26
40
 
41
+ return idx < entriesNo-maxEntriesNo
27
42
  }
28
43
 
29
44
  </script>
@@ -32,18 +47,17 @@
32
47
  <ol class="inline-flex items-center space-x-1 md:space-x-2 rtl:space-x-reverse flex-wrap">
33
48
 
34
49
  {#if (segments && segments.length > 1)}
35
- {#each segments as segment, idx (segment.href)}
50
+ {#each segments as segment, idx (segment.uniqueKey)}
36
51
  {@const isFirst = idx == 0}
37
52
  {@const isLast = idx == segments.length-1}
38
- {@const collapsable = collapseLonger && segments.length > 5}
39
- {@const isCollapsed = collapsable && idx > 0 && idx < segments.length-3}
40
- {@const isFirstCollapsed = isCollapsed && idx == 1}
53
+ {@const isCollapsed = shouldBeCollapsed(idx)}
54
+ {@const isFirstCollapsed = isCollapsed && idx == 0}
41
55
 
42
56
  {#if isCollapsed}
43
57
  {#if isFirstCollapsed}
44
- <svg class="rtl:rotate-180 w-3 h-3 text-stone-400 mx-1" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 6 10">
58
+ <!--svg class="rtl:rotate-180 w-3 h-3 text-stone-400 mx-1" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 6 10">
45
59
  <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 9 4-4-4-4"/>
46
- </svg>
60
+ </svg-->
47
61
  <span class="ms-1 text-sm md:ms-2 font-semibold text-stone-900 dark:text-stone-100 whitespace-nowrap">
48
62
  ...
49
63
  </span>
@@ -58,12 +72,18 @@
58
72
  {/if}
59
73
  {#if isLast}
60
74
  <span class="ms-1 text-sm md:ms-2 font-semibold text-stone-900 dark:text-stone-100 whitespace-nowrap">
61
- {segment.name}
75
+ {ext(segment.name)}
62
76
  </span>
63
77
  {:else}
64
- <a href={getSegmentHRef(segment.href, idx)} use:link class="ms-1 text-sm font-medium md:ms-2 text-stone-700 hover:text-stone-900 dark:text-stone-400 dark:hover:text-white whitespace-nowrap">
65
- {segment.name}
66
- </a>
78
+ {#if segment.href}
79
+ <a href={segment.href} use:link class="ms-1 text-sm font-medium md:ms-2 text-stone-700 hover:text-stone-900 dark:text-stone-400 dark:hover:text-white whitespace-nowrap">
80
+ {ext(segment.name)}
81
+ </a>
82
+ {:else}
83
+ <span class="ms-1 text-sm font-medium md:ms-2 text-stone-700 dark:text-stone-400 whitespace-nowrap">
84
+ {ext(segment.name)}
85
+ </span>
86
+ {/if}
67
87
  {/if}
68
88
  </div>
69
89
  </li>
@@ -0,0 +1,78 @@
1
+ <script>
2
+ import {location, link, querystring} from 'svelte-spa-router'
3
+ import { breadcrumbParse, breadcrumbStringify } from './breadcrumb_utils';
4
+
5
+ export let path = '';
6
+ export let collapseLonger = false
7
+
8
+ let segments = []
9
+ let userClass = $$props.class ?? ''
10
+
11
+ $: init($location, $querystring)
12
+
13
+ function init(...args)
14
+ {
15
+ if(path)
16
+ segments = breadcrumbParse(path);
17
+ else
18
+ segments = []
19
+ }
20
+
21
+ function getSegmentHRef(href, idx)
22
+ {
23
+ let prevSegments = []
24
+ if(idx > 0)
25
+ prevSegments = segments.slice(0, idx)
26
+
27
+ const prevPath = breadcrumbStringify(prevSegments)
28
+ return `${href}?path=${prevPath}`
29
+
30
+ }
31
+
32
+ </script>
33
+
34
+ <nav class="flex {userClass}" aria-label="Breadcrumb">
35
+ <ol class="inline-flex items-center space-x-1 md:space-x-2 rtl:space-x-reverse flex-wrap">
36
+
37
+ {#if (segments && segments.length > 1)}
38
+ {#each segments as segment, idx (segment.href)}
39
+ {@const isFirst = idx == 0}
40
+ {@const isLast = idx == segments.length-1}
41
+ {@const collapsable = collapseLonger && segments.length > 5}
42
+ {@const isCollapsed = collapsable && idx > 0 && idx < segments.length-3}
43
+ {@const isFirstCollapsed = isCollapsed && idx == 1}
44
+
45
+ {#if isCollapsed}
46
+ {#if isFirstCollapsed}
47
+ <svg class="rtl:rotate-180 w-3 h-3 text-stone-400 mx-1" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 6 10">
48
+ <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 9 4-4-4-4"/>
49
+ </svg>
50
+ <span class="ms-1 text-sm md:ms-2 font-semibold text-stone-900 dark:text-stone-100 whitespace-nowrap">
51
+ ...
52
+ </span>
53
+ {/if}
54
+ {:else}
55
+ <li>
56
+ <div class="flex items-center">
57
+ {#if !isFirst}
58
+ <svg class="rtl:rotate-180 w-3 h-3 text-stone-400 mx-1" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 6 10">
59
+ <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 9 4-4-4-4"/>
60
+ </svg>
61
+ {/if}
62
+ {#if isLast}
63
+ <span class="ms-1 text-sm md:ms-2 font-semibold text-stone-900 dark:text-stone-100 whitespace-nowrap">
64
+ {segment.name}
65
+ </span>
66
+ {:else}
67
+ <a href={getSegmentHRef(segment.href, idx)} use:link class="ms-1 text-sm font-medium md:ms-2 text-stone-700 hover:text-stone-900 dark:text-stone-400 dark:hover:text-white whitespace-nowrap">
68
+ {segment.name}
69
+ </a>
70
+ {/if}
71
+ </div>
72
+ </li>
73
+ {/if}
74
+ {/each}
75
+ {/if}
76
+
77
+ </ol>
78
+ </nav>
@@ -0,0 +1,27 @@
1
+ /** @typedef {typeof __propDef.props} Breadcrumb2Props */
2
+ /** @typedef {typeof __propDef.events} Breadcrumb2Events */
3
+ /** @typedef {typeof __propDef.slots} Breadcrumb2Slots */
4
+ export default class Breadcrumb2 extends SvelteComponentTyped<{
5
+ [x: string]: any;
6
+ path?: string | undefined;
7
+ collapseLonger?: boolean | undefined;
8
+ }, {
9
+ [evt: string]: CustomEvent<any>;
10
+ }, {}> {
11
+ }
12
+ export type Breadcrumb2Props = typeof __propDef.props;
13
+ export type Breadcrumb2Events = typeof __propDef.events;
14
+ export type Breadcrumb2Slots = typeof __propDef.slots;
15
+ import { SvelteComponentTyped } from "svelte";
16
+ declare const __propDef: {
17
+ props: {
18
+ [x: string]: any;
19
+ path?: string | undefined;
20
+ collapseLonger?: boolean | undefined;
21
+ };
22
+ events: {
23
+ [evt: string]: CustomEvent<any>;
24
+ };
25
+ slots: {};
26
+ };
27
+ export {};
@@ -5,18 +5,20 @@ import {
5
5
  selectable,
6
6
  activateItem,
7
7
  isActive,
8
- getActive,
9
8
  editable,
10
- startEditing
9
+ startEditing,
10
+ addActiveItem,
11
+ removeActiveItem
11
12
  } from "../../../utils";
12
13
  import { showGridMenu, showMenu } from "../../menu";
13
14
  import { pushChanges, informModification } from "../../../updates";
14
15
  import Summary from "./list.element.summary.svelte";
15
16
  import Properties from "./list.element.props.svelte";
16
17
  import { isDeviceSmallerThan } from "../../../utils";
18
+ import Icon from "../../icon.svelte";
17
19
  import { rList_definition, rList_property_type } from "../List";
18
20
  import { push, link } from "svelte-spa-router";
19
- import { FaExternalLinkAlt } from "svelte-icons/fa/";
21
+ import { FaExternalLinkAlt, FaRegSquare, FaRegCheckSquare } from "svelte-icons/fa/";
20
22
  import Tags from "../../tags.svelte";
21
23
  import { ext } from "../../../i18n";
22
24
  export let item;
@@ -25,7 +27,10 @@ export let summary = "";
25
27
  export let typename = void 0;
26
28
  export let toolbarOperations = void 0;
27
29
  export let contextMenu = void 0;
30
+ export let multiselecOperations = (items) => [];
28
31
  export let key = "";
32
+ export let selectionKey = "props";
33
+ export let multiselect = false;
29
34
  let definition = getContext("rList-definition");
30
35
  let placeholder = "";
31
36
  let props_sm;
@@ -69,15 +74,9 @@ function calc_horz_division() {
69
74
  }
70
75
  }
71
76
  function calculate_active(...args) {
72
- const activeItem = getActive("props");
73
- if (!activeItem)
74
- return false;
75
- const activeKey = getItemKey(activeItem);
76
- const itemKey = getItemKey(item);
77
- if (activeKey == itemKey) {
78
- return true;
79
- } else
80
- return false;
77
+ const key2 = getItemKeyName(item);
78
+ const active = isActive(selectionKey, item, key2);
79
+ return active;
81
80
  }
82
81
  function selected(...args) {
83
82
  return isSelected(item);
@@ -92,6 +91,19 @@ function getItemKey(item2) {
92
91
  else
93
92
  return 0;
94
93
  }
94
+ function getItemKeyName(item2) {
95
+ if (key)
96
+ return key;
97
+ else {
98
+ const keys = Object.keys(item2);
99
+ if (keys.findIndex((e) => e == "$ref") >= 0)
100
+ return "$ref";
101
+ else if (keys.findIndex((e) => e == "Id") >= 0)
102
+ return "Id";
103
+ else
104
+ return "";
105
+ }
106
+ }
95
107
  async function change_name(text) {
96
108
  if (definition.on_title_changed) {
97
109
  definition.on_title_changed(item, text, title);
@@ -167,11 +179,11 @@ function getHRef() {
167
179
  function activate_row(e, item2) {
168
180
  const openable = !!definition.title_href || !!definition.title_href_func;
169
181
  if (toolbarOperations) {
170
- activateItem("props", item2, toolbarOperations(item2));
182
+ activateItem(selectionKey, item2, toolbarOperations(item2));
171
183
  if (e)
172
184
  e.stopPropagation();
173
- } else if (openable) {
174
- activateItem("props", item2, []);
185
+ } else {
186
+ activateItem(selectionKey, item2, []);
175
187
  if (e)
176
188
  e.stopPropagation();
177
189
  }
@@ -252,6 +264,14 @@ export function scrollToView() {
252
264
  }
253
265
  );
254
266
  }
267
+ function onToggleMultiSelect(e) {
268
+ if (!is_row_active)
269
+ addActiveItem(selectionKey, item, multiselecOperations);
270
+ else
271
+ removeActiveItem(selectionKey, item, multiselecOperations);
272
+ if (e)
273
+ e.stopPropagation();
274
+ }
255
275
  </script>
256
276
 
257
277
  <!-- svelte-ignore a11y-click-events-have-key-events -->
@@ -263,6 +283,13 @@ export function scrollToView() {
263
283
  tabindex="-1"
264
284
  bind:this={rootElement}> <!-- on:contextmenu={on_contextmenu} -->
265
285
 
286
+ {#if multiselect}
287
+ {@const icon=is_row_active ? FaRegCheckSquare : FaRegSquare}
288
+ <Icon component={icon}
289
+ class="flex-none h-5 w-5 sm:h-4 sm:w-4 text-stone-500 dark:text-stone-400 cursor-pointer mt-2 sm:mt-1.5 ml-2 mr-3 "
290
+ on:click={onToggleMultiSelect}/>
291
+ {/if}
292
+
266
293
  <slot name="left" element={item}/>
267
294
 
268
295
  <i class="hidden sm:w-1/2 sm:w-2/3 sm:w-1/3"></i> <!-- just to force tailwind classes including -->
@@ -7,7 +7,10 @@ declare const __propDef: {
7
7
  typename?: string | undefined;
8
8
  toolbarOperations?: undefined;
9
9
  contextMenu?: undefined;
10
+ multiselecOperations?: ((items: any) => never[]) | undefined;
10
11
  key?: string | undefined;
12
+ selectionKey?: string | undefined;
13
+ multiselect?: boolean | undefined;
11
14
  activate?: (() => void) | undefined;
12
15
  editProperty?: ((field: string) => void) | undefined;
13
16
  scrollToView?: (() => void) | undefined;
@@ -1,6 +1,8 @@
1
1
  <script>import { setContext, getContext, afterUpdate, tick, onMount } from "svelte";
2
2
  import { data_tick_store, contextItemsStore, contextTypesStore } from "../../stores";
3
- import { activateItem, getActive, clearActiveItem, parseWidthDirective, getPrev, getNext, swapElements, getLast, insertAfter } from "../../utils";
3
+ import { activateItem, getActive, clearActiveItem, parseWidthDirective, getPrev, getNext, swapElements, getLast, insertAfter, getActiveCount, addActiveItem } from "../../utils";
4
+ import Icon from "../icon.svelte";
5
+ import { FaRegSquare, FaRegCheckSquare } from "svelte-icons/fa/";
4
6
  import { rList_definition } from "./List";
5
7
  import List_element from "./internal/list.element.svelte";
6
8
  import Inserter from "./internal/list.inserter.svelte";
@@ -15,7 +17,10 @@ export let typename = "";
15
17
  export let c = "";
16
18
  export let toolbarOperations = void 0;
17
19
  export let contextMenu = void 0;
20
+ export let multiselecOperations = (items2) => [];
18
21
  export let key = "";
22
+ export let selectionKey = "props";
23
+ export let multiselect = false;
19
24
  export const CLEAR_SELECTION = 0;
20
25
  export const KEEP_SELECTION = -1;
21
26
  export const SELECT_PREVIOUS = -2;
@@ -37,7 +42,7 @@ let rows = [];
37
42
  let activate_after_dom_update = null;
38
43
  let inserter;
39
44
  if (toolbarOperations)
40
- clearActiveItem("props");
45
+ clearActiveItem(selectionKey);
41
46
  let last_tick = -1;
42
47
  $:
43
48
  setup($data_tick_store, $contextItemsStore);
@@ -78,7 +83,7 @@ export function rereder() {
78
83
  setup();
79
84
  }
80
85
  export function reload(data, selectElement = KEEP_SELECTION) {
81
- let currentSelectedItem = getActive("props");
86
+ let currentSelectedItem = getActive(selectionKey);
82
87
  let currentSelectedItemKey = currentSelectedItem ? getItemKey(currentSelectedItem) : null;
83
88
  let selectElementId = null;
84
89
  let altSelectElementId = null;
@@ -169,9 +174,9 @@ export async function addRowAfter(after = null) {
169
174
  if (!definition.can_insert)
170
175
  return;
171
176
  show_insertion_row_after_element = after ?? END_OF_LIST;
172
- last_activated_element = getActive("props");
177
+ last_activated_element = getActive(selectionKey);
173
178
  let fake_item = {};
174
- activateItem("props", fake_item);
179
+ activateItem(selectionKey, fake_item);
175
180
  await tick();
176
181
  if (!inserter)
177
182
  return;
@@ -183,14 +188,14 @@ export async function addRowAfter(after = null) {
183
188
  activate_after_dom_update = last_activated_element;
184
189
  else {
185
190
  if (detail.incremental) {
186
- let current_active = getActive("props");
191
+ let current_active = getActive(selectionKey);
187
192
  await addRowAfter(current_active);
188
193
  }
189
194
  }
190
195
  });
191
196
  }
192
197
  function scrollToSelectedElement() {
193
- const activeItem = getActive("props");
198
+ const activeItem = getActive(selectionKey);
194
199
  if (!activeItem)
195
200
  return;
196
201
  const activeItemKey = getItemKey(activeItem);
@@ -202,12 +207,12 @@ export function remove(element) {
202
207
  let removing_idx = items?.findIndex((e) => e == element);
203
208
  if (removing_idx < 0)
204
209
  return;
205
- let active_element = getActive("props");
210
+ let active_element = getActive(selectionKey);
206
211
  if (active_element == element) {
207
212
  if (removing_idx + 1 < items.length)
208
213
  rows[removing_idx + 1].activate();
209
214
  else
210
- activateItem("props", null, []);
215
+ activateItem(selectionKey, null, []);
211
216
  }
212
217
  items = items.filter((t) => t != element);
213
218
  }
@@ -217,6 +222,17 @@ export function edit(element, property_name) {
217
222
  return;
218
223
  rows[editing_idx].editProperty(property_name);
219
224
  }
225
+ export function toggleMultiselection() {
226
+ multiselect = !multiselect;
227
+ let lastSelectedItem = getActive(selectionKey);
228
+ if (lastSelectedItem) {
229
+ let ops = [];
230
+ if (toolbarOperations)
231
+ ops = toolbarOperations(lastSelectedItem);
232
+ activateItem(selectionKey, lastSelectedItem, ops);
233
+ } else
234
+ clearActiveItem(selectionKey);
235
+ }
220
236
  function reorderElements(items2, from = null) {
221
237
  let fromIdx;
222
238
  let fromOrder;
@@ -275,6 +291,26 @@ async function insert(title2, summary, after) {
275
291
  items = [...items, insertedElement];
276
292
  activate_after_dom_update = insertedElement;
277
293
  }
294
+ const SELECT_ALL = 0;
295
+ const UNSELECT_ALL = 1;
296
+ function calcMultiSelectionMode(...args) {
297
+ const multiselectionCount = getActiveCount(selectionKey);
298
+ if (multiselectionCount > 0)
299
+ return UNSELECT_ALL;
300
+ else
301
+ return SELECT_ALL;
302
+ }
303
+ $:
304
+ multiselectionMode = calcMultiSelectionMode($contextItemsStore);
305
+ function toggleSelectAll(e) {
306
+ if (multiselectionMode == UNSELECT_ALL)
307
+ clearActiveItem(selectionKey);
308
+ else {
309
+ const operations = multiselecOperations(items);
310
+ items?.forEach((itm) => addActiveItem(selectionKey, itm, operations));
311
+ }
312
+ e.stopPropagation();
313
+ }
278
314
  </script>
279
315
 
280
316
  <slot/> <!-- Launch definition settings -->
@@ -289,12 +325,21 @@ async function insert(title2, summary, after) {
289
325
 
290
326
 
291
327
  {#if items && items.length > 0 }
328
+ {#if multiselect}
329
+ {@const icon = (multiselectionMode == SELECT_ALL) ? FaRegSquare : FaRegCheckSquare}
330
+ <Icon component={icon} class="h-5 w-5 sm:h-4 sm:w-4 text-stone-500 dark:text-stone-400 cursor-pointer mt-2 sm:mt-1.5 ml-2 mr-3"
331
+ on:click={toggleSelectAll}/>
332
+ {/if}
333
+
292
334
  {#each items as element, i (getItemKey(element))}
293
335
 
294
336
  <List_element item={element}
295
337
  {toolbarOperations}
296
338
  {contextMenu}
297
339
  {key}
340
+ {multiselect}
341
+ {multiselecOperations}
342
+ {selectionKey}
298
343
  bind:this={rows[i]}
299
344
  >
300
345
 
@@ -11,7 +11,10 @@ declare const __propDef: {
11
11
  c?: string | undefined;
12
12
  toolbarOperations?: undefined;
13
13
  contextMenu?: undefined;
14
+ multiselecOperations?: ((items: any) => never[]) | undefined;
14
15
  key?: string | undefined;
16
+ selectionKey?: string | undefined;
17
+ multiselect?: boolean | undefined;
15
18
  CLEAR_SELECTION?: 0 | undefined;
16
19
  KEEP_SELECTION?: -1 | undefined;
17
20
  SELECT_PREVIOUS?: -2 | undefined;
@@ -26,6 +29,7 @@ declare const __propDef: {
26
29
  addRowAfter?: ((after?: object | null) => Promise<void>) | undefined;
27
30
  remove?: ((element: object) => void) | undefined;
28
31
  edit?: ((element: object, property_name: string) => void) | undefined;
32
+ toggleMultiselection?: (() => void) | undefined;
29
33
  };
30
34
  events: {
31
35
  [evt: string]: CustomEvent<any>;
@@ -55,5 +59,6 @@ export default class List extends SvelteComponentTyped<ListProps, ListEvents, Li
55
59
  get addRowAfter(): (after?: object | null) => Promise<void>;
56
60
  get remove(): (element: object) => void;
57
61
  get edit(): (element: object, property_name: string) => void;
62
+ get toggleMultiselection(): () => void;
58
63
  }
59
64
  export {};
package/index.d.ts CHANGED
@@ -60,7 +60,7 @@ export { KanbanColumnTop, KanbanColumnBottom } from './components/kanban/Kanban'
60
60
  export { default as Paginator } from './components/paginator.svelte';
61
61
  export { default as Breadcrumb } from './components/breadcrumb.svelte';
62
62
  export { breadcrumbAdd, breadcrumbParse, breadcrumbStringify, breadcrumbClipName } from './components/breadcrumb_utils';
63
- export { selectItem, activateItem, clearActiveItem, isActive, isSelected, getActive, editable, startEditing, saveCurrentEditable, selectable, handleSelect, isDeviceSmallerThan, resizeImage, refreshToolbarOperations, isOnScreenKeyboardVisible, randomString, UI, NAV_MODE_SIDEBAR, NAV_MODE_FULL_PAGE, navGetMode, navIsVisible, navGetKey, navShow, navHide, navToggle, navPrevVisibleKey, navAutoHide, } from './utils';
63
+ export { selectItem, activateItem, clearActiveItem, isActive, isSelected, getActive, getActiveItems, getActiveCount, addActiveItem, removeActiveItem, editable, startEditing, saveCurrentEditable, selectable, handleSelect, isDeviceSmallerThan, resizeImage, refreshToolbarOperations, isOnScreenKeyboardVisible, randomString, UI, NAV_MODE_SIDEBAR, NAV_MODE_FULL_PAGE, navGetMode, navIsVisible, navGetKey, navShow, navHide, navToggle, navPrevVisibleKey, navAutoHide, } from './utils';
64
64
  export { getNiceStringDateTime, getFormattedStringDate, getNiceStringDate, dayName, monthName } from './components/date_utils';
65
65
  export { mainContentPageReloader, reloadMainContentPage, reloadWholeApp, wholeAppReloader, alerts, addAlert, onErrorShowAlert, main_sidebar_visible_store, navKey, tagsReloader, reloadVisibleTags, dark_mode_store, showFABAlways } from './stores.js';
66
66
  export { data_tick_store, // tmp
package/index.js CHANGED
@@ -66,7 +66,7 @@ export { KanbanColumnTop, KanbanColumnBottom } from './components/kanban/Kanban'
66
66
  export { default as Paginator } from './components/paginator.svelte';
67
67
  export { default as Breadcrumb } from './components/breadcrumb.svelte';
68
68
  export { breadcrumbAdd, breadcrumbParse, breadcrumbStringify, breadcrumbClipName } from './components/breadcrumb_utils';
69
- export { selectItem, activateItem, clearActiveItem, isActive, isSelected, getActive, editable, startEditing, saveCurrentEditable, selectable, handleSelect, isDeviceSmallerThan, resizeImage, refreshToolbarOperations, isOnScreenKeyboardVisible, randomString, UI, NAV_MODE_SIDEBAR, NAV_MODE_FULL_PAGE, navGetMode, navIsVisible, navGetKey, navShow, navHide, navToggle, navPrevVisibleKey, navAutoHide, } from './utils';
69
+ export { selectItem, activateItem, clearActiveItem, isActive, isSelected, getActive, getActiveItems, getActiveCount, addActiveItem, removeActiveItem, editable, startEditing, saveCurrentEditable, selectable, handleSelect, isDeviceSmallerThan, resizeImage, refreshToolbarOperations, isOnScreenKeyboardVisible, randomString, UI, NAV_MODE_SIDEBAR, NAV_MODE_FULL_PAGE, navGetMode, navIsVisible, navGetKey, navShow, navHide, navToggle, navPrevVisibleKey, navAutoHide, } from './utils';
70
70
  export { getNiceStringDateTime, getFormattedStringDate, getNiceStringDate, dayName, monthName } from './components/date_utils';
71
71
  export { mainContentPageReloader, reloadMainContentPage, reloadWholeApp, wholeAppReloader, alerts, addAlert, onErrorShowAlert, main_sidebar_visible_store, navKey, tagsReloader, reloadVisibleTags, dark_mode_store, showFABAlways } from './stores.js';
72
72
  export { data_tick_store, // tmp
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@humandialog/forms.svelte",
3
- "version": "1.6.6",
3
+ "version": "1.6.8",
4
4
  "description": "Basic Svelte UI components for Object Reef applications",
5
5
  "devDependencies": {
6
6
  "@playwright/test": "^1.28.1",
@@ -71,6 +71,7 @@
71
71
  "exports": {
72
72
  "./package.json": "./package.json",
73
73
  "./components/breadcrumb.svelte": "./components/breadcrumb.svelte",
74
+ "./components/breadcrumb2.svelte": "./components/breadcrumb2.svelte",
74
75
  "./components/breadcrumb_utils": "./components/breadcrumb_utils.js",
75
76
  "./components/button.svelte": "./components/button.svelte",
76
77
  "./components/checkbox.svelte": "./components/checkbox.svelte",
package/stores.d.ts CHANGED
@@ -18,6 +18,7 @@ export const contextItemsStore: import("svelte/store").Writable<{
18
18
  focused: string;
19
19
  data: null;
20
20
  sel: null;
21
+ props: null;
21
22
  }>;
22
23
  export const context_info_store: import("svelte/store").Writable<{
23
24
  data: string;
package/stores.js CHANGED
@@ -5,7 +5,7 @@ import {navGetKey} from './utils.js'
5
5
  import { location } from 'svelte-spa-router';
6
6
 
7
7
  export const data_tick_store = writable(1);
8
- export const contextItemsStore = writable({focused:'', data: null, sel: null})
8
+ export const contextItemsStore = writable({focused:'', data: null, sel: null, props: null})
9
9
  export const context_info_store = writable({data: '', sel: ''})
10
10
  export const contextTypesStore = writable({focused:'', data: null, sel: null})
11
11
  export const contextToolbarOperations = writable([]);
package/utils.d.ts CHANGED
@@ -2,10 +2,14 @@ export function isDeviceSmallerThan(br: any): boolean;
2
2
  export function selectItem(itm: any): void;
3
3
  export function activateItem(context_level: any, itm: any, operations?: null): void;
4
4
  export function clearActiveItem(context_level: any): void;
5
- export function refreshToolbarOperations(): void;
5
+ export function addActiveItem(context_level: any, itm: any, operations?: null): void;
6
+ export function removeActiveItem(context_level: any, itm: any, operations?: null): void;
6
7
  export function isSelected(itm: any): boolean;
7
- export function isActive(context_level: any, itm: any): boolean;
8
+ export function isActive(context_level: any, itm: any, key?: undefined): boolean;
8
9
  export function getActive(context_level: any): any;
10
+ export function getActiveItems(context_level: any): any[];
11
+ export function getActiveCount(context_level: any): number;
12
+ export function refreshToolbarOperations(): void;
9
13
  export function editable(node: any, params: any): {
10
14
  destroy(): void;
11
15
  } | undefined;
package/utils.js CHANGED
@@ -17,9 +17,6 @@ export function isDeviceSmallerThan(br)
17
17
  return window.innerWidth < SCREEN_SIZES[br]
18
18
  }
19
19
 
20
- //export const chnages = {
21
- // just_changed_context: false
22
- //}
23
20
 
24
21
  export function selectItem(itm)
25
22
  {
@@ -56,7 +53,7 @@ export function activateItem(context_level, itm, operations=null)
56
53
 
57
54
  //chnages.just_changed_context = true;
58
55
 
59
- if(operations)
56
+ if(operations && context_level == 'props')
60
57
  {
61
58
  if(Array.isArray(operations))
62
59
  contextToolbarOperations.set( [...operations] )
@@ -70,6 +67,7 @@ export function clearActiveItem(context_level)
70
67
  let data_context = get(contextItemsStore);
71
68
  data_context[context_level] = null;
72
69
  data_context.focused = context_level;
70
+ data_context.sel = null
73
71
  contextItemsStore.set( {...data_context} )
74
72
 
75
73
 
@@ -79,9 +77,187 @@ export function clearActiveItem(context_level)
79
77
 
80
78
  //chnages.just_changed_context = true;
81
79
 
82
- contextToolbarOperations.set( [] )
80
+ if(context_level == 'props')
81
+ contextToolbarOperations.set( [] )
83
82
  }
84
83
 
84
+ export function addActiveItem(context_level, itm, operations = null)
85
+ {
86
+ let data_context = get(contextItemsStore);
87
+ data_context['sel'] = itm; //null;
88
+
89
+ let multi = data_context[context_level]
90
+
91
+ if(multi && Array.isArray(multi))
92
+ multi = [...multi, itm]
93
+ else if(multi instanceof Object)
94
+ multi = [multi, itm]
95
+ else
96
+ multi = [itm]
97
+
98
+ data_context[context_level] = multi;
99
+ data_context.focused = context_level;
100
+ contextItemsStore.set( {...data_context} )
101
+
102
+
103
+ let ticket = get(data_tick_store)
104
+ ticket++;
105
+ data_tick_store.set(ticket)
106
+
107
+ //chnages.just_changed_context = true;
108
+
109
+ if(operations && context_level == 'props')
110
+ {
111
+ if(typeof operations === 'function')
112
+ {
113
+ const calculatedOps = operations(multi)
114
+ contextToolbarOperations.set(calculatedOps)
115
+ }
116
+ else if(Array.isArray(operations))
117
+ contextToolbarOperations.set( [...operations] )
118
+ else
119
+ contextToolbarOperations.set( {...operations} )
120
+ }
121
+
122
+ }
123
+
124
+ export function removeActiveItem(context_level, itm, operations = null)
125
+ {
126
+ let data_context = get(contextItemsStore);
127
+ let multi = data_context[context_level]
128
+
129
+ if(multi && Array.isArray(multi))
130
+ {
131
+ const idx = multi.findIndex(el => el == itm)
132
+ if(idx >= 0)
133
+ multi.splice(idx, 1)
134
+ }
135
+ else
136
+ multi = []
137
+
138
+ if(multi.length == 1)
139
+ multi = multi[0]
140
+
141
+ data_context[context_level] = multi;
142
+
143
+ contextItemsStore.set( {...data_context} )
144
+
145
+ let ticket = get(data_tick_store)
146
+ ticket++;
147
+ data_tick_store.set(ticket)
148
+
149
+
150
+ if(context_level == 'props')
151
+ {
152
+ if(multi.length == 0)
153
+ contextToolbarOperations.set( [] )
154
+ else
155
+ {
156
+ if(operations)
157
+ {
158
+ if(typeof operations === 'function')
159
+ {
160
+ const calculatedOps = operations(multi)
161
+ contextToolbarOperations.set(calculatedOps)
162
+ }
163
+ else if(Array.isArray(operations))
164
+ contextToolbarOperations.set( [...operations] )
165
+ else
166
+ contextToolbarOperations.set( {...operations} )
167
+ }
168
+ }
169
+ }
170
+
171
+ }
172
+
173
+
174
+ export function isSelected(itm)
175
+ {
176
+ let data_context = get(contextItemsStore);
177
+ if(!!data_context && !!data_context['sel'] && data_context['sel'] == itm)
178
+ return true;
179
+ else
180
+ return false;
181
+ }
182
+
183
+
184
+ export function isActive(context_level, itm, key = undefined)
185
+ {
186
+ let data_context = get(contextItemsStore);
187
+
188
+ if(!data_context)
189
+ return false
190
+
191
+ const slot = data_context[context_level];
192
+ if(!slot)
193
+ return false
194
+
195
+ if(Array.isArray(slot))
196
+ {
197
+ const idx = slot.findIndex(el => {
198
+ if(key)
199
+ return el[key] == itm[key]
200
+ else
201
+ return el == itm
202
+ })
203
+ return idx >= 0
204
+ }
205
+ else if(key)
206
+ return slot[key] == itm[key]
207
+ else
208
+ return slot == itm
209
+ }
210
+
211
+ export function getActive(context_level)
212
+ {
213
+ let data_context = get(contextItemsStore);
214
+ if(data_context != undefined)
215
+ {
216
+ const prop = data_context[context_level]
217
+ if(prop && Array.isArray(prop) && prop.length > 0)
218
+ return prop[prop.length-1]
219
+ else
220
+ return prop;
221
+ }
222
+ else
223
+ return null;
224
+ }
225
+
226
+ export function getActiveItems(context_level)
227
+ {
228
+ let data_context = get(contextItemsStore);
229
+ if(data_context != undefined)
230
+ {
231
+ const prop = data_context[context_level]
232
+ if(prop && Array.isArray(prop))
233
+ return prop
234
+ else if(prop)
235
+ return [prop]
236
+ else
237
+ return []
238
+ }
239
+ else
240
+ return [];
241
+ }
242
+
243
+ export function getActiveCount(context_level)
244
+ {
245
+ let data_context = get(contextItemsStore);
246
+
247
+ if(!data_context)
248
+ return 0
249
+
250
+ const slot = data_context[context_level];
251
+ if(!slot)
252
+ return 0
253
+
254
+ if(Array.isArray(slot))
255
+ return slot.length
256
+ else
257
+ return 1
258
+ }
259
+
260
+
85
261
  export function refreshToolbarOperations()
86
262
  {
87
263
 
@@ -135,34 +311,6 @@ export function refreshToolbarOperations()
135
311
  }
136
312
  }
137
313
 
138
- export function isSelected(itm)
139
- {
140
- let data_context = get(contextItemsStore);
141
- if(!!data_context && !!data_context['sel'] && data_context['sel'] == itm)
142
- return true;
143
- else
144
- return false;
145
- }
146
-
147
-
148
- export function isActive(context_level, itm)
149
- {
150
- let data_context = get(contextItemsStore);
151
- if(data_context != undefined && data_context[context_level] != undefined && data_context[context_level] == itm)
152
- return true;
153
- else
154
- return false;
155
- }
156
-
157
- export function getActive(context_level)
158
- {
159
- let data_context = get(contextItemsStore);
160
- if(data_context != undefined)
161
- return data_context[context_level]
162
- else
163
- return null;
164
- }
165
-
166
314
  export let currentEditable = null;
167
315
 
168
316
  export function editable(node, params)