@kws3/ui 1.1.0 → 1.2.2

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.
@@ -0,0 +1,149 @@
1
+ <!--
2
+ @component
3
+
4
+
5
+ @param {object} [value=null] - Value of the Input
6
+
7
+ This property can be bound to, to fetch the current value, Default: `null`
8
+ @param {string} [placeholder="Please select..."] - Placeholder text for the input, Default: `"Please select..."`
9
+ @param {array} [options=[]] - Array of strings, or objects.
10
+ Used to populate the list of options in the dropdown, Default: `[]`
11
+ @param {string} [search_key="name"] - If `options` is an array of objects,
12
+ this property of each object will be searched, Default: `"name"`
13
+ @param {string} [value_key="id"] - If `options` is an array of objects,
14
+ this property of each object will be returned as the value, Default: `"id"`
15
+ @param {''|'small'|'medium'|'large'} [size=""] - Size of the input, Default: `""`
16
+ @param {''|'primary'|'success'|'warning'|'info'|'danger'|'dark'|'light'} [color=""] - Color of the input, Default: `""`
17
+ @param {string} [style=""] - Inline CSS for input container, Default: `""`
18
+ @param {boolean} [readonly=false] - Marks component as read-only, Default: `false`
19
+ @param {boolean} [disabled=false] - Disables the component, Default: `false`
20
+ @param {string} [selected_icon="check"] - Icon used to mark selected items in dropdown list, Default: `"check"`
21
+ @param {string} [no_options_msg="No matching options"] - Message to display when no matching options are found, Default: `"No matching options"`
22
+ @param {string} [remove_all_tip="Clear Selection"] - Tooltip text for the Clear selection button, Default: `"Clear Selection"`
23
+ @param {string} [class=""] - CSS classes for input container, Default: `""`
24
+
25
+ ### Events
26
+ - `change` - Triggered when the value changes
27
+ - `blur` - Triggered when the input loses focus
28
+
29
+ ### Slots
30
+ - `<slot name="default" {search_key} {option} />` - Slot containing text for each selectable item
31
+
32
+ Default value: `<span>{option[search_key] || option}</span>`
33
+
34
+ -->
35
+ <MultiSelect
36
+ bind:value
37
+ class={klass}
38
+ max={1}
39
+ {placeholder}
40
+ {options}
41
+ {search_key}
42
+ {value_key}
43
+ {size}
44
+ {color}
45
+ {style}
46
+ {readonly}
47
+ {disabled}
48
+ {selected_icon}
49
+ {remove_all_tip}
50
+ {no_options_msg}
51
+ on:change={change}
52
+ on:blur={blur}
53
+ let:option
54
+ let:search_key>
55
+ <!--
56
+ Slot containing text for each selectable item
57
+
58
+ Default value: `<span>{option[search_key] || option}</span>`
59
+ --><slot
60
+ {search_key}
61
+ {option}>{option[search_key] || option}</slot>
62
+ </MultiSelect>
63
+
64
+ <script>
65
+ import { createEventDispatcher } from "svelte";
66
+ import { MultiSelect } from "@kws3/ui";
67
+
68
+ const fire = createEventDispatcher();
69
+
70
+ /**
71
+ * Value of the Input
72
+ *
73
+ * This property can be bound to, to fetch the current value
74
+ */
75
+ export let value = null;
76
+ /**
77
+ * Placeholder text for the input
78
+ */
79
+ export let placeholder = "Please select...";
80
+ /**
81
+ * Array of strings, or objects.
82
+ * Used to populate the list of options in the dropdown
83
+ */
84
+ export let options = [];
85
+
86
+ /**
87
+ * If `options` is an array of objects,
88
+ * this property of each object will be searched
89
+ */
90
+ export let search_key = "name";
91
+ /**
92
+ * If `options` is an array of objects,
93
+ * this property of each object will be returned as the value
94
+ */
95
+ export let value_key = "id";
96
+ /**
97
+ * Size of the input
98
+ * @type {''|'small'|'medium'|'large'}
99
+ */
100
+ export let size = "";
101
+ /**
102
+ * Color of the input
103
+ * @type {''|'primary'|'success'|'warning'|'info'|'danger'|'dark'|'light'}
104
+ */
105
+ export let color = "";
106
+ /**
107
+ * Inline CSS for input container
108
+ */
109
+ export let style = "";
110
+ /**
111
+ * Marks component as read-only
112
+ */
113
+ export let readonly = false;
114
+ /**
115
+ * Disables the component
116
+ */
117
+ export let disabled = false;
118
+ /**
119
+ * Icon used to mark selected items in dropdown list
120
+ */
121
+ export let selected_icon = "check";
122
+ /**
123
+ * Message to display when no matching options are found
124
+ */
125
+ export let no_options_msg = "No matching options";
126
+ /**
127
+ * Tooltip text for the Clear selection button
128
+ */
129
+ export let remove_all_tip = "Clear Selection";
130
+
131
+ /**
132
+ * CSS classes for input container
133
+ */
134
+ let klass = "";
135
+ export { klass as class };
136
+
137
+ function change({ detail }) {
138
+ /**
139
+ * Triggered when the value changes
140
+ */
141
+ fire("change", detail);
142
+ }
143
+ function blur({ detail }) {
144
+ /**
145
+ * Triggered when the input loses focus
146
+ */
147
+ fire("blur", detail);
148
+ }
149
+ </script>
@@ -8,7 +8,7 @@
8
8
  @param {string} [copied_icon="check"] - Icon displayed on successful copy operation, Default: `"check"`
