@keenthemes/ktui 1.0.11 → 1.0.12

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 (129) hide show
  1. package/dist/ktui.js +1283 -1096
  2. package/dist/ktui.min.js +1 -1
  3. package/dist/ktui.min.js.map +1 -1
  4. package/examples/select/basic-usage.html +43 -0
  5. package/examples/select/combobox-icons.html +58 -0
  6. package/examples/select/combobox.html +46 -0
  7. package/examples/select/description.html +69 -0
  8. package/examples/select/disable-option.html +43 -0
  9. package/examples/select/disable-select.html +34 -0
  10. package/examples/select/icon-description.html +56 -0
  11. package/examples/select/icon-multiple.html +58 -0
  12. package/examples/select/icon.html +58 -0
  13. package/examples/select/max-selection.html +39 -0
  14. package/examples/select/modal.html +70 -0
  15. package/examples/select/multiple.html +42 -0
  16. package/examples/select/placeholder.html +43 -0
  17. package/examples/select/remote-data.html +32 -0
  18. package/examples/select/search.html +49 -0
  19. package/examples/select/tags-icons.html +58 -0
  20. package/examples/select/tags-selected.html +59 -0
  21. package/examples/select/tags.html +58 -0
  22. package/examples/select/template-customization.html +65 -0
  23. package/examples/select/test.html +94 -0
  24. package/examples/toast/example.html +427 -0
  25. package/lib/cjs/components/component.js +1 -1
  26. package/lib/cjs/components/component.js.map +1 -1
  27. package/lib/cjs/components/datatable/datatable.js +22 -6
  28. package/lib/cjs/components/datatable/datatable.js.map +1 -1
  29. package/lib/cjs/components/select/combobox.js +38 -120
  30. package/lib/cjs/components/select/combobox.js.map +1 -1
  31. package/lib/cjs/components/select/config.js +4 -16
  32. package/lib/cjs/components/select/config.js.map +1 -1
  33. package/lib/cjs/components/select/dropdown.js +10 -49
  34. package/lib/cjs/components/select/dropdown.js.map +1 -1
  35. package/lib/cjs/components/select/index.js +2 -1
  36. package/lib/cjs/components/select/index.js.map +1 -1
  37. package/lib/cjs/components/select/option.js +21 -4
  38. package/lib/cjs/components/select/option.js.map +1 -1
  39. package/lib/cjs/components/select/remote.js +1 -37
  40. package/lib/cjs/components/select/remote.js.map +1 -1
  41. package/lib/cjs/components/select/search.js +11 -41
  42. package/lib/cjs/components/select/search.js.map +1 -1
  43. package/lib/cjs/components/select/select.js +213 -326
  44. package/lib/cjs/components/select/select.js.map +1 -1
  45. package/lib/cjs/components/select/tags.js +39 -31
  46. package/lib/cjs/components/select/tags.js.map +1 -1
  47. package/lib/cjs/components/select/templates.js +120 -179
  48. package/lib/cjs/components/select/templates.js.map +1 -1
  49. package/lib/cjs/components/select/types.js +0 -12
  50. package/lib/cjs/components/select/types.js.map +1 -1
  51. package/lib/cjs/components/select/utils.js +204 -257
  52. package/lib/cjs/components/select/utils.js.map +1 -1
  53. package/lib/cjs/components/toast/index.js +10 -0
  54. package/lib/cjs/components/toast/index.js.map +1 -0
  55. package/lib/cjs/components/toast/toast.js +543 -0
  56. package/lib/cjs/components/toast/toast.js.map +1 -0
  57. package/lib/cjs/components/toast/types.js +7 -0
  58. package/lib/cjs/components/toast/types.js.map +1 -0
  59. package/lib/cjs/helpers/dom.js +24 -0
  60. package/lib/cjs/helpers/dom.js.map +1 -1
  61. package/lib/cjs/index.js +5 -1
  62. package/lib/cjs/index.js.map +1 -1
  63. package/lib/esm/components/component.js +1 -1
  64. package/lib/esm/components/component.js.map +1 -1
  65. package/lib/esm/components/datatable/datatable.js +22 -6
  66. package/lib/esm/components/datatable/datatable.js.map +1 -1
  67. package/lib/esm/components/select/combobox.js +39 -121
  68. package/lib/esm/components/select/combobox.js.map +1 -1
  69. package/lib/esm/components/select/config.js +3 -15
  70. package/lib/esm/components/select/config.js.map +1 -1
  71. package/lib/esm/components/select/dropdown.js +10 -49
  72. package/lib/esm/components/select/dropdown.js.map +1 -1
  73. package/lib/esm/components/select/index.js +1 -1
  74. package/lib/esm/components/select/index.js.map +1 -1
  75. package/lib/esm/components/select/option.js +21 -4
  76. package/lib/esm/components/select/option.js.map +1 -1
  77. package/lib/esm/components/select/remote.js +1 -37
  78. package/lib/esm/components/select/remote.js.map +1 -1
  79. package/lib/esm/components/select/search.js +12 -42
  80. package/lib/esm/components/select/search.js.map +1 -1
  81. package/lib/esm/components/select/select.js +214 -327
  82. package/lib/esm/components/select/select.js.map +1 -1
  83. package/lib/esm/components/select/tags.js +39 -31
  84. package/lib/esm/components/select/tags.js.map +1 -1
  85. package/lib/esm/components/select/templates.js +119 -178
  86. package/lib/esm/components/select/templates.js.map +1 -1
  87. package/lib/esm/components/select/types.js +1 -11
  88. package/lib/esm/components/select/types.js.map +1 -1
  89. package/lib/esm/components/select/utils.js +201 -255
  90. package/lib/esm/components/select/utils.js.map +1 -1
  91. package/lib/esm/components/toast/index.js +6 -0
  92. package/lib/esm/components/toast/index.js.map +1 -0
  93. package/lib/esm/components/toast/toast.js +540 -0
  94. package/lib/esm/components/toast/toast.js.map +1 -0
  95. package/lib/esm/components/toast/types.js +6 -0
  96. package/lib/esm/components/toast/types.js.map +1 -0
  97. package/lib/esm/helpers/dom.js +24 -0
  98. package/lib/esm/helpers/dom.js.map +1 -1
  99. package/lib/esm/index.js +3 -0
  100. package/lib/esm/index.js.map +1 -1
  101. package/package.json +8 -6
  102. package/src/components/alert/alert.css +15 -2
  103. package/src/components/component.ts +4 -0
  104. package/src/components/datatable/datatable.ts +24 -16
  105. package/src/components/input/input.css +3 -1
  106. package/src/components/link/link.css +2 -2
  107. package/src/components/select/combobox.ts +42 -149
  108. package/src/components/select/config.ts +38 -33
  109. package/src/components/select/dropdown.ts +8 -55
  110. package/src/components/select/index.ts +1 -1
  111. package/src/components/select/option.ts +28 -7
  112. package/src/components/select/remote.ts +2 -42
  113. package/src/components/select/search.ts +14 -54
  114. package/src/components/select/select.css +49 -0
  115. package/src/components/select/select.ts +231 -437
  116. package/src/components/select/tags.ts +40 -37
  117. package/src/components/select/templates.ts +166 -303
  118. package/src/components/select/types.ts +0 -10
  119. package/src/components/select/utils.ts +214 -304
  120. package/src/components/textarea/textarea.css +2 -1
  121. package/src/components/toast/index.ts +7 -0
  122. package/src/components/toast/toast.css +60 -0
  123. package/src/components/toast/toast.ts +605 -0
  124. package/src/components/toast/types.ts +169 -0
  125. package/src/helpers/dom.ts +30 -0
  126. package/src/index.ts +4 -0
  127. package/styles/main.css +3 -0
  128. package/styles/vars.css +138 -0
  129. package/styles.css +1 -0
