@streamscloud/kit 0.2.1 → 0.2.3

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 (107) hide show
  1. package/dist/styles/_input.scss +98 -0
  2. package/dist/styles/_mixins.scss +2 -2
  3. package/dist/styles/reset.css +1 -1
  4. package/dist/ui/button/resources/button-base.svelte +2 -2
  5. package/dist/ui/button/resources/button-theme.svelte +18 -15
  6. package/dist/ui/color-picker/cmp.color-picker.svelte +3 -12
  7. package/dist/ui/color-picker/cmp.color-picker.svelte.d.ts +3 -9
  8. package/dist/ui/cropper/img-cropper/cmp.img-cropper-toolbar.svelte +1 -1
  9. package/dist/ui/dialog/cmp.dialog.svelte +1 -1
  10. package/dist/ui/dropdown/cmp.dropdown-item.svelte +93 -0
  11. package/dist/ui/dropdown/cmp.dropdown-item.svelte.d.ts +32 -0
  12. package/dist/ui/dropdown/cmp.dropdown-panel.svelte +29 -0
  13. package/dist/ui/dropdown/cmp.dropdown-panel.svelte.d.ts +18 -0
  14. package/dist/ui/dropdown/cmp.dropdown.svelte +72 -7
  15. package/dist/ui/dropdown/cmp.dropdown.svelte.d.ts +3 -1
  16. package/dist/ui/dropdown/index.d.ts +2 -0
  17. package/dist/ui/dropdown/index.js +2 -0
  18. package/dist/ui/dynamic-component/cmp.dynamic-component.svelte +0 -5
  19. package/dist/ui/dynamic-component/cmp.dynamic-component.svelte.d.ts +2 -8
  20. package/dist/ui/emoji-picker/cmp.emoji-panel.svelte +186 -0
  21. package/dist/ui/emoji-picker/cmp.emoji-panel.svelte.d.ts +21 -0
  22. package/dist/ui/emoji-picker/cmp.emoji-picker.svelte +35 -0
  23. package/dist/ui/emoji-picker/cmp.emoji-picker.svelte.d.ts +15 -0
  24. package/dist/ui/emoji-picker/emoji-list.d.ts +2 -0
  25. package/dist/ui/emoji-picker/emoji-list.js +1754 -0
  26. package/dist/ui/emoji-picker/emoji-picker-localization.d.ts +5 -0
  27. package/dist/ui/emoji-picker/emoji-picker-localization.js +40 -0
  28. package/dist/ui/emoji-picker/index.d.ts +2 -0
  29. package/dist/ui/emoji-picker/index.js +2 -0
  30. package/dist/ui/emoji-picker/types.d.ts +8 -0
  31. package/dist/ui/emoji-picker/types.js +1 -0
  32. package/dist/ui/form-group/cmp.form-group-label.svelte.d.ts +1 -0
  33. package/dist/ui/form-group/cmp.form-group.svelte.d.ts +1 -0
  34. package/dist/ui/icon-text/cmp.icon-text.svelte +34 -22
  35. package/dist/ui/icon-text/cmp.icon-text.svelte.d.ts +14 -13
  36. package/dist/ui/inputs/index.d.ts +6 -0
  37. package/dist/ui/inputs/index.js +5 -0
  38. package/dist/ui/inputs/input/cmp.input-validatable.svelte +57 -0
  39. package/dist/ui/inputs/input/cmp.input-validatable.svelte.d.ts +56 -0
  40. package/dist/ui/inputs/input/cmp.input.svelte +235 -0
  41. package/dist/ui/inputs/input/cmp.input.svelte.d.ts +60 -0
  42. package/dist/ui/inputs/input/index.d.ts +2 -0
  43. package/dist/ui/inputs/input/index.js +2 -0
  44. package/dist/ui/inputs/input-emoji-picker/cmp.input-emoji-picker.svelte +44 -0
  45. package/dist/ui/inputs/input-emoji-picker/cmp.input-emoji-picker.svelte.d.ts +9 -0
  46. package/dist/ui/inputs/input-emoji-picker/index.d.ts +2 -0
  47. package/dist/ui/inputs/input-emoji-picker/index.js +2 -0
  48. package/dist/ui/inputs/input-emoji-picker/input-emoji-picker-container.d.ts +2 -0
  49. package/dist/ui/inputs/input-emoji-picker/input-emoji-picker-container.js +16 -0
  50. package/dist/ui/inputs/numeral-input/cmp.numeral-input-validatable.svelte +55 -0
  51. package/dist/ui/inputs/numeral-input/cmp.numeral-input-validatable.svelte.d.ts +62 -0
  52. package/dist/ui/inputs/numeral-input/cmp.numeral-input.svelte +248 -0
  53. package/dist/ui/inputs/numeral-input/cmp.numeral-input.svelte.d.ts +66 -0
  54. package/dist/ui/inputs/numeral-input/index.d.ts +2 -0
  55. package/dist/ui/inputs/numeral-input/index.js +2 -0
  56. package/dist/ui/inputs/pin-input/cmp.pin-input.svelte +58 -0
  57. package/dist/ui/inputs/pin-input/cmp.pin-input.svelte.d.ts +23 -0
  58. package/dist/ui/inputs/pin-input/index.d.ts +1 -0
  59. package/dist/ui/inputs/pin-input/index.js +1 -0
  60. package/dist/ui/inputs/pin-input/pin-input-generator.d.ts +27 -0
  61. package/dist/ui/inputs/pin-input/pin-input-generator.js +114 -0
  62. package/dist/ui/inputs/rich-text-input/cmp.rich-text-input.svelte +55 -0
  63. package/dist/ui/inputs/rich-text-input/cmp.rich-text-input.svelte.d.ts +43 -0
  64. package/dist/ui/inputs/rich-text-input/index.d.ts +2 -0
  65. package/dist/ui/inputs/rich-text-input/index.js +1 -0
  66. package/dist/ui/inputs/rich-text-input/rich-text-input-localization.d.ts +12 -0
  67. package/dist/ui/inputs/rich-text-input/rich-text-input-localization.js +48 -0
  68. package/dist/ui/inputs/rich-text-input/tinymce-input.svelte +250 -0
  69. package/dist/ui/inputs/rich-text-input/tinymce-input.svelte.d.ts +25 -0
  70. package/dist/ui/inputs/rich-text-input/tinymce.declarations.d.ts +7 -0
  71. package/dist/ui/inputs/rich-text-input/types.d.ts +4 -0
  72. package/dist/ui/inputs/rich-text-input/types.js +1 -0
  73. package/dist/ui/inputs/rich-text-input/validated-link-button.d.ts +3 -0
  74. package/dist/ui/inputs/rich-text-input/validated-link-button.js +78 -0
  75. package/dist/ui/inputs/textarea/cmp.textarea-validatable.svelte +35 -0
  76. package/dist/ui/inputs/textarea/cmp.textarea-validatable.svelte.d.ts +53 -0
  77. package/dist/ui/inputs/textarea/cmp.textarea.svelte +247 -0
  78. package/dist/ui/inputs/textarea/cmp.textarea.svelte.d.ts +57 -0
  79. package/dist/ui/inputs/textarea/index.d.ts +2 -0
  80. package/dist/ui/inputs/textarea/index.js +2 -0
  81. package/dist/ui/media-viewer-dialog/cmp.media-viewer-dialog.svelte.d.ts +2 -0
  82. package/dist/ui/selects/_multiselect.scss +282 -0
  83. package/dist/ui/selects/_singleselect.scss +175 -0
  84. package/dist/ui/selects/cmp.multiselect.svelte +530 -0
  85. package/dist/ui/selects/cmp.multiselect.svelte.d.ts +85 -0
  86. package/dist/ui/selects/cmp.search-multiselect.svelte +532 -0
  87. package/dist/ui/selects/cmp.search-multiselect.svelte.d.ts +67 -0
  88. package/dist/ui/selects/cmp.singleselect.svelte +381 -0
  89. package/dist/ui/selects/cmp.singleselect.svelte.d.ts +78 -0
  90. package/dist/ui/selects/index.d.ts +5 -0
  91. package/dist/ui/selects/index.js +4 -0
  92. package/dist/ui/selects/select-localization.d.ts +6 -0
  93. package/dist/ui/selects/select-localization.js +27 -0
  94. package/dist/ui/selects/types.d.ts +29 -0
  95. package/dist/ui/selects/types.js +1 -0
  96. package/dist/ui/time-ago/cmp.time-ago.svelte +0 -6
  97. package/dist/ui/time-ago/cmp.time-ago.svelte.d.ts +2 -6
  98. package/dist/ui/validatable/_validatable.scss +34 -0
  99. package/dist/ui/validatable/cmp.validatable.svelte +57 -0
  100. package/dist/ui/validatable/cmp.validatable.svelte.d.ts +49 -0
  101. package/dist/ui/validatable/cmp.validation-error.svelte +52 -0
  102. package/dist/ui/validatable/cmp.validation-error.svelte.d.ts +42 -0
  103. package/dist/ui/validatable/index.d.ts +2 -0
  104. package/dist/ui/validatable/index.js +2 -0
  105. package/package.json +31 -5
  106. package/dist/ui/color-picker/cmp.input-stub.svelte +0 -98
  107. package/dist/ui/color-picker/cmp.input-stub.svelte.d.ts +0 -40
