@kws3/ui 1.7.2 → 1.8.0

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.
@@ -16,9 +16,16 @@ this property of each object will be returned as the value, Default: `"id"`
16
16
  @param {''|'primary'|'success'|'warning'|'info'|'danger'|'dark'|'light'} [color=""] - Color of the input, Default: `""`
17
17
  @param {string} [style=""] - Inline CSS for input container, Default: `""`
18
18
  @param {boolean} [readonly=false] - Marks component as read-only, Default: `false`
19
+ @param {function|null} [search=null] - Async function to fetch options
20
+
21
+ Only send this prop if you want to fetch `options` asynchronously.
22
+ `options` prop will be ignored if this prop is set., Default: `null`
23
+ @param {'fuzzy'|'strict'} [search_strategy="fuzzy"] - Filtered options to be displayed strictly based on search text or perform a fuzzy match.
24
+ Fuzzy match will not work if `search` function is set, as the backend service is meant to do the matching., Default: `"fuzzy"`
19
25
  @param {boolean} [disabled=false] - Disables the component, Default: `false`
20
26
  @param {string} [selected_icon="check"] - Icon used to mark selected items in dropdown list, Default: `"check"`
21
27
  @param {string} [no_options_msg="No matching options"] - Message to display when no matching options are found, Default: `"No matching options"`
28
+ @param {string} [async_search_prompt="Start typing to search..."] - Message to display in dropdown when async search can be performed, Default: `"Start typing to search..."`
22
29
  @param {string} [remove_all_tip="Clear Selection"] - Tooltip text for the Clear selection button, Default: `"Clear Selection"`
23
30
  @param {HTMLElement|string} [dropdown_portal=undefined] - Where to render the dropdown list.
24
31
  Can be a DOM element or a `string` with the CSS selector of the element.
@@ -44,13 +51,16 @@ Default value: `<span>{option[search_key] || option}</span>`
44
51
  {options}
45
52
  {search_key}
46
53
  {value_key}
54
+ {search_strategy}
47
55
  {size}
48
56
  {color}
49
57
  {style}
50
58
  {readonly}
51
59
  {disabled}
60
+ {search}
52
61
  {selected_icon}
53
62
  {remove_all_tip}
63
+ async_search_prompt={value ? "Backspace to clear" : async_search_prompt}
54
64
  {no_options_msg}
55
65
  {dropdown_portal}
56
66
  on:change={change}
@@ -118,6 +128,21 @@ Default value: `<span>{option[search_key] || option}</span>`
118
128
  * Marks component as read-only
119
129
  */
120
130
  export let readonly = false;
131
+ /**
132
+ * Async function to fetch options
133
+ *
134
+ * Only send this prop if you want to fetch `options` asynchronously.
135
+ * `options` prop will be ignored if this prop is set.
136
+ *
137
+ * @type {function|null}
138
+ */
139
+ export let search = null;
140
+ /**
141
+ * Filtered options to be displayed strictly based on search text or perform a fuzzy match.
142
+ * Fuzzy match will not work if `search` function is set, as the backend service is meant to do the matching.
143
+ * @type {'fuzzy'|'strict'}
144
+ */
145
+ export let search_strategy = "fuzzy";
121
146
  /**
122
147
  * Disables the component
123
148
  */
@@ -130,6 +155,10 @@ Default value: `<span>{option[search_key] || option}</span>`
130
155
  * Message to display when no matching options are found
131
156
  */
132
157
  export let no_options_msg = "No matching options";
158
+ /**
159
+ * Message to display in dropdown when async search can be performed
160
+ */
161
+ export let async_search_prompt = "Start typing to search...";
133
162
  /**
134
163
  * Tooltip text for the Clear selection button
135
164
  */
@@ -19,7 +19,9 @@ If `false` , the component won't have a close button, and will not close on clic
19
19
 
20
20
  -->
21
21
 
