@humandialog/forms.svelte 0.4.13 → 0.4.15

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.
Files changed (49) hide show
  1. package/components/Floating_container.svelte +43 -10
  2. package/components/Floating_container.svelte.d.ts +4 -2
  3. package/components/Grid.menu.svelte +5 -3
  4. package/components/Grid.menu.svelte.d.ts +2 -2
  5. package/components/combo/combo.d.ts +2 -0
  6. package/components/combo/combo.js +2 -0
  7. package/components/combo/combo.source.svelte +6 -2
  8. package/components/combo/combo.source.svelte.d.ts +3 -1
  9. package/components/combo/combo.svelte +127 -83
  10. package/components/combo/combo.svelte.d.ts +5 -0
  11. package/components/contextmenu.svelte +23 -9
  12. package/components/contextmenu.svelte.d.ts +4 -2
  13. package/components/date.svelte +142 -25
  14. package/components/date.svelte.d.ts +7 -0
  15. package/components/list/List.d.ts +28 -0
  16. package/components/list/List.js +34 -0
  17. package/components/list/internal/list.element.svelte +295 -0
  18. package/components/list/internal/list.element.svelte.d.ts +29 -0
  19. package/components/list/internal/list.inserter.svelte +20 -0
  20. package/components/list/internal/list.inserter.svelte.d.ts +18 -0
  21. package/components/list/list.combo.svelte +20 -0
  22. package/components/list/list.combo.svelte.d.ts +21 -0
  23. package/components/list/list.date.svelte +14 -0
  24. package/components/list/list.date.svelte.d.ts +18 -0
  25. package/components/list/list.inserter.svelte +6 -0
  26. package/components/list/list.inserter.svelte.d.ts +16 -0
  27. package/components/list/list.summary.svelte +7 -0
  28. package/components/list/list.summary.svelte.d.ts +17 -0
  29. package/components/list/list.svelte +148 -0
  30. package/components/list/list.svelte.d.ts +41 -0
  31. package/components/list/list.title.svelte +7 -0
  32. package/components/list/list.title.svelte.d.ts +17 -0
  33. package/components/menu.d.ts +3 -3
  34. package/components/menu.js +20 -10
  35. package/components/sidebar/sidebar.item.svelte +27 -15
  36. package/components/sidebar/sidebar.item.svelte.d.ts +3 -0
  37. package/components/table/table.svelte +1 -1
  38. package/desk.svelte +67 -35
  39. package/horizontal.toolbar.svelte +11 -5
  40. package/index.d.ts +10 -3
  41. package/index.js +11 -3
  42. package/operations.svelte +11 -5
  43. package/operations.svelte.d.ts +3 -1
  44. package/package.json +11 -2
  45. package/page.svelte +8 -2
  46. package/stores.js +4 -3
  47. package/utils.d.ts +8 -0
  48. package/utils.js +59 -9
  49. package/vertical.toolbar.svelte +11 -4
@@ -1,45 +1,78 @@
1
- <script>import { tick } from "svelte";
1
+ <script>import { tick, afterUpdate } from "svelte";
2
+ import { is_device_smaller_than } from "../utils";
2
3
  let x;
3
4
  let y;
4
5
  let visible = false;
5
6
  let toolbar;
6
7
  let props = {};
8
+ let around_rect;
7
9
  let root_element;
8
10
  let invisible_button;
9
11
  $:
10
12
  display = visible ? "fixed" : "hidden";