@@ -0,0 +1,169 @@
1
+ /**
2
+ * KTUI - Free & Open-Source Tailwind UI Components by Keenthemes
3
+ * Copyright 2025 by Keenthemes Inc
4
+ */
5
+
6
+ /**
7
+ * Toast variant types
8
+ */
9
+ export type KTToastVariantType =
10
+ | 'info'
11
+ | 'success'
12
+ | 'error'
13
+ | 'warning'
14
+ | 'primary'
15
+ | 'secondary'
16
+ | 'destructive'
17
+ | 'mono';
18
+
19
+ /**
20
+ * Toast appearance types
21
+ */
22
+ export type KTToastAppearanceType = 'solid' | 'outline' | 'light';
23
+
24
+ /**
25
+ * Toast size types
26
+ */
27
+ export type KTToastSizeType = 'sm' | 'md' | 'lg';
28
+
29
+ /**
30
+ * Toast position types
31
+ */
32
+ export type KTToastPosition =
33
+ | 'top-end'
34
+ | 'top-center'
35
+ | 'top-start'
36
+ | 'bottom-end'
37
+ | 'bottom-center'
38
+ | 'bottom-start';
39
+
40
+ /**
41
+ * Toast action interface
42
+ */
43
+ export interface KTToastAction {
44
+ label?: string; // Button label
45
+ onClick?: (toastId: string) => void; // Click handler
46
+ className?: string; // Button classes
47
+ }
48
+
49
+ /**
50
+ * Allows overriding all internal class names for headless usage.
51
+ * Each property corresponds to a slot in the toast UI.
52
+ */
53
+ export interface KTToastClassNames {
54
+ container?: string; // Toast container
55
+ toast?: string; // Taast
56
+ icon?: string; // Icon
57
+ message?: string; // Message
58
+ toolbar?: string; // Toolbar
59
+ actions?: string; // Actions
60
+ }
61
+
62
+ /**
63
+ * Toast configuration
64
+ * @property offset - The vertical offset (in px) from the edge of the screen for stacking toasts.
65
+ */
66
+ export interface KTToastConfigInterface {
67
+ classNames?: Partial<KTToastClassNames>; // Override internal class names
68
+ position?: KTToastPosition; // Toast position
69
+ duration?: number; // Auto-dismiss duration (ms)
70
+ className?: string; // Custom class for toast root
71
+ maxToasts?: number; // Max toasts at once
72
+ offset?: number; // Offset from edge (px)
73
+ message?: string | HTMLElement | (() => HTMLElement); // Main message
74
+ description?: string | HTMLElement | (() => HTMLElement); // Description
75
+ icon?: string | HTMLElement | (() => HTMLElement); // Icon
76
+ action?: KTToastAction; // Action button
77
+ cancel?: KTToastAction; // Cancel button
78
+ dismiss?: boolean; // Show close button
79
+ variant?: KTToastVariantType; // Toast color/variant
80
+ appearance?: KTToastAppearanceType; // Appearance style
81
+ size?: KTToastSizeType; // Toast size
82
+ important?: boolean;
83
+ onAutoClose?: (id: string) => void;
84
+ onDismiss?: (id: string) => void;
85
+ closeButton?: boolean;
86
+ style?: Partial<CSSStyleDeclaration>;
87
+ invert?: boolean;
88
+ role?: string;
89
+ id?: string;
90
+ progress?: boolean;
91
+ }
92
+
93
+ export interface KTToastInterface {}
94
+
95
+ export interface KTToastOptions {
96
+ /** Custom content for the toast. HTMLElement, function returning HTMLElement, or string (DOM id). If set, replaces all default markup. */
97
+ content?: HTMLElement | (() => HTMLElement) | string; // Custom content (overrides default markup)
98
+ /** Override internal class names for headless usage */
99
+ classNames?: Partial<KTToastClassNames>;
100
+ /** Show/hide progress indicator */
101
+ progress?: boolean;
102
+ /** Main content of the toast */
103
+ message?: string | HTMLElement | (() => HTMLElement); // Main content/message
104
+ /** Leading icon or visual */
105
+ icon?: string | boolean; // Leading icon or visual
106
+ /** Primary action button */
107
+ action?: KTToastAction | boolean; // Primary action button
108
+ /** Cancel/secondary action button */
109
+ cancel?: KTToastAction | boolean; // Cancel/secondary action button
110
+ /** Close button */
111
+ dismiss?: KTToastAction | boolean; // Close button
112
+ /** Toast variant */
113
+ variant?: KTToastVariantType; // Toast variant
114
+ /** Toast appearance */
115
+ appearance?: KTToastAppearanceType; // Toast appearance
116
+ /** Toast size */
117
+ size?: KTToastSizeType; // Toast size
118
+ /** Auto-dismiss duration (ms) */
119
+ duration?: number; // Auto-dismiss duration (ms)
120
+ /** Prevents auto-dismiss if true */
121
+ important?: boolean; // Prevent auto-dismiss
122
+ /** Called when auto-dismiss fires */
123
+ onAutoClose?: (id: string) => void; // Called when auto-dismiss fires
124
+ /** Called when toast is dismissed (manual or auto) */
125
+ onDismiss?: (id: string) => void; // Called when toast is dismissed
126
+ /** Toast position */
127
+ position?: KTToastPosition; // Toast position
128
+ /** Toast maxToasts */
129
+ maxToasts?: number; // Max toasts allowed
130
+ /** Prevents auto-dismiss when toast is focused */
131
+ pauseOnHover?: boolean; // Pause auto-dismiss on hover
132
+ /** Custom class for toast */
133
+ className?: string; // Custom class for toast
134
+ /** ARIA role */
135
+ role?: string; // ARIA role
136
+ /** Beep sound */
137
+ beep?: boolean; // Beep sound
138
+ }
139
+
140
+ /**
141
+ * Example: Set global config for all toasts
142
+ *
143
+ * import { KTToast } from './toast';
144
+ *
145
+ * KTToast.configToast({
146
+ * position: 'bottom-end', // Default position
147
+ * duration: 5000, // Default auto-dismiss duration (ms)
148
+ * maxToasts: 3, // Max toasts visible at once
149
+ * className: 'my-toast-root', // Custom class
150
+ * gap: 20, // Gap between stacked toasts
151
+ * dismiss: true // Show close button by default
152
+ * });
153
+ */
154
+ export interface KTToastConfig {
155
+ classNames?: Partial<KTToastClassNames>; // Override internal class names
156
+ position?: KTToastPosition; // Toast position
157
+ duration?: number; // Auto-dismiss duration (ms)
158
+ className?: string; // Custom class for toast root
159
+ maxToasts?: number; // Max toasts at once
160
+ offset?: number; // Offset from edge (px)
161
+ gap?: number; // Gap between toasts (px)
162
+ dismiss?: boolean; // Show close button
163
+ }
164
+
165
+ export interface KTToastInstance {
166
+ id: string; // Toast unique ID
167
+ element: HTMLElement; // Toast DOM element
168
+ timeoutId: number; // Timer ID for auto-dismiss
169
+ }
@@ -391,6 +391,36 @@ const KTDom = {
391
391
  return attributes;
392
392
  },