22
- <div class="modal {klass} {is_active ? 'is-active' : ''}" {style}>
22
+ <div
23
+ class="modal kws-action-sheet-outer {klass} {is_active ? 'is-active' : ''}"
24
+ {style}>
23
25
  {#if is_active}<div
24
26
  transition:fade={{ duration: transitionDuration }}
25
27
  class="modal-background"
@@ -34,7 +34,6 @@ Only visible when the
34
34
  transition:fade={{ duration: transitionDuration }}
35
35
  class="modal-background"
36
36
  on:click={clickOutside} />
37
-
38
37
  <div
39
38
  transition:scale={{
40
39
  duration: transitionDuration,
@@ -83,6 +82,17 @@ Only visible when the
83
82
  </div>
84
83
 
85
84
  <style lang="scss">
85
+ .modal {
86
+ display: flex;
87
+ visibility: hidden;
88
+ &.is-active {
89
+ visibility: visible;
90
+ }
91
+ .modal-card,
92
+ .modal-background {
93
+ transition: all 0.3s;
94
+ }
95
+ }
86
96
  @media screen and (min-width: 769px), print {
87
97
  .modal-card {
88
98
  min-width: 640px;
@@ -12,6 +12,8 @@ function createDialog(msg, props) {
12
12
 
13
13
  dialog.$on("_done", ({ detail }) => {
14
14
  fulfil(detail);
15
+ //Does not outro out because of
16
+ //https://github.com/sveltejs/svelte/issues/4056
15
17
  dialog.$destroy();
16
18
  });
17
19
  });
@@ -26,7 +26,6 @@ Only programmatic closing is possible, Default: `true`
26
26
  transition:fade={{ duration: transitionDuration }}
27
27
  class="modal-background"
28
28
  on:click={clickOutside} />
29
-
30
29
  <div
31
30
  transition:scale={{
32
31
  duration: transitionDuration,
@@ -47,9 +46,19 @@ Only programmatic closing is possible, Default: `true`
47
46
  </div>
48
47
 
49
48
  <style lang="scss">
50
- @media screen and (min-width: 769px), print {
49
+ .modal {
50
+ display: flex;
51
+ visibility: hidden;
52
+ &.is-active {
53
+ visibility: visible;
54
+ }
51
55
  .modal-content,
52
- .modal-card {
56
+ .modal-background {
57
+ transition: all 0.3s;
58
+ }
59
+ }
60
+ @media screen and (min-width: 769px), print {
61
+ .modal-content {
53
62
  min-width: 640px;
54
63
  &.is-medium {
55
64
  width: 70%;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kws3/ui",
3
- "version": "1.7.2",
3
+ "version": "1.8.0",
4
4
  "description": "UI components for use with Svelte v3 applications.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -23,11 +23,12 @@
23
23
  "access": "public"
24
24
  },
25
25
  "dependencies": {
26
- "apexcharts": "^3.32.0",
26
+ "apexcharts": "3.33.2",
27
27
  "flatpickr": "^4.5.2",
28
+ "fuzzysearch": "^1.0.3",
28
29
  "svelte-portal": "^2.1.2",
29
30
  "text-mask-core": "^5.1.2",
30
31
  "tippy.js": "^6.3.1"
31
32
  },
32
- "gitHead": "227e2a0e081adad79a4a46096d1f846bd307d6e3"
33
+ "gitHead": "8da0698c240f93ae1b371a9279d2473409646b10"
33
34
  }
@@ -18,24 +18,40 @@ This will work only when `track_height` is set to `true`
18
18
  - `<slot name="default" />` - Used to display content
19
19
 
20
20
  -->
21
- <div
22
- bind:clientHeight={_height}
23
- class="sliding-pane {v_center ? 'v-centered' : ''} {h_center
24
- ? 'h-centered'
25
- : ''} {active ? 'is-active' : ''} {klass}"
26
- {style}>
21
+ {#if hasResizeObserver}
27
22
  <div
28
- bind:this={slideInner}
29
- class="sliding-pane-inner {v_center ? 'v-centered' : ''} {h_center
30
- ? 'h-centered'
31
- : ''}">
32
- <!--Used to display content--><slot />
23
+ class="sliding-pane with-resize-observer {v_center
24
+ ? 'v-centered'
25
+ : ''} {h_center ? 'h-centered' : ''} {active ? 'is-active' : ''} {klass}"
26
+ {style}>
27
+ <div
28
+ bind:this={slideInner}
29
+ class="sliding-pane-inner {v_center ? 'v-centered' : ''} {h_center
30
+ ? 'h-centered'
31
+ : ''}">
32
+ <!--Used to display content--><slot />
33
+ </div>
33
34
  </div>
34
- </div>
35
+ {:else}
36
+ <div
37
+ bind:clientHeight={_height}
38
+ class="sliding-pane with-legacy-observer {v_center
39
+ ? 'v-centered'
40
+ : ''} {h_center ? 'h-centered' : ''} {active ? 'is-active' : ''} {klass}"
41
+ {style}>
42
+ <div
43
+ bind:this={slideInner}
44
+ class="sliding-pane-inner {v_center ? 'v-centered' : ''} {h_center
45
+ ? 'h-centered'
46
+ : ''}">
47
+ <!--Used to display content--><slot />
48
+ </div>
49
+ </div>
50
+ {/if}
35
51
 
36
52
  <script>
37
53
  import { onMount, createEventDispatcher } from "svelte";
38
- import { rAF } from "../utils";
54
+ import { debounce } from "@kws3/ui/utils";
39
55
 
40
56
  const fire = createEventDispatcher();
41
57
 
@@ -60,7 +76,8 @@ This will work only when `track_height` is set to `true`
60
76
  */
61
77
  track_height = true;
62
78
 
63
- let _height, slideInner;
79
+ const hasResizeObserver = typeof window.ResizeObserver != "undefined";
80
+ let _height, slideInner, Observer;
64
81
 
65
82
  /**
66
83
  * CSS classes for the panel
@@ -68,15 +85,9 @@ This will work only when `track_height` is set to `true`
68
85
  let klass = "";
69
86
  export { klass as class };
70
87
 
71
- onMount(() => {
72
- pollForRender();
73
- });
74
-
75
88
  $: {
76
89
  if (active && track_height && (active || _height)) {
77
- rAF(() => {
78
- fireSizeChange();
79
- });
90
+ fireSizeChange();
80
91
  }
81
92
  }
82
93
 
@@ -86,11 +97,12 @@ This will work only when `track_height` is set to `true`
86
97
  } else {
87
98
  setTimeout(() => {
88
99
  pollForRender();
89
- }, 200);
100
+ }, 50);
90
101
  }
91
102
  }
92
103
 
93
104
  function init() {
105
+ setupResizeObserver();
94
106
  fireSizeChange();
95
107
  }
96
108
 
@@ -99,21 +111,41 @@ This will work only when `track_height` is set to `true`
99
111
  if (!slideInner || typeof slideInner == "undefined") {
100
112
  pollForRender();
101
113
  } else {
102
- rAF(() => {
103
- if (!slideInner || typeof slideInner == "undefined") {
104
- return;
105
- }
106
- var h1 = slideInner.scrollHeight,
107
- h2 = slideInner.clientHeight;
108
- var new_height = Math.max(h1, h2);
109
- /**
110
- * Event fired when the height of the pane changes
111
- *
112
- * This will work only when `track_height` is set to `true`
113
- */
114
- fire("heightChange", { height: new_height });
115
- });
114
+ if (!slideInner || typeof slideInner == "undefined") {
115
+ return;
116
+ }
117
+ var h1 = slideInner.scrollHeight,
118
+ h2 = slideInner.clientHeight;
119
+ var new_height = Math.max(h1, h2);
120
+ /**
121
+ * Event fired when the height of the pane changes
122
+ *
123
+ * This will work only when `track_height` is set to `true`
124
+ */
125
+ fire("heightChange", { height: new_height });
116
126
  }
117
127
  }
