@flightlesslabs/dodo-ui 0.8.0 → 0.9.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 (54) hide show
  1. package/dist/index.d.ts +13 -2
  2. package/dist/index.js +8 -0
  3. package/dist/stories/components/Form/NumericInput/Events/Events.stories.svelte +126 -0
  4. package/dist/stories/components/Form/NumericInput/Events/Events.stories.svelte.d.ts +18 -0
  5. package/dist/stories/components/Form/NumericInput/NumericInput.stories.svelte +79 -0
  6. package/dist/stories/components/Form/NumericInput/NumericInput.stories.svelte.d.ts +21 -0
  7. package/dist/stories/components/Form/NumericInput/NumericInput.svelte +161 -0
  8. package/dist/stories/components/Form/NumericInput/NumericInput.svelte.d.ts +69 -0
  9. package/dist/stories/components/Form/NumericInput/Validation/Validation.stories.svelte +84 -0
  10. package/dist/stories/components/Form/NumericInput/Validation/Validation.stories.svelte.d.ts +18 -0
  11. package/dist/stories/components/Form/PasswordInput/Events/Events.stories.svelte +27 -6
  12. package/dist/stories/components/Form/PasswordInput/PasswordInput.svelte +5 -3
  13. package/dist/stories/components/Form/PasswordInput/PasswordInput.svelte.d.ts +7 -1
  14. package/dist/stories/components/Form/Select/Events/Events.stories.svelte +27 -0
  15. package/dist/stories/components/Form/Select/Select.svelte +4 -1
  16. package/dist/stories/components/Form/Select/Select.svelte.d.ts +7 -1
  17. package/dist/stories/components/Form/TextInput/Events/Events.stories.svelte +27 -0
  18. package/dist/stories/components/Form/TextInput/TextInput.svelte +5 -3
  19. package/dist/stories/components/Form/TextInput/TextInput.svelte.d.ts +10 -1
  20. package/dist/stories/components/Layout/Menu/DynamicMenu/DynamicMenu.svelte +1 -1
  21. package/dist/stories/developer tools/components/DynamicInput/DynamicInput.svelte +23 -5
  22. package/dist/stories/developer tools/components/DynamicInput/DynamicInput.svelte.d.ts +13 -2
  23. package/dist/stories/developer tools/components/DynamicInput/Events/Events.stories.svelte +115 -0
  24. package/dist/stories/developer tools/components/DynamicInput/Events/Events.stories.svelte.d.ts +18 -0
  25. package/dist/stories/developer tools/helpers/Numbers/cleanNumericString/cleanNumericString.d.ts +13 -0
  26. package/dist/stories/developer tools/helpers/Numbers/cleanNumericString/cleanNumericString.js +26 -0
  27. package/dist/stories/developer tools/helpers/Numbers/cleanNumericString/index.mdx +20 -0
  28. package/dist/stories/developer tools/helpers/Numbers/isValidNumberValue/index.mdx +71 -0
  29. package/dist/stories/developer tools/helpers/Numbers/isValidNumberValue/isValidNumberValue.d.ts +51 -0
  30. package/dist/stories/developer tools/helpers/Numbers/isValidNumberValue/isValidNumberValue.js +96 -0
  31. package/dist/stories/developer tools/helpers/logger/index.mdx +63 -0
  32. package/dist/stories/developer tools/helpers/logger/logger.d.ts +24 -0
  33. package/dist/stories/developer tools/helpers/logger/logger.js +31 -0
  34. package/package.json +1 -1
  35. package/src/lib/index.ts +20 -0
  36. package/src/lib/stories/components/Form/NumericInput/Events/Events.stories.svelte +134 -0
  37. package/src/lib/stories/components/Form/NumericInput/NumericInput.stories.svelte +84 -0
  38. package/src/lib/stories/components/Form/NumericInput/NumericInput.svelte +286 -0
  39. package/src/lib/stories/components/Form/NumericInput/Validation/Validation.stories.svelte +87 -0
  40. package/src/lib/stories/components/Form/PasswordInput/Events/Events.stories.svelte +28 -6
  41. package/src/lib/stories/components/Form/PasswordInput/PasswordInput.svelte +15 -3
  42. package/src/lib/stories/components/Form/Select/Events/Events.stories.svelte +31 -1
  43. package/src/lib/stories/components/Form/Select/Select.svelte +13 -0
  44. package/src/lib/stories/components/Form/TextInput/Events/Events.stories.svelte +28 -0
  45. package/src/lib/stories/components/Form/TextInput/TextInput.svelte +18 -3
  46. package/src/lib/stories/components/Layout/Menu/DynamicMenu/DynamicMenu.svelte +1 -1
  47. package/src/lib/stories/developer tools/components/DynamicInput/DynamicInput.svelte +43 -4
  48. package/src/lib/stories/developer tools/components/DynamicInput/Events/Events.stories.svelte +121 -0
  49. package/src/lib/stories/developer tools/helpers/Numbers/cleanNumericString/cleanNumericString.ts +27 -0
  50. package/src/lib/stories/developer tools/helpers/Numbers/cleanNumericString/index.mdx +20 -0
  51. package/src/lib/stories/developer tools/helpers/Numbers/isValidNumberValue/index.mdx +71 -0
  52. package/src/lib/stories/developer tools/helpers/Numbers/isValidNumberValue/isValidNumberValue.ts +156 -0
  53. package/src/lib/stories/developer tools/helpers/logger/index.mdx +63 -0
  54. package/src/lib/stories/developer tools/helpers/logger/logger.ts +46 -0