@@ -0,0 +1,2 @@
1
+ export { default as Input } from './cmp.input.svelte';
2
+ export { default as InputValidatable } from './cmp.input-validatable.svelte';
@@ -0,0 +1,44 @@
1
+ <script lang="ts">import { Dropdown } from '../../dropdown';
2
+ import { EmojiPanel } from '../../emoji-picker';
3
+ import { Icon } from '../../icon';
4
+ import IconEmoji from '@fluentui/svg-icons/icons/emoji_20_regular.svg?raw';
5
+ let toggleDropdown = $state();
6
+ let { on } = $props();
7
+ </script>
8
+
9
+ <button type="button" class="input-emoji-picker-trigger" onclick={() => toggleDropdown?.()}>
10
+ <Icon src={IconEmoji} />
11
+ </button>
12
+
13
+ <div class="input-emoji-picker">
14
+ <Dropdown position="bottom-end" matchTriggerWidth on={{ mounted: (e) => (toggleDropdown = e.toggleOpen) }} keepDropdownOpen={true}>
15
+ {#snippet trigger()}
16
+ <div class="input-emoji-picker__trigger-stub"></div>
17
+ {/snippet}
18
+ <EmojiPanel on={{ select: on.select }} />
19
+ </Dropdown>
20
+ </div>
21
+
22
+ <!--
23
+ @component
24
+ Emoji picker dropdown with trigger icon. Wraps EmojiPanel in a Dropdown for positioning.
25
+ -->
26
+
27
+ <style>.input-emoji-picker-trigger {
28
+ --_input-emoji-picker--trigger--opacity: var(--input-emoji-picker--trigger--opacity, 0);
29
+ --sc-kit--icon--size: 1em;
30
+ --sc-kit--icon--color: light-dark(#9ca3af, #6b7280);
31
+ opacity: var(--_input-emoji-picker--trigger--opacity);
32
+ position: absolute;
33
+ right: 0.25rem;
34
+ bottom: 0.25rem;
35
+ transition: opacity 150ms cubic-bezier(0.4, 0, 0.2, 1);
36
+ }
37
+
38
+ .input-emoji-picker {
39
+ --sc-kit--dropdown--width: 100%;
40
+ position: absolute;
41
+ bottom: 0;
42
+ left: 0;
43
+ right: 0;
44
+ }</style>
@@ -0,0 +1,9 @@
1
+ type Props = {
2
+ on: {
3
+ select: (value: string) => void;
4
+ };
5
+ };
6
+ /** Emoji picker dropdown with trigger icon. Wraps EmojiPanel in a Dropdown for positioning. */
7
+ declare const Cmp: import("svelte").Component<Props, {}, "">;
8
+ type Cmp = ReturnType<typeof Cmp>;
9
+ export default Cmp;
@@ -0,0 +1,2 @@
1
+ export { default as InputEmojiPicker } from './cmp.input-emoji-picker.svelte';
2
+ export { inputEmojiPickerContainer } from './input-emoji-picker-container';
@@ -0,0 +1,2 @@
1
+ export { default as InputEmojiPicker } from './cmp.input-emoji-picker.svelte';
2
+ export { inputEmojiPickerContainer } from './input-emoji-picker-container';
@@ -0,0 +1,2 @@
1
+ import type { Action } from 'svelte/action';
2
+ export declare const inputEmojiPickerContainer: Action;
@@ -0,0 +1,16 @@
1
+ export const inputEmojiPickerContainer = (node) => {
2
+ const handleHover = () => {
3
+ node.style.setProperty('--input-emoji-picker--trigger--opacity', '1');
4
+ };
5
+ const handleHoverOut = () => {
6
+ node.style.setProperty('--input-emoji-picker--trigger--opacity', '');
7
+ };
8
+ node.addEventListener('mouseenter', handleHover);
9
+ node.addEventListener('mouseleave', handleHoverOut);
10
+ return {
11
+ destroy() {
12
+ node.removeEventListener('mouseenter', handleHover);
13
+ node.removeEventListener('mouseleave', handleHoverOut);
14
+ }
15
+ };
16
+ };
@@ -0,0 +1,55 @@
1
+ <script lang="ts" generics="T extends Record<string, unknown>">import { Utils } from '../../../core/utils';
2
+ import { FormValidationHandler } from '../../../core/validation';
3
+ import { Validatable } from '../../validatable';
4
+ import { default as NumeralInput } from './cmp.numeral-input.svelte';
5
+ let { name, handler, id = undefined, debounce = 0, disabled = false, autofocus = false, placeholder = '', min = null, max = null, numeralDecimalScale = 2, clearable = false, validateOnChange = false, validateAsString = false, on, icon, clearButton } = $props();
6
+ const validateValue = (value) => {
7
+ const valueToValidate = validateAsString ? value.toString() : value;
8
+ handler.updateValidateField(name, valueToValidate);
9
+ };
10
+ const onInput = (value) => {
11
+ if (!validateOnChange) {
12
+ validateValue(value);
13
+ }
14
+ on?.input?.(value);
15
+ };
16
+ const onChange = (value) => {
17
+ if (validateOnChange) {
18
+ validateValue(value);
19
+ }
20
+ on?.change?.(value);
21
+ };
22
+ const onBlur = (value) => {
23
+ validateValue(value);
24
+ };
25
+ const handleInputDebounced = $derived(debounce ? Utils.debounce(onInput, debounce) : onInput);
26
+ const handleChangeDebounced = $derived(debounce ? Utils.debounce(onChange, debounce) : onChange);
27
+ </script>
28
+
29
+ <Validatable handler={handler} name={name}>
30
+ <NumeralInput
31
+ value={handler.form[name] as string | number | null | undefined}
32
+ name={name}
33
+ id={id}
34
+ autofocus={autofocus}
35
+ disabled={disabled}
36
+ placeholder={placeholder}
37
+ min={min}
38
+ max={max}
39
+ numeralDecimalScale={numeralDecimalScale}
40
+ clearable={clearable}
41
+ title={!!handler.touched[name] && !!handler.errors[name] ? handler.errors[name] : ''}
42
+ on={{
43
+ input: handleInputDebounced,
44
+ change: handleChangeDebounced,
45
+ mounted: (e) => on?.mounted?.(e),
46
+ blur: onBlur
47
+ }}
48
+ icon={icon}
49
+ clearButton={clearButton} />
50
+ </Validatable>
51
+
52
+ <!--
53
+ @component
54
+ Numeral input wrapped with form validation. Validates on input or change based on `validateOnChange` prop.
55
+ -->
@@ -0,0 +1,62 @@
1
+ import { FormValidationHandler } from '../../../core/validation';
2
+ import type { Snippet } from 'svelte';
3
+ declare function $$render<T extends Record<string, unknown>>(): {
4
+ props: {
5
+ /** Field name in the form handler */
6
+ name: keyof T & string;
7
+ /** Form validation handler instance */
8
+ handler: FormValidationHandler<T>;
9
+ id?: string;
10
+ /** Debounce delay in ms for input/change handlers @default 0 */
11
+ debounce?: number;
12
+ disabled?: boolean;
13
+ autofocus?: boolean;
14
+ placeholder?: string;
15
+ /** Minimum allowed value */
16
+ min?: string | number | null;
17
+ /** Maximum allowed value */
18
+ max?: string | number | null;
19
+ /** Number of decimal places @default 2 */
20
+ numeralDecimalScale?: number;
21
+ /** Show clear button when value is present */
22
+ clearable?: boolean;
23
+ /** Validate on change event instead of input @default false */
24
+ validateOnChange?: boolean;
25
+ /** Pass numeric value as string to the validator @default false */
26
+ validateAsString?: boolean;
27
+ on?: {
28
+ input?: (value: number) => void;
29
+ change?: (value: number) => void;
30
+ /** Fires after mount, provides the input element ref */
31
+ mounted?: (data: {
32
+ input: HTMLInputElement;
33
+ }) => void;
34
+ };
35
+ /** Left icon snippet */
36
+ icon?: Snippet;
37
+ /** Custom clear button snippet */
38
+ clearButton?: Snippet;
39
+ };
40
+ exports: {};
41
+ bindings: "";
42
+ slots: {};
43
+ events: {};
44
+ };
45
+ declare class __sveltets_Render<T extends Record<string, unknown>> {
46
+ props(): ReturnType<typeof $$render<T>>['props'];
47
+ events(): ReturnType<typeof $$render<T>>['events'];
48
+ slots(): ReturnType<typeof $$render<T>>['slots'];
49
+ bindings(): "";
50
+ exports(): {};
51
+ }
52
+ interface $$IsomorphicComponent {
53
+ new <T extends Record<string, unknown>>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<T>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<T>['props']>, ReturnType<__sveltets_Render<T>['events']>, ReturnType<__sveltets_Render<T>['slots']>> & {
54
+ $$bindings?: ReturnType<__sveltets_Render<T>['bindings']>;
55
+ } & ReturnType<__sveltets_Render<T>['exports']>;
56
+ <T extends Record<string, unknown>>(internal: unknown, props: ReturnType<__sveltets_Render<T>['props']> & {}): ReturnType<__sveltets_Render<T>['exports']>;
57
+ z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
58
+ }
59
+ /** Numeral input wrapped with form validation. Validates on input or change based on `validateOnChange` prop. */
60
+ declare const Cmp: $$IsomorphicComponent;
61
+ type Cmp<T extends Record<string, unknown>> = InstanceType<typeof Cmp<T>>;
62
+ export default Cmp;
@@ -0,0 +1,248 @@
1
+ <script lang="ts">import { Icon } from '../../icon';
2
+ import IconDismiss from '@fluentui/svg-icons/icons/dismiss_20_regular.svg?raw';
3
+ import { formatNumeral, NumeralThousandGroupStyles, registerCursorTracker } from 'cleave-zen';
4
+ let { value, name = '', id = null, placeholder = '', disabled = false, inert = false, autofocus = false, clearable = false, borderless = false, title = '', min = null, max = null, numeralDecimalScale = 2, on, icon, clearButton } = $props();
5
+ let inputRef = $state(undefined);
6
+ const formatNumeralOptions = $derived({
7
+ delimiter: ' ',
8
+ numeralDecimalScale,
9
+ numeralThousandsGroupStyle: NumeralThousandGroupStyles.THOUSAND,
10
+ numeralIntegerScale: 14
11
+ });
12
+ const valueParsed = $derived(formatNumeral(value?.toString() ?? '', formatNumeralOptions));
13
+ const initInput = (node) => {
14
+ inputRef = node;
15
+ if (autofocus) {
16
+ node.focus();
17
+ }
18
+ registerCursorTracker({ input: node, delimiter: formatNumeralOptions.delimiter, delimiters: [] });
19
+ on?.mounted?.({ input: node });
20
+ };
21
+ const clearButtonVisible = $derived(!disabled && clearable && !!value);
22
+ const getNumericValue = () => {
23
+ if (!inputRef) {
24
+ return 0;
25
+ }
26
+ try {
27
+ let valueFormatted = formatNumeral(inputRef.value.replace(/,/, '.'), formatNumeralOptions);
28
+ if (!valueFormatted) {
29
+ valueFormatted = '0';
30
+ }
31
+ let numericValue = parseFloat(valueFormatted.replace(/\s/g, ''));
32
+ if (min !== null && numericValue < Number(min)) {
33
+ numericValue = Number(min);
34
+ valueFormatted = formatNumeral(numericValue.toString(), formatNumeralOptions);
35
+ }
36
+ if (max !== null && numericValue > Number(max)) {
37
+ numericValue = Number(max);
38
+ valueFormatted = formatNumeral(numericValue.toString(), formatNumeralOptions);
39
+ }
40
+ inputRef.value = valueFormatted;
41
+ return isNaN(numericValue) ? 0 : numericValue;
42
+ }
43
+ catch {
44
+ inputRef.value = '0';
45
+ return 0;
46
+ }
47
+ };
48
+ const onInput = () => {
49
+ on?.input?.(getNumericValue());
50
+ };
51
+ const onChange = () => {
52
+ on?.change?.(getNumericValue());
53
+ };
54
+ const clearValue = (e) => {
55
+ e.preventDefault();
56
+ if (!inputRef) {
57
+ return;
58
+ }
59
+ inputRef.value = '';
60
+ on?.input?.(0);
61
+ on?.change?.(0);
62
+ inputRef.focus();
63
+ };
64
+ const focusInput = () => {
65
+ inputRef?.focus();
66
+ };
67
+ const onBlur = () => {
68
+ const numericValue = getNumericValue();
69
+ if (inputRef) {
70
+ inputRef.value = valueParsed;
71
+ }
72
+ on?.blur?.(numericValue);
73
+ };
74
+ </script>
75
+
76
+ <div
77
+ class="numeral-input"
78
+ class:numeral-input--disabled={disabled}
79
+ class:numeral-input--inert={inert}
80
+ class:numeral-input--borderless={borderless}
81
+ onclick={focusInput}
82
+ onkeydown={() => ({})}
83
+ role="none">
84
+ {#if icon}
85
+ <div class="numeral-input__icon">
86
+ {@render icon()}
87
+ </div>
88
+ {/if}
89
+ <input
90
+ use:initInput
91
+ inert={inert}
92
+ type="text"
93
+ name={name}
94
+ id={id}
95
+ placeholder={placeholder}
96
+ class="numeral-input__input"
97
+ value={valueParsed}
98
+ disabled={disabled}
99
+ title={title}
100
+ oninput={onInput}
101
+ onchange={onChange}
102
+ onblur={() => onBlur()}
103
+ onfocus={() => on?.focus?.()} />
104
+ {#if clearButtonVisible || clearButton}
105
+ <div class="numeral-input__clear-wrapper">
106
+ {#if clearButton}
107
+ {@render clearButton()}
108
+ {:else}
109
+ <button type="button" class="numeral-input__clear-button" onclick={clearValue}>
110
+ <Icon src={IconDismiss} />
111
+ </button>
112
+ {/if}
113
+ </div>
114
+ {/if}
115
+ </div>
116
+
117
+ <!--
118
+ @component
119
+ Formatted numeral input with thousand separators, decimal scale, and min/max clamping.
120
+ Uses cleave-zen for formatting and cursor tracking.
121
+
122
+ ### CSS Custom Properties
123
+ | Property | Description | Default |
124
+ |---|---|---|
125
+ | `--sc-kit--input--root--font-size` | Root font size for em scaling | `1rem` |
126
+ | `--sc-kit--input--height` | Container height | `2em` |
127
+ | `--sc-kit--input--width` | Container width | `100%` |
128
+ | `--sc-kit--input--padding--block` | Block (vertical) padding | `0` |
129
+ | `--sc-kit--input--padding--inline` | Inline (horizontal) padding | `0.5em` |
130
+ | `--sc-kit--input--accent-color` | Focus accent color | light-dark primary-500/primary-400 |
131
+ | `--sc-kit--input--background` | Background color | light-dark white/gray-900 |
132
+ | `--sc-kit--input--background--disabled` | Disabled background | light-dark neutral-50/neutral-800 |
133
+ | `--sc-kit--input--border-color` | Border color | light-dark neutral-300/neutral-600 |
134
+ | `--sc-kit--input--border-radius` | Border radius | `0.25em` |
135
+ | `--sc-kit--input--text--font-size` | Text font size | `0.875em` |
136
+ | `--sc-kit--input--text--color` | Text color | light-dark gray-800/white |
137
+ | `--sc-kit--input--placeholder--color` | Placeholder text color | inherited from border |
138
+ | `--sc-kit--input--icon--size` | Icon size | `1em` |
139
+ | `--sc-kit--input--icon--color` | Icon color | inherited from border |
140
+ | `--sc-kit--input--cursor--inert` | Cursor when inert | `default` |
141
+ -->
142
+
143
+ <style>.numeral-input {
144
+ --_--input--root--font-size: var(--sc-kit--input--root--font-size);
145
+ --_--input--height: var(--sc-kit--input--height);
146
+ --_--input--width: var(--sc-kit--input--width);
147
+ --_--input--background: var(--sc-kit--input--background);
148
+ --_--input--background--disabled: var(--sc-kit--input--background--disabled);
149
+ --_--input--border-color: var(--sc-kit--input--border-color);
150
+ --_--input--border-radius: var(--sc-kit--input--border-radius);
151
+ --_--input--icon--size: var(--sc-kit--input--icon--size);
152
+ --_--input--icon--color: var(--sc-kit--input--icon--color);
153
+ --_--input--text--font-size: var(--sc-kit--input--text--font-size);
154
+ --_--input--text--color: var(--sc-kit--input--text--color);
155
+ --_--input--placeholder--color: var(--sc-kit--input--placeholder--color);
156
+ --_--input--accent-color: var(--sc-kit--input--accent-color);
157
+ --_--input--padding--inline: var(--sc-kit--input--padding--inline);
158
+ --_--input--padding--block: var(--sc-kit--input--padding--block);
159
+ --_input--cursor--inert: var(--sc-kit--input--cursor--inert);
160
+ --_input--root--font-size: var(--_--input--root--font-size, 1rem);
161
+ --_input--height: var(--_--input--height, 2em);
162
+ --_input--width: var(--_--input--width, 100%);
163
+ --_input--background: var(--_--input--background, light-dark(#ffffff, #1c1c1c));
164
+ --_input--background--disabled: var(--_--input--background--disabled, light-dark(#f9fafb, #1f2937));
165
+ --_input--border-color: var(--_--input--border-color, light-dark(#d1d5db, #4b5563));
166
+ --_input--border-radius: var(--_--input--border-radius, 0.25em);
167
+ --_input--icon--size: var(--_--input--icon--size, 1em);
168
+ --_input--icon--color: var(--_--input--icon--color, var(--_input--border-color));
169
+ --_input--text--font-size: var(--_--input--text--font-size, 0.875em);
170
+ --_input--text--color: var(--_--input--text--color, light-dark(#2e2e2e, #ffffff));
171
+ --_input--placeholder--color: var(--_--input--placeholder--color, var(--_input--border-color));
172
+ --_input--accent-color: var(--_--input--accent-color, light-dark(#144ab0, #5a8dec));
173
+ --_input--padding--inline: var(--_--input--padding--inline, 0.5em);
174
+ --_input--padding--block: var(--_--input--padding--block, 0);
175
+ --_input--padding-top: var(--_--input--padding-top, var(--_input--padding--block));
176
+ --_input--padding-right: var(--_--input--padding-right, var(--_input--padding--inline));
177
+ --_input--padding-bottom: var(--_--input--padding-bottom, var(--_input--padding--block));
178
+ --_input--padding-left: var(--_--input--padding-left, var(--_input--padding--inline));
179
+ font-size: var(--_input--root--font-size);
180
+ height: var(--_input--height);
181
+ color: var(--_input--text--color);
182
+ border: 1px solid var(--_input--border-color);
183
+ border-radius: var(--_input--border-radius);
184
+ width: var(--_input--width);
185
+ min-width: var(--_input--width);
186
+ background: var(--_input--background);
187
+ padding-top: var(--_input--padding-top);
188
+ padding-right: var(--_input--padding-right);
189
+ padding-bottom: var(--_input--padding-bottom);
190
+ padding-left: var(--_input--padding-left);
191
+ --_input--default-shadow-color: transparent;
192
+ --_input--accent-shadow: var(--_input--explicit-shadow-color, var(--_input--default-shadow-color));
193
+ position: relative;
194
+ box-shadow: inset 0 -0.13em var(--_input--accent-shadow);
195
+ transition: box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1);
196
+ }
197
+ .numeral-input:focus, .numeral-input:focus-within {
198
+ --_input--default-shadow-color: var(--_input--accent-color);
199
+ }
200
+ .numeral-input--disabled {
201
+ background-color: var(--_input--background--disabled);
202
+ cursor: default;
203
+ }
204
+ .numeral-input {
205
+ display: flex;
206
+ align-items: center;
207
+ cursor: text;
208
+ }
209
+ .numeral-input--inert {
210
+ cursor: var(--_input--cursor--inert);
211
+ }
212
+ .numeral-input--borderless {
213
+ --_input--border-color: transparent;
214
+ --_input--background: transparent;
215
+ --_input--background--disabled: transparent;
216
+ --_input--accent-color: transparent;
217
+ --_input--explicit-shadow-color: transparent;
218
+ --_input--height: auto;
219
+ }
220
+ .numeral-input__input {
221
+ flex: 1;
222
+ height: 100%;
223
+ padding: 0;
224
+ background-color: transparent !important;
225
+ font-size: var(--_input--text--font-size);
226
+ color: var(--_input--text--color);
227
+ }
228
+ .numeral-input__input::placeholder {
229
+ color: var(--_input--placeholder--color);
230
+ }
231
+ .numeral-input__input:-webkit-autofill {
232
+ -webkit-text-fill-color: var(--_input--text--color) !important;
233
+ }
234
+ .numeral-input__icon {
235
+ margin-right: 0.625em;
236
+ color: var(--_input--icon--color);
237
+ font-size: var(--_input--icon--size);
238
+ }
239
+ :global(.numeral-input__icon:not(:has(*))) {
240
+ margin-right: 0 !important;
241
+ }
242
+ .numeral-input__clear-wrapper {
243
+ color: var(--_input--icon--color);
244
+ font-size: var(--_input--icon--size);
245
+ }
246
+ .numeral-input__clear-button {
247
+ margin-left: 0.625em;
248
+ }</style>
@@ -0,0 +1,66 @@
1
+ import type { Snippet } from 'svelte';
2
+ type Props = {
3
+ value: string | number | null | undefined;
4
+ name?: string;
5
+ id?: string | null;
6
+ placeholder?: string;
7
+ disabled?: boolean;
8
+ /** Make input non-interactive (visual display only) */
9
+ inert?: boolean;
10
+ autofocus?: boolean;
11
+ /** Show clear button when value is present */
12
+ clearable?: boolean;
13
+ /** Remove border, background, and accent shadow */
14
+ borderless?: boolean;
15
+ title?: string;
16
+ /** Minimum allowed value */
17
+ min?: string | number | null;
18
+ /** Maximum allowed value */
19
+ max?: string | number | null;
20
+ /** Number of decimal places @default 2 */
21
+ numeralDecimalScale?: number;
22
+ on: {
23
+ /** Fires on input with the parsed numeric value */
24
+ input?: (value: number) => void;
25
+ /** Fires on change with the parsed numeric value */
26
+ change?: (value: number) => void;
27
+ /** Fires after mount, provides the input element ref */
28
+ mounted?: (data: {
29
+ input: HTMLInputElement;
30
+ }) => void;
31
+ /** Fires on blur with the parsed numeric value */
32
+ blur?: (value: number) => void;
33
+ focus?: () => void;
34
+ };
35
+ /** Left icon snippet */
36
+ icon?: Snippet;
37
+ /** Custom clear button snippet */
38
+ clearButton?: Snippet;
39
+ };
40
+ /**
41
+ * Formatted numeral input with thousand separators, decimal scale, and min/max clamping.
42
+ * Uses cleave-zen for formatting and cursor tracking.
43
+ *
44
+ * ### CSS Custom Properties
45
+ * | Property | Description | Default |
46
+ * |---|---|---|
47
+ * | `--sc-kit--input--root--font-size` | Root font size for em scaling | `1rem` |
48
+ * | `--sc-kit--input--height` | Container height | `2em` |
49
+ * | `--sc-kit--input--width` | Container width | `100%` |
50
+ * | `--sc-kit--input--padding--block` | Block (vertical) padding | `0` |
51
+ * | `--sc-kit--input--padding--inline` | Inline (horizontal) padding | `0.5em` |
52
+ * | `--sc-kit--input--accent-color` | Focus accent color | light-dark primary-500/primary-400 |
53
+ * | `--sc-kit--input--background` | Background color | light-dark white/gray-900 |
54
+ * | `--sc-kit--input--background--disabled` | Disabled background | light-dark neutral-50/neutral-800 |
55
+ * | `--sc-kit--input--border-color` | Border color | light-dark neutral-300/neutral-600 |
56
+ * | `--sc-kit--input--border-radius` | Border radius | `0.25em` |
57
+ * | `--sc-kit--input--text--font-size` | Text font size | `0.875em` |
58
+ * | `--sc-kit--input--text--color` | Text color | light-dark gray-800/white |
59
+ * | `--sc-kit--input--placeholder--color` | Placeholder text color | inherited from border |
60
+ * | `--sc-kit--input--icon--size` | Icon size | `1em` |
61
+ * | `--sc-kit--input--icon--color` | Icon color | inherited from border |
62
+ * | `--sc-kit--input--cursor--inert` | Cursor when inert | `default` |
63
+ */
64
+ declare const Cmp: import("svelte").Component<Props, {}, "">;
65
+ type Cmp = ReturnType<typeof Cmp>;
66
+ export default Cmp;
@@ -0,0 +1,2 @@
1
+ export { default as NumeralInput } from './cmp.numeral-input.svelte';
2
+ export { default as NumeralInputValidatable } from './cmp.numeral-input-validatable.svelte';
@@ -0,0 +1,2 @@
1
+ export { default as NumeralInput } from './cmp.numeral-input.svelte';
2
+ export { default as NumeralInputValidatable } from './cmp.numeral-input-validatable.svelte';
@@ -0,0 +1,58 @@
1
+ <script lang="ts">import { PinInputGenerator } from './pin-input-generator';
2
+ let { charsNumber = 6, on } = $props();
3
+ const initContainer = (node) => {
4
+ new PinInputGenerator(node, {
5
+ onInput: (val) => {
6
+ on.input(val);
7
+ },
8
+ count: charsNumber
9
+ });
10
+ };
11
+ </script>
12
+
13
+ <div class="pin-input" use:initContainer></div>
14
+
15
+ <!--
16
+ @component
17
+ A PIN code input with configurable number of character cells. Each cell accepts a single digit.
18
+
19
+ ### CSS Custom Properties
20
+ | Property | Description | Default |
21
+ |---|---|---|
22
+ | `--sc-kit--pin-input--background` | Cell background | light-dark white/gray-900 |
23
+ | `--sc-kit--pin-input--border-color` | Default border color | light-dark neutral-300/neutral-600 |
24
+ | `--sc-kit--pin-input--border-color--filled` | Filled cell border | light-dark success-500/success-400 |
25
+ | `--sc-kit--pin-input--border-color--focused` | Focused cell border | light-dark primary-500/primary-400 |
26
+ | `--sc-kit--pin-input--border-radius` | Cell border radius | `0.25em` |
27
+ | `--sc-kit--pin-input--color` | Text color | light-dark gray-800/white |
28
+ -->
29
+
30
+ <style>.pin-input {
31
+ --_pin-input--color: var(--sc-kit--pin-input--color, light-dark(#2e2e2e, #ffffff));
32
+ --_pin-input--background: var(--sc-kit--pin-input--background, light-dark(#ffffff, #1c1c1c));
33
+ --_pin-input--border-color: var(--sc-kit--pin-input--border-color, light-dark(#d1d5db, #4b5563));
34
+ --_pin-input--border-color--focused: var(
35
+ --sc-kit--pin-input--border-color--focused,
36
+ light-dark(#144ab0, #5a8dec)
37
+ );
38
+ --_pin-input--border-color--filled: var(--sc-kit--pin-input--border-color--filled, light-dark(#0cce6b, #0de374));
39
+ --_pin-input--border-radius: var(--sc-kit--pin-input--border-radius, 0.25em);
40
+ display: flex;
41
+ justify-content: space-between;
42
+ }
43
+ .pin-input :global(.pin-input__input) {
44
+ font-size: 2em;
45
+ color: var(--_pin-input--color);
46
+ border: 1px solid var(--_pin-input--border-color);
47
+ border-radius: var(--_pin-input--border-radius);
48
+ padding: 0.3em;
49
+ width: 1.8em;
50
+ background: var(--_pin-input--background);
51
+ text-align: center;
52
+ }
53
+ .pin-input :global(.pin-input__input--focused) {
54
+ border-color: var(--_pin-input--border-color--focused);
55
+ }
56
+ .pin-input :global(.pin-input__input--filled) {
57
+ border-color: var(--_pin-input--border-color--filled);
58
+ }</style>
@@ -0,0 +1,23 @@
1
+ type Props = {
2
+ /** Number of PIN input cells @default 6 */
3
+ charsNumber?: number;
4
+ on: {
5
+ input: (value: string) => void;
6
+ };
7
+ };
8
+ /**
9
+ * A PIN code input with configurable number of character cells. Each cell accepts a single digit.
10
+ *
11
+ * ### CSS Custom Properties
12
+ * | Property | Description | Default |
13
+ * |---|---|---|
14
+ * | `--sc-kit--pin-input--background` | Cell background | light-dark white/gray-900 |
15
+ * | `--sc-kit--pin-input--border-color` | Default border color | light-dark neutral-300/neutral-600 |
16
+ * | `--sc-kit--pin-input--border-color--filled` | Filled cell border | light-dark success-500/success-400 |
17
+ * | `--sc-kit--pin-input--border-color--focused` | Focused cell border | light-dark primary-500/primary-400 |
18
+ * | `--sc-kit--pin-input--border-radius` | Cell border radius | `0.25em` |
19
+ * | `--sc-kit--pin-input--color` | Text color | light-dark gray-800/white |
20
+ */
21
+ declare const Cmp: import("svelte").Component<Props, {}, "">;
22
+ type Cmp = ReturnType<typeof Cmp>;
23
+ export default Cmp;
@@ -0,0 +1 @@
1
+ export { default as PinInput } from './cmp.pin-input.svelte';
@@ -0,0 +1 @@
1
+ export { default as PinInput } from './cmp.pin-input.svelte';
@@ -0,0 +1,27 @@
1
+ interface PinInputArgs {
2
+ count?: number;
3
+ onInput: (value: string) => void;
4
+ secure?: boolean;
5
+ previewDuration?: number;
6
+ numeric?: boolean;
7
+ }
8
+ export declare class PinInputGenerator {
9
+ private _container;
10
+ private _onInput;
11
+ private _count;
12
+ private _secure;
13
+ private _previewDuration;
14
+ private _numeric;
15
+ private _cells;
16
+ private _focusedCellIndex;
17
+ constructor(container: HTMLElement, args: PinInputArgs);
18
+ private _initCells;
19
+ private _onCellChanged;
20
+ private _onKeyDown;
21
+ private _focusPreviousCell;
22
+ private _focusNextCell;
23
+ private _focusCellByIndex;
24
+ private _isTheCellValid;
25
+ private _notifyValueChanged;
26
+ }
27
+ export {};