118
128
  }
129
+
130
+ const debouncedFireSizeChange = debounce(fireSizeChange, 150, false);
131
+
132
+ const setupResizeObserver = () => {
133
+ if (hasResizeObserver) {
134
+ if (!slideInner || typeof slideInner == "undefined") {
135
+ pollForRender();
136
+ } else {
137
+ Observer = new ResizeObserver(() => {
138
+ debouncedFireSizeChange();
139
+ });
140
+ Observer.observe(slideInner);
141
+ }
142
+ }
143
+ };
144
+
145
+ onMount(() => {
146
+ pollForRender();
147
+ return () => {
148
+ Observer && Observer.disconnect();
149
+ };
150
+ });
119
151
  </script>
@@ -2,6 +2,16 @@ $kws-actionsheet-background: $background !default;
2
2
  $kws-actionsheet-box-shadow: $card-shadow !default;
3
3
  $kws-actionsheet-box-radius: $radius !default;
4
4
 
5
+ .kws-action-sheet-outer {
6
+ display: flex;
7
+ visibility: hidden;
8
+ &.is-active {
9
+ visibility: visible;
10
+ }
11
+ .modal-background {
12
+ transition: all 0.3s;
13
+ }
14
+ }
5
15
  .kws-action-sheet {
6
16
  border-radius: $kws-actionsheet-box-radius $kws-actionsheet-box-radius 0 0;
7
17
  box-shadow: $kws-actionsheet-box-shadow;