@kws3/ui 1.9.3 → 2.0.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.
Files changed (80) hide show
  1. package/CHANGELOG.mdx +68 -48
  2. package/buttons/ConfirmButton.svelte +11 -3
  3. package/buttons/DeleteButton.svelte +2 -3
  4. package/buttons/ProcessButton.svelte +3 -4
  5. package/buttons/SubmitButton.svelte +11 -3
  6. package/charts/AreaChart.svelte +1 -1
  7. package/charts/BarChart.svelte +1 -1
  8. package/charts/Chart.svelte +1 -0
  9. package/charts/DonutChart.svelte +1 -1
  10. package/charts/LineChart.svelte +1 -1
  11. package/charts/MixedChart.svelte +1 -1
  12. package/charts/PieChart.svelte +1 -1
  13. package/charts/RadialChart.svelte +1 -1
  14. package/charts/utils.js +1 -0
  15. package/controls/Checkbox.svelte +10 -4
  16. package/controls/FileUpload.svelte +14 -8
  17. package/controls/NumberInput.svelte +19 -10
  18. package/controls/Radio.svelte +8 -2
  19. package/controls/RangeSlider.svelte +8 -2
  20. package/controls/Toggle.svelte +9 -2
  21. package/controls/ToggleButtons.svelte +10 -3
  22. package/datagrid/DataSearch/DataSearch.svelte +1 -1
  23. package/datagrid/GridView/GridCell.svelte +3 -0
  24. package/datagrid/GridView/GridRow.svelte +15 -0
  25. package/datagrid/GridView/GridView.svelte +21 -3
  26. package/datagrid/Pagination/Pagination.svelte +3 -3
  27. package/datagrid/TileView/TileView.svelte +46 -5
  28. package/datagrid/TileView/TileViewItem.svelte +4 -0
  29. package/form/index.js +160 -0
  30. package/forms/AutoComplete.svelte +67 -28
  31. package/forms/Datepicker.svelte +22 -5
  32. package/forms/PasswordValidator/PasswordValidator.svelte +8 -8
  33. package/forms/PasswordValidator/validatePassword.js +13 -2
  34. package/forms/SearchInput.svelte +180 -0
  35. package/forms/Timepicker.svelte +69 -4
  36. package/forms/actions.js +21 -15
  37. package/forms/colorpicker/Colorpicker.js +28 -3
  38. package/forms/colorpicker/Colorpicker.svelte +2 -2
  39. package/forms/select/MultiSelect.svelte +81 -28
  40. package/forms/select/SearchableSelect.svelte +6 -5
  41. package/helpers/CardModal.svelte +2 -1
  42. package/helpers/ClipboardCopier.svelte +4 -1
  43. package/helpers/Dialog/Dialog.svelte +13 -8
  44. package/helpers/Dialog/index.js +6 -0
  45. package/helpers/Divider.svelte +2 -2
  46. package/helpers/FloatingUI/Floatie.svelte +6 -6
  47. package/helpers/FloatingUI/index.js +2 -1
  48. package/helpers/Icon.svelte +25 -9
  49. package/helpers/Loader.svelte +10 -3
  50. package/helpers/Message.svelte +2 -2
  51. package/helpers/Modal.svelte +2 -1
  52. package/helpers/Notification.svelte +1 -1
  53. package/helpers/Popover.svelte +4 -4
  54. package/helpers/ScrollableList.svelte +12 -8
  55. package/helpers/Skeleton.svelte +4 -1
  56. package/helpers/Timeline/Timeline.svelte +1 -1
  57. package/helpers/Timeline/TimelineItem.svelte +5 -5
  58. package/helpers/Tooltip.js +1 -1
  59. package/index.js +10 -4
  60. package/{utils → internal}/fuzzy.js +1 -1
  61. package/internal/index.js +27 -0
  62. package/internal/scrollIntoActiveElement.js +22 -0
  63. package/keyboard/index.js +94 -0
  64. package/package.json +6 -3
  65. package/{utils/resizeObserver.js → resizeObserver/index.js} +0 -0
  66. package/search/index.js +52 -0
  67. package/settings.js +1 -1
  68. package/sliding-panes/SlidingPane.svelte +1 -4
  69. package/styles/AutoComplete.scss +2 -1
  70. package/styles/Datepicker.scss +1 -1
  71. package/styles/Grid.scss +14 -0
  72. package/styles/Select.scss +2 -1
  73. package/transitions/components/Scale.svelte +1 -0
  74. package/transitions/components/getEasing.js +18 -5
  75. package/types/ambient.d.ts +16 -0
  76. package/types/index.d.ts +46 -0
  77. package/types/type-defs/index.ts +14 -0
  78. package/utils/index.js +110 -9
  79. package/utils/fuzzysearch.js +0 -41
  80. package/utils/keyboard-events.js +0 -32