393
393
 
394
+ getDataAttributesByJson(element: HTMLElement, prefix: string): object {
395
+ if (!element) {
396
+ return {};
397
+ }
398
+
399
+ const rawValue = element.dataset[prefix];
400
+
401
+ if (!rawValue) {
402
+ return {};
403
+ }
404
+
405
+ const parsedValue = KTUtils.parseDataAttribute(rawValue);
406
+
407
+ if (typeof parsedValue === 'string') {
408
+ try {
409
+ return JSON.parse(parsedValue);
410
+ } catch (e) {
411
+ console.error(`Invalid JSON format for '${prefix}': ${e instanceof Error ? e.message : e} ${rawValue}`);
412
+ }
413
+ }
414
+
415
+ // If it's already an object, return as is
416
+ if (typeof parsedValue === 'object' && parsedValue !== null) {
417
+ return parsedValue;
418
+ }
419
+
420
+ // For other types (number, boolean, null), return an empty object
421
+ return {};
422
+ },
423
+
394
424
  ready(callback: CallableFunction): void {
395
425
  if (document.readyState === 'loading') {
396
426
  document.addEventListener('DOMContentLoaded', () => {
package/src/index.ts CHANGED
@@ -27,6 +27,7 @@ import { KTTogglePassword } from './components/toggle-password';
27
27
  import { KTDataTable } from './components/datatable';
28
28
  import { KTDatepicker } from './components/datepicker';
29
29
  import { KTSelect } from './components/select';
30
+ import { KTToast } from './components/toast';
30
31
 
31
32
  export { KTDropdown } from './components/dropdown';
32
33
  export { KTModal } from './components/modal';
@@ -49,6 +50,7 @@ export { KTTogglePassword } from './components/toggle-password';
49
50
  export { KTDataTable } from './components/datatable';
50
51
  export { KTDatepicker } from './components/datepicker';
51
52
  export { KTSelect } from './components/select';
53
+ export { KTToast } from './components/toast';
52
54
 
53
55
  const KTComponents = {
54
56
  init(): void {
@@ -73,6 +75,7 @@ const KTComponents = {
73
75
  KTDataTable.init();
74
76
  KTDatepicker.init();
75
77
  KTSelect.init();
78
+ KTToast.init();
76
79
  },
77
80
  };
78
81
 
@@ -102,6 +105,7 @@ declare global {
102
105
  KTDataTable: typeof KTDataTable;
103
106
  KTDatepicker: typeof KTDatepicker;
104
107
  KTSelect: typeof KTSelect;
108
+ KTToast: typeof KTToast;
105
109
  KTComponents: typeof KTComponents;
106
110
  }
107
111
  }
@@ -0,0 +1,3 @@
1
+ @import "tailwindcss";
2
+ @import "./vars.css";
3
+ @import "../styles.css";
@@ -0,0 +1,138 @@
1
+ /** Colors **/
2
+ :root {
3
+ /** Base Colors **/
4
+ --background: oklch(1 0 0);
5
+ /* --color-white */
6
+ --foreground: oklch(14.1% 0.005 285.823);
7
+ /* --color-zinc-950 */
8
+ --card: oklch(1 0 0);
9
+ /* --color-white */
10
+ --card-foreground: oklch(14.1% 0.005 285.823);
11
+ /* --color-zinc-950 */
12
+ --popover: oklch(1 0 0);
13
+ /* --color-white */
14
+ --popover-foreground: oklch(14.1% 0.005 285.823);
15
+ /* --color-zinc-950 */
16
+ --primary: oklch(62.3% 0.214 259.815);
17
+ /* --color-blue-500 */
18
+ --primary-foreground: oklch(1 0 0);
19
+ /* --color-white */
20
+ --secondary: oklch(96.7% 0.003 264.542);
21
+ /* --color-zinc-100 */
22
+ --secondary-foreground: oklch(21% 0.006 285.885);
23
+ /* --color-zinc-900 */
24
+ --muted: oklch(96.7% 0.003 264.542);
25
+ /* --color-zinc-100 */
26
+ --muted-foreground: oklch(55.2% 0.016 285.938);
27
+ /* --color-zinc-500 */
28
+ --accent: oklch(96.7% 0.003 264.542);
29
+ /* --color-zinc-100 */
30
+ --accent-foreground: oklch(21% 0.006 285.885);
31
+ /* --color-zinc-900 */
32
+ --destructive: oklch(57.7% 0.245 27.325);
33
+ /* --color-red-600 */
34
+ --destructive-foreground: oklch(1 0 0);
35
+ /* --color-white */
36
+ --mono: oklch(14.1% 0.005 285.823);
37
+ /* --color-zinc-950 */
38
+ --mono-foreground: oklch(1 0 0);
39
+ /* --color-white */
40
+
41
+ /** Base Styles **/
42
+ --border: oklch(94% 0.004 286.32);
43
+ /* between --color-zinc-100 and --color-zinc-200 */
44
+ --input: oklch(92% 0.004 286.32);
45
+ /* --color-zinc-200 */
46
+ --ring: oklch(87.1% 0.006 286.286);
47
+ /* --color-zinc-400 */
48
+ --radius: 0.5rem;
49
+ }
50
+
51
+ .dark {
52
+ /** Base Colors **/
53
+ --background: oklch(14.1% 0.005 285.823);
54
+ /* --color-zinc-950 */
55
+ --foreground: oklch(98.5% 0 0);
56
+ /* --color-zinc-50 */
57
+ --card: oklch(14.1% 0.005 285.823);
58
+ /* --color-zinc-950 */
59
+ --card-foreground: oklch(98.5% 0 0);
60
+ /* --color-zinc-50 */
61
+ --popover: oklch(14.1% 0.005 285.823);
62
+ /* --color-zinc-950 */
63
+ --popover-foreground: oklch(98.5% 0 0);
64
+ /* --color-zinc-50 */
65
+ --primary: oklch(54.6% 0.245 262.881);
66
+ /* --color-blue-600 */
67
+ --primary-foreground: oklch(1 0 0);
68
+ /* --color-white */
69
+ --secondary: oklch(27.4% 0.006 286.033);
70
+ /* --color-zinc-800 */
71
+ --secondary-foreground: oklch(98.5% 0 0);
72
+ /* --color-zinc-50 */
73
+ --muted: oklch(21% 0.006 285.885);
74
+ /* --color-zinc-900 */
75
+ --muted-foreground: oklch(55.2% 0.016 285.938);
76
+ /* --color-zinc-500 */
77
+ --accent: oklch(21% 0.006 285.885);
78
+ /* --color-zinc-900 */
79
+ --accent-foreground: oklch(98.5% 0 0);
80
+ /* --color-zinc-50 */
81
+ --destructive: oklch(57.7% 0.245 27.325);
82
+ /* --color-red-600 */
83
+ --destructive-foreground: oklch(1 0 0);
84
+ /* --color-white */
85
+ --mono: oklch(87.1% 0.006 286.286);
86
+ /* --color-zinc-300 */
87
+ --mono-foreground: oklch(0 0 0);
88
+ /* --color-black */
89
+
90
+ /** Base Styles **/
91
+ --border: oklch(27.4% 0.006 286.033);
92
+ /* --color-zinc-800 */
93
+ --input: oklch(27.4% 0.006 286.033);
94
+ /* --color-zinc-800 */
95
+ --ring: oklch(27.4% 0.006 286.033);
96
+ /* --color-zinc-600 */
97
+ }
98
+
99
+ /** Theme Setup **/
100
+ @theme inline {
101
+ /** Base Colors **/
102
+ --color-background: var(--background);
103
+ --color-foreground: var(--foreground);
104
+
105
+ --color-card: var(--card);
106
+ --color-card-foreground: var(--card-foreground);
107
+
108
+ --color-popover: var(--popover);
109
+ --color-popover-foreground: var(--popover-foreground);
110
+
111
+ --color-muted: var(--muted);
112
+ --color-muted-foreground: var(--muted-foreground);
113
+
114
+ --color-accent: var(--accent);
115
+ --color-accent-foreground: var(--accent-foreground);
116
+
117
+ --color-primary: var(--primary);
118
+ --color-primary-foreground: var(--primary-foreground);
119
+
120
+ --color-secondary: var(--secondary);
121
+ --color-secondary-foreground: var(--secondary-foreground);
122
+
123
+ --color-destructive: var(--destructive);
124
+ --color-destructive-foreground: var(--destructive-foreground);
125
+
126
+ --color-mono: var(--mono);
127
+ --color-mono-foreground: var(--mono-foreground);
128
+
129
+ /** Base Styles **/
130
+ --color-border: var(--border);
131
+ --color-input: var(--input);
132
+ --color-ring: var(--ring);
133
+
134
+ --radius-xl: calc(var(--radius) + 4px);
135
+ --radius-lg: var(--radius);
136
+ --radius-md: calc(var(--radius) - 2px);
137
+ --radius-sm: calc(var(--radius) - 4px);
138
+ }
package/styles.css CHANGED
@@ -43,6 +43,7 @@
43
43
  @import './src/components/skeleton/skeleton.css';
44
44
  @import './src/components/kbd/kbd.css';
45
45
  @import './src/components/breadcrumb/breadcrumb.css';
46
+ @import './src/components/toast/toast.css';
46
47
 
47
48
  /** Dark Mode Variant **/
48
49
  @custom-variant dark (&:is(.dark *));