9
9
  @param {string} [copy=""] - Text to be copied into clipboard, Default: `""`
10
10
  @param {boolean} [copied=false] - Determines if the copy operation has taken place, Default: `false`
11
- @param {''|'primary'|'success'|'warning'|'info'|'danger'|'dark'|'light'} [copied_icon_color="success"] - Colour of the Icon after a succesful copy operation
11
+ @param {''|'primary'|'success'|'warning'|'info'|'danger'|'dark'|'light'} [copied_icon_color="success"] - Colour of the `copied_icon` after a succesful copy operation
12
12
 
13
13
  If `''` is selected, Icon will not change colour after copying, Default: `"success"`
14
14
  @param {string} [class=""] - CSS classes for the whole component, Default: `""`
@@ -28,7 +28,7 @@ If `''` is selected, Icon will not change colour after copying, Default: `"succe
28
28
  icon={copied ? copied_icon : icon}
29
29
  size="small"
30
30
  color={copied ? copied_icon_color : ""}
31
- icon_class={copied ? "is-bouncing-once" : ""} />
31
+ class={copied ? "is-bouncing-once" : ""} />
32
32
  </span>
33
33
 
34
34
  <style lang="scss">
@@ -0,0 +1,141 @@
1
+ <!--
2
+ @component
3
+
4
+ @param {string} [title=""] - Title for display, Default: `""`
5
+ @param {string} [message=""] - Message for display, Default: `""`
6
+ @param {number} [duration=3000] - Duration for display message, Default: `3000`
7
+ @param {'warning'|'info'|'danger'|'primary'|'success'} [color="primary"] - Message background color, Default: `"primary"`
8
+ @param {'top'|'bottom'|'top-left'|'top-right'|'bottom-left'|'bottom-right'} [position=""] - Position of the message, Default: `""`
9
+ @param {boolean} [dismissable=true] - Dismissable message, Default: `true`
10
+ @param {boolean} [persistent=false] - Persistent message, Default: `false`
11
+ @param {string} [context=""] - Context value, Default: `""`
12
+ @param {object} [component=null] - Custom component, Default: `null`
13
+ @param {function} [beforeClose(props)] - Callback function call before close event
14
+ @param {function} [afterClose(props)] - Callback function call after close event
15
+ -->
16
+
17
+ {#if variant == "snackbar"}
18
+ <div class="snackbar is-{color} {light ? 'is-light' : ''}">
19
+ <div class="text">{message}</div>
20
+ <div class="action">
21
+ {#each buttonsToRender as { text, color: text_color, click }}
22
+ <button
23
+ class="button is-{color} has-text-{text_color}"
24
+ on:click={click}
25
+ on:click={destroy}>{text}</button>
26
+ {/each}
27
+ </div>
28
+ {#if !persistent}
29
+ <div class="floatie-progress" style="animation-duration:{duration}ms" />
30
+ {/if}
31
+ </div>
32
+ {:else if variant == "toast"}
33
+ <div class="toast is-{color} {light ? 'is-light' : ''}">
34
+ {message}
35
+ </div>
36
+ {:else}
37
+ <div class="notification is-{color} {light ? 'is-light' : ''}">
38
+ {#if component}
39
+ <svelte:component this={component} {...$$props} on:destroy={destroy} />
40
+ {:else}
41
+ {#if dismissable}
42
+ <button class="delete" on:click={destroy} />
43
+ {/if}
44
+ {#if title}
45
+ <h4 class="title is-5 is-marginless">{title}</h4>
46
+ {/if}
47
+
48
+ <p>{@html message}</p>
49
+
50
+ {#if !persistent}
51
+ <div class="floatie-progress" style="animation-duration:{duration}ms" />
52
+ {/if}
53
+ {/if}
54
+ </div>
55
+ {/if}
56
+
57
+ <script>
58
+ //TODO: Icon support
59
+ import { onMount, onDestroy, createEventDispatcher } from "svelte";
60
+
61
+ const fire = createEventDispatcher();
62
+
63
+ /**
64
+ * Title/Heading of the notification
65
+ */
66
+ export let title = "",
67
+ /**
68
+ * Message in the notification
69
+ */
70
+ message = "",
71
+ /**
72
+ * variation of floating UI
73
+ * @type {'notification'|'snackbar'|'toast'}
74
+ */
75
+ variant = "notification",
76
+ /**
77
+ * Duration of the notification
78
+ */
79
+ duration = 3000,
80
+ /**
81
+ * Toast notification background color
82
+ * @type {''|'primary'|'success'|'warning'|'info'|'danger'|'dark'|'light'}
83
+ */
84
+ color = "primary",
85
+ /**
86
+ * Inverted colors for notification box and contents
87
+ */
88
+ light = false,
89
+ /**
90
+ * Determines if notification is dismissable
91
+ */
92
+ dismissable = true,
93
+ /**
94
+ * A persistent notification without duration, stays till dismissed
95
+ */
96
+ persistent = false,
97
+ /**
98
+ * Context value
99
+ */
100
+ context = "",
101
+ /**
102
+ * Custom component
103
+ */
104
+ component = null,
105
+ /**
106
+ * Callback function call before close event
107
+ */
108
+ beforeClose = (props) => {},
109
+ /**
110
+ * Callback function call after close event
111
+ */
112
+ afterClose = (props) => {},
113
+ /**
114
+ * List of buttons to show in snackbar
115
+ */
116
+ buttons = ["Ok"];
117
+
118
+ let timeout;
119
+
120
+ $: buttonsToRender = (buttons || []).map((b) => {
121
+ let defaults = { text: "Ok", color: "", click: () => {} },
122
+ obj = b;
123
+ if (typeof b == "string") {
124
+ obj = { text: b };
125
+ }
126
+ return Object.assign({}, defaults, obj);
127
+ });
128
+
129
+ const destroy = () =>
130
+ Promise.resolve(beforeClose($$props))
131
+ .then(() => fire("destroy", $$props))
132
+ .then(() => afterClose($$props));
133
+
134
+ onMount(() => {
135
+ timeout = setTimeout(() => {
136
+ if (!persistent) destroy();
137
+ }, duration);
138
+ });
139
+
140
+ onDestroy(() => clearTimeout(timeout));
141
+ </script>
@@ -0,0 +1,34 @@
1
+ {#each Object.keys($FloatiesStore) as position}
2
+ {#each Object.keys($FloatiesStore[position]) as variant}
3
+ <div class="kws-floatie-output is-{position} is-{variant}-holder">
4
+ {#each $FloatiesStore[position][variant] as item (item.id)}
5
+ <div
6
+ class="kws-floatie-item has-{variant} is-{item.position}"
7
+ id={item.id}
8
+ animate:flip={{ easing: sineOut }}
9
+ transition:fly={{
10
+ y: transitionDistance(item.position),
11
+ duration: transitionDuration,
12
+ easing: sineOut,
13
+ }}>
14
+ <Floatie {...item} on:destroy={destroy} />
15
+ </div>
16
+ {/each}
17
+ </div>
18
+ {/each}
19
+ {/each}
20
+
21
+ <script>
22
+ import { fly } from "svelte/transition";
23
+ import { sineOut } from "svelte/easing";
24
+ import { flip } from "svelte/animate";
25
+ import { FloatiesStore } from "./index";
26
+ import { hasTransitions } from "../../settings";
27
+ import Floatie from "./Floatie.svelte";
28
+
29
+ const destroy = ({ detail }) => FloatiesStore.remove(detail);
30
+ const transitionDistance = (position) =>
31
+ position.indexOf("top") === 0 ? -50 : 50;
32
+
33
+ $: transitionDuration = $hasTransitions ? 150 : 0;
34
+ </script>
@@ -0,0 +1,156 @@
1
+ import FloatingUIOutput from "./FloatingUIOutput.svelte";
2
+ import { writable, get } from "svelte/store";
3
+ import {
4
+ defaultToastPlacement,
5
+ defaultSnackbarPlacement,
6
+ defaultNotificationPlacement,
7
+ } from "../../settings";
8
+
9
+ const DEFAULT_POSITIONS = {
10
+ notification: get(defaultNotificationPlacement),
11
+ snackbar: get(defaultSnackbarPlacement),
12
+ toast: get(defaultToastPlacement),
13
+ };
14
+
15
+ let OUTPUT_IS_ON_PAGE = false;
16
+
17
+ function ensureOutputIsOnPage() {
18
+ if (OUTPUT_IS_ON_PAGE) {
19
+ return;
20
+ }
21
+
22
+ OUTPUT_IS_ON_PAGE = new FloatingUIOutput({
23
+ target: document.body,
24
+ });
25
+ }
26
+
27
+ const getPosition = (props) => {
28
+ if (props.position) {
29
+ return props.position.indexOf("top") === 0 ? "top" : "bottom";
30
+ }
31
+ if (DEFAULT_POSITIONS[props.variant]) {
32
+ return DEFAULT_POSITIONS[props.variant].indexOf("top") === 0
33
+ ? "top"
34
+ : "bottom";
35
+ }
36
+ return "top";
37
+ };
38
+
39
+ export const FloatiesStore = (() => {
40
+ const { update, subscribe } = writable({
41
+ top: {
42
+ notification: [],
43
+ snackbar: [],
44
+ toast: [],
45
+ },
46
+ bottom: {
47
+ notification: [],
48
+ snackbar: [],
49
+ toast: [],
50
+ },
51
+ });
52
+
53
+ const create = (newItem) => {
54
+ update((items) => {
55
+ ensureOutputIsOnPage();
56
+
57
+ //verify we have a correct variant
58
+ if (!newItem.variant) {
59
+ newItem.variant = "notification";
60
+ }
61
+ if (!["notification", "snackbar", "toast"].includes(newItem.variant)) {
62
+ newItem.variant = "notification";
63
+ }
64
+
65
+ if (!newItem.position || newItem.position == "") {
66
+ newItem.position = DEFAULT_POSITIONS[newItem.variant];
67
+ }
68
+
69
+ if (!newItem.id) {
70
+ newItem.id = `__kws_${newItem.variant}_${new Date().getTime()}`;
71
+ }
72
+
73
+ items[getPosition(newItem)][newItem.variant].push(newItem);
74
+
75
+ return items;
76
+ });
77
+
78
+ return {
79
+ props: newItem,
80
+ destroy: () => remove(newItem),
81
+ };
82
+ };
83
+
84
+ const remove = (props) => {
85
+ update((items) => {
86
+ let _position = getPosition(props);
87
+ let _variant = props.variant;
88
+ let _items = items[_position][_variant];
89
+
90
+ items[_position][_variant] = _items.slice().filter((el) => {
91
+ return el && el.id && el.id != props.id;
92
+ });
93
+
94
+ return items;
95
+ });
96
+ };
97
+
98
+ return { create, remove, subscribe };
99
+ })();
100
+
101
+ const buildInitialiser = (defaultOpts, mandatoryOpts) => {
102
+ return (opts) => {
103
+ let _opts = Object.assign({}, defaultOpts, opts, mandatoryOpts);
104
+ return FloatiesStore.create(_opts);
105
+ };
106
+ };
107
+
108
+ export const Notifications = {
109
+ create: buildInitialiser(
110
+ {
111
+ //default Options
112
+ position: DEFAULT_POSITIONS["notification"],
113
+ dismissable: true,
114
+ persistent: false,
115
+ },
116
+ {
117
+ //mandatory options
118
+ variant: "notification",
119
+ }
120
+ ),
121
+ remove: FloatiesStore.remove,
122
+ };
123
+
124
+ export const Toasts = {
125
+ create: buildInitialiser(
126
+ {
127
+ //default Options
128
+ position: DEFAULT_POSITIONS["toast"],
129
+ },
130
+ {
131
+ //mandatory options
132
+ variant: "toast",
133
+ dismissable: true,
134
+ persistent: false,
135
+ title: "",
136
+ }
137
+ ),
138
+ remove: FloatiesStore.remove,
139
+ };
140
+
141
+ export const Snackbars = {
142
+ create: buildInitialiser(
143
+ {
144
+ //default Options
145
+ position: DEFAULT_POSITIONS["snackbar"],
146
+ dismissable: true,
147
+ persistent: false,
148
+ },
149
+ {
150
+ //mandatory options
151
+ variant: "snackbar",
152
+ title: "",
153
+ }
154
+ ),
155
+ remove: FloatiesStore.remove,
156
+ };
@@ -5,7 +5,7 @@
5
5
  @param {''|'small'|'medium'|'large'} [size=""] - Size of the Icon, Default: `""`
6
6
  @param {''|'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, defaults to global family set via `setDefaultIconType()`
8
+ @param {''|'fa'|'lar'|'las'|'gg'|'unicons'} [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: `""`
@@ -67,7 +67,7 @@ Ultimately defaults to `fa`, if family is not set anywhere, Default: `""`
67
67
  */
68
68
  icon = "",
69
69
  /**
70
- * Icon family, defaults to global family set via `setDefaultIconType()`
70
+ * Icon family, can be modified globally in framework settings
71
71
  *
72
72
  * Ultimately defaults to `fa`, if family is not set anywhere
73
73
  * @type {''|'fa'|'lar'|'las'|'gg'|'unicons'}
package/index.js CHANGED
@@ -12,6 +12,12 @@ export { default as Notification } from "./helpers/Notification.svelte";
12
12
  export { default as Loader } from "./helpers/Loader.svelte";
13
13
  export { default as ActionSheet } from "./helpers/ActionSheet.svelte";
14
14
  export { alert, confirm, prompt, default as Dialog } from "./helpers/Dialog";
15
+ export {
16
+ Notifications,
17
+ Toasts,
18
+ Snackbars,
19
+ FloatiesStore,
20
+ } from "./helpers/FloatingUI";
15
21
 
16
22
  export { default as ConfirmButton } from "./buttons/ConfirmButton.svelte";
17
23
  export { default as DeleteButton } from "./buttons/DeleteButton.svelte";
@@ -31,7 +37,8 @@ export { default as Nl2br } from "./helpers/Nl2br.svelte";
31
37
  export { default as Transition } from "./transitions/Transition.svelte";
32
38
  export { default as SlidingPane } from "./sliding-panes/SlidingPane.svelte";
33
39
  export { default as SlidingPaneSet } from "./sliding-panes/SlidingPaneSet.svelte";
34
- export { default as SearchableSelect } from "./forms/SearchableSelect.svelte";
40
+ export { default as SearchableSelect } from "./forms/select/SearchableSelect.svelte";
41
+ export { default as MultiSelect } from "./forms/select/MultiSelect.svelte";
35
42
  export { default as MaskedInput } from "./forms/MaskedInput.svelte";
36
43
 
37
44
  export { default as Colorpicker } from "./forms/colorpicker/Colorpicker.svelte";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kws3/ui",
3
- "version": "1.1.0",
3
+ "version": "1.2.2",
4
4
  "description": "UI components for use with Svelte v3 applications.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -27,5 +27,5 @@
27
27
  "text-mask-core": "^5.1.2",
28
28
  "tippy.js": "^6.3.1"
29
29
  },
30
- "gitHead": "bf983cded2a2272cacedfc58dde2576a7d6ef612"
30
+ "gitHead": "1f87ee1cde62bfc3f4fd94e41c3141dd9eec688c"
31
31
  }
package/settings.js CHANGED
@@ -1,20 +1,32 @@
1
1
  import { writable } from "svelte/store";
2
2
 
3
3
  const defaultIconFamily = writable("fa");
4
- const defaultToastPlacement = writable("top-right");
4
+ const defaultToastPlacement = writable("bottom");
5
+ const defaultSnackbarPlacement = writable("bottom-right");
6
+ const defaultNotificationPlacement = writable("top-right");
5
7
  const hasTransitions = writable(true);
6
8
 
7
9
  const SETTINGS = {
8
10
  defaultIconFamily,
9
11
  defaultToastPlacement,
12
+ defaultSnackbarPlacement,
13
+ defaultNotificationPlacement,
10
14
  hasTransitions,
11
15
  };
12
16
 
13
- export { defaultIconFamily, defaultToastPlacement, hasTransitions };
17
+ export {
18
+ defaultIconFamily,
19
+ defaultToastPlacement,
20
+ defaultSnackbarPlacement,
21
+ defaultNotificationPlacement,
22
+ hasTransitions,
23
+ };
14
24
 
15
25
  /**
16
26
  * - `defaultIconFamily`: `"fa"` - default icon family
17
- * - `defaultToastPlacement`: `"top-right"` - default placement of toast notifications
27
+ * - `defaultToastPlacement`: `"bottom"` - default placement of toast notifications
28
+ * - `defaultSnackbarPlacement`: `"bottom-right"` - default placement of snackbar notifications
29
+ * - `defaultNotificationPlacement`: `"top-right"` - default placement of floating notifications
18
30
  * - `hasTransitions`: `true` - Transitions are applied
19
31
  *
20
32
  * @param {*} object containing all settings