ikon-react-components-lib 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,1225 @@
1
+ # IKON COMPONENT LIBRARY (React)
2
+
3
+ A comprehensive React component library with UI components, form utilities, data tables, charts, and more. Built with React, TypeScript, Tailwind CSS, and ShadCN UI.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm i ikoncomponents
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ### 1. Install Dependencies
14
+
15
+ Delete your `node_modules` folder and reinstall:
16
+
17
+ ```bash
18
+ rm -rf node_modules
19
+ npm i
20
+ ```
21
+
22
+ ### 2. Setup Global Styles
23
+
24
+ Update your `global.css` or `index.css`:
25
+
26
+ ```css
27
+ @import "tailwindcss";
28
+ @import "tw-animate-css";
29
+ @import "ikoncomponents/dist/styles.css";
30
+ ```
31
+
32
+ ### 3. Configure the Library
33
+
34
+ In your **entry point** (typically `main.tsx` or `index.tsx`), configure the library **before** rendering:
35
+
36
+ ```tsx
37
+ import React from "react";
38
+ import ReactDOM from "react-dom/client";
39
+ import App from "./App";
40
+ import { setIkonConfig } from "ikoncomponents";
41
+ import "./global.css";
42
+
43
+ // Configure BEFORE rendering
44
+ setIkonConfig({
45
+ IKON_BASE_API_URL: "https://ikoncloud-dev.keross.com/ikon-api",
46
+ IKON_PLATFORM_UI_URL: "/",
47
+ LOGIN_PAGE_URL: "/login.html",
48
+ });
49
+
50
+ ReactDOM.createRoot(document.getElementById("root")!).render(
51
+ <React.StrictMode>
52
+ <App />
53
+ </React.StrictMode>
54
+ );
55
+ ```
56
+
57
+ #### `IkonConfigProps`
58
+
59
+ | Property | Type | Required | Description |
60
+ |-----------------------|----------|----------|----------------------------------------|
61
+ | `IKON_BASE_API_URL` | `string` | Yes | The Ikon API base URL |
62
+ | `IKON_PLATFORM_UI_URL`| `string` | Yes | The platform UI base URL |
63
+ | `LOGIN_PAGE_URL` | `string` | Yes | URL to redirect to for login |
64
+
65
+ ### 4. Wrap with ProviderWrapper
66
+
67
+ In your root `App.tsx`, wrap your application with `<ProviderWrapper>`:
68
+
69
+ ```tsx
70
+ import { ProviderWrapper } from "ikoncomponents";
71
+
72
+ function App() {
73
+ return (
74
+ <ProviderWrapper>
75
+ {/* Your application content */}
76
+ </ProviderWrapper>
77
+ );
78
+ }
79
+
80
+ export default App;
81
+ ```
82
+
83
+ > **Important:** `setIkonConfig()` must be called **before** `<ProviderWrapper>` is rendered. Failure to do so will result in configuration not being applied.
84
+
85
+ ---
86
+
87
+ ## Navigation Components
88
+
89
+ ### Sidebar Navigation & Breadcrumbs
90
+
91
+ Use `RenderSidebarNav` and `RenderAppBreadcrumb` to build a full navigation layout:
92
+
93
+ ```tsx
94
+ import { RenderAppBreadcrumb, RenderSidebarNav } from "ikoncomponents";
95
+ import { LayoutDashboard, Settings, Users, FileText } from "lucide-react";
96
+
97
+ function App() {
98
+ const navItems = [
99
+ {
100
+ title: "Dashboard",
101
+ url: "/dashboard",
102
+ icon: LayoutDashboard,
103
+ default: true,
104
+ },
105
+ {
106
+ title: "Users",
107
+ url: "/users",
108
+ icon: Users,
109
+ isActive: false,
110
+ },
111
+ {
112
+ title: "Settings",
113
+ url: "/settings",
114
+ icon: Settings,
115
+ items: [
116
+ { title: "Profile", url: "/settings/profile" },
117
+ { title: "Account", url: "/settings/account" },
118
+ { title: "Security", url: "/settings/security" },
119
+ ],
120
+ },
121
+ {
122
+ title: "Documentation",
123
+ url: "/docs",
124
+ icon: FileText,
125
+ },
126
+ ];
127
+
128
+ const breadcrumbItem = {
129
+ level: 1,
130
+ title: "Dashboard",
131
+ href: "/dashboard",
132
+ };
133
+
134
+ return (
135
+ <>
136
+ <RenderSidebarNav items={navItems} />
137
+ <RenderAppBreadcrumb breadcrumb={breadcrumbItem} />
138
+ <main className="p-8">
139
+ {/* Page content here */}
140
+ </main>
141
+ </>
142
+ );
143
+ }
144
+ ```
145
+
146
+ #### Navigation Item Structure
147
+
148
+ ```tsx
149
+ interface NavItem {
150
+ title: string; // Display text
151
+ url: string; // Navigation URL
152
+ icon: LucideIcon; // Icon component from lucide-react
153
+ default?: boolean; // Set as default/home
154
+ isActive?: boolean; // Highlight as active
155
+ items?: NavItem[]; // Submenu items (nested)
156
+ }
157
+ ```
158
+
159
+ ### Refreshing & Updating UI
160
+
161
+ Use `useRefresh()` hook to refresh the API or trigger sidebar re-render:
162
+
163
+ ```tsx
164
+ import { useRefresh } from "ikoncomponents";
165
+ import { TextButton } from "ikoncomponents";
166
+
167
+ function SettingsPage() {
168
+ const { refresh } = useRefresh();
169
+
170
+ const handleSave = async () => {
171
+ // Save logic here
172
+ await saveSomeData();
173
+
174
+ // Refresh sidebar/API
175
+ refresh();
176
+ };
177
+
178
+ return (
179
+ <TextButton onClick={handleSave} variant="default">
180
+ Save Changes
181
+ </TextButton>
182
+ );
183
+ }
184
+ ```
185
+
186
+ ---
187
+
188
+ ## ShadCN Components
189
+
190
+ All standard ShadCN components are included. Full documentation: [https://ui.shadcn.com/docs/components](https://ui.shadcn.com/docs/components)
191
+
192
+ | | | | |
193
+ |---|---|---|---|
194
+ | accordion | alert-dialog | alert | avatar |
195
+ | badge | button | calendar | card |
196
+ | checkbox | command | date-input | date-range-picker |
197
+ | dialog | dropdown-menu | hover-card | input |
198
+ | label | navigation-menu | popover | progress |
199
+ | radio-group | scroll-area | select | separator |
200
+ | sheet | sidebar | skeleton | slider |
201
+ | sonner | switch | table | tabs |
202
+ | textarea | tooltip | toggle | aspect-ratio |
203
+ | breadcrumb | collapsible | drawer | form |
204
+ | input-otp | toggle-group | | |
205
+
206
+ ---
207
+
208
+ ## Ikon Components
209
+
210
+ ### ActionMenu
211
+
212
+ ```tsx
213
+ import { ActionMenu } from "ikoncomponents";
214
+ ```
215
+
216
+ #### Props
217
+
218
+ | Property | Type | Optional | Description |
219
+ |---------------------|-----------------------|----------|------------------------------------|
220
+ | `actionMenus` | `ActionMenuProps[]` | No | Array of menu items |
221
+ | `extraActionParams` | `ExtraActionParams` | Yes | Extra params passed to callbacks |
222
+
223
+ #### `ActionMenuProps`
224
+
225
+ | Property | Type | Optional | Description |
226
+ |-------------|-------------------------------------------------------------------|----------|------------------------------------|
227
+ | `items` | `ActionMenuProps[]` | Yes | Sub-items for nested menus |
228
+ | `type` | `"sub" \| "group" \| "separator" \| "label" \| null` | Yes | Item type |
229
+ | `label` | `((...args: any) => string) \| string` | No | Display label (string or function) |
230
+ | `icon` | `ForwardRefExoticComponent<Omit<LucideProps, "ref"> & RefAttributes<SVGSVGElement>>` | Yes | Lucide icon component |
231
+ | `disabled` | `boolean` | Yes | Whether the item is disabled |
232
+ | `visibility` | `((...args: any) => boolean) \| boolean` | Yes | Whether the item is visible |
233
+ | `onClick` | `(...args: any) => void` | Yes | Click handler |
234
+
235
+ #### `ExtraActionParams`
236
+
237
+ | Property | Type | Optional | Description |
238
+ |-------------|---------|----------|------------------------------------|
239
+ | `arguments` | `any[]` | Yes | Arguments passed to label/onClick/visibility functions |
240
+
241
+ ---
242
+
243
+ ### AssistantComponent
244
+
245
+ AI chat assistant powered by `@assistant-ui/react`.
246
+
247
+ ```tsx
248
+ import { AssistantComponent } from "ikoncomponents";
249
+ ```
250
+
251
+ **Required dependencies:**
252
+
253
+ ```bash
254
+ npm install @assistant-ui/react@^0.12.12
255
+ npm install @assistant-ui/react-ai-sdk@^1.3.9
256
+ npm install @assistant-ui/react-markdown@^0.12.5
257
+ ```
258
+
259
+ #### Props
260
+
261
+ | Property | Type | Optional | Default | Description |
262
+ |-------------------------|-----------|----------|-----------------------|-----------------------------------------|
263
+ | `provider` | `string` | Yes | `"openai"` | LLM provider (e.g. `"openai"`) |
264
+ | `model` | `string` | Yes | `"gpt-4o-mini"` | Model identifier |
265
+ | `agentId` | `string` | Yes | `"default-agent"` | Unique agent identifier |
266
+ | `agentName` | `string` | Yes | `"Default Agent"` | Display name for the agent |
267
+ | `temperature` | `number` | Yes | `0.7` | Controls response randomness (0–2) |
268
+ | `maxTokens` | `number` | Yes | `2048` | Max response length |
269
+ | `className` | `string` | Yes | | Custom CSS class |
270
+ | `baseUrl` | `string` | Yes | `"http://localhost:3000"` | API endpoint URL |
271
+ | `additionalReferenceInfo`| `object` | Yes | `{}` | Extra context/reference info |
272
+ | `appId` | `string` | No | | Application ID for fetching agents |
273
+ | `currentUserDetails` | `UserData`| No | | Logged-in user metadata |
274
+
275
+ #### `UserData`
276
+
277
+ | Property | Type | Optional |
278
+ |-----------------|------------------|----------|
279
+ | `userId` | `string` | No |
280
+ | `userName` | `string` | No |
281
+ | `userLogin` | `string` | No |
282
+ | `password` | `string` | No |
283
+ | `userPhone` | `string` | Yes |
284
+ | `userEmail` | `string` | No |
285
+ | `userThumbnail` | `string \| null` | Yes |
286
+ | `userType` | `string` | Yes |
287
+ | `active` | `boolean` | Yes |
288
+ | `accountId` | `string` | Yes |
289
+ | `userDeleted` | `boolean` | Yes |
290
+
291
+ ---
292
+
293
+ ### BigCalendar
294
+
295
+ ```tsx
296
+ import { BigCalendar } from "ikoncomponents";
297
+ ```
298
+
299
+ #### Props
300
+
301
+ | Property | Type | Optional | Description |
302
+ |--------------------|---------------------------|----------|------------------------------|
303
+ | `events` | `BigCalendarEventProps[]` | No | Array of calendar events |
304
+ | `extraParamsEvent` | `ExtraParamsEvent` | Yes | Extra configuration options |
305
+ | `extraTools` | `ReactNode[]` | Yes | Additional toolbar elements |
306
+ | `onDateClick` | `(date: Date) => void` | Yes | Callback when a date is clicked |
307
+
308
+ #### `BigCalendarEventProps`
309
+
310
+ | Property | Type | Optional | Description |
311
+ |----------------|---------------------------|----------|---------------------------------|
312
+ | `title` | `string` | Yes | Event title |
313
+ | `isEditable` | `boolean` | Yes | Whether this event is editable |
314
+ | `isViewable` | `boolean` | Yes | Whether this event is viewable |
315
+ | `start` | `Date` | No | Event start datetime |
316
+ | `end` | `Date` | No | Event end datetime |
317
+ | `onEventClick` | `(event: any) => void` | Yes | Click handler for this event |
318
+
319
+ #### `ExtraParamsEvent`
320
+
321
+ | Property | Type | Optional | Description |
322
+ |--------------------|------------------------------------------|----------|--------------------------------------|
323
+ | `defaultView` | `string` | Yes | `"day"`, `"week"`, `"month"`, `"work week"`, `"agenda"` |
324
+ | `isEditableAll` | `boolean` | Yes | Enable editing for all events |
325
+ | `isViewable` | `boolean` | Yes | Enable viewing for all events |
326
+ | `onEditEventClick` | `(event: BigCalendarEventProps) => void` | Yes | Callback when an event edit is clicked |
327
+ | `onViewEventClick` | `(event: BigCalendarEventProps) => void` | Yes | Callback when an event view is clicked |
328
+ | `height` | `string` | Yes | Calendar container height |
329
+ | `margin` | `string` | Yes | Calendar container margin |
330
+
331
+ ---
332
+
333
+ ### Buttons
334
+
335
+ ```tsx
336
+ import {
337
+ TextButton,
338
+ TextButtonWithTooltip,
339
+ IconTextButton,
340
+ IconTextButtonWithTooltip,
341
+ IconButton,
342
+ IconButtonWithTooltip,
343
+ } from "ikoncomponents";
344
+ ```
345
+
346
+ All button components share a common props interface extending `React.ButtonHTMLAttributes<HTMLButtonElement>`:
347
+
348
+ | Property | Type | Optional | Description |
349
+ |-----------|--------------------------|----------|---------------------------------------------|
350
+ | `children` | `React.ReactNode` | No | Button content |
351
+ | `asChild` | `boolean` | Yes | Renders child as slot (defaults to `false`) |
352
+ | `variant` | `string` | Yes | `"default"`, `"destructive"`, `"outline"`, `"secondary"`, `"ghost"`, `"dashed"`, `"link"` |
353
+ | `size` | `string` | Yes | `"default"`, `"sm"`, `"lg"`, `"icon"`, `"smIcon"`, `"circular"`, `"lgIcon"` |
354
+ | `...props` | `ButtonHTMLAttributes` | Yes | Any standard HTML button attribute |
355
+
356
+ **Tooltip variants** additionally accept:
357
+
358
+ | Property | Type | Optional | Description |
359
+ |-----------------|------------------------------|----------|--------------------------|
360
+ | `tooltipContent` | `string \| React.ReactNode` | No | Content shown in tooltip |
361
+
362
+ ---
363
+
364
+ ### ComboboxInput
365
+
366
+ ```tsx
367
+ import { ComboboxInput } from "ikoncomponents";
368
+ ```
369
+
370
+ #### `ComboBoxInputProps`
371
+
372
+ | Property | Type | Optional | Description |
373
+ |---------------|------------------------------------------|----------|-----------------------------|
374
+ | `placeholder` | `string` | Yes | Placeholder text |
375
+ | `items` | `ComboboxItemProps[]` | No | Array of selectable items |
376
+ | `onSelect` | `(value: string \| string[]) => void` | Yes | Callback when value changes |
377
+ | `disabled` | `((...args: any) => boolean) \| boolean` | Yes | Disable the input |
378
+ | `defaultValue`| `string` | Yes | Default selected value |
379
+
380
+ #### `ComboboxItemProps`
381
+
382
+ | Property | Type | Optional | Description |
383
+ |-----------|------------------------------------------|----------|--------------------------|
384
+ | `value` | `string` | No | The item value |
385
+ | `label` | `string \| undefined` | Yes | Display label |
386
+ | `extra` | `any` | Yes | Extra data |
387
+ | `disabled` | `((...args: any) => boolean) \| boolean` | Yes | Disable this item |
388
+
389
+ ---
390
+
391
+ ### MultiCombobox
392
+
393
+ ```tsx
394
+ import { MultiCombobox } from "ikoncomponents";
395
+ ```
396
+
397
+ #### Props
398
+
399
+ | Property | Type | Optional | Default | Description |
400
+ |-----------------|-------------------------------------------------------------------------------|----------|---------|-------------------------------------|
401
+ | `placeholder` | `string` | No | | Placeholder text |
402
+ | `items` | `{ value: string; label?: string; disabled?: boolean \| ((item: any) => boolean) }[]` | No | | Selectable items |
403
+ | `onValueChange` | `(selectedItems: string[]) => void` | No | | Callback with selected values array |
404
+ | `defaultValue` | `string[]` | Yes | | Default selected values |
405
+ | `defaultOptions`| `number` | Yes | `2` | Number of visible chips before "+N" |
406
+
407
+ ---
408
+
409
+ ### CustomAlertDialog
410
+
411
+ ```tsx
412
+ import { CustomAlertDialog } from "ikoncomponents";
413
+ ```
414
+
415
+ #### Props
416
+
417
+ | Property | Type | Optional | Description |
418
+ |-----------------|-------------|----------|------------------------------------------|
419
+ | `title` | `string` | No | Dialog title |
420
+ | `description` | `string` | Yes | Dialog description |
421
+ | `fontSize` | `string` | Yes | Tailwind font size class (e.g. `"text-sm"`) |
422
+ | `cancelText` | `string` | Yes | Custom cancel button text |
423
+ | `confirmText` | `string` | Yes | Custom confirm button text |
424
+ | `thirdOptionText`| `string` | Yes | Custom third button text |
425
+ | `onCancel` | `() => void`| Yes | Cancel callback |
426
+ | `onConfirm` | `() => void`| Yes | Confirm callback |
427
+ | `onThird` | `() => void`| Yes | Third button callback |
428
+
429
+ ---
430
+
431
+ ### DataTable\<TData, TValue\>
432
+
433
+ A fully-featured data table with sorting, filtering, pagination, grouping, and column customization.
434
+
435
+ ```tsx
436
+ import { DataTable } from "ikoncomponents";
437
+ import { ColumnDef } from "@tanstack/react-table";
438
+ ```
439
+
440
+ #### Complete DataTable Example
441
+
442
+ ```tsx
443
+ import { useState } from "react";
444
+ import { DataTable } from "ikoncomponents";
445
+ import type { DTExtraParamsProps } from "ikoncomponents";
446
+ import { ColumnDef } from "@tanstack/react-table";
447
+
448
+ interface User {
449
+ id: string;
450
+ name: string;
451
+ email: string;
452
+ role: string;
453
+ status: "active" | "inactive";
454
+ }
455
+
456
+ function UsersTable() {
457
+ const [users, setUsers] = useState<User[]>([
458
+ { id: "1", name: "John Doe", email: "john@example.com", role: "Admin", status: "active" },
459
+ { id: "2", name: "Jane Smith", email: "jane@example.com", role: "User", status: "active" },
460
+ { id: "3", name: "Bob Johnson", email: "bob@example.com", role: "Editor", status: "inactive" },
461
+ ]);
462
+
463
+ const columns: ColumnDef<User>[] = [
464
+ {
465
+ accessorKey: "id",
466
+ header: "ID",
467
+ title: "ID",
468
+ },
469
+ {
470
+ accessorKey: "name",
471
+ header: "Name",
472
+ title: "Full Name",
473
+ headerClassName: "text-left",
474
+ },
475
+ {
476
+ accessorKey: "email",
477
+ header: "Email",
478
+ title: "Email Address",
479
+ },
480
+ {
481
+ accessorKey: "role",
482
+ header: "Role",
483
+ title: "User Role",
484
+ },
485
+ {
486
+ accessorKey: "status",
487
+ header: "Status",
488
+ cell: (info) => (
489
+ <span className={info.getValue() === "active" ? "text-green-600" : "text-red-600"}>
490
+ {info.getValue() as string}
491
+ </span>
492
+ ),
493
+ },
494
+ ];
495
+
496
+ const extraParams: DTExtraParamsProps = {
497
+ sorting: true,
498
+ paginationBar: true,
499
+ rowsPerPage: true,
500
+ pagination: true,
501
+ pageSize: 10,
502
+ pageSizeArray: [5, 10, 25, 50],
503
+ defaultTools: ["search", "filter", "columnFilter"],
504
+ checkBoxColumn: true,
505
+ checkBoxColumnCallback: (selectedRows) => {
506
+ console.log("Selected rows:", selectedRows);
507
+ },
508
+ };
509
+
510
+ return (
511
+ <div className="w-full">
512
+ <DataTable
513
+ data={users}
514
+ columns={columns}
515
+ extraParams={extraParams}
516
+ onTableReady={(table) => {
517
+ console.log("Table initialized:", table);
518
+ }}
519
+ />
520
+ </div>
521
+ );
522
+ }
523
+
524
+ export default UsersTable;
525
+ ```
526
+
527
+ #### Props
528
+
529
+ | Property | Type | Optional | Description |
530
+ |---------------|---------------------------------------|----------|-----------------------------------|
531
+ | `data` | `TData[]` | No | Array of row data |
532
+ | `columns` | `DTColumnsProps<TData, TValue>[]` | No | Column definitions |
533
+ | `extraParams` | `DTExtraParamsProps` | Yes | Table configuration |
534
+ | `onTableReady` | `(table: any) => void` | Yes | Callback when table initializes |
535
+
536
+ #### `DTColumnsProps<TData, TValue>`
537
+
538
+ Extends TanStack Table's `ColumnDef<TData, TValue>`.
539
+
540
+ | Property | Type | Optional | Description |
541
+ |-------------------|---------|----------|--------------------------------|
542
+ | `title` | `string` | Yes | Column title for display |
543
+ | `headerClassName` | `string` | Yes | CSS class for the header cell |
544
+
545
+ #### `DTExtraParamsProps`
546
+
547
+ | Property | Type | Optional | Description |
548
+ |------------------------|-----------------------------------------------------|----------|-------------------------------------------|
549
+ | `defaultGroups` | `string[]` | Yes | Default column groupings |
550
+ | `grouping` | `boolean` | Yes | Enable row grouping |
551
+ | `header` | `boolean` | Yes | Show table header |
552
+ | `footer` | `boolean` | Yes | Show table footer |
553
+ | `defaultTools` | `("columnFilter" \| "search" \| "filter")[] \| boolean` | Yes | Toolbar tools to show |
554
+ | `extraTools` | `any` | Yes | Additional toolbar elements |
555
+ | `sorting` | `boolean` | Yes | Enable sorting |
556
+ | `paginationBar` | `boolean` | Yes | Show pagination bar |
557
+ | `rowsPerPage` | `boolean` | Yes | Show rows-per-page selector |
558
+ | `pagination` | `boolean` | Yes | Enable pagination |
559
+ | `numberOfRows` | `boolean` | Yes | Show row count |
560
+ | `checkBoxColumn` | `boolean` | Yes | Show checkbox column |
561
+ | `checkBoxColumnCallback`| `(selectedRows: any[]) => void` | Yes | Callback for selected rows |
562
+ | `actionMenu` | `DTActionMenuProps` | Yes | Row-level action menu |
563
+ | `groupActionMenu` | `DTActionMenuProps` | Yes | Group-level action menu |
564
+ | `pageSize` | `number` | Yes | Initial page size |
565
+ | `pageIndex` | `number` | Yes | Initial page index |
566
+ | `pageSizeArray` | `number[]` | Yes | Available page size options |
567
+ | `rowSelection` | `boolean` | Yes | Enable row selection |
568
+ | `onPaginationChange` | `(state: PaginationState) => void` | Yes | Pagination state change callback |
569
+ | `defaultRowSelection` | `(row: any) => boolean` | Yes | Function to determine default selected rows |
570
+
571
+ #### `DTActionMenuProps`
572
+
573
+ | Property | Type | Optional | Description |
574
+ |------------------|--------------------|----------|----------------------------|
575
+ | `items` | `ActionMenuProps[]` | No | Action menu items |
576
+ | `extraArguments` | `any[]` | Yes | Extra args passed to items |
577
+
578
+ ---
579
+
580
+ ### EChart
581
+
582
+ ```tsx
583
+ import { EChart } from "ikoncomponents";
584
+ ```
585
+
586
+ Uses `forwardRef` — you can access `ref` methods.
587
+
588
+ #### Props
589
+
590
+ | Property | Type | Optional | Default | Description |
591
+ |------------------|---------------------------------|----------|-------------|----------------------------------|
592
+ | `parentDivProps` | `any` | Yes | `{}` | Props for container div |
593
+ | `option` | `Record<string \| number, any>` | Yes | `{}` | ECharts option object |
594
+ | `style` | `Record<string, string>` | Yes | `{}` | CSS styles for chart container |
595
+ | `settings` | `Record<string, any>` | Yes | `{}` | ECharts `setOption` settings |
596
+ | `loading` | `boolean` | Yes | `true` | Show loading state |
597
+ | `theme` | `string \| object \| null` | Yes | `undefined` | ECharts theme |
598
+ | `isConfigurable` | `boolean` | Yes | `false` | Show configure toolbox button |
599
+ | `resizeKey` | `null \| boolean \| number \| string` | Yes | `undefined` | Key to trigger chart resize |
600
+ | `onClick` | `(...args: any) => void` | Yes | `() => {}` | Click event callback |
601
+ | `onConfigure` | `(...args: any) => void` | Yes | `() => {}` | Configure button callback |
602
+
603
+ #### Ref Methods
604
+
605
+ | Method | Description |
606
+ |---------------------------|------------------------------------------------|
607
+ | `getChartObject()` | Returns the ECharts instance |
608
+ | `setOption(option, settings)` | Sets chart option |
609
+ | `resize(secondResizeDelay?)` | Resizes the chart |
610
+ | `loadingVisible(visibility?)` | Show/hide loading spinner |
611
+ | `dispose()` | Disposes the chart instance |
612
+ | `on(eventName, callback)` | Adds an event listener |
613
+
614
+ ---
615
+
616
+ ### FileUploader
617
+
618
+ ```tsx
619
+ import { FileUploader, getImageFromObject } from "ikoncomponents";
620
+ ```
621
+
622
+ #### `FileUploaderProps`
623
+
624
+ | Property | Type | Optional | Default | Description |
625
+ |---------------|-----------------------------------------------------|----------|------------------|---------------------------------------|
626
+ | `label` | `string` | Yes | `"Upload File"` | Label text |
627
+ | `isDrag` | `boolean` | Yes | `false` | Enable drag & drop upload |
628
+ | `onFileSelect` | `(fileObj: FileObjType) => Promise<FileObjType> \| void` | No | | Callback with the processed file |
629
+
630
+ #### `FileObjType`
631
+
632
+ | Property | Type | Description |
633
+ |----------------|-----------|------------------------------|
634
+ | `message` | `string` | Status message |
635
+ | `fileName` | `string` | Original file name |
636
+ | `size` | `number` | File size in bytes |
637
+ | `type` | `string` | MIME type |
638
+ | `lastModified` | `number` | Last modified timestamp |
639
+ | `base64` | `string` | Base64-encoded file content |
640
+
641
+ #### Usage
642
+
643
+ ```tsx
644
+ // Simple upload
645
+ <FileUploader onFileSelect={(fileObj) => console.log(fileObj)} />
646
+
647
+ // Drag & drop upload
648
+ <FileUploader isDrag={true} onFileSelect={handleFileUpload} />
649
+
650
+ // Display uploaded image
651
+ const [imgSrc, setImgSrc] = useState<string | null>(null);
652
+
653
+ const handleFileUpload = async (fileObj: FileObjType) => {
654
+ const imgUrl = getImageFromObject(fileObj);
655
+ setImgSrc(imgUrl);
656
+ };
657
+
658
+ <FileUploader onFileSelect={handleFileUpload} />
659
+ {imgSrc && <img src={imgSrc} className="w-40 h-40 mt-4" />}
660
+ ```
661
+
662
+ ---
663
+
664
+ ### GlowingEffect
665
+
666
+ ```tsx
667
+ import { GlowingEffect } from "ikoncomponents";
668
+ ```
669
+
670
+ #### Props
671
+
672
+ | Property | Type | Optional | Default | Description |
673
+ |--------------------|--------------------------|----------|--------------|--------------------------------|
674
+ | `blur` | `number` | Yes | `0` | Blur radius |
675
+ | `inactiveZone` | `number` | Yes | `0.7` | Inner zone where glow is inactive |
676
+ | `proximity` | `number` | Yes | `0` | Activation proximity distance |
677
+ | `spread` | `number` | Yes | `20` | Gradient spread angle |
678
+ | `variant` | `"default" \| "white"` | Yes | `"default"` | Color variant |
679
+ | `glow` | `boolean` | Yes | `false` | Enable glow effect |
680
+ | `className` | `string` | Yes | | Custom CSS class |
681
+ | `disabled` | `boolean` | Yes | `true` | Disable the effect |
682
+ | `movementDuration` | `number` | Yes | `2` | Animation duration (seconds) |
683
+ | `borderWidth` | `number` | Yes | `1` | Border width (px) |
684
+
685
+ ---
686
+
687
+ ### Icon
688
+
689
+ ```tsx
690
+ import { Icon } from "ikoncomponents";
691
+ ```
692
+
693
+ Dynamically renders any [Lucide icon](https://lucide.dev/icons) by name.
694
+
695
+ #### Props
696
+
697
+ | Property | Type | Optional | Description |
698
+ |--------------|---------------------|----------|--------------------------|
699
+ | `name` | `string` | No | Lucide icon name |
700
+ | `size` | `number \| string` | Yes | Icon size |
701
+ | `color` | `string` | Yes | Icon color |
702
+ | `className` | `string` | Yes | CSS class |
703
+ | `strokeWidth` | `number` | Yes | Stroke width |
704
+
705
+ ---
706
+
707
+ ### LoadingSpinner
708
+
709
+ ```tsx
710
+ import { LoadingSpinner } from "ikoncomponents";
711
+ ```
712
+
713
+ #### Props
714
+
715
+ | Property | Type | Optional | Default | Description |
716
+ |------------|----------------------|----------|---------|--------------------------|
717
+ | `size` | `number` | Yes | `48` | Spinner size (px) |
718
+ | `className` | `string` | Yes | | CSS class |
719
+ | `visible` | `boolean` | Yes | `true` | Whether to show spinner |
720
+ | `...props` | `React.SVGProps` | Yes | | Additional SVG props |
721
+
722
+ ---
723
+
724
+ ### NoDataComponent
725
+
726
+ ```tsx
727
+ import { NoDataComponent } from "ikoncomponents";
728
+ ```
729
+
730
+ #### Props
731
+
732
+ | Property | Type | Optional | Default | Description |
733
+ |---------|---------|----------|----------------------|-----------------------|
734
+ | `text` | `string` | Yes | `"No Data Available"` | Message to display |
735
+
736
+ ---
737
+
738
+ ### PageWrapper
739
+
740
+ ```tsx
741
+ import { PageWrapper } from "ikoncomponents";
742
+ ```
743
+
744
+ #### Props
745
+
746
+ | Property | Type | Optional | Description |
747
+ |-----------|---------------------------|----------|------------------------------|
748
+ | `title` | `string \| ReactNode` | Yes | Page title |
749
+ | `subtitle` | `string \| ReactNode` | Yes | Page subtitle |
750
+ | `tools` | `ReactNode` | Yes | Action buttons / tools area |
751
+ | `children` | `ReactNode` | No | Page content |
752
+
753
+ ---
754
+
755
+ ### PasswordStrengthMeter
756
+
757
+ ```tsx
758
+ import { PasswordStrengthMeter } from "ikoncomponents";
759
+ ```
760
+
761
+ #### Props
762
+
763
+ | Property | Type | Optional | Description |
764
+ |---------|---------|----------|------------------------------------------------|
765
+ | `value` | `string` | No | The password string to evaluate strength for |
766
+
767
+ Displays a color-coded progress bar: Very weak → Weak → Fair → Good → Strong.
768
+
769
+ ---
770
+
771
+ ### SimpleWidget
772
+
773
+ ```tsx
774
+ import { SimpleWidget } from "ikoncomponents";
775
+ ```
776
+
777
+ #### Props
778
+
779
+ | Property | Type | Optional | Default | Description |
780
+ |-----------------|-----------------------------------|----------|---------|----------------------------------|
781
+ | `title` | `string` | No | | Widget title |
782
+ | `iconName` | `string` | Yes | | Lucide icon name |
783
+ | `iconSize` | `number` | Yes | `20` | Icon size |
784
+ | `iconClass` | `string` | Yes | `""` | Icon CSS class |
785
+ | `primaryText` | `number \| string \| ReactNode` | No | | Main display value |
786
+ | `secondaryText` | `string \| ReactNode` | Yes | | Secondary text |
787
+ | `mainClassName` | `string` | Yes | `""` | Container CSS class |
788
+ | `loading` | `boolean` | Yes | | Show loading state |
789
+ | `loadingMessage` | `string` | Yes | `"Loading..."` | Loading state text |
790
+
791
+ ---
792
+
793
+ ### Tabs (CustomTabs)
794
+
795
+ ```tsx
796
+ import { CustomTabs } from "ikoncomponents";
797
+ ```
798
+
799
+ #### Props
800
+
801
+ | Property | Type | Optional | Default | Description |
802
+ |---------------------|-----------------------------|----------|---------|--------------------------------|
803
+ | `children` | `ReactNode` | Yes | | Content for the active tab |
804
+ | `tabArray` | `TabArray[]` | No | | Array of tab definitions |
805
+ | `tabListClass` | `string` | Yes | `""` | CSS class for tab list |
806
+ | `tabListInnerClass` | `string` | Yes | `""` | CSS class for inner tab list |
807
+ | `tabListButtonClass` | `string` | Yes | `""` | CSS class for tab buttons |
808
+ | `tabContentClass` | `string` | Yes | `""` | CSS class for tab content |
809
+ | `pathName` | `string` | Yes | | Current pathname (for routing) |
810
+ | `headerEndComponent` | `React.ReactNode` | Yes | | Component at end of tab header |
811
+ | `onTabChange` | `(tabId: string) => void` | Yes | | Tab change callback |
812
+ | `isSeperatePage` | `boolean` | Yes | `false` | Tabs mapped to separate pages |
813
+
814
+ #### `TabArray`
815
+
816
+ | Property | Type | Optional | Description |
817
+ |-------------|---------------------|----------|-------------------------------|
818
+ | `tabName` | `string` | No | Display name of the tab |
819
+ | `tabId` | `string` | No | Unique identifier |
820
+ | `default` | `boolean` | No | Whether this tab is default |
821
+ | `tabContent` | `React.ReactNode` | Yes | Content rendered for this tab |
822
+ | `url` | `string` | Yes | URL for page-based tabs |
823
+
824
+ ---
825
+
826
+ ### TitleProgress
827
+
828
+ ```tsx
829
+ import { TitleProgress } from "ikoncomponents";
830
+ ```
831
+
832
+ #### Props
833
+
834
+ | Property | Type | Optional | Default | Description |
835
+ |--------------------|-----------|----------|---------|-----------------------------------|
836
+ | `title` | `string` | No | | Progress title |
837
+ | `value` | `number` | No | | Progress value (0–100) |
838
+ | `valueText` | `string` | Yes | | Custom value text |
839
+ | `isPercent` | `boolean` | Yes | `true` | Append `%` to value |
840
+ | `className` | `string` | Yes | | Container CSS class |
841
+ | `titleClassName` | `string` | Yes | | Title CSS class |
842
+ | `valueClassName` | `string` | Yes | | Value CSS class |
843
+ | `progressClassName` | `string` | Yes | | Progress bar CSS class |
844
+
845
+ ---
846
+
847
+ ### TooltipComponent
848
+
849
+ ```tsx
850
+ import { TooltipComponent } from "ikoncomponents";
851
+ ```
852
+
853
+ #### Props
854
+
855
+ | Property | Type | Optional | Description |
856
+ |-----------------|-----------------------------|----------|----------------------------|
857
+ | `tooltipContent` | `string \| ReactNode` | No | Content shown in tooltip |
858
+ | `children` | `ReactNode` | No | Element that triggers tooltip |
859
+
860
+ ---
861
+
862
+ ### Widgets
863
+
864
+ ```tsx
865
+ import { Widgets } from "ikoncomponents";
866
+ ```
867
+
868
+ #### Props
869
+
870
+ | Property | Type | Optional | Description |
871
+ |-------------|-----------------|----------|--------------------------|
872
+ | `widgetData` | `WidgetProps[]` | No | Array of widget items |
873
+
874
+ #### `WidgetProps`
875
+
876
+ | Property | Type | Optional | Description |
877
+ |---------------------|-----------------------------------------------------------------|----------|------------------------------------|
878
+ | `id` | `string` | No | Unique widget identifier |
879
+ | `widgetText` | `string` | No | Widget title text |
880
+ | `widgetNumber` | `string` | No | Displayed numeric value |
881
+ | `iconName` | `string` | Yes | Lucide icon name |
882
+ | `onButtonClickfunc` | `(...params: (string \| Record<string, string>)[]) => void` | Yes | Click handler |
883
+
884
+ ---
885
+
886
+ ### Skeleton Loaders
887
+
888
+ #### GradeTableLoader
889
+
890
+ ```tsx
891
+ import { GradeTableLoader } from "ikoncomponents";
892
+ ```
893
+
894
+ | Property | Type | Optional | Default | Description |
895
+ |--------------|-----------|----------|---------|-----------------------------|
896
+ | `rowCount` | `number` | Yes | `6` | Number of skeleton rows |
897
+ | `showToolbar` | `boolean` | Yes | `true` | Show skeleton toolbar |
898
+
899
+ #### SkeletonWidget
900
+
901
+ ```tsx
902
+ import { SkeletonWidget } from "ikoncomponents";
903
+ ```
904
+
905
+ | Property | Type | Optional | Description |
906
+ |---------|---------|----------|-----------------------------------|
907
+ | `count` | `number` | No | Number of skeleton widget cards |
908
+
909
+ ---
910
+
911
+ ### SheetComponent
912
+
913
+ ```tsx
914
+ import { SheetComponent } from "ikoncomponents";
915
+ ```
916
+
917
+ #### Props
918
+
919
+ | Property | Type | Optional | Description |
920
+ |-------------------|--------------------|----------|------------------------------|
921
+ | `buttonText` | `React.ReactNode` | Yes | Text on trigger button |
922
+ | `buttonIcon` | `React.ReactNode` | Yes | Icon on trigger button |
923
+ | `buttonStyle` | `string` | Yes | Trigger button CSS class |
924
+ | `sheetTitle` | `React.ReactNode` | Yes | Sheet title |
925
+ | `sheetDescription` | `React.ReactNode` | Yes | Sheet description |
926
+ | `sheetContent` | `React.ReactNode` | Yes | Sheet body content |
927
+ | `closeButton` | `boolean` | Yes | Show close button |
928
+
929
+ ---
930
+
931
+ ## Form Components
932
+
933
+ All form components are designed to work with **react-hook-form** and integrate seamlessly with `<Form>` from ShadCN. They provide automatic validation, error handling, and consistent styling.
934
+
935
+ ### Complete Form Example
936
+
937
+ Here's a full example using multiple form components:
938
+
939
+ ```tsx
940
+ import { useForm } from "react-hook-form";
941
+ import { zodResolver } from "@hookform/resolvers/zod";
942
+ import { z } from "zod";
943
+ import {
944
+ Form,
945
+ FormInput,
946
+ FormPasswordInput,
947
+ FormDateInput,
948
+ FormComboboxInput,
949
+ FormTextarea,
950
+ TextButton,
951
+ } from "ikoncomponents";
952
+
953
+ const registrationSchema = z.object({
954
+ username: z.string().min(3, "Username must be 3+ chars"),
955
+ email: z.string().email("Invalid email"),
956
+ password: z.string().min(8, "Password must be 8+ chars"),
957
+ dateOfBirth: z.date(),
958
+ country: z.string().min(1, "Select a country"),
959
+ bio: z.string().optional(),
960
+ });
961
+
962
+ function RegisterForm() {
963
+ const form = useForm<z.infer<typeof registrationSchema>>({
964
+ resolver: zodResolver(registrationSchema),
965
+ });
966
+
967
+ const onSubmit = async (data) => {
968
+ console.log("Form data:", data);
969
+ // Send to API
970
+ };
971
+
972
+ return (
973
+ <Form {...form}>
974
+ <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
975
+ <FormInput
976
+ formControl={form.control}
977
+ name="username"
978
+ label="Username"
979
+ placeholder="Choose a username"
980
+ formDescription="3+ characters"
981
+ />
982
+
983
+ <FormInput
984
+ formControl={form.control}
985
+ name="email"
986
+ label="Email"
987
+ type="email"
988
+ placeholder="your@email.com"
989
+ />
990
+
991
+ <FormPasswordInput
992
+ formControl={form.control}
993
+ name="password"
994
+ label="Password"
995
+ placeholder="Create a strong password"
996
+ formDescription="8+ characters with uppercase and numbers"
997
+ />
998
+
999
+ <FormDateInput
1000
+ formControl={form.control}
1001
+ name="dateOfBirth"
1002
+ label="Date of Birth"
1003
+ />
1004
+
1005
+ <FormComboboxInput
1006
+ formControl={form.control}
1007
+ name="country"
1008
+ label="Country"
1009
+ placeholder="Select country"
1010
+ items={[
1011
+ { value: "US", label: "United States" },
1012
+ { value: "UK", label: "United Kingdom" },
1013
+ { value: "CA", label: "Canada" },
1014
+ ]}
1015
+ />
1016
+
1017
+ <FormTextarea
1018
+ formControl={form.control}
1019
+ name="bio"
1020
+ label="Bio"
1021
+ placeholder="Tell us about yourself"
1022
+ />
1023
+
1024
+ <TextButton type="submit" variant="default">
1025
+ Create Account
1026
+ </TextButton>
1027
+ </form>
1028
+ </Form>
1029
+ );
1030
+ }
1031
+
1032
+ export default RegisterForm;
1033
+ ```
1034
+
1035
+ ### FormInput
1036
+
1037
+ Standard text input field with validation.
1038
+
1039
+ ```tsx
1040
+ import { FormInput } from "ikoncomponents";
1041
+ ```
1042
+
1043
+ #### Props
1044
+
1045
+ | Property | Type | Optional | Description |
1046
+ |----------------------|------------------------------------|----------|------------------------------------|
1047
+ | `formControl` | `Control<any>` | No | `form.control` from react-hook-form |
1048
+ | `name` | `string` | No | Field name |
1049
+ | `label` | `string` | Yes | Label text |
1050
+ | `placeholder` | `string` | Yes | Placeholder text |
1051
+ | `formDescription` | `string` | Yes | Help text below field |
1052
+ | `formItemClass` | `string` | Yes | CSS class for container |
1053
+ | `extraFormComponent` | `(value: string) => ReactNode` | Yes | Custom component with field value |
1054
+ | `...inputProps` | `InputHTMLAttributes` | Yes | HTML input attributes (type, disabled, min, max, etc.) |
1055
+
1056
+ ### FormPasswordInput
1057
+
1058
+ ```tsx
1059
+ import { FormPasswordInput } from "ikoncomponents";
1060
+ ```
1061
+
1062
+ Same props as `FormInput`. Renders a password field with a show/hide toggle button.
1063
+
1064
+ ### FormTextarea
1065
+
1066
+ ```tsx
1067
+ import { FormTextarea } from "ikoncomponents";
1068
+ ```
1069
+
1070
+ #### Props
1071
+
1072
+ Extends `FormFieldProps` + `TextareaHTMLAttributes<HTMLTextAreaElement>`.
1073
+
1074
+ | Property | Type | Optional | Description |
1075
+ |----------------------|------------------------------------|----------|------------------------------------|
1076
+ | `formControl` | `any` | No | `form.control` from react-hook-form |
1077
+ | `name` | `string` | No | Field name |
1078
+ | `label` | `string` | Yes | Label text |
1079
+ | `formDescription` | `string` | Yes | Help text below field |
1080
+ | `formItemClass` | `string` | Yes | CSS for form item wrapper |
1081
+ | `extraFormComponent` | `(value: string) => ReactNode` | Yes | Extra component rendered with value |
1082
+ | `...textAreaProps` | `TextareaHTMLAttributes` | Yes | Standard HTML textarea attributes |
1083
+
1084
+ ### FormDateInput
1085
+
1086
+ ```tsx
1087
+ import { FormDateInput } from "ikoncomponents";
1088
+ ```
1089
+
1090
+ #### Props
1091
+
1092
+ | Property | Type | Optional | Description |
1093
+ |------------------------|-----------|----------|-------------------------------------------|
1094
+ | `formControl` | `any` | No | `form.control` from react-hook-form |
1095
+ | `name` | `string` | No | Field name |
1096
+ | `label` | `string` | Yes | Label text |
1097
+ | `placeholder` | `string` | Yes | Placeholder text |
1098
+ | `dateFormat` | `string` | Yes | Date display format (default: `"PPP"`) |
1099
+ | `calendarDateDisabled` | `Matcher` | Yes | Disable certain dates (react-day-picker) |
1100
+ | `formDescription` | `string` | Yes | Help text below field |
1101
+ | `disabled` | `boolean` | Yes | Disable the input |
1102
+
1103
+ ### FormComboboxInput
1104
+
1105
+ ```tsx
1106
+ import { FormComboboxInput } from "ikoncomponents";
1107
+ ```
1108
+
1109
+ #### Props
1110
+
1111
+ | Property | Type | Optional | Description |
1112
+ |----------------------|------------------------------------------|----------|------------------------------------|
1113
+ | `formControl` | `any` | No | `form.control` from react-hook-form |
1114
+ | `name` | `string` | No | Field name |
1115
+ | `label` | `string` | Yes | Label text |
1116
+ | `placeholder` | `string` | Yes | Placeholder text |
1117
+ | `formDescription` | `string` | Yes | Help text below field |
1118
+ | `items` | `FormComboboxItemProps[]` | No | Selectable items |
1119
+ | `disabled` | `((...args: any) => boolean) \| boolean` | Yes | Disable the input |
1120
+ | `onSelect` | `(value: string \| string[]) => void` | Yes | Selection callback |
1121
+ | `defaultValue` | `[]` | Yes | Default selected value |
1122
+
1123
+ ### FormComboboxInputWithValue
1124
+
1125
+ ```tsx
1126
+ import { FormComboboxInputWithValue } from "ikoncomponents";
1127
+ ```
1128
+
1129
+ A controlled variant of `FormComboboxInput` that accepts external `value` and `onChange`.
1130
+
1131
+ #### Props
1132
+
1133
+ | Property | Type | Optional | Description |
1134
+ |----------------------|---------------------------------------------------------------|----------|------------------------------------|
1135
+ | `formControl` | `Control<any>` | No | `form.control` from react-hook-form |
1136
+ | `name` | `string` | No | Field name |
1137
+ | `label` | `string` | Yes | Label text |
1138
+ | `placeholder` | `string` | Yes | Placeholder text |
1139
+ | `formDescription` | `string` | Yes | Help text |
1140
+ | `items` | `{ value: string; label: string; disabled?: boolean \| ((item: any) => boolean) }[]` | No | Items |
1141
+ | `disabled` | `boolean \| ((...args: any[]) => boolean)` | Yes | Disable the input |
1142
+ | `onSelect` | `(value: any) => void` | Yes | Selection callback |
1143
+ | `value` | `string` | Yes | Controlled value |
1144
+ | `onChange` | `(value: any) => void` | Yes | Controlled change handler |
1145
+
1146
+ ### FormMultiComboboxInput
1147
+
1148
+ ```tsx
1149
+ import { FormMultiComboboxInput } from "ikoncomponents";
1150
+ ```
1151
+
1152
+ #### Props
1153
+
1154
+ | Property | Type | Optional | Default | Description |
1155
+ |----------------------|------------------------------------------|----------|---------|------------------------------------|
1156
+ | `formControl` | `any` | No | | `form.control` from react-hook-form |
1157
+ | `name` | `string` | No | | Field name |
1158
+ | `label` | `string` | Yes | | Label text |
1159
+ | `placeholder` | `string` | Yes | | Placeholder text |
1160
+ | `formDescription` | `string` | Yes | | Help text |
1161
+ | `items` | `FormComboboxItemProps[]` | Yes | `[]` | Selectable items |
1162
+ | `disabled` | `((...args: any) => boolean) \| boolean` | Yes | | Disable the input |
1163
+ | `onSelect` | `(value: string \| string[]) => void` | Yes | | Selection callback |
1164
+ | `defaultValue` | `any[]` | Yes | `[]` | Default selected values |
1165
+ | `defaultOptions` | `number` | Yes | `2` | Visible chips before "+N" |
1166
+
1167
+ ### FormOtpInput
1168
+
1169
+ ```tsx
1170
+ import { FormOtpInput } from "ikoncomponents";
1171
+ ```
1172
+
1173
+ Same props as `FormInput`. Renders a 4-digit OTP input.
1174
+
1175
+ ---
1176
+
1177
+ ## ImageCropperProvider
1178
+
1179
+ ```tsx
1180
+ import { ImageCropperProvider, useImageCropper } from "ikoncomponents";
1181
+ ```
1182
+
1183
+ Provides an image cropper context and modal for cropping images into landscape, portrait, and icon aspect ratios.
1184
+
1185
+ #### `ImageCropperProps`
1186
+
1187
+ | Property | Type | Optional | Description |
1188
+ |--------------------|------------------------------------------------------------------------------------------|----------|-----------------------------------------|
1189
+ | `children` | `ReactNode` | No | Wrapped content |
1190
+ | `uploadedImages` | `CropperUploadImagesInfoProps \| null` | No | Pre-uploaded images to initialize with |
1191
+ | `onCropperChange` | `(originalImage: OriginalImageProps, aspectRatioWiseImages: AspectRatioWiseImagesProps) => void` | No | Callback with cropped results |
1192
+ | `modalOpen` | `boolean` | Yes | Control modal visibility |
1193
+ | `onModalOpenChange` | `(open: boolean) => void` | Yes | Modal open state change callback |
1194
+
1195
+ #### `useImageCropper()` Hook
1196
+
1197
+ Returns:
1198
+
1199
+ | Property | Type | Description |
1200
+ |--------------------------|-----------------------------------------------------------|--------------------------------|
1201
+ | `originalImage` | `OriginalImageProps` | Current original image state |
1202
+ | `setOriginalImage` | `(img: OriginalImageProps) => void` | Set original image |
1203
+ | `aspectRatioWiseImages` | `AspectRatioWiseImagesProps` | Cropped images per ratio |
1204
+ | `setAspectRatioWiseImages`| `(imgs: AspectRatioWiseImagesProps) => void` | Set cropped images |
1205
+
1206
+ ---
1207
+
1208
+ ## ThemeToggleBtn
1209
+
1210
+ ```tsx
1211
+ import { ThemeToggleBtn } from "ikoncomponents";
1212
+ ```
1213
+
1214
+ Renders a theme toggle button (light/dark/system). No props required.
1215
+
1216
+ ---
1217
+
1218
+ ## WorkInProgress
1219
+
1220
+ ```tsx
1221
+ import { WorkInProgress } from "ikoncomponents";
1222
+ ```
1223
+
1224
+ Renders a "Work In Progress" placeholder. No props required.
1225
+