@@ -10,7 +10,6 @@
10
10
  @param {boolean} [light=false] - Inverted colors for notification box and contents, Default: `false`
11
11
  @param {boolean} [dismissable=true] - Determines if notification is dismissable, Default: `true`
12
12
  @param {boolean} [persistent=false] - A persistent notification without duration, stays till dismissed, Default: `false`
13
- @param {string} [context=""] - Context value, Default: `""`
14
13
  @param {object} [component=null] - Custom component, Default: `null`
15
14
  @param {function} [beforeClose(props)] - Callback function call before close event
16
15
  @param {function} [afterClose(props)] - Callback function call after close event
@@ -66,6 +65,10 @@
66
65
 
67
66
  const fire = createEventDispatcher();
68
67
 
68
+ /**
69
+ * @typedef {import('@kws3/ui/types').ColorOptions} ColorOptions
70
+ */
71
+
69
72
  /**
70
73
  * Title/Heading of the notification
71
74
  */
@@ -85,7 +88,7 @@
85
88
  duration = 3000,
86
89
  /**
87
90
  * Toast notification background color
88
- * @type {''|'primary'|'success'|'warning'|'info'|'danger'|'dark'|'light'}
91
+ * @type {ColorOptions}
89
92
  */
90
93
  color = "primary",
91
94
  /**
@@ -100,10 +103,6 @@
100
103
  * A persistent notification without duration, stays till dismissed
101
104
  */
102
105
  persistent = false,
103
- /**
104
- * Context value
105
- */
106
- context = "",
107
106
  /**
108
107
  * Custom component
109
108
  */
@@ -131,6 +130,7 @@
131
130
  let defaults = { text: "Ok", color: "", click: () => {} },
132
131
  obj = b;
133
132
  if (typeof b == "string") {
133
+ // @ts-ignore
134
134
  obj = { text: b };
135
135
  }
136
136
  return Object.assign({}, defaults, obj);
@@ -1,4 +1,4 @@
1
- import { FloatingUIOutput } from "@kws3/ui";
1
+ import FloatingUIOutput from "./FloatingUIOutput.svelte";
2
2
  import { writable, get } from "svelte/store";