11
- export async function show(_x, _y, _toolbar, _props = {}) {
12
- x = _x;
13
- y = _y;
13
+ export async function show(around, _toolbar, _props = {}) {
14
+ if (around instanceof DOMRect) {
15
+ x = around.left;
16
+ y = around.bottom;
17
+ around_rect = around;
18
+ } else if (around instanceof DOMPoint) {
19
+ x = around.x;
20
+ y = around.y;
21
+ around_rect = new DOMRect(x, y, 0, 0);
22
+ }
14
23
  visible = true;
15
24
  toolbar = _toolbar;
16
25
  props = _props;
26
+ props.onhide = () => {
27
+ hide();
28
+ };
17
29
  await tick();
18
30
  focus_first_element();
19
31
  }
32
+ export function is_visible() {
33
+ return visible;
34
+ }
20
35
  export function hide() {
21
36
  visible = false;
22
37
  }
38
+ afterUpdate(() => {
39
+ if (!root_element)
40
+ return;
41
+ let rect = root_element.getBoundingClientRect();
42
+ if (rect.height == 0)
43
+ return;
44
+ let container_rect = new DOMRect(0, 0, window.innerWidth, window.innerHeight);
45
+ if (rect.right > container_rect.right)
46
+ x = container_rect.right - rect.width;
47
+ if (rect.bottom > container_rect.bottom)
48
+ y = container_rect.bottom - rect.height - around_rect.height;
49
+ if (rect.left < container_rect.left)
50
+ x = container_rect.left;
51
+ if (rect.top < container_rect.top)
52
+ y = container_rect.top;
53
+ });
23
54
  function focus_first_element() {
24
55
  invisible_button.focus();
25
56
  return;
26
57
  let focusable = root_element.querySelector('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');
27
- console.log(focusable);
28
58
  focusable.focus();
29
59
  }
30
60
  function on_focus_out(e) {
31
- if (e.relatedTarget && root_element?.contains(e.relatedTarget)) {
32
- } else
33
- hide();
61
+ if (!is_device_smaller_than("sm")) {
62
+ if (e.relatedTarget && root_element?.contains(e.relatedTarget)) {
63
+ } else
64
+ hide();
65
+ } else {
66
+ }
34
67
  }
35
68
  </script>
36
69
 
37
70
  <div id="__hd_svelte_floating_container"
38
71
  class="p-2 bg-slate-100 dark:bg-slate-800 rounded-lg shadow {display}"
39
- style="left:{x}px; top:{y}px"
72
+ style="left:{x}px; top:{y}px; width: max-content; height:max-content"
40
73
  on:focusout={on_focus_out}
41
74
  bind:this={root_element}>
42
75
  <button class="w-0 h-0 fixed bg-transparent " bind:this={invisible_button}></button>
43
- <svelte:component this={toolbar} {...props} hide={() => hide()}/>
76
+ <svelte:component this={toolbar} {...props} />
44
77
  </div>
45
78
 
@@ -1,7 +1,8 @@
1
1
  import { SvelteComponentTyped } from "svelte";
2
2
  declare const __propDef: {
3
3
  props: {
4
- show?: ((_x: number, _y: number, _toolbar: any, _props?: {}) => Promise<void>) | undefined;
4
+ show?: ((around: DOMRect | DOMPoint, _toolbar: any, _props?: {}) => Promise<void>) | undefined;
5
+ is_visible?: (() => boolean) | undefined;
5
6
  hide?: (() => void) | undefined;
6
7
  };
7
8
  events: {
@@ -13,7 +14,8 @@ export type FloatingContainerProps = typeof __propDef.props;
13
14
  export type FloatingContainerEvents = typeof __propDef.events;
14
15
  export type FloatingContainerSlots = typeof __propDef.slots;
15
16
  export default class FloatingContainer extends SvelteComponentTyped<FloatingContainerProps, FloatingContainerEvents, FloatingContainerSlots> {
16
- get show(): (_x: number, _y: number, _toolbar: any, _props?: {}) => Promise<void>;
17
+ get show(): (around: DOMRect | DOMPoint, _toolbar: any, _props?: {}) => Promise<void>;
18
+ get is_visible(): () => boolean;
17
19
  get hide(): () => void;
18
20
  }
19
21
  export {};
@@ -2,7 +2,7 @@
2
2
  import {context_items_store} from '../stores.js'
3
3
 
4
4
  export let operations = []
5
- export let hide = undefined;
5
+ export let onhide = undefined;
6
6
 
7
7
  $: grid_cols = init(operations);
8
8
 
@@ -94,8 +94,10 @@
94
94
 
95
95
  function execute_action(e, operation)
96
96
  {
97
- if(hide != undefined)
98
- hide();
97
+ if(!!onhide)
98
+ onhide();
99
+
100
+ e.stopPropagation();
99
101
 
100
102
  if(!operation)
101
103
  return;
@@ -2,7 +2,7 @@
2
2
  /** @typedef {typeof __propDef.events} GridEvents */
3
3
  /** @typedef {typeof __propDef.slots} GridSlots */
4
4
  export default class Grid extends SvelteComponentTyped<{
5
- hide?: any;
5
+ onhide?: any;
6
6
  operations?: any[] | undefined;
7
7
  }, {
8
8
  [evt: string]: CustomEvent<any>;
@@ -14,7 +14,7 @@ export type GridSlots = typeof __propDef.slots;
14
14
  import { SvelteComponentTyped } from "svelte";
15
15
  declare const __propDef: {
16
16
  props: {
17
- hide?: any;
17
+ onhide?: any;
18
18
  operations?: any[] | undefined;
19
19
  };
20
20
  events: {
@@ -7,6 +7,8 @@ export declare class rCombo_item {
7
7
  export declare class rCombo_definition {
8
8
  source: rCombo_item[];
9
9
  collection_expr: string | undefined;
10
+ collection_path: string | undefined;
11
+ collection: object[] | undefined;
10
12
  on_collect: undefined;
11
13
  element_key: string | undefined;
12
14
  element_name: string | undefined;
@@ -7,6 +7,8 @@ export class rCombo_item {
7
7
  export class rCombo_definition {
8
8
  source = [];
9
9
  collection_expr;
10
+ collection_path;
11
+ collection;
10
12
  on_collect = undefined;
11
13
  element_key;
12
14
  element_name;
@@ -1,11 +1,15 @@
1
1
  <script>import { getContext } from "svelte";
2
- export let collection = "";
2
+ export let association = void 0;
3
+ export let path = void 0;
4
+ export let objects = void 0;
3
5
  export let on_collect = void 0;
4
6
  export let key = "";
5
7
  export let name = "";
6
8
  export let avatar = "";
7
9
  let definition = getContext("rCombo-definition");
8
- definition.collection_expr = collection;
10
+ definition.collection_expr = association;
11
+ definition.collection_path = path;
12
+ definition.collection = objects;
9
13
  definition.on_collect = on_collect;
10
14
  definition.element_key = key;
11
15
  definition.element_name = name;
@@ -1,7 +1,9 @@
1
1
  import { SvelteComponentTyped } from "svelte";
2
2
  declare const __propDef: {
3
3
  props: {
4
- collection?: string | undefined;
4
+ association?: string | undefined;
5
+ path?: string | undefined;
6
+ objects?: object[] | undefined;
5
7
  on_collect?: undefined;
6
8
  key?: string | undefined;
7
9
  name?: string | undefined;
@@ -1,7 +1,7 @@
1
1
  <script>import { data_tick_store, context_items_store, context_types_store } from "../../stores.js";
2
2
  import { inform_modification, push_changes } from "../../updates.js";
3
3
  import { parse_width_directive, should_be_comapact } from "../../utils.js";
4
- import { afterUpdate, getContext, setContext } from "svelte";
4
+ import { afterUpdate, getContext, onMount, setContext } from "svelte";
5
5
  import { rCombo_definition, rCombo_item, cached_sources } from "./combo";
6
6
  import FaChevronDown from "svelte-icons/fa/FaChevronDown.svelte";
7
7
  import Icon from "../icon.svelte";
@@ -9,19 +9,25 @@ import { Auth } from "@humandialog/auth.svelte/dist/index.js";
9
9
  export let label = "";
10
10
  export let self = null;
11
11
  export let a = "";
12
+ export let is_association = false;
12
13
  export let context = "";
13
14
  export let typename = "";
14
15
  export let choice_callback = "";
15
16
  export let on_select = void 0;
17
+ export let definition = null;
18
+ export let changed = void 0;
16
19
  export let icon = false;
17
20
  export let placeholder = "Choose wisely...";
18
21
  export let s = "sm";
19
22
  export let c = "";
20
23
  export let compact = false;
21
24
  export let in_context = "sel";
25
+ export let cached = false;
22
26
  let is_compact = getContext("rIs-table-component") || compact;
23
- let definition = new rCombo_definition();
24
- setContext("rCombo-definition", definition);
27
+ if (!definition) {
28
+ definition = new rCombo_definition();
29
+ setContext("rCombo-definition", definition);
30
+ }
25
31
  let is_dropdown_open = false;
26
32
  let dropdown_position = "";
27
33
  let combo;
@@ -56,9 +62,7 @@ switch (s) {
56
62
  let background_class = is_compact && !icon ? "bg-slate-900/10 dark:bg-slate-100/10 rounded-lg" : "";
57
63
  let appearance_class;
58
64
  if (is_compact)
59
- appearance_class = ` text-gray-900 ${font_size}
60
- focus:ring-primary-600 block w-full ${input_pb} ${input_pt} px-2.5 dark:bg-gray-700
61
- dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 ${background_class}`;
65
+ appearance_class = `${font_size}`;
62
66
  else
63
67
  appearance_class = ` bg-gray-50 border border-gray-300 text-gray-900 ${font_size} rounded-lg
64
68
  focus:ring-primary-600 focus:border-primary-600 block w-full ${input_pb} ${input_pt} px-2.5 dark:bg-gray-700
@@ -78,13 +82,27 @@ function setup(...args) {
78
82
  label = a;
79
83
  tick_request_internal = tick_request_internal + 1;
80
84
  if (is_compact) {
81
- if ($context_items_store[in_context] != self)
82
- can_be_activated = false;
83
- else
84
- can_be_activated = true;
85
+ can_be_activated = false;
86
+ let contexts = in_context.split(" ");
87
+ contexts.forEach((ctx2) => {
88
+ if ($context_items_store[ctx2] == item)
89
+ can_be_activated = true;
90
+ });
85
91
  } else
86
92
  can_be_activated = true;
87
93
  }
94
+ onMount(() => {
95
+ if (definition.on_collect)
96
+ definition.on_collect().then((source) => source_fetched(source));
97
+ else if (definition.collection_expr)
98
+ fetch_source_from_association().then((source) => source_fetched(source));
99
+ else if (definition.collection_path)
100
+ get_source_collection(definition.collection_path, `${definition.collection_path}`).then((source) => source_fetched(source));
101
+ else if (definition.collection)
102
+ source_fetched(definition.collection);
103
+ return () => {
104
+ };
105
+ });
88
106
  afterUpdate(() => {
89
107
  if (is_dropdown_open && textbox && document.activeElement != textbox)
90
108
  textbox.focus();
@@ -172,14 +190,8 @@ export function show(event, hide_callback) {
172
190
  characterData: true,
173
191
  subtree: true
174
192
  });
175
- if (definition.collection_expr)
176
- fetch_source().then((source) => source_fetched(source));
177
- else if (definition.on_collect) {
178
- definition.on_collect().then((source) => source_fetched(source));
179
- } else {
180
- filtered_source = definition.source.map((e) => e);
181
- highlighted_option = filtered_source.length > 0 ? filtered_source[0] : null;
182
- }
193
+ filtered_source = definition.source.map((e) => e);
194
+ highlighted_option = filtered_source.length > 0 ? filtered_source[0] : null;
183
195
  }
184
196
  export function hide() {
185
197
  if (mutation_observer)
@@ -236,41 +248,82 @@ function get_combo_text() {
236
248
  }
237
249
  async function on_choose(itm) {
238
250
  hide();
239
- if (choice_callback) {
240
- let body = {
241
- choice: {
242
- $ref: itm.Key
243
- }
244
- };
245
- let path = `${typename}/${item.Id}/${choice_callback}`;
246
- let fields = calc_path_fields_param();
247
- if (fields)
248
- path += fields;
249
- let res = await Auth.fetch(
250
- `json/yav1/${path}`,
251
- {
252
- method: "POST",
253
- body: JSON.stringify(body)
254
- }
255
- );
256
- if (res.ok) {
257
- let result_item = await res.json();
258
- let result_typename = Object.keys(result_item)[0];
259
- item[a] = result_item[result_typename];
260
- tick_request_internal = tick_request_internal + 1;
261
- } else
262
- console.error(res);
263
- } else if (on_select) {
251
+ if (on_select) {
264
252
  await on_select(item, itm.Key, itm.Name);
265
253
  tick_request_internal = tick_request_internal + 1;
266
254
  } else {
267
- item[a] = itm.Key ?? itm.Name;
268
- tick_request_internal = tick_request_internal + 1;
269
- if (item && a && typename) {
270
- inform_modification(item, a, typename);
271
- push_changes();
255
+ if (is_association) {
256
+ if (choice_callback) {
257
+ let body = {
258
+ choice: {
259
+ $ref: itm.Key
260
+ }
261
+ };
262
+ let path;
263
+ if (item.$ref)
264
+ path = `${item.$ref}/${choice_callback}`;
265
+ else
266
+ path = `${typename}/${item.Id}/${choice_callback}`;
267
+ let fields = calc_path_fields_param();
268
+ if (fields)
269
+ path += fields;
270
+ let result = await Auth.post(`json/yav1/${path}`, body);
271
+ if (result) {
272
+ let result_typename = Object.keys(result)[0];
273
+ item[a] = result[result_typename];
274
+ tick_request_internal = tick_request_internal + 1;
275
+ }
276
+ } else {
277
+ let path;
278
+ if (item.$ref)
279
+ path = `json/yav1/${item.$ref}/set`;
280
+ else if (typename && item.Id)
281
+ path = `json/yav1/${typename}/${item.Id}/set`;
282
+ let result = await Auth.post(
283
+ path,
284
+ {
285
+ [a]: {
286
+ $ref: itm.Key
287
+ }
288
+ }
289
+ );
290
+ if (result) {
291
+ let name = definition.element_name ?? "$display";
292
+ item[a] = {
293
+ $ref: itm.Key,
294
+ [name]: itm.Name
295
+ };
296
+ tick_request_internal = tick_request_internal + 1;
297
+ }
298
+ }
299
+ } else {
300
+ if (choice_callback) {
301
+ let path;
302
+ if (item.$ref)
303
+ path = `json/yav1/${item.$ref}/${choice_callback}`;
304
+ else
305
+ path = `json/yav1/${typename}/${item.Id}/${choice_callback}`;
306
+ let fields = calc_path_fields_param();
307
+ if (fields)
308
+ path += fields;
309
+ let value = itm.Key ?? itm.Name;
310
+ let result = await Auth.post(path, { choice: value });
311
+ if (result) {
312
+ item[a] = result;
313
+ tick_request_internal = tick_request_internal + 1;
314
+ }
315
+ } else {
316
+ item[a] = itm.Key ?? itm.Name;
317
+ tick_request_internal = tick_request_internal + 1;
318
+ if (item && a && typename) {
319
+ inform_modification(item, a, typename);
320
+ push_changes();
321
+ }
322
+ }
272
323
  }
273
324
  }
325
+ if (!!changed)
326
+ changed(itm.Key, itm.Name);
274
327
  }
275
328
  function on_keydown(e) {
276
329
  switch (e.key) {
@@ -337,7 +390,7 @@ let last_tick_internal = -1;
337
390
  function on_mouse_move(over) {
338
391
  highlighted_option = over;
339
392
  }
340
- async function fetch_source() {
393
+ async function fetch_source_from_association() {
341
394
  if (item.hasOwnProperty(definition.collection_expr)) {
342
395
  let prop = item[definition.collection_expr];
343
396
  if (!prop)
@@ -353,7 +406,11 @@ async function fetch_source() {
353
406
  } else
354
407
  return null;
355
408
  } else {
356
- let path = `${typename}/${item.Id}/${definition.collection_expr}`;
409
+ let path;
410
+ if (item.$ref)
411
+ path = `${item.$ref}/${definition.collection_expr}`;
412
+ else
413
+ path = `${typename}/${item.Id}/${definition.collection_expr}`;
357
414
  return await get_source_collection(path, `${typename}_${definition.collection_expr}`);
358
415
  }
359
416
  }
@@ -378,23 +435,16 @@ function calc_path_fields_param() {
378
435
  async function get_source_collection(path, cache_key) {
379
436
  if (!cached_sources.has(cache_key)) {
380
437
  let promise2 = new Promise(async (resolve, fail) => {
381
- try {
382
- let fields = calc_path_fields_param();
383
- if (fields)
384
- path += fields;
385
- let res = await Auth.fetch(`json/yav1/${path}`, {
386
- method: "POST"
387
- });
388
- if (res.ok)
389
- resolve(await res.json());
390
- else
391
- resolve(null);
392
- } catch (err) {
393
- console.error(err);
394
- resolve(null);
395
- }
438
+ let fields = calc_path_fields_param();
439
+ if (fields)
440
+ path += fields;
441
+ let res = await Auth.get(`json/yav1/${path}`);
442
+ resolve(res);
396
443
  });
397
- cached_sources.set(cache_key, promise2);
444
+ if (!cached)
445
+ return await promise2;
446
+ else
447
+ cached_sources.set(cache_key, promise2);
398
448
  }
399
449
  let promise = cached_sources.get(cache_key);
400
450
  return await promise;
@@ -409,18 +459,21 @@ function source_fetched(source) {
409
459
  let type = Object.keys(source)[0];
410
460
  array = source[type];
411
461
  }
412
- item[definition.collection_expr] = [...array];
413
462
  definition.source = [];
414
463
  array.forEach((e) => {
415
464
  let el = new rCombo_item();
416
465
  if (definition.element_name)
417
466
  el.Name = e[definition.element_name];
418
- else
467
+ else if (e.$display)
419
468
  el.Name = e.$display;
469
+ else
470
+ el.Name = e.toString();
420
471
  if (definition.element_key)
421
472
  el.Key = e[definition.element_key];
422
- else
473
+ else if (e.$ref)
423
474
  el.Key = e.$ref;
475
+ else
476
+ el.Key = el.Name;
424
477
  if (icon) {
425
478
  if (definition.element_avatar)
426
479
  el.Avatar = e[definition.element_avatar];
@@ -429,8 +482,6 @@ function source_fetched(source) {
429
482
  }
430
483
  definition.source.push(el);
431
484
  });
432
- filtered_source = definition.source.map((e) => e);
433
- highlighted_option = filtered_source.length > 0 ? filtered_source[0] : null;
434
485
  }
435
486
  function setup_view(...args) {
436
487
  if (tick_request_internal <= last_tick_internal)
@@ -454,7 +505,7 @@ function on_focus_out(e) {
454
505
  {#if true}
455
506
  {@const c = setup_view(item, a, tick_request_internal) }
456
507
 
457
- <div class={cs}
508
+ <div class="{cs} max-w-full inline-block"
458
509
  on:focusout={on_focus_out}
459
510
  bind:this={root_element}>
460
511
  {#if !is_compact}
@@ -462,12 +513,12 @@ function on_focus_out(e) {
462
513
  {/if}
463
514
  <!-- svelte-ignore a11y-click-events-have-key-events -->
464
515
  <div bind:this={combo}
465
- on:click={show}
466
- class="{appearance_class} flex flex-row content-between items-center"
516
+ on:click={(e) => { show(e, undefined) }}
467
517
  class:cursor-pointer={can_be_activated && is_compact}
518
+ class="max-w-full {appearance_class} flex flex-row content-between items-center"
468
519
  >
469
520
 
470
- <div class="flex-1 flex flex-row items-center">
521
+ <div class="max-w-full flex-1 flex flex-row items-center">
471
522
  {#if !is_dropdown_open}
472
523
  {#if icon && sel_item}
473
524
  {#if sel_item.Color}
@@ -480,7 +531,7 @@ function on_focus_out(e) {
480
531
 
481
532
 
482
533
  <p bind:this={textbox}
483
- class="dark:text-white {line_h}"
534
+ class="dark:text-white {line_h} truncate px-2.5 {background_class}"
484
535
  class:ml-2={icon}
485
536
  class:text-gray-400={ (!is_dropdown_open) && (!sel_item)}
486
537
  class:text-gray-700={ is_dropdown_open || sel_item }
@@ -500,13 +551,6 @@ function on_focus_out(e) {
500
551
  style={dropdown_position}
501
552
  use:dropdown_action>
502
553
  <ul class="py-1">
503
- <!-- {#if is_dropdown_open && definition.collection_expr}
504
- {#await fetch_source()}
505
- <p>Loading...</p>
506
- {:then source}
507
- {@const c = source_fetched(source)}
508
- {/await}
509
- {/if} -->
510
554
 
511
555
  {#if definition.source && definition.source.length}
512
556
  {@const _filtered_source = filtered_source ? filtered_source : definition.source}
@@ -1,19 +1,24 @@
1
1
  import { SvelteComponentTyped } from "svelte";
2
+ import { rCombo_definition } from './combo';
2
3
  declare const __propDef: {
3
4
  props: {
4
5
  label?: string | undefined;
5
6
  self?: null | undefined;
6
7
  a?: string | undefined;
8
+ is_association?: boolean | undefined;
7
9
  context?: string | undefined;
8
10
  typename?: string | undefined;
9
11
  choice_callback?: string | undefined;
10
12
  on_select?: undefined;
13
+ definition?: rCombo_definition | null | undefined;
14
+ changed?: undefined;
11
15
  icon?: boolean | undefined;
12
16
  placeholder?: string | undefined;
13
17
  s?: string | undefined;
14
18
  c?: string | undefined;
15
19
  compact?: boolean | undefined;
16
20
  in_context?: string | undefined;
21
+ cached?: boolean | undefined;
17
22
  show?: ((event: any, hide_callback: any) => void) | undefined;
18
23
  hide?: (() => void) | undefined;
19
24
  };
@@ -1,6 +1,7 @@
1
1
  <script>import { afterUpdate, tick } from "svelte";
2
2
  import Icon from "./icon.svelte";
3
3
  import { context_items_store } from "../stores";
4
+ import { is_device_smaller_than } from "../utils";
4
5
  export let width_px = 400;
5
6
  export let menu_items_id_prefix = "__hd_svelte_menuitem_";
6
7
  export let owner_menu_item = void 0;
@@ -13,6 +14,7 @@ let min_width_px = 200;
13
14
  let focused_index = 0;
14
15
  let menu_items = [];
15
16
  let submenus = [];
17
+ let around_rect;
16
18
  $:
17
19
  display = visible ? "block" : "none";
18
20
  afterUpdate(() => {
@@ -23,15 +25,22 @@ afterUpdate(() => {
23
25
  if (rect.right > container_rect.right)
24
26
  x = container_rect.right - rect.width;
25
27
  if (rect.bottom > container_rect.bottom)
26
- y = container_rect.bottom - rect.height;
28
+ y = container_rect.bottom - rect.height - around_rect.height;
27
29
  if (rect.left < container_rect.left)
28
30
  x = container_rect.left;
29
31
  if (rect.top < container_rect.top)
30
32
  y = container_rect.top;
31
33
  });
32
- export async function show(_x, _y, _operations) {
33
- x = _x;
34
- y = _y;
34
+ export async function show(around, _operations) {
35
+ if (around instanceof DOMRect) {
36
+ x = around.left;
37
+ y = around.bottom;
38
+ around_rect = around;
39
+ } else if (around instanceof DOMPoint) {
40
+ x = around.x;
41
+ y = around.y;
42
+ around_rect = new DOMRect(x, y, 0, 0);
43
+ }
35
44
  visible = true;
36
45
  operations = [..._operations];
37
46
  focused_index = 0;
@@ -39,6 +48,9 @@ export async function show(_x, _y, _operations) {
39
48
  if (menu_items.length)
40
49
  focus_menu_item(focused_index);
41
50
  }
51
+ export function is_visible() {
52
+ return visible;
53
+ }
42
54
  export function hide() {
43
55
  visible = false;
44
56
  }
@@ -91,10 +103,12 @@ function navigate_down() {
91
103
  }
92
104
  }
93
105
  function on_change_focus(e) {
94
- if (e.relatedTarget && e.relatedTarget.id.startsWith(menu_items_id_prefix))
95
- return;
96
- else
97
- hide();
106
+ if (!is_device_smaller_than("sm")) {
107
+ if (e.relatedTarget && e.relatedTarget.id.startsWith(menu_items_id_prefix))
108
+ return;
109
+ else
110
+ hide();
111
+ }
98
112
  }
99
113
  function on_mouse_move(index) {
100
114
  focus_menu_item(index);
@@ -142,7 +156,7 @@ function hide_submenu() {
142
156
  </script>
143
157
 
144
158
  <div id="__hd_svelte_contextmenu"
145
- class="bg-white dark:bg-gray-800 text-gray-500 dark:text-gray-400 rounded-lg border border-gray-200 dark:border-gray-700 shadow-md z-20 fixed min-w-[{min_width_px}px]"
159
+ class="bg-white dark:bg-gray-800 text-gray-500 dark:text-gray-400 rounded-lg border border-gray-200 dark:border-gray-700 shadow-md z-20 fixed min-w-[{min_width_px}px] w-max"
146
160
  style={`left:${x}px; top:${y}px; display:${display}`}
147
161
  bind:this={menu_root}
148
162
  on:focusout={on_change_focus}>
@@ -4,7 +4,8 @@ declare const __propDef: {
4
4
  width_px?: number | undefined;
5
5
  menu_items_id_prefix?: string | undefined;
6
6
  owner_menu_item?: HTMLElement | undefined;
7
- show?: ((_x: number, _y: number, _operations: any) => Promise<void>) | undefined;
7
+ show?: ((around: DOMRect | DOMPoint, _operations: any) => Promise<void>) | undefined;
8
+ is_visible?: (() => boolean) | undefined;
8
9
  hide?: (() => void) | undefined;
9
10
  get_rendered_rect?: (() => DOMRect | undefined) | undefined;
10
11
  };
@@ -17,7 +18,8 @@ export type ContextmenuProps = typeof __propDef.props;
17
18
  export type ContextmenuEvents = typeof __propDef.events;
18
19
  export type ContextmenuSlots = typeof __propDef.slots;
19
20
  export default class Contextmenu extends SvelteComponentTyped<ContextmenuProps, ContextmenuEvents, ContextmenuSlots> {
20
- get show(): (_x: number, _y: number, _operations: any) => Promise<void>;
21
+ get show(): (around: DOMRect | DOMPoint, _operations: any) => Promise<void>;
22
+ get is_visible(): () => boolean;
21
23
  get hide(): () => void;
22
24
  get get_rendered_rect(): () => DOMRect | undefined;
23
25
  }