@cloudparker/moldex.js 0.0.87 → 0.0.88

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.
@@ -35,7 +35,7 @@ export declare function openAlertDialog(params?: DialogProps & {
35
35
  export declare function openDeleteConfirmDialog({ msg, title, footerOkButtonLable, footerOkButtonClassName, ...params }?: DialogProps & {
36
36
  msg?: string;
37
37
  }): Promise<unknown>;
38
- export declare function openPickerDialog<R>({ items, value, multiple, hasCheckbox, hasArrow, maxlength, maxlengthMsg, identityFieldName, titleFieldName, searchFieldName, subtitleFieldName, ...params }: DialogProps & PickerDialogProps): Promise<R>;
38
+ export declare function openPickerDialog<R>({ items, value, multiple, hasCheckbox, hasArrow, maxlength, maxlengthMsg, identityFieldName, titleFieldName, searchFieldName, subtitleFieldName, itemTileSnippet, ...params }: DialogProps & PickerDialogProps): Promise<R>;
39
39
  export declare function openNumberFieldDialog({ title, value, label, name, maxlength, fieldClassName, autofocus, required, appearance, size, floatingLabel, ...params }?: DialogProps & InputFieldProps & {
40
40
  fieldClassName?: string;
41
41
  }): Promise<unknown>;
@@ -81,7 +81,7 @@ export async function openDeleteConfirmDialog({ msg = 'Are you sure to delete?',
81
81
  ...params,
82
82
  });
83
83
  }
84
- export async function openPickerDialog({ items, value, multiple, hasCheckbox = true, hasArrow, maxlength, maxlengthMsg, identityFieldName, titleFieldName, searchFieldName, subtitleFieldName, ...params }) {
84
+ export async function openPickerDialog({ items, value, multiple, hasCheckbox = true, hasArrow, maxlength, maxlengthMsg, identityFieldName, titleFieldName, searchFieldName, subtitleFieldName, itemTileSnippet, ...params }) {
85
85
  if (hasArrow) {
86
86
  multiple = false;
87
87
  hasCheckbox = false;
@@ -100,6 +100,7 @@ export async function openPickerDialog({ items, value, multiple, hasCheckbox = t
100
100
  titleFieldName,
101
101
  searchFieldName,
102
102
  subtitleFieldName,
103
+ itemTileSnippet,
103
104
  },
104
105
  hasHeader: true,
105
106
  hasTitle: true,
@@ -1,8 +1,12 @@
1
1
  <script lang="ts" module></script>
2
2
 
3
- <script lang="ts">import { showToast } from "../../../../../services";
3
+ <script lang="ts">import { DialogSizeEnum, getDialogSize, showToast } from "../../../../../services";
4
4
  import ButtonListItem from "../../../button/components/button-list-item/button-list-item.svelte";
5
5
  import ButtonSearch from "../../../button/components/button-search/button-search.svelte";
6
+ import { onMount } from "svelte";
7
+ import Icon from "../../../icon/components/icon/icon.svelte";
8
+ import { mdiCheckCircle, mdiCheckCircleOutline, mdiChevronRight } from "../../../icon";
9
+ import { SvelteSet } from "svelte/reactivity";
6
10
  let {
7
11
  value,
8
12
  items = [],
@@ -15,13 +19,23 @@ let {
15
19
  hasArrow,
16
20
  maxlength = 0,
17
21
  maxlengthMsg = "Selection limit reached!",
22
+ checkboxIconPath = mdiCheckCircle,
23
+ uncheckboxIconPath = mdiCheckCircleOutline,
24
+ arrowIconPath = mdiChevronRight,
25
+ checkboxIconClassName = "",
26
+ uncheckboxIconClassName = "",
27
+ arrowClassName = "",
28
+ checkboxClassName = "",
29
+ itemTileSnippet,
18
30
  closeDialog,
19
31
  setResult,
20
32
  setOnOkClick,
21
33
  setHeaderSnippet,
22
34
  setDialogTitle
23
35
  } = $props();
24
- let selected = $state({ items: {} });
36
+ let selectedSet = $state(
37
+ value ? new SvelteSet(Array.isArray(value) ? value : [value]) : new SvelteSet()
38
+ );
25
39
  let searchText = $state("");
26
40
  let records = $derived.by(() => {
27
41
  if (items && typeof items[0] == "string") {
@@ -42,40 +56,29 @@ let filteredRecords = $derived.by(() => {
42
56
  }
43
57
  return records;
44
58
  });
45
- $effect(() => {
46
- if (value) {
47
- if (Array.isArray(value)) {
48
- value.forEach((val) => selected.items[val] = val);
49
- } else {
50
- selected.items[value] = value;
51
- }
52
- }
53
- });
54
59
  function handleItemClick(ev, item, index) {
55
60
  let itemId = item[identityFieldName];
56
61
  if (!multiple) {
57
- if (selected.items[itemId]) {
58
- selected.items = {};
62
+ if (selectedSet.has(itemId)) {
63
+ selectedSet.delete(itemId);
64
+ setResult(void 0);
59
65
  } else {
60
- selected.items = { [itemId]: itemId };
66
+ selectedSet.add(itemId);
67
+ setResult(itemId);
61
68
  }
62
- let selectedItemId = Object.keys(selected.items)[0];
63
- setResult(selectedItemId);
64
69
  closeDialog();
65
70
  } else {
66
- if (selected.items[itemId]) {
67
- delete selected.items[itemId];
71
+ if (selectedSet.has(itemId)) {
72
+ selectedSet.delete(itemId);
68
73
  } else {
69
- let itemLength2 = Object.keys(selected.items).length;
70
- if (maxlength > 0 && itemLength2 >= maxlength) {
74
+ if (selectedSet.size >= maxlength) {
71
75
  showToast({ msg: maxlengthMsg });
72
76
  } else {
73
- selected.items[itemId] = itemId;
77
+ selectedSet.add(itemId);
74
78
  }
75
79
  }
76
- let itemLength = Object.keys(selected.items).length;
77
- if (itemLength) {
78
- setDialogTitle(`Selected (${itemLength})`);
80
+ if (selectedSet.size) {
81
+ setDialogTitle(`Selected (${selectedSet.size})`);
79
82
  } else {
80
83
  setDialogTitle("");
81
84
  }
@@ -83,32 +86,63 @@ function handleItemClick(ev, item, index) {
83
86
  }
84
87
  function handleOkClick(ev) {
85
88
  if (multiple) {
86
- closeDialog(Object.keys(selected.items));
89
+ closeDialog(Array.from(selectedSet));
87
90
  }
88
91
  }
89
92
  function handleSearch(txt) {
90
93
  searchText = txt;
91
94
  }
92
- setOnOkClick(handleOkClick);
93
- setHeaderSnippet(headerSnippet);
95
+ onMount(() => {
96
+ setOnOkClick(handleOkClick);
97
+ setHeaderSnippet(headerSnippet);
98
+ });
94
99
  </script>
95
100
 
96
101
  {#snippet headerSnippet()}
97
102
  <ButtonSearch className="rounded-full !p-3 " onSearch={handleSearch} />
98
103
  {/snippet}
99
104
 
100
- <div class="mb-4">
105
+ <div class="mb-4 min-h-80">
101
106
  {#each filteredRecords as record, index}
102
- {@const isSelected = !!selected.items[record[identityFieldName]]}
107
+ {@const isSelected = selectedSet.has(record[identityFieldName])}
103
108
  <div>
104
- <ButtonListItem
105
- onClick={(ev) => handleItemClick(ev, record, index)}
106
- title={record[titleFieldName]}
107
- subtitle={record[subtitleFieldName || ''] || ''}
108
- {hasCheckbox}
109
- {hasArrow}
110
- isChecked={isSelected}
111
- />
109
+ {#if itemTileSnippet}
110
+ <ButtonListItem onClick={(ev) => handleItemClick(ev, record, index)}>
111
+ {@render itemTileSnippet(record, index)}
112
+ {#if hasCheckbox}
113
+ <div>
114
+ <Icon
115
+ path={isSelected ? checkboxIconPath : uncheckboxIconPath}
116
+ className="w-5 h-5 {checkboxClassName} {isSelected
117
+ ? `text-primary ${checkboxIconClassName}`
118
+ : `text-base-400 ${uncheckboxIconClassName}`}"
119
+ />
120
+ </div>
121
+ {/if}
122
+
123
+ {#if hasArrow}
124
+ <div>
125
+ <Icon path={arrowIconPath} className="w-5 h-5 text-base-500 {arrowClassName} " />
126
+ </div>
127
+ {/if}
128
+ </ButtonListItem>
129
+ {:else}
130
+ <ButtonListItem
131
+ onClick={(ev) => handleItemClick(ev, record, index)}
132
+ title={record[titleFieldName]}
133
+ subtitle={record[subtitleFieldName || ''] || ''}
134
+ {hasCheckbox}
135
+ {hasArrow}
136
+ isChecked={isSelected}
137
+ {checkboxIconPath}
138
+ {uncheckboxIconPath}
139
+ {checkboxIconClassName}
140
+ {uncheckboxIconClassName}
141
+ {checkboxClassName}
142
+ {arrowIconPath}
143
+ {arrowClassName}
144
+ />
145
+ {/if}
112
146
  </div>
113
147
  {/each}
114
148
  </div>
@@ -1,7 +1,7 @@
1
1
  export type PickerDialogProps = {
2
2
  items?: string[] | any[];
3
3
  multiple?: boolean;
4
- value?: string | string[];
4
+ value?: any;
5
5
  identityFieldName?: string;
6
6
  titleFieldName?: string;
7
7
  searchFieldName?: string;
@@ -10,7 +10,16 @@ export type PickerDialogProps = {
10
10
  hasArrow?: boolean;
11
11
  maxlength?: number;
12
12
  maxlengthMsg?: string;
13
+ checkboxIconPath?: string;
14
+ uncheckboxIconPath?: string;
15
+ checkboxIconClassName?: string;
16
+ uncheckboxIconClassName?: string;
17
+ checkboxClassName?: string;
18
+ arrowIconPath?: string;
19
+ arrowClassName?: string;
20
+ itemTileSnippet?: Snippet<[item: any, index: number]>;
13
21
  };
22
+ import { type Snippet } from 'svelte';
14
23
  import type { DialogExports } from '../dialog/dialog.svelte';
15
24
  interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
16
25
  new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
@@ -1,9 +1,9 @@
1
1
  <script lang="ts">import Icon from "../icon/icon.svelte";
2
- let { circleClassName, iconPath, iconClassName = "text-primary" } = $props();
2
+ let { circleClassName, iconPath, iconClassName = "w-5 h-5 text-primary" } = $props();
3
3
  </script>
4
4
 
5
5
  <div
6
- class="aspect-square bg-primary-100 rounded-full w-12 h-12 flex items-center justify-center {circleClassName}"
6
+ class="aspect-square bg-primary-100 rounded-full w-10 h-10 flex items-center justify-center {circleClassName}"
7
7
  >
8
8
  <Icon path={iconPath!} className={iconClassName} />
9
9
  </div>
@@ -2,11 +2,16 @@
2
2
 
3
3
  <script lang="ts">import ButtonListItem from "../../../button/components/button-list-item/button-list-item.svelte";
4
4
  import Button from "../../../button/components/button/button.svelte";
5
- import { mdiUnfoldMoreHorizontal } from "../../../icon";
5
+ import {
6
+ mdiCheckCircle,
7
+ mdiCheckCircleOutline,
8
+ mdiUnfoldMoreHorizontal
9
+ } from "../../../icon";
6
10
  import Icon from "../../../icon/components/icon/icon.svelte";
7
11
  import NoData from "../../../no-data/components/no-data/no-data.svelte";
8
12
  import InputField, {} from "../input-field/input-field.svelte";
9
13
  import SearchField from "../search-field/search-field.svelte";
14
+ import { SvelteSet } from "svelte/reactivity";
10
15
  let {
11
16
  appearance,
12
17
  chipClassName,
@@ -54,11 +59,20 @@ let {
54
59
  titleClassName,
55
60
  titleFieldName = "name",
56
61
  value = $bindable(),
62
+ checkboxIconPath = mdiCheckCircle,
63
+ uncheckboxIconPath = mdiCheckCircleOutline,
64
+ checkboxIconClassName = "",
65
+ uncheckboxIconClassName = "",
66
+ checkboxClassName = "",
67
+ itemTileSnippet,
57
68
  ...props
58
69
  } = $props();
59
70
  let searchFieldRef = $state(null);
60
71
  let isPlaced = $state(false);
61
72
  let searchText = $state("");
73
+ let selectedItemsSet = $state(
74
+ value ? new SvelteSet(Array.isArray(value) ? value : [value]) : new SvelteSet()
75
+ );
62
76
  let comboboxIconSizeClassName = $derived.by(() => {
63
77
  if (size) {
64
78
  switch (size) {
@@ -120,17 +134,6 @@ let displayText = $derived.by(() => {
120
134
  }
121
135
  return "";
122
136
  });
123
- let selectedItemsSet = $derived.by(() => {
124
- let set = /* @__PURE__ */ new Set();
125
- if (value != null) {
126
- if (Array.isArray(value)) {
127
- value.forEach((v) => set.add(v));
128
- } else if (value) {
129
- set.add(value);
130
- }
131
- }
132
- return set;
133
- });
134
137
  let preparedItems = $derived.by(() => {
135
138
  return (items || []).map((item, index) => {
136
139
  let res = {};
@@ -329,6 +332,7 @@ function handleItemClick(ev, item, index) {
329
332
  {:else if filteredItems?.length}
330
333
  <ul>
331
334
  {#each filteredItems as item, index}
335
+ {@const isSelected = selectedItemsSet.has(item[identityFieldName])}
332
336
  <li
333
337
  class="select-none"
334
338
  id="item-{index}"
@@ -336,16 +340,38 @@ function handleItemClick(ev, item, index) {
336
340
  tabindex="-1"
337
341
  aria-selected={item.isChecked}
338
342
  >
339
- <ButtonListItem
340
- title={item[titleFieldName] || ''}
341
- subtitle={item[subtitleFieldName || ''] || ''}
342
- {index}
343
- {hasCheckbox}
344
- className=" {itemClassName}"
345
- titleClassName=" {titleClassName}"
346
- subtitleClassName=" {subtitleClassName}"
347
- onClick={(ev) => handleItemClick(ev, item, index)}
348
- />
343
+ {#if itemTileSnippet}
344
+ <ButtonListItem onClick={(ev) => handleItemClick(ev, item, index)}>
345
+ {@render itemTileSnippet(item, index)}
346
+ {#if hasCheckbox}
347
+ <div>
348
+ <Icon
349
+ path={isSelected ? checkboxIconPath : uncheckboxIconPath}
350
+ className="w-5 h-5 {checkboxClassName} {isSelected
351
+ ? `text-primary ${checkboxIconClassName}`
352
+ : `text-base-400 ${uncheckboxIconClassName}`}"
353
+ />
354
+ </div>
355
+ {/if}
356
+ </ButtonListItem>
357
+ {:else}
358
+ <ButtonListItem
359
+ title={item[titleFieldName] || ''}
360
+ subtitle={item[subtitleFieldName || ''] || ''}
361
+ {index}
362
+ {hasCheckbox}
363
+ className=" {itemClassName}"
364
+ titleClassName=" {titleClassName}"
365
+ subtitleClassName=" {subtitleClassName}"
366
+ isChecked={isSelected}
367
+ {checkboxIconPath}
368
+ {uncheckboxIconPath}
369
+ {checkboxIconClassName}
370
+ {uncheckboxIconClassName}
371
+ {checkboxClassName}
372
+ onClick={(ev) => handleItemClick(ev, item, index)}
373
+ />
374
+ {/if}
349
375
  </li>
350
376
  {/each}
351
377
  </ul>
@@ -38,6 +38,12 @@ export type ComboboxFieldProps = {
38
38
  subtitleFieldName?: string;
39
39
  titleClassName?: string;
40
40
  titleFieldName?: string;
41
+ checkboxIconPath?: string;
42
+ uncheckboxIconPath?: string;
43
+ checkboxIconClassName?: string;
44
+ uncheckboxIconClassName?: string;
45
+ checkboxClassName?: string;
46
+ itemTileSnippet?: Snippet<[item: any, index: any]>;
41
47
  };
42
48
  import type { Snippet } from 'svelte';
43
49
  import { type InputFieldProps } from '../input-field/input-field.svelte';
@@ -1,9 +1,9 @@
1
1
  <script module lang="ts"></script>
2
2
 
3
3
  <script lang="ts">import { ripple } from "../../../../../actions";
4
+ import { getDialogSize, openPickerDialog } from "../../../../../services";
4
5
  import EasyScriptLoader from "@cloudparker/easy-script-loader-svelte";
5
6
  import InputField, {} from "../input-field/input-field.svelte";
6
- import { isMobileScreen, openPickerDialog } from "../../../../../services";
7
7
  let {
8
8
  id,
9
9
  name,
@@ -60,18 +60,15 @@ function formatDialCode(dialcode) {
60
60
  }
61
61
  return dialcode;
62
62
  }
63
- async function hanleDialCodePicker() {
63
+ async function handleDialCodePicker() {
64
64
  if (EasyCountryData) {
65
65
  let items = EasyCountryData.getCountries();
66
- let size2 = isMobileScreen() ? "full" : "sm";
66
+ let size2 = getDialogSize();
67
67
  let res = await openPickerDialog({
68
- items
69
- // itemTitle: 'dialCode',
70
- // itemSubtitle: 'name',
71
- // size,
72
- // hasCheck: true,
73
- // identity: 'dialCode',
74
- // search: ['name', 'dialCode', 'isoCode']
68
+ value: dialCode,
69
+ items,
70
+ identityFieldName: "dialCode",
71
+ itemTileSnippet: dialCodePickerItemTile
75
72
  });
76
73
  console.log(res);
77
74
  if (res) {
@@ -118,13 +115,22 @@ function handleNumberKeyDown(ev) {
118
115
  }
119
116
  </script>
120
117
 
121
- {#snippet showPasswordButton()}
118
+ {#snippet dialCodePickerItemTile(item: any, index: number)}
119
+ <div class="w-14 text-sm font-bold text-base">
120
+ {item.dialCode}
121
+ </div>
122
+ <div class="flex-grow">
123
+ {item.name}
124
+ </div>
125
+ {/snippet}
126
+
127
+ {#snippet showDialCodeButton()}
122
128
  <button
123
129
  id="btn-dialcode-picker-{name || id}"
124
130
  type="button"
125
131
  class="w-16 h-full hover:bg-gray-100 font-bold text-gray-400 focus:outline-primary {btnRoundedClassName} {buttonClassName}"
126
132
  use:ripple
127
- onclick={hanleDialCodePicker}
133
+ onclick={handleDialCodePicker}
128
134
  >
129
135
  {_dailCode}
130
136
  </button>
@@ -150,7 +156,7 @@ function handleNumberKeyDown(ev) {
150
156
  {id}
151
157
  {name}
152
158
  maxlength={props?.maxlength || 12}
153
- leftSnippet={showPasswordButton}
159
+ leftSnippet={showDialCodeButton}
154
160
  {size}
155
161
  {appearance}
156
162
  {floatingLabel}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudparker/moldex.js",
3
- "version": "0.0.87",
3
+ "version": "0.0.88",
4
4
  "author": "cloudparker.com",
5
5
  "license": "MIT",
6
6
  "keywords": [