@@ -31,7 +31,6 @@ const { Story } = defineMeta({
31
31
  }}
32
32
  />
33
33
 
34
- <!-- `e: PasswordInputToggleEvent` -->
35
34
  <Story
36
35
  name="Toggle"
37
36
  args={{
@@ -43,7 +42,6 @@ const { Story } = defineMeta({
43
42
  }}
44
43
  />
45
44
 
46
- <!-- `e: TextInputFocusEvent` -->
47
45
  <Story
48
46
  name="Focus"
49
47
  args={{
@@ -55,7 +53,6 @@ const { Story } = defineMeta({
55
53
  }}
56
54
  />
57
55
 
58
- <!-- `e: TextInputFocusEvent` -->
59
56
  <Story
60
57
  name="Blur"
61
58
  args={{
@@ -67,7 +64,6 @@ const { Story } = defineMeta({
67
64
  }}
68
65
  />
69
66
 
70
- <!-- `e: TextInputClipboardEvent` -->
71
67
  <Story
72
68
  name="Copy"
73
69
  args={{
@@ -79,7 +75,6 @@ const { Story } = defineMeta({
79
75
  }}
80
76
  />
81
77
 
82
- <!-- `e: TextInputClipboardEvent` -->
83
78
  <Story
84
79
  name="Cut"
85
80
  args={{
@@ -91,7 +86,6 @@ const { Story } = defineMeta({
91
86
  }}
92
87
  />
93
88
 
94
- <!-- `e: TextInputClipboardEvent` -->
95
89
  <Story
96
90
  name="Paste"
97
91
  args={{
@@ -102,3 +96,30 @@ const { Story } = defineMeta({
102
96
  },
103
97
  }}
104
98
  />
99
+
100
+ <Story
101
+ name="KeyDown"
102
+ args={{
103
+ onkeydown: (e: TextInputKeyboardEvent) => {
104
+ console.log('onkeydown Event', e.key);
105
+ },
106
+ }}
107
+ />
108
+
109
+ <Story
110
+ name="KeyPress"
111
+ args={{
112
+ onkeypress: (e: TextInputKeyboardEvent) => {
113
+ console.log('onkeypress Event', e.key);
114
+ },
115
+ }}
116
+ />
117
+
118
+ <Story
119
+ name="KeyUp"
120
+ args={{
121
+ onkeyup: (e: TextInputKeyboardEvent) => {
122
+ console.log('onkeyup Event', e.key);
123
+ },
124
+ }}
125
+ />
@@ -5,21 +5,19 @@
5
5
  import UtilityButton from '../../../developer tools/components/UtilityButton/UtilityButton.svelte';
6
6
  import InputEnclosure from '../../../developer tools/components/InputEnclosure/InputEnclosure.svelte';
7
7
  import { DynamicInput } from '../../../../index.js';
8
- let { size = 'normal', roundness = 1, outline = true, name, id, class: className = '', disabled = false, oninput, onchange, onblur, onfocus, onpaste, oncopy, oncut, before, after, customPasswordToggleIcon, error = false, passwordToggle = true, passwordToggleState = $bindable(), value = $bindable(), placeholder, ontoggle, ref = $bindable(), readonly = false, } = $props();
8
+ let { size = 'normal', roundness = 1, outline = true, name, id, class: className = '', disabled = false, oninput, onchange, onblur, onfocus, onpaste, oncopy, oncut, onkeydown, onkeypress, onkeyup, before, after, customPasswordToggleIcon, error = false, passwordToggle = true, passwordToggleState = $bindable(), value = $bindable(), placeholder, ontoggle, ref = $bindable(), readonly = false, } = $props();
9
9
  let focused = $state(false);
10
10
  let toggle = $state(passwordToggleState);
11
11
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
12
12
  let customPasswordToggleIconTyped = customPasswordToggleIcon;
13
13
  function onfocusMod(e) {
14
14
  const eTyped = e;
15
- focused = true;
16
15
  if (onfocus) {
17
16
  onfocus(eTyped);
18
17
  }
19
18
  }
20
19
  function onblurMod(e) {
21
20
  const eTyped = e;
22
- focused = false;
23
21
  if (onblur) {
24
22
  onblur(eTyped);
25
23
  }
@@ -51,6 +49,7 @@ function ontoggleMod(e) {
51
49
  {id}
52
50
  {disabled}
53
51
  bind:ref
52
+ bind:focused
54
53
  {oninput}
55
54
  {onchange}
56
55
  onfocus={onfocusMod}
@@ -58,6 +57,9 @@ function ontoggleMod(e) {
58
57
  {onpaste}
59
58
  {oncopy}
60
59
  {oncut}
60
+ onkeydown={onkeydown ? (e) => onkeydown(e as TextInputKeyboardEvent) : undefined}
61
+ onkeypress={onkeypress ? (e) => onkeypress(e as TextInputKeyboardEvent) : undefined}
62
+ onkeyup={onkeyup ? (e) => onkeyup(e as TextInputKeyboardEvent) : undefined}
61
63
  {placeholder}
62
64
  bind:value
63
65
  {readonly}
@@ -1,7 +1,7 @@
1
1
  import type { ComponentSize } from '../../../../types/size.js';
2
2
  import type { ComponentRoundness } from '../../../../types/roundness.js';
3
3
  import type { Snippet } from 'svelte';
4
- import type { ChangeEventHandler, ClipboardEventHandler, FocusEventHandler, FormEventHandler } from 'svelte/elements';
4
+ import type { ChangeEventHandler, ClipboardEventHandler, FocusEventHandler, FormEventHandler, KeyboardEventHandler } from 'svelte/elements';
5
5
  export type PasswordInputToggleEvent = {
6
6
  event: Event;
7
7
  toggle: boolean;
@@ -57,6 +57,12 @@ export interface PasswordInputProps {
57
57
  oncut?: ClipboardEventHandler<HTMLInputElement>;
58
58
  /** ontoggle event handler */
59
59
  ontoggle?: (e: PasswordInputToggleEvent) => void;
60
+ /** onkeydown event handler */
61
+ onkeydown?: KeyboardEventHandler<HTMLInputElement>;
62
+ /** onkeypress event handler */
63
+ onkeypress?: KeyboardEventHandler<HTMLInputElement>;
64
+ /** onkeyup event handler */
65
+ onkeyup?: KeyboardEventHandler<HTMLInputElement>;
60
66
  }
61
67
  declare const PasswordInput: import("svelte").Component<PasswordInputProps, {}, "ref" | "value" | "passwordToggleState">;
62
68
  type PasswordInput = ReturnType<typeof PasswordInput>;
@@ -136,3 +136,30 @@ let value = $state(options[0]);
136
136
  },
137
137
  }}
138
138
  />
139
+
140
+ <Story
141
+ name="KeyDown"
142
+ args={{
143
+ onkeydown: (e: DynamicInputKeyboardEvent) => {
144
+ console.log('onkeydown Event', e.key);
145
+ },
146
+ }}
147
+ />
148
+
149
+ <Story
150
+ name="KeyPress"
151
+ args={{
152
+ onkeypress: (e: DynamicInputKeyboardEvent) => {
153
+ console.log('onkeypress Event', e.key);
154
+ },
155
+ }}
156
+ />
157
+
158
+ <Story
159
+ name="KeyUp"
160
+ args={{
161
+ onkeyup: (e: DynamicInputKeyboardEvent) => {
162
+ console.log('onkeyup Event', e.key);
163
+ },
164
+ }}
165
+ />
@@ -5,7 +5,7 @@
5
5
  import UtilityButton from '../../../developer tools/components/UtilityButton/UtilityButton.svelte';
6
6
  import Icon from '@iconify/svelte';
7
7
  import { DynamicInput, DynamicMenu, Popper, } from '../../../../index.js';
8
- let { size = 'normal', roundness = 1, outline = true, name, id, class: className = '', disabled = false, onchange, oninput, onselect, onblur, onfocus, onpaste, oncopy, oncut, before, after, error = false, value, placeholder, ref = $bindable(), readonly = false, searchable = false, clearable = false, onclear, options: optionsRaw, customInputContent: customInputContentInternal, customMenuItemContent: customMenuItemContentInternal, customPopupContent: customPopupContentInternal, customPlaceholderMenuItemContent: customPlaceholderMenuItemContentInternal, customDropdownArrowIcon: customDropdownArrowIconInternal, popupMaxHeight = '300px', paperProps, popperProps, menuProps, menuItemProps, optionsPlaceholder = 'No Options', dropdownArrowPosition = 'after', popupPositionX, popupPositionY, lockPoistions, popperHeightForVerticalPosition, } = $props();
8
+ let { size = 'normal', roundness = 1, outline = true, name, id, class: className = '', disabled = false, onchange, oninput, onselect, onblur, onfocus, onpaste, oncopy, oncut, onkeydown, onkeypress, onkeyup, before, after, error = false, value, placeholder, ref = $bindable(), readonly = false, searchable = false, clearable = false, onclear, options: optionsRaw, customInputContent: customInputContentInternal, customMenuItemContent: customMenuItemContentInternal, customPopupContent: customPopupContentInternal, customPlaceholderMenuItemContent: customPlaceholderMenuItemContentInternal, customDropdownArrowIcon: customDropdownArrowIconInternal, popupMaxHeight = '300px', paperProps, popperProps, menuProps, menuItemProps, optionsPlaceholder = 'No Options', dropdownArrowPosition = 'after', popupPositionX, popupPositionY, lockPoistions, popperHeightForVerticalPosition, } = $props();
9
9
  function convertOptionsToDynamicMenuItemOptions(options) {
10
10
  const newOptions = options.map((option) => ({
11
11
  id: `opt-${option.value}`,
@@ -170,6 +170,9 @@ function onKeyBoardEnter(e, selectedItemIndex) {
170
170
  {onpaste}
171
171
  {oncopy}
172
172
  {oncut}
173
+ {onkeydown}
174
+ {onkeypress}
175
+ {onkeyup}
173
176
  {placeholder}
174
177
  value={searchable ? searchTerm : selectedOption?.label}
175
178
  {readonly}
@@ -1,7 +1,7 @@
1
1
  import type { ComponentSize } from '../../../../types/size.js';
2
2
  import type { ComponentRoundness } from '../../../../types/roundness.js';
3
3
  import type { Snippet } from 'svelte';
4
- import type { ChangeEventHandler, ClipboardEventHandler, FocusEventHandler, FormEventHandler, MouseEventHandler } from 'svelte/elements';
4
+ import type { ChangeEventHandler, ClipboardEventHandler, FocusEventHandler, FormEventHandler, KeyboardEventHandler, MouseEventHandler } from 'svelte/elements';
5
5
  export type SelectOption = {
6
6
  value: string | number | boolean | null | undefined;
7
7
  label: string;
@@ -63,6 +63,12 @@ export interface SelectProps {
63
63
  oncopy?: ClipboardEventHandler<HTMLInputElement>;
64
64
  /** oncut event handler */
65
65
  oncut?: ClipboardEventHandler<HTMLInputElement>;
66
+ /** onkeydown event handler */
67
+ onkeydown?: KeyboardEventHandler<HTMLInputElement | HTMLButtonElement>;
68
+ /** onkeypress event handler */
69
+ onkeypress?: KeyboardEventHandler<HTMLInputElement | HTMLButtonElement>;
70
+ /** onkeyup event handler */
71
+ onkeyup?: KeyboardEventHandler<HTMLInputElement | HTMLButtonElement>;
66
72
  /** custom Content Formatting for variant button */
67
73
  customInputContent?: (val: SelectOption) => Snippet;
68
74
  /** custom Content Formatting for variant button */
@@ -90,3 +90,30 @@ const { Story } = defineMeta({
90
90
  },
91
91
  }}
92
92
  />
93
+
94
+ <Story
95
+ name="KeyDown"
96
+ args={{
97
+ onkeydown: (e: TextInputKeyboardEvent) => {
98
+ console.log('onkeydown Event', e.key);
99
+ },
100
+ }}
101
+ />
102
+
103
+ <Story
104
+ name="KeyPress"
105
+ args={{
106
+ onkeypress: (e: TextInputKeyboardEvent) => {
107
+ console.log('onkeypress Event', e.key);
108
+ },
109
+ }}
110
+ />
111
+
112
+ <Story
113
+ name="KeyUp"
114
+ args={{
115
+ onkeyup: (e: TextInputKeyboardEvent) => {
116
+ console.log('onkeyup Event', e.key);
117
+ },
118
+ }}
119
+ />
@@ -10,18 +10,16 @@
10
10
 
11
11
  <script lang="ts">import InputEnclosure from '../../../developer tools/components/InputEnclosure/InputEnclosure.svelte';
12
12
  import DynamicInput, {} from '../../../developer tools/components/DynamicInput/DynamicInput.svelte';
13
- let { type = 'text', size = 'normal', roundness = 1, outline = true, name, id, class: className = '', disabled = false, oninput, onchange, onblur, onfocus, onpaste, oncopy, oncut, before, after, error = false, value = $bindable(), placeholder, ref = $bindable(), readonly = false, } = $props();
13
+ let { type = 'text', size = 'normal', roundness = 1, outline = true, name, id, class: className = '', disabled = false, oninput, onchange, onblur, onfocus, onpaste, oncopy, oncut, onkeydown, onkeypress, onkeyup, before, after, error = false, value = $bindable(), placeholder, ref = $bindable(), readonly = false, } = $props();
14
14
  let focused = $state(false);
15
15
  function onfocusMod(e) {
16
16
  const eTyped = e;
17
- focused = true;
18
17
  if (onfocus) {
19
18
  onfocus(eTyped);
20
19
  }
21
20
  }
22
21
  function onblurMod(e) {
23
22
  const eTyped = e;
24
- focused = false;
25
23
  if (onblur) {
26
24
  onblur(eTyped);
27
25
  }
@@ -42,6 +40,7 @@ function onblurMod(e) {
42
40
  {id}
43
41
  {disabled}
44
42
  bind:ref
43
+ bind:focused
45
44
  {oninput}
46
45
  {onchange}
47
46
  onfocus={onfocusMod}
@@ -49,6 +48,9 @@ function onblurMod(e) {
49
48
  {onpaste}
50
49
  {oncopy}
51
50
  {oncut}
51
+ onkeydown={onkeydown ? (e) => onkeydown(e as TextInputKeyboardEvent) : undefined}
52
+ onkeypress={onkeypress ? (e) => onkeypress(e as TextInputKeyboardEvent) : undefined}
53
+ onkeyup={onkeyup ? (e) => onkeyup(e as TextInputKeyboardEvent) : undefined}
52
54
  {placeholder}
53
55
  bind:value
54
56
  {readonly}
@@ -1,7 +1,7 @@
1
1
  import type { ComponentRoundness } from '../../../../types/roundness.js';
2
2
  import type { ComponentSize } from '../../../../types/size.js';
3
3
  import type { Snippet } from 'svelte';
4
- import type { ChangeEventHandler, ClipboardEventHandler, FocusEventHandler, FormEventHandler } from 'svelte/elements';
4
+ import type { ChangeEventHandler, ClipboardEventHandler, FocusEventHandler, FormEventHandler, KeyboardEventHandler } from 'svelte/elements';
5
5
  export type TextInputType = 'text' | 'tel' | 'email' | 'password' | 'url' | 'number';
6
6
  export declare const textInputTypeArray: TextInputType[];
7
7
  export type TextInputFocusEvent = FocusEvent & {
@@ -13,6 +13,9 @@ export type TextInputClipboardEvent = ClipboardEvent & {
13
13
  export type TextInputInputEvent = Event & {
14
14
  currentTarget: EventTarget & HTMLInputElement;
15
15
  };
16
+ export type TextInputKeyboardEvent = KeyboardEvent & {
17
+ currentTarget: EventTarget & HTMLInputElement;
18
+ };
16
19
  export interface TextInputProps {
17
20
  /** Input type? */
18
21
  type?: TextInputType;
@@ -58,6 +61,12 @@ export interface TextInputProps {
58
61
  oncopy?: ClipboardEventHandler<HTMLInputElement>;
59
62
  /** oncut event handler */
60
63
  oncut?: ClipboardEventHandler<HTMLInputElement>;
64
+ /** onkeydown event handler */
65
+ onkeydown?: KeyboardEventHandler<HTMLInputElement>;
66
+ /** onkeypress event handler */
67
+ onkeypress?: KeyboardEventHandler<HTMLInputElement>;
68
+ /** onkeyup event handler */
69
+ onkeyup?: KeyboardEventHandler<HTMLInputElement>;
61
70
  }
62
71
  declare const TextInput: import("svelte").Component<TextInputProps, {}, "ref" | "value">;
63
72
  type TextInput = ReturnType<typeof TextInput>;
@@ -36,7 +36,7 @@ function onKeyboardNavigation(e) {
36
36
  }
37
37
  return;
38
38
  }
39
- else if (keyHit === 'Esc') {
39
+ else if (keyHit === 'Escape') {
40
40
  if (onEsc) {
41
41
  onEsc(e, menuItemIndex);
42
42
  }
@@ -3,7 +3,7 @@ export const dynamicInputVariantArray = ['input', 'button'];
3
3
  </script>
4
4
 
5
5
  <script lang="ts">"use strict";
6
- let { type = 'text', name, id, class: className = '', disabled = false, onchange, oninput, onblur, onfocus, onpaste, oncopy, oncut, value = $bindable(), placeholder, ref = $bindable(), readonly = false, variant = 'input', size = 'normal', onclick, customInputContent, } = $props();
6
+ let { type = 'text', name, id, class: className = '', disabled = false, onchange, oninput, onblur, onfocus, onpaste, oncopy, oncut, onkeydown, onkeypress, onkeyup, value = $bindable(), focused = $bindable(), placeholder, ref = $bindable(), readonly = false, variant = 'input', size = 'normal', onclick, customInputContent, } = $props();
7
7
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
8
8
  let customInputContentTyped = customInputContent;
9
9
  function onclickMod(e) {
@@ -14,6 +14,18 @@ function onclickMod(e) {
14
14
  onclick(e);
15
15
  }
16
16
  }
17
+ function onfocusMod(e) {
18
+ focused = true;
19
+ if (onfocus) {
20
+ onfocus(e);
21
+ }
22
+ }
23
+ function onblurMod(e) {
24
+ focused = false;
25
+ if (onblur) {
26
+ onblur(e);
27
+ }
28
+ }
17
29
  </script>
18
30
 
19
31
  {#if variant === 'button'}
@@ -28,8 +40,11 @@ function onclickMod(e) {
28
40
  ].join(' ')}
29
41
  bind:this={ref}
30
42
  onclick={onclickMod}
31
- {onfocus}
32
- {onblur}
43
+ {onkeydown}
44
+ {onkeypress}
45
+ {onkeyup}
46
+ onfocus={onfocusMod}
47
+ onblur={onblurMod}
33
48
  {disabled}
34
49
  >
35
50
  {#if customInputContentTyped}
@@ -47,11 +62,14 @@ function onclickMod(e) {
47
62
  {disabled}
48
63
  {oninput}
49
64
  {onchange}
50
- {onfocus}
51
- {onblur}
65
+ onfocus={onfocusMod}
66
+ onblur={onblurMod}
52
67
  {onpaste}
53
68
  {oncopy}
54
69
  {oncut}
70
+ {onkeydown}
71
+ {onkeypress}
72
+ {onkeyup}
55
73
  {placeholder}
56
74
  bind:value
57
75
  bind:this={ref}
@@ -1,6 +1,6 @@
1
1
  import { type ComponentSize, type TextInputType } from '../../../../index.js';
2
2
  import type { Snippet } from 'svelte';
3
- import type { ChangeEventHandler, ClipboardEventHandler, FocusEventHandler, FormEventHandler, MouseEventHandler } from 'svelte/elements';
3
+ import type { ChangeEventHandler, ClipboardEventHandler, FocusEventHandler, FormEventHandler, KeyboardEventHandler, MouseEventHandler } from 'svelte/elements';
4
4
  export type DynamicInputVariant = 'input' | 'button';
5
5
  export declare const dynamicInputVariantArray: DynamicInputVariant[];
6
6
  export type DynamicInputClickEvent = MouseEvent & {
@@ -9,6 +9,9 @@ export type DynamicInputClickEvent = MouseEvent & {
9
9
  export type DynamicInputFocusEvent = FocusEvent & {
10
10
  currentTarget: EventTarget & (HTMLInputElement | HTMLButtonElement);
11
11
  };
12
+ export type DynamicInputKeyboardEvent = KeyboardEvent & {
13
+ currentTarget: EventTarget & (HTMLInputElement | HTMLButtonElement);
14
+ };
12
15
  export interface DynamicInputProps {
13
16
  /** How large should the button be? */
14
17
  size?: ComponentSize;
@@ -18,6 +21,8 @@ export interface DynamicInputProps {
18
21
  ref?: HTMLInputElement | HTMLButtonElement;
19
22
  /** Input value */
20
23
  value?: string | number;
24
+ /** is focused, set focused */
25
+ focused?: boolean;
21
26
  /** variant */
22
27
  variant?: DynamicInputVariant;
23
28
  /** How round should the border radius be? */
@@ -52,9 +57,15 @@ export interface DynamicInputProps {
52
57
  oncopy?: ClipboardEventHandler<HTMLInputElement>;
53
58
  /** oncut event handler */
54
59
  oncut?: ClipboardEventHandler<HTMLInputElement>;
60
+ /** onkeydown event handler */
61
+ onkeydown?: KeyboardEventHandler<HTMLInputElement | HTMLButtonElement>;
62
+ /** onkeypress event handler */
63
+ onkeypress?: KeyboardEventHandler<HTMLInputElement | HTMLButtonElement>;
64
+ /** onkeyup event handler */
65
+ onkeyup?: KeyboardEventHandler<HTMLInputElement | HTMLButtonElement>;
55
66
  /** custom Content Formatting for variant button */
56
67
  customInputContent?: (value: string | number) => Snippet;
57
68
  }
58
- declare const DynamicInput: import("svelte").Component<DynamicInputProps, {}, "ref" | "value">;
69
+ declare const DynamicInput: import("svelte").Component<DynamicInputProps, {}, "ref" | "focused" | "value">;
59
70
  type DynamicInput = ReturnType<typeof DynamicInput>;
60
71
  export default DynamicInput;
@@ -0,0 +1,115 @@
1
+ <script module lang="ts">import { defineMeta } from '@storybook/addon-svelte-csf';
2
+ import { storyDynamicInputArgTypes } from '../DynamicInput.stories.svelte';
3
+ import DynamicInput, {} from '../DynamicInput.svelte';
4
+ // More on how to set up stories at: https://storybook.js.org/docs/writing-stories
5
+ const { Story } = defineMeta({
6
+ component: DynamicInput,
7
+ tags: ['autodocs'],
8
+ argTypes: storyDynamicInputArgTypes,
9
+ args: { value: 'Hello world!' },
10
+ });
11
+ </script>
12
+
13
+ <Story
14
+ name="Input"
15
+ args={{
16
+ oninput: (e: Event) => {
17
+ const target = e.target as HTMLInputElement;
18
+
19
+ console.log('Input Event', target.value);
20
+ },
21
+ }}
22
+ />
23
+
24
+ <Story
25
+ name="Change"
26
+ args={{
27
+ onchange: (e: Event) => {
28
+ const target = e.target as HTMLInputElement;
29
+
30
+ console.log('onChange Event', target.value);
31
+ },
32
+ }}
33
+ />
34
+
35
+ <Story
36
+ name="Focus"
37
+ args={{
38
+ onfocus: (e: DynamicInputFocusEvent) => {
39
+ const target = e.target as HTMLInputElement;
40
+
41
+ console.log('onfocus Event', target);
42
+ },
43
+ }}
44
+ />
45
+
46
+ <Story
47
+ name="Blur"
48
+ args={{
49
+ onblur: (e: DynamicInputFocusEvent) => {
50
+ const target = e.target as HTMLInputElement;
51
+
52
+ console.log('onblur Event', target);
53
+ },
54
+ }}
55
+ />
56
+
57
+ <Story
58
+ name="Copy"
59
+ args={{
60
+ oncopy: (e: TextInputClipboardEvent) => {
61
+ const target = e.target as HTMLInputElement;
62
+
63
+ console.log('oncopy Event', target);
64
+ },
65
+ }}
66
+ />
67
+
68
+ <Story
69
+ name="Cut"
70
+ args={{
71
+ oncut: (e: TextInputClipboardEvent) => {
72
+ const target = e.target as HTMLInputElement;
73
+
74
+ console.log('oncut Event', target);
75
+ },
76
+ }}
77
+ />
78
+
79
+ <Story
80
+ name="Paste"
81
+ args={{
82
+ onpaste: (e: TextInputClipboardEvent) => {
83
+ const target = e.target as HTMLInputElement;
84
+
85
+ console.log('onpaste Event', target);
86
+ },
87
+ }}
88
+ />
89
+
90
+ <Story
91
+ name="KeyDown"
92
+ args={{
93
+ onkeydown: (e: DynamicInputKeyboardEvent) => {
94
+ console.log('onkeydown Event', e.key);
95
+ },
96
+ }}
97
+ />
98
+
99
+ <Story
100
+ name="KeyPress"
101
+ args={{
102
+ onkeypress: (e: DynamicInputKeyboardEvent) => {
103
+ console.log('onkeypress Event', e.key);
104
+ },
105
+ }}
106
+ />
107
+
108
+ <Story
109
+ name="KeyUp"
110
+ args={{
111
+ onkeyup: (e: DynamicInputKeyboardEvent) => {
112
+ console.log('onkeyup Event', e.key);
113
+ },
114
+ }}
115
+ />
@@ -0,0 +1,18 @@
1
+ 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> {
2
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
3
+ $$bindings?: Bindings;
4
+ } & Exports;
5
+ (internal: unknown, props: {
6
+ $$events?: Events;
7
+ $$slots?: Slots;
8
+ }): Exports & {
9
+ $set?: any;
10
+ $on?: any;
11
+ };
12
+ z_$$bindings?: Bindings;
13
+ }
14
+ declare const Events: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
15
+ [evt: string]: CustomEvent<any>;
16
+ }, {}, {}, string>;
17
+ type Events = InstanceType<typeof Events>;
18
+ export default Events;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Cleans the input string by removing all characters except numeric digits (0-9) and a single decimal point.
3
+ * Only the first decimal point is retained; all subsequent dots are removed.
4
+ *
5
+ * @param {string} input - The input string to be cleaned.
6
+ * @returns {string} - A string containing only digits and at most one decimal point.
7
+ *
8
+ * @example
9
+ * cleanNumericString("abc123.45.67def"); // returns "123.4567"
10
+ * cleanNumericString("a1b2c3"); // returns "123"
11
+ * cleanNumericString("...12.3.4..5"); // returns "12.345"
12
+ */
13
+ export default function cleanNumericString(input: string): string;
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Cleans the input string by removing all characters except numeric digits (0-9) and a single decimal point.
3
+ * Only the first decimal point is retained; all subsequent dots are removed.
4
+ *
5
+ * @param {string} input - The input string to be cleaned.
6
+ * @returns {string} - A string containing only digits and at most one decimal point.
7
+ *
8
+ * @example
9
+ * cleanNumericString("abc123.45.67def"); // returns "123.4567"
10
+ * cleanNumericString("a1b2c3"); // returns "123"
11
+ * cleanNumericString("...12.3.4..5"); // returns "12.345"
12
+ */
13
+ export default function cleanNumericString(input) {
14
+ // Remove all characters except digits and dots
15
+ const filtered = input.replace(/[^0-9.]/g, '');
16
+ // Split by dot to separate parts
17
+ const parts = filtered.split('.');
18
+ if (parts.length === 1) {
19
+ // No dot present, just digits
20
+ return parts[0];
21
+ }
22
+ else {
23
+ // Keep only first dot, join the rest parts without dots
24
+ return parts[0] + '.' + parts.slice(1).join('');
25
+ }
26
+ }
@@ -0,0 +1,20 @@
1
+ import { Source } from '@storybook/blocks';
2
+
3
+ # cleanNumericString
4
+
5
+ Cleans the input string by removing all characters except numeric digits (0-9) and a single decimal point.
6
+ Only the first decimal point is retained; all subsequent dots are removed.
7
+
8
+ ---
9
+
10
+ ## Basic Usage
11
+
12
+ <Source
13
+ dark
14
+ language="ts"
15
+ code={`
16
+ import { cleanNumericString } from '@flightlesslabs/dodo-ui';
17
+
18
+ const result = cleanNumericString("abc123.45.67def"); // result === "123.4567"
19
+ `}
20
+ />