3
3
  import {
4
4
  defaultToastPlacement,
@@ -19,6 +19,7 @@ function ensureOutputIsOnPage() {
19
19
  return;
20
20
  }
21
21
 
22
+ //@ts-ignore
22
23
  OUTPUT_IS_ON_PAGE = new FloatingUIOutput({
23
24
  target: document.body,
24
25
  });
@@ -2,10 +2,10 @@
2
2
  @component
3
3
 
4
4
 
5
- @param {''|'small'|'medium'|'large'} [size=""] - Size of the Icon, Default: `""`
6
- @param {''|'primary'|'success'|'warning'|'info'|'danger'|'dark'|'light'} [color=""] - Color of the Icon, Default: `""`
5
+ @param {string|''|'small'|'medium'|'large'} [size=""] - Size of the Icon, Default: `""`
6
+ @param {string|''|'primary'|'success'|'warning'|'info'|'danger'|'dark'|'light'} [color=""] - Color of the Icon, Default: `""`
7
7
  @param {string} [icon=""] - The name of the icon that is to be displayed, from the relevant icon family, Default: `""`
8
- @param {''|'fa'|'lar'|'las'|'gg'|'unicons'} [family=""] - Icon family, can be modified globally in framework settings
8
+ @param {string|''|'fa'|'lar'|'las'|'gg'|'unicons'|'material'} [family=""] - Icon family, can be modified globally in framework settings
9
9
 
10
10
  Ultimately defaults to `fa`, if family is not set anywhere, Default: `""`
11
11
  @param {string} [style=""] - Inline CSS for icon container, Default: `""`
@@ -18,7 +18,7 @@ Ultimately defaults to `fa`, if family is not set anywhere, Default: `""`
18
18
  <span class="icon is-{size} has-text-{color} {klass}" {style}>
19
19
  <i
20
20
  class="icon-i {familyClass}{icon} {internal_size} {inner_class}"
21
- style={inner_style} />
21
+ style={inner_style}>{inner_icon}</i>
22
22
  </span>
23
23
 
24
24
  <style>
@@ -47,6 +47,19 @@ Ultimately defaults to `fa`, if family is not set anywhere, Default: `""`
47
47
  .icon .uil.fa-3x {
48
48
  font-size: 3em;
49
49
  }
50
+
51
+ .icon .material-icons {
52
+ font-size: 1.25em;
53
+ }
54
+ .icon .material-icons.fa-lg {
55
+ font-size: 1.5em;
56
+ }
57
+ .icon .material-icons.fa-2x {
58
+ font-size: 2em;
59
+ }
60
+ .icon .material-icons.fa-3x {
61
+ font-size: 3em;
62
+ }
50
63
  </style>
51
64
 
52
65
  <script>
@@ -54,12 +67,12 @@ Ultimately defaults to `fa`, if family is not set anywhere, Default: `""`
54
67
 
55
68
  /**
56
69
  * Size of the Icon
57
- * @type {''|'small'|'medium'|'large'}
70
+ * @type {import('@kws3/ui/types').SizeOptions}
58
71
  */
59
72
  export let size = "",
60
73
  /**
61
74
  * Color of the Icon
62
- * @type {''|'primary'|'success'|'warning'|'info'|'danger'|'dark'|'light'}
75
+ * @type {import('@kws3/ui/types').ColorOptions | 'grey'}
63
76
  */
64
77
  color = "",
65
78
  /**
@@ -70,7 +83,7 @@ Ultimately defaults to `fa`, if family is not set anywhere, Default: `""`
70
83
  * Icon family, can be modified globally in framework settings
71
84
  *
72
85
  * Ultimately defaults to `fa`, if family is not set anywhere
73
- * @type {''|'fa'|'lar'|'las'|'gg'|'unicons'}
86
+ * @type {string|''|'fa'|'lar'|'las'|'gg'|'unicons'|'material'}
74
87
  */
75
88
  family = "",
76
89
  /**
@@ -97,9 +110,9 @@ Ultimately defaults to `fa`, if family is not set anywhere, Default: `""`
97
110
  internal_size,
98
111
  usedFamily;
99
112
 
113
+ $: inner_icon = family === "material" ? icon : "";
100
114
  $: {
101
- usedFamily =
102
- family && family !== "" ? family : globalFamily ? globalFamily : "fa";
115
+ usedFamily = family !== "" ? family : globalFamily ? globalFamily : "fa";
103
116
 
104
117
  switch (usedFamily) {
105
118
  case "lar":
@@ -117,6 +130,9 @@ Ultimately defaults to `fa`, if family is not set anywhere, Default: `""`
117
130
  case "unicons":
118
131
  familyClass = "uil uil-";
119
132
  break;
133
+ case "material":
134
+ familyClass = "material-icons material-symbols-outlined ";
135
+ break;
120
136
  default:
121
137
  familyClass = "fa fa-";
122
138
  break;
@@ -31,20 +31,27 @@ The overlay is absolutely positioned. Ensure that the parent container is relati
31
31
  </div>
32
32
 
33
33
  <script>
34
+ /**
35
+
36
+ * @typedef {import('@kws3/ui/types').SpinnerColorOptions} SpinnerColorOptions
37
+ * @typedef {import('@kws3/ui/types').SizeOptions} SizeOptions
38
+ * @typedef {import('@kws3/ui/types').BGColorOptions} BGColorOptions
39
+ *
40
+ */
34
41
  /**
35
42
  * Color of the Spinner
36
43
  * @link https://bulma.io/documentation/helpers/color-helpers/
37
- * @type {'grey' | 'light' | 'warning' | 'info' | 'danger' | 'primary' | 'success'}
44
+ * @type {SpinnerColorOptions}
38
45
  */
39
46
  export let spinner_color = "grey",
40
47
  /**
41
48
  * Size of the Spinner
42
- * @type {'small'|'medium'|'large'}
49
+ * @type {SizeOptions}
43
50
  */
44
51
  spinner_size = "medium",
45
52
  /**
46
53
  * Backgound color of the Spinner container
47
- * @type {'transparent' | 'warning' | 'info' | 'danger' | 'primary' | 'success' | 'link'}
54
+ * @type {BGColorOptions}
48
55
  */
49
56
  background_color = "transparent",
50
57
  /**
@@ -70,12 +70,12 @@ The parent can then decide what to do with the component
70
70
 
71
71
  /**
72
72
  * Size of the Message
73
- * @type {''|'small'|'medium'|'large'}
73
+ * @type {import('@kws3/ui/types').SizeOptions}
74
74
  */
75
75
  export let size = "",
76
76
  /**
77
77
  * Color of the Message box
78
- * @type {''|'primary'|'warning'|'info'|'danger'|'dark'|'light'}
78
+ * @type {import('@kws3/ui/types').ColorOptions | 'grey'}
79
79
  */
80
80
  color = "info",
81
81
  /**
@@ -29,6 +29,7 @@ Only programmatic closing is possible, Default: `true`
29
29
  <div
30
30
  transition:scale={{
31
31
  duration: transitionDuration,
32
+ // @ts-ignore
32
33
  from: 0.8,
33
34
  to: 1,
34
35
  delay: transitionDelay,
@@ -75,7 +76,7 @@ Only programmatic closing is possible, Default: `true`
75
76
  import { hasTransitions } from "../settings";
76
77
  /**
77
78
  * Size of the modal
78
- * @type {'small'|'medium'|'large'}
79
+ * @type {import('@kws3/ui/types').SizeOptions}
79
80
  */
80
81
  export let size = "small",
81
82
  /**
@@ -35,7 +35,7 @@ The parent can then decide what to do with the component
35
35
 
36
36
  /**
37
37
  * Color of the Notification box
38
- * @type {''|'primary'|'success'|'warning'|'info'|'danger'|'light'|'dark'}
38
+ * @type {import('@kws3/ui/types').ColorOptions}
39
39
  */
40
40
  export let color = "info";
41
41
 
@@ -3,8 +3,8 @@
3
3
 
4
4
 
5
5
  @param {string} [icon="info-circle"] - Icon used when default slot has no content, Default: `"info-circle"`
6
- @param {''|'primary'|'success'|'warning'|'info'|'danger'|'dark'|'light'} [icon_color="primary"] - Colour of the trigger icon displayed when default slot has no content, Default: `"primary"`
7
- @param {''|'small'|'medium'|'large'} [icon_size="small"] - Size of the trigger icon displayed when default slot has no content, Default: `"small"`
6
+ @param {string|''|'primary'|'success'|'warning'|'info'|'danger'|'dark'|'light'} [icon_color="primary"] - Colour of the trigger icon displayed when default slot has no content, Default: `"primary"`
7
+ @param {string|''|'small'|'medium'|'large'} [icon_size="small"] - Size of the trigger icon displayed when default slot has no content, Default: `"small"`
8
8
  @param {string} [trigger="click"] - Determines the events that cause the Popover to show. Multiple event names are separated by spaces.
9
9
 
10
10
  **Examples:** `click`, `mouseenter`, `mouseenter focus`
@@ -85,12 +85,12 @@ It can be any CSS value associated with `max-width` property, including `"none"`
85
85
  export let icon = "info-circle";
86
86
  /**
87
87
  * Colour of the trigger icon displayed when default slot has no content
88
- * @type {''|'primary'|'success'|'warning'|'info'|'danger'|'dark'|'light'}
88
+ * @type {import('@kws3/ui/types').ColorOptions | 'grey'}
89
89
  */
90
90
  export let icon_color = "primary";
91
91
  /**
92
92
  * Size of the trigger icon displayed when default slot has no content
93
- * @type {''|'small'|'medium'|'large'}
93
+ * @type {import('@kws3/ui/types').SizeOptions}
94
94
  */
95
95
  export let icon_size = "small";
96
96
  /**
@@ -8,6 +8,7 @@
8
8
  @param {number} [start=0] - First item index rendered inside viewport - readonly, Default: `0`
9
9
  @param {number} [end=0] - Last item index rendered inside viewport - readonly, Default: `0`
10
10
  @param {number} [end_threshold=10] - `end` event will be fired when the list reaches this many items before the end of the list., Default: `10`
11
+ @param {number} [padding_threshold=5] - render 'n' number of items on outside the viewport (top and bottom) to avoid visible glitches on scrolling., Default: `5`
11
12
  @param {string} [style=""] - Inline CSS for scroller container, Default: `""`
12
13
  @param {string} [class=""] - CSS classes for scroller container, Default: `""`
13
14
 
@@ -77,10 +78,7 @@ while more items are loading
77
78
  <script>
78
79
  import { onMount, tick } from "svelte";
79
80
  import { createEventDispatcher } from "svelte";
80
- import {
81
- resizeObserver,
82
- hasResizeObserver,
83
- } from "@kws3/ui/utils/resizeObserver";
81
+ import { resizeObserver, hasResizeObserver } from "@kws3/ui/resizeObserver";
84
82
 
85
83
  const fire = createEventDispatcher();
86
84
  /**
@@ -108,6 +106,10 @@ while more items are loading
108
106
  * `end` event will be fired when the list reaches this many items before the end of the list.
109
107
  */
110
108
  end_threshold = 10,
109
+ /**
110
+ * render 'n' number of items on outside the viewport (top and bottom) to avoid visible glitches on scrolling.
111
+ */
112
+ padding_threshold = 5,
111
113
  /**
112
114
  * Inline CSS for scroller container
113
115
  */
@@ -132,9 +134,11 @@ while more items are loading
132
134
  average_height,
133
135
  items_count = 0;
134
136
 
135
- $: visible = items.slice(start, end).map((data, i) => {
136
- return { index: i + start, data };
137
- });
137
+ $: padStart = start > padding_threshold ? start - padding_threshold : start;
138
+ $: padEnd = end + padding_threshold;
139
+ $: visible = items
140
+ .slice(padStart, padEnd)
141
+ .map((data, i) => ({ index: i + padStart, data }));
138
142
 
139
143
  // whenever `items` changes, invalidate the current heightmap
140
144
  $: items, viewport_height, item_height, mounted, refresh();
@@ -176,7 +180,7 @@ while more items are loading
176
180
  const row_height = height_map[i] || average_height;
177
181
  if (y + row_height > scrollTop) {
178
182
  start = i;
179
- top = y;
183
+ top = y - row_height * padding_threshold;
180
184
  break;
181
185
  }
182
186
  y += row_height;
@@ -25,6 +25,9 @@ If this is set to `true`, the `radius` property will be ignored., Default: `fals
25
25
  {/each}
26
26
 
27
27
  <script>
28
+ /**
29
+ * @typedef {import('@kws3/ui/types').BGColorOptions} BGColorOptions
30
+ */
28
31
  export let /**
29
32
  * Number of lines of text to display.
30
33
  */
@@ -51,7 +54,7 @@ If this is set to `true`, the `radius` property will be ignored., Default: `fals
51
54
  circle = false,
52
55
  /**
53
56
  * Color of the Skeleton lines
54
- * @type {'' | 'transparent' | 'warning' | 'info' | 'danger' | 'primary' | 'success' | 'link'}
57
+ * @type {BGColorOptions}
55
58
  */
56
59
  color = "";
57
60
 
@@ -16,7 +16,7 @@
16
16
  <script>
17
17
  /**
18
18
  * Alignment of the Timeline child items
19
- * @type {'left'|'center'|'right'}
19
+ * @type {string|'left'|'center'|'right'}
20
20
  */
21
21
  export let align = "left";
22
22
 
@@ -3,8 +3,8 @@
3
3
 
4
4
 
5
5
  @param {''|'dark' | 'light' | 'warning' | 'info' | 'danger' | 'primary' | 'success'} [color="primary"] - Color of marker and border, Default: `"primary"`
6
- @param {string} [marker_icon="null"] - Any icon name accepted by the Icon component, icon will be placed inside the marker, Default: `"null"`
7
- @param {string} [marker_image="null"] - Any image URL, the image will be placed inside the marker, Default: `"null"`
6
+ @param {string} [marker_icon=""] - Any icon name accepted by the Icon component, icon will be placed inside the marker, Default: `"null"`
7
+ @param {string} [marker_image=""] - Any image URL, the image will be placed inside the marker, Default: `"null"`
8
8
  @param {string} [class=""] - CSS classes for the TimelineItem container, Default: `""`
9
9
 
10
10
  ### Slots
@@ -48,19 +48,19 @@
48
48
 
49
49
  /**
50
50
  * Color of marker and border
51
- * @type {''|'dark' | 'light' | 'warning' | 'info' | 'danger' | 'primary' | 'success'}
51
+ * @type {import('@kws3/ui/types').ColorOptions}
52
52
  */
53
53
  export let color = "primary";
54
54
  /**
55
55
  * Any icon name accepted by the Icon component, icon will be placed inside the marker
56
56
  * @type {string}
57
57
  */
58
- export let marker_icon = null;
58
+ export let marker_icon = "";
59
59
  /**
60
60
  * Any image URL, the image will be placed inside the marker
61
61
  * @type {string}
62
62
  */
63
- export let marker_image = null;
63
+ export let marker_image = "";
64
64
 
65
65
  /**
66
66
  * CSS classes for the TimelineItem container
@@ -5,7 +5,7 @@ import tippy, { delegate } from "tippy.js";
5
5
  * @param {string} container - CSS selector of container
6
6
  * @param {object} opts - tooltip options
7
7
  */
8
- export function activateTooltips(container, opts) {
8
+ export function activateTooltips(container, opts = {}) {
9
9
  let _opts = Object.assign(
10
10
  {
11
11
  target: "[data-tooltip]",
package/index.js CHANGED
@@ -1,6 +1,6 @@
1
- export { applySettings } from "./settings";
1
+ export { applySettings } from "./settings.js";
2
2
 
3
- export { activateTooltips, tooltip, popover } from "./helpers/Tooltip";
3
+ export { activateTooltips, tooltip, popover } from "./helpers/Tooltip.js";
4
4
  export { default as Popover } from "./helpers/Popover.svelte";
5
5
  export { default as Icon } from "./helpers/Icon.svelte";
6
6
  export { default as Message } from "./helpers/Message.svelte";
@@ -18,13 +18,18 @@ export { default as TimelineHeader } from "./helpers/Timeline/TimelineHeader.sve
18
18
  export { default as Nl2br } from "./helpers/Nl2br.svelte";
19
19
  export { default as ClipboardCopier } from "./helpers/ClipboardCopier.svelte";
20
20
  export { default as ScrollableList } from "./helpers/ScrollableList.svelte";
21
- export { alert, confirm, prompt, default as Dialog } from "./helpers/Dialog";
21
+ export {
22
+ alert,
23
+ confirm,
24
+ prompt,
25
+ default as Dialog,
26
+ } from "./helpers/Dialog/index.js";
22
27
  export {
23
28
  Notifications,
24
29
  Toasts,
25
30
  Snackbars,
26
31
  FloatiesStore,
27
- } from "./helpers/FloatingUI";
32
+ } from "./helpers/FloatingUI/index.js";
28
33
  export { default as FloatingUIOutput } from "./helpers/FloatingUI/FloatingUIOutput.svelte";
29
34
  export { default as Floatie } from "./helpers/FloatingUI/Floatie.svelte";
30
35
  export { portal } from "svelte-portal";
@@ -56,6 +61,7 @@ export { default as MaskedInput } from "./forms/MaskedInput.svelte";
56
61
  export { default as Colorpicker } from "./forms/colorpicker/Colorpicker.svelte";
57
62
  export { default as Datepicker } from "./forms/Datepicker.svelte";
58
63
  export { default as Timepicker } from "./forms/Timepicker.svelte";
64
+ export { default as SearchInput } from "./forms/SearchInput.svelte";
59
65
  export { datepicker as DatepickerAction } from "./forms/actions.js";
60
66
  export { timepicker as TimepickerAction } from "./forms/actions.js";
61
67
  export { default as PasswordValidator } from "./forms/PasswordValidator/PasswordValidator.svelte";
@@ -36,7 +36,7 @@
36
36
  * This can be configured through opts.analyzeSubTermDepth = 10.
37
37
  */
38
38
 
39
- export default function fuzzy(term, query, opts = {}) {
39
+ export function fuzzy(term, query, opts = {}) {
40
40
  let analyzeSubTerms = opts.analyzeSubTerms ? opts.analyzeSubTerms : false;
41
41
  let analyzeSubTermDepth = opts.analyzeSubTermDepth
42
42
  ? opts.analyzeSubTermDepth
@@ -0,0 +1,27 @@
1
+ export { scrollIntoActiveElement } from "./scrollIntoActiveElement";
2
+ export { fuzzy } from "./fuzzy.js";
3
+
4
+ /**
5
+ * Detect whether a user has pressed Enter.
6
+ * @param {object} [e=[]] - Event object., Default: `[]`
7
+ */
8
+ export function isEnterKey(e) {
9
+ return e.keyCode && e.keyCode === 13;
10
+ }
11
+
12
+ /**
13
+ * Detect whether a user has pressed Escape key.
14
+ * @param {object} [e=[]] - Event object., Default: `[]`
15
+ */
16
+ export function isEscKey(e) {
17
+ return e.keyCode && e.keyCode === 27;
18
+ }
19
+
20
+ export const IS_MAC =
21
+ "navigator" in window
22
+ ? /mac/i.test(
23
+ window.navigator.userAgentData
24
+ ? window.navigator.userAgentData.platform
25
+ : window.navigator.platform
26
+ )
27
+ : false;
@@ -0,0 +1,22 @@
1
+ export function scrollIntoActiveElement(listElement, activeElelement) {
2
+ if (listElement && activeElelement) {
3
+ const dropdownRect = listElement.getBoundingClientRect();
4
+ const activeElemRect = activeElelement.getBoundingClientRect();
5
+ const overScroll = activeElelement.offsetHeight / 3;
6
+
7
+ if (activeElemRect.bottom + overScroll > dropdownRect.bottom) {
8
+ listElement.scrollTop = Math.min(
9
+ activeElelement.offsetTop +
10
+ activeElelement.clientHeight -
11
+ listElement.offsetHeight +
12
+ overScroll,
13
+ listElement.scrollHeight
14
+ );
15
+ } else if (activeElemRect.top - overScroll < dropdownRect.top) {
16
+ listElement.scrollTop = Math.max(
17
+ activeElelement.offsetTop - overScroll,
18
+ 0
19
+ );
20
+ }
21
+ }
22
+ }
@@ -0,0 +1,94 @@
1
+ import { IS_MAC } from "../internal";
2
+ const ctrlKeys = {
3
+ ctrl: "ctrlKey",
4
+ meta: "metaKey",
5
+ shift: "shiftKey",
6
+ alt: "altKey",
7
+ };
8
+
9
+ /**
10
+ * @param {string | number} definition - can be a string like 'Enter', 'Tab' or number as keyCode, also allow combination key like 'ctrl+d', 'ctrl+alt+x'
11
+ * @param {boolean} CommandKey - if true, in mac 'ctrl' key binding will be shift on 'command' key.
12
+ * @returns {function} .
13
+ */
14
+
15
+ export function makeKeyDefinition(definition, CommandKey = false) {
16
+ let def = definition;
17
+ let keys = [];
18
+
19
+ if (typeof def === "number") {
20
+ keys = [def];
21
+ }
22
+
23
+ if (typeof def === "string") {
24
+ if (CommandKey) {
25
+ if (IS_MAC) {
26
+ def = def.replace("ctrl", "meta");
27
+ }
28
+ }
29
+ keys = def.split("+");
30
+ }
31
+
32
+ return function (node, fire) {
33
+ function keydownHandler(event) {
34
+ event.preventDefault();
35
+ let firedCount = 0;
36
+ let which = event.which || event.keyCode;
37
+ keys.forEach((key) => {
38
+ if (event[ctrlKeys[key]]) {
39
+ firedCount++;
40
+ }
41
+ if (
42
+ key === event.key ||
43
+ ("key" + key).toLowerCase() === event.code.toLowerCase()
44
+ ) {
45
+ firedCount++;
46
+ }
47
+ if (key === which) {
48
+ firedCount++;
49
+ }
50
+ });
51
+
52
+ let valid = false;
53
+ if (keys.length === firedCount) {
54
+ valid = true;
55
+ }
56
+
57
+ if (valid) {
58
+ fire(event);
59
+ }
60
+ }
61
+
62
+ node.addEventListener("keydown", keydownHandler, false);
63
+
64
+ return {
65
+ destroy() {
66
+ node.removeEventListener("keydown", keydownHandler, false);
67
+ },
68
+ };
69
+ };
70
+ }
71
+
72
+ export let enter = makeKeyDefinition("Enter");
73
+ export let tab = makeKeyDefinition("Tab");
74
+ export let escape = makeKeyDefinition("Escape");
75
+ export let space = makeKeyDefinition(" ");
76
+ export let leftarrow = makeKeyDefinition("ArrowLeft");
77
+ export let rightarrow = makeKeyDefinition("ArrowRight");
78
+ export let downarrow = makeKeyDefinition("ArrowDown");
79
+ export let uparrow = makeKeyDefinition("ArrowUp");
80
+ export let backspace = makeKeyDefinition("Backspace");
81
+ export let del = makeKeyDefinition("Delete");
82
+
83
+ export default {
84
+ enter,
85
+ tab,
86
+ escape,
87
+ space,
88
+ leftarrow,
89
+ rightarrow,
90
+ downarrow,
91
+ uparrow,
92
+ backspace,
93
+ del,
94
+ };
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "@kws3/ui",
3
- "version": "1.9.3",
3
+ "version": "2.0.0",
4
4
  "description": "UI components for use with Svelte v3 applications.",
5
5
  "main": "index.js",
6
+ "svelte": "index.js",
6
7
  "scripts": {
7
8
  "test": "echo \"Error: no test specified\" && exit 1"
8
9
  },
@@ -17,11 +18,13 @@
17
18
  "contributors": [
18
19
  "Sharif Ahmed <me.sharifahmed@gmail.com>",
19
20
  "Sabir <sabirveli@gmail.com>",
20
- "Suneesh S K <suneeshsk3@gmail.com>"
21
+ "Suneesh S K <suneeshsk3@gmail.com>",
22
+ "Nikeeta <nikeetaa231@gmail.com>"
21
23
  ],
22
24
  "publishConfig": {
23
25
  "access": "public"
24
26
  },
27
+ "types": "types/index.d.ts",
25
28
  "dependencies": {
26
29
  "apexcharts": "3.33.2",
27
30
  "flatpickr": "^4.5.2",
@@ -29,5 +32,5 @@
29
32
  "text-mask-core": "^5.1.2",
30
33
  "tippy.js": "^6.3.1"
31
34
  },
32
- "gitHead": "c6a60f59d36f7bb3a6e4475c6c727c036d235581"
35
+ "gitHead": "9606d798a4c6d550863290f2c0b6baac3a61a09e"
33
36
  }
@@ -0,0 +1,52 @@
1
+ import { fuzzy } from "../internal";
2
+
3
+ /**
4
+ * @typedef {import('@kws3/ui/types').SearchOptions} SearchOptions - contains search options and fuzzy lib options
5
+ * @typedef {import('@kws3/ui/types').SearchHelper} SearchHelper - returned search helper function which take unction take params `needle` and `haystack`.
6
+ */
7
+
8
+ /**
9
+ * @param {SearchOptions} opts
10
+ */
11
+ export function makeSearchEngine(opts) {
12
+ let search_key = opts.search_key ? opts.search_key : "value";
13
+ let scoreThreshold = opts.scoreThreshold ? opts.scoreThreshold : 5;
14
+ let fuzzyOpts = opts.fuzzyOpts ? opts.fuzzyOpts : {};
15
+
16
+ /**
17
+ * @param {string} needle
18
+ * @param {array} haystack
19
+ * @returns {array}
20
+ */
21
+ return function (needle, haystack) {
22
+ let OPTS = haystack.map((option) => {
23
+ let item = { ...option };
24
+ item.original = { ...option };
25
+ if (typeof item === "object") {
26
+ if (!Array.isArray(search_key)) {
27
+ search_key = [search_key];
28
+ }
29
+
30
+ search_key.forEach((s_key) => {
31
+ if (`${s_key}` in item) {
32
+ let output = fuzzy(option[s_key], needle, fuzzyOpts);
33
+ item.original[s_key] = output.highlightedTerm;
34
+ item.score =
35
+ !item.score || (item.score && item.score < output.score)
36
+ ? output.score
37
+ : item.score || 0;
38
+ }
39
+ });
40
+ }
41
+ return item;
42
+ });
43
+
44
+ let maxScore = Math.max(...OPTS.map((i) => i.score));
45
+ let calculatedLimit = maxScore - scoreThreshold;
46
+
47
+ OPTS = OPTS.filter(
48
+ (r) => r.score > (calculatedLimit > 0 ? calculatedLimit : 0)
49
+ );
50
+ return OPTS.map((i) => i.original);
51
+ };
52
+ }