@noxickon/onyx 4.1.5 → 5.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/AI-README.md +467 -103
- package/dist/_internal/styles/checkbox.variants.d.ts +5 -0
- package/dist/_internal/styles/index.d.ts +3 -0
- package/dist/_internal/styles/radio.variants.d.ts +5 -0
- package/dist/_internal/styles/switch.variants.d.ts +9 -0
- package/dist/_internal/types.d.ts +1 -0
- package/dist/_internal/utils/Portal/PortalContainerContext.d.ts +2 -0
- package/dist/_internal/utils/Portal/index.d.ts +1 -0
- package/dist/chunks/hooks-B58X4Fdh.js +46 -0
- package/dist/chunks/hooks-iUUmqFrq.js +7056 -0
- package/dist/chunks/ui-Bz7A98Kq.js +13 -0
- package/dist/chunks/ui-CezxuKW0.js +22994 -0
- package/dist/contexts/contexts.cjs.js +2 -2
- package/dist/contexts/contexts.es.js +55 -55
- package/dist/forms/Checkbox/Checkbox.stories.d.ts +10 -3
- package/dist/forms/Checkbox/index.d.ts +3 -3
- package/dist/forms/Checkbox/src/Checkbox.d.ts +1 -1
- package/dist/forms/Checkbox/src/Checkbox.types.d.ts +11 -4
- package/dist/forms/Checkbox/src/CheckboxGroup.d.ts +1 -1
- package/dist/forms/Checkbox/src/CheckboxGroupItem.d.ts +1 -1
- package/dist/forms/Checkbox/src/context/CheckboxGroupContext.types.d.ts +5 -2
- package/dist/forms/Input/Date/src/useDateInput.d.ts +2 -2
- package/dist/forms/Input/Number/src/Number.types.d.ts +4 -4
- package/dist/forms/Input/Number/src/context/NumberContext.types.d.ts +2 -2
- package/dist/forms/Input/Time/src/useTimeInput.d.ts +2 -2
- package/dist/forms/Radio/Radio.stories.d.ts +14 -3
- package/dist/forms/Radio/index.d.ts +2 -2
- package/dist/forms/Radio/src/Radio.types.d.ts +9 -7
- package/dist/forms/Radio/src/RadioGroup.d.ts +1 -1
- package/dist/forms/Radio/src/RadioGroupItem.d.ts +1 -1
- package/dist/forms/Radio/src/context/RadioGroupContext.types.d.ts +5 -2
- package/dist/forms/Select/Select.stories.d.ts +53 -4
- package/dist/forms/Select/index.d.ts +1 -1
- package/dist/forms/Select/src/Select.d.ts +1 -1
- package/dist/forms/Select/src/Select.types.d.ts +17 -5
- package/dist/forms/Switch/Switch.stories.d.ts +1 -0
- package/dist/forms/Switch/src/Switch.d.ts +1 -1
- package/dist/forms/Switch/src/Switch.types.d.ts +2 -0
- package/dist/hooks/hooks.cjs.js +1 -1
- package/dist/hooks/hooks.es.js +11 -10
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/useControllableState/src/useControllableState.types.d.ts +3 -6
- package/dist/hooks/useSort/UseSort.stories.d.ts +6 -0
- package/dist/hooks/useSort/index.d.ts +2 -0
- package/dist/hooks/useSort/src/useSort.d.ts +3 -0
- package/dist/hooks/useSort/src/useSort.types.d.ts +20 -0
- package/dist/hooks/useSort/test/useSort.test.d.ts +1 -0
- package/dist/layouts/layouts.cjs.js +1 -1
- package/dist/layouts/layouts.es.js +31 -32
- package/dist/legacy/index.d.ts +1 -0
- package/dist/legacy/legacy.cjs.js +1 -1
- package/dist/legacy/legacy.es.js +766 -604
- package/dist/legacy/ui/Floating/Floating.stories.d.ts +1 -1
- package/dist/legacy/ui/Floating/index.d.ts +1 -1
- package/dist/legacy/ui/Floating/src/Floating.types.d.ts +1 -1
- package/dist/legacy/ui/Floating/src/FloatingTrigger.d.ts +1 -1
- package/dist/legacy/ui/Toast/Toast.stories.d.ts +9 -0
- package/dist/legacy/ui/Toast/index.d.ts +5 -0
- package/dist/legacy/ui/Toast/src/Toast.d.ts +2 -0
- package/dist/legacy/ui/Toast/src/Toast.types.d.ts +29 -0
- package/dist/legacy/ui/Toast/src/ToastItem.d.ts +2 -0
- package/dist/legacy/ui/Toast/src/context/ToastContext.d.ts +2 -0
- package/dist/legacy/ui/Toast/src/context/ToastContext.types.d.ts +28 -0
- package/dist/legacy/ui/Toast/src/context/ToastProvider.d.ts +2 -0
- package/dist/legacy/ui/Toast/src/context/useToast.d.ts +2 -0
- package/dist/legacy/ui/Toast/test/Toast.test.d.ts +1 -0
- package/dist/onyx.cjs.js +1 -1
- package/dist/onyx.es.js +19 -18
- package/dist/pages/pages.cjs.js +1 -1
- package/dist/pages/pages.es.js +37 -37
- package/dist/routes/routes.cjs.js +1 -1
- package/dist/routes/routes.es.js +3 -3
- package/dist/styles.css +1 -0
- package/dist/ui/Breadcrumb/Breadcrumb.stories.d.ts +1 -1
- package/dist/ui/Breadcrumb/index.d.ts +1 -1
- package/dist/ui/Breadcrumb/src/Breadcrumb.types.d.ts +1 -1
- package/dist/ui/Breadcrumb/src/BreadcrumbLink.d.ts +1 -1
- package/dist/ui/Button/Button.stories.d.ts +2 -2
- package/dist/ui/Button/src/Button.d.ts +1 -1
- package/dist/ui/Button/src/Button.types.d.ts +1 -1
- package/dist/ui/Dropdown/Dropdown.stories.d.ts +23 -3
- package/dist/ui/Dropdown/index.d.ts +8 -2
- package/dist/ui/Dropdown/src/Dropdown.types.d.ts +31 -4
- package/dist/ui/Dropdown/src/DropdownCheckboxItem.d.ts +2 -0
- package/dist/ui/Dropdown/src/DropdownGroup.d.ts +2 -0
- package/dist/ui/Dropdown/src/DropdownRadioGroup.d.ts +2 -0
- package/dist/ui/Dropdown/src/DropdownRadioItem.d.ts +2 -0
- package/dist/ui/Dropdown/src/DropdownSubMenu.d.ts +2 -0
- package/dist/ui/Dropdown/src/DropdownSubMenuContent.d.ts +2 -0
- package/dist/ui/Dropdown/src/DropdownSubMenuTrigger.d.ts +2 -0
- package/dist/ui/Dropdown/src/DropdownTrigger.d.ts +1 -1
- package/dist/ui/Dropdown/src/context/DropdownContext.types.d.ts +2 -0
- package/dist/ui/Dropdown/src/context/DropdownRadioContext.d.ts +2 -0
- package/dist/ui/Dropdown/src/context/DropdownRadioContext.types.d.ts +5 -0
- package/dist/ui/Dropdown/src/context/DropdownSubMenuContext.d.ts +2 -0
- package/dist/ui/Dropdown/src/context/DropdownSubMenuContext.types.d.ts +14 -0
- package/dist/ui/Dropdown/src/context/useDropdownRadioContext.d.ts +1 -0
- package/dist/ui/Dropdown/src/context/useDropdownSubMenuContext.d.ts +1 -0
- package/dist/ui/HoverCard/HoverCard.stories.d.ts +1 -1
- package/dist/ui/HoverCard/index.d.ts +1 -1
- package/dist/ui/HoverCard/src/HoverCard.types.d.ts +1 -1
- package/dist/ui/HoverCard/src/HoverCardTrigger.d.ts +1 -1
- package/dist/ui/Link/Link.stories.d.ts +1 -1
- package/dist/ui/Link/src/Link.d.ts +1 -1
- package/dist/ui/Link/src/Link.types.d.ts +1 -1
- package/dist/ui/Pagination/Pagination.stories.d.ts +3 -3
- package/dist/ui/Pagination/index.d.ts +3 -3
- package/dist/ui/Pagination/src/Pagination.types.d.ts +3 -3
- package/dist/ui/Pagination/src/PaginationLink.d.ts +1 -1
- package/dist/ui/Pagination/src/PaginationNext.d.ts +1 -1
- package/dist/ui/Pagination/src/PaginationPrevious.d.ts +1 -1
- package/dist/ui/Popover/Popover.stories.d.ts +1 -1
- package/dist/ui/Popover/index.d.ts +1 -1
- package/dist/ui/Popover/src/Popover.types.d.ts +1 -1
- package/dist/ui/Popover/src/PopoverTrigger.d.ts +1 -1
- package/dist/ui/Popper/index.d.ts +1 -1
- package/dist/ui/Popper/src/Popper.types.d.ts +1 -1
- package/dist/ui/Popper/src/PopperAnchor.d.ts +1 -1
- package/dist/ui/Table/Table.stories.d.ts +7 -4
- package/dist/ui/Table/index.d.ts +3 -3
- package/dist/ui/Table/src/Table.d.ts +1 -1
- package/dist/ui/Table/src/Table.types.d.ts +8 -0
- package/dist/ui/Table/src/TableHead.d.ts +1 -1
- package/dist/ui/Table/src/TableRow.d.ts +1 -1
- package/dist/ui/Table/src/context/TableContext.types.d.ts +6 -0
- package/dist/ui/Toast/Toast.stories.d.ts +4 -2
- package/dist/ui/Toast/index.d.ts +1 -1
- package/dist/ui/Toast/src/Toast.d.ts +2 -2
- package/dist/ui/Toast/src/Toast.types.d.ts +23 -23
- package/dist/ui/Toast/src/context/ToastContext.types.d.ts +15 -23
- package/dist/ui/Toast/src/context/ToastProvider.d.ts +2 -2
- package/dist/ui/Toast/src/context/useToast.d.ts +2 -1
- package/dist/ui.css +1 -1
- package/dist/utils/utils.cjs.js +1 -1
- package/dist/utils/utils.es.js +6 -6
- package/package.json +17 -16
- package/dist/chunks/hooks-BMXCuU2h.js +0 -7318
- package/dist/chunks/hooks-H39lCrRt.js +0 -31
- package/dist/chunks/ui-Be695bGj.js +0 -20915
- package/dist/chunks/ui-DQDo-5EK.js +0 -9
- package/dist/ui/Dropdown/src/DropdownLabel.d.ts +0 -2
- package/dist/ui/Toast/src/ToastItem.d.ts +0 -2
package/AI-README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Onyx Component Library - AI Reference Guide
|
|
2
2
|
|
|
3
|
-
**Version:** 3.0.0 • **Updated:**
|
|
3
|
+
**Version:** 3.0.0 • **Updated:** 2026-02-04 • **Built from:** a0a8ed34
|
|
4
4
|
|
|
5
5
|
> This comprehensive reference guide provides detailed information about all components, hooks, contexts, utilities, and patterns in the Onyx component library. Designed for AI assistants and developers to quickly understand component APIs and usage.
|
|
6
6
|
|
|
@@ -90,7 +90,7 @@ import '@noxickon/onyx/animations'; // Animations (optional)
|
|
|
90
90
|
|
|
91
91
|
---
|
|
92
92
|
|
|
93
|
-
# UI Components (
|
|
93
|
+
# UI Components (45)
|
|
94
94
|
|
|
95
95
|
## OxAccordion
|
|
96
96
|
|
|
@@ -226,7 +226,8 @@ interface OxAspectRatioFallbackProps extends ComponentPropsWithRef<'div'> {
|
|
|
226
226
|
|
|
227
227
|
Avatar component with status indicators and loading states.
|
|
228
228
|
|
|
229
|
-
**Pattern**: Simple Component
|
|
229
|
+
**Pattern**: Simple Component + Compound Component (OxAvatarField)
|
|
230
|
+
**Sub-components**: `OxAvatarField`, `OxAvatarField.Content`, `OxAvatarField.Name`, `OxAvatarField.Subtitle`
|
|
230
231
|
|
|
231
232
|
### Props
|
|
232
233
|
|
|
@@ -242,11 +243,31 @@ interface OxAvatarProps extends Omit<ComponentPropsWithRef<'div'>, 'children'> {
|
|
|
242
243
|
src?: string;
|
|
243
244
|
status?: 'online' | 'offline' | 'away' | 'busy';
|
|
244
245
|
}
|
|
246
|
+
|
|
247
|
+
interface OxAvatarFieldProps extends ComponentPropsWithRef<'div'> {
|
|
248
|
+
children: ReactNode;
|
|
249
|
+
orientation?: 'horizontal' | 'vertical'; // Layout direction
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
interface OxAvatarFieldContentProps extends ComponentPropsWithRef<'div'> {
|
|
253
|
+
children: ReactNode;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
interface OxAvatarFieldNameProps extends ComponentPropsWithRef<'span'> {
|
|
257
|
+
children: ReactNode;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
interface OxAvatarFieldSubtitleProps extends ComponentPropsWithRef<'span'> {
|
|
261
|
+
children: ReactNode;
|
|
262
|
+
}
|
|
245
263
|
```
|
|
246
264
|
|
|
247
265
|
### Example
|
|
248
266
|
|
|
249
267
|
```tsx
|
|
268
|
+
{
|
|
269
|
+
/* Basic avatar */
|
|
270
|
+
}
|
|
250
271
|
<OxAvatar
|
|
251
272
|
src="/avatar.jpg"
|
|
252
273
|
alt="User Name"
|
|
@@ -255,7 +276,18 @@ interface OxAvatarProps extends Omit<ComponentPropsWithRef<'div'>, 'children'> {
|
|
|
255
276
|
showStatus
|
|
256
277
|
status="online"
|
|
257
278
|
fallback="UN"
|
|
258
|
-
|
|
279
|
+
/>;
|
|
280
|
+
|
|
281
|
+
{
|
|
282
|
+
/* Avatar with field layout */
|
|
283
|
+
}
|
|
284
|
+
<OxAvatarField orientation="horizontal">
|
|
285
|
+
<OxAvatar src="/avatar.jpg" alt="John Doe" size="md" />
|
|
286
|
+
<OxAvatarField.Content>
|
|
287
|
+
<OxAvatarField.Name>John Doe</OxAvatarField.Name>
|
|
288
|
+
<OxAvatarField.Subtitle>Software Engineer</OxAvatarField.Subtitle>
|
|
289
|
+
</OxAvatarField.Content>
|
|
290
|
+
</OxAvatarField>;
|
|
259
291
|
```
|
|
260
292
|
|
|
261
293
|
---
|
|
@@ -266,7 +298,7 @@ Notification badge for displaying counts or status indicators on UI elements. De
|
|
|
266
298
|
|
|
267
299
|
**Pattern**: Simple Component
|
|
268
300
|
|
|
269
|
-
> **Note:** Badges are optimized for ghost buttons and icons.
|
|
301
|
+
> **Note:** Badges are optimized for ghost buttons and icons. Count badges use subtle backgrounds; dot badges use solid colors for status indicators. Use the `variant` prop to change colors.
|
|
270
302
|
|
|
271
303
|
### Props
|
|
272
304
|
|
|
@@ -341,7 +373,7 @@ interface OxTagProps extends ComponentPropsWithRef<'span'> {
|
|
|
341
373
|
|
|
342
374
|
## OxBreadcrumb
|
|
343
375
|
|
|
344
|
-
Breadcrumb navigation with
|
|
376
|
+
Breadcrumb navigation with asSlot pattern support.
|
|
345
377
|
|
|
346
378
|
**Pattern**: Compound Component
|
|
347
379
|
**Sub-components**: `Ellipsis`, `Item`, `Link`, `Page`, `Separator`
|
|
@@ -358,7 +390,7 @@ interface OxBreadcrumbItemProps extends ComponentPropsWithRef<'li'> {
|
|
|
358
390
|
}
|
|
359
391
|
|
|
360
392
|
interface OxBreadcrumbLinkProps extends ComponentPropsWithRef<'a'> {
|
|
361
|
-
|
|
393
|
+
asSlot?: boolean; // Renders as child component (e.g., Next.js Link)
|
|
362
394
|
children: ReactNode;
|
|
363
395
|
current?: boolean; // Marks as current page
|
|
364
396
|
href?: string;
|
|
@@ -390,9 +422,9 @@ interface OxBreadcrumbEllipsisProps extends ComponentPropsWithRef<'span'> {}
|
|
|
390
422
|
</OxBreadcrumb>;
|
|
391
423
|
|
|
392
424
|
{
|
|
393
|
-
/* Using
|
|
425
|
+
/* Using asSlot with Next.js Link */
|
|
394
426
|
}
|
|
395
|
-
<OxBreadcrumb.Link
|
|
427
|
+
<OxBreadcrumb.Link asSlot>
|
|
396
428
|
<Link to="/dashboard">Dashboard</Link>
|
|
397
429
|
</OxBreadcrumb.Link>;
|
|
398
430
|
```
|
|
@@ -405,13 +437,13 @@ Button component with variants, sizes, and loading states.
|
|
|
405
437
|
|
|
406
438
|
**Pattern**: Simple Component
|
|
407
439
|
|
|
408
|
-
> **Note:** For links styled as buttons, use `OxButton` with `
|
|
440
|
+
> **Note:** For links styled as buttons, use `OxButton` with `asSlot` prop. Use `OxLink` only for text-based links with underline.
|
|
409
441
|
|
|
410
442
|
### Props
|
|
411
443
|
|
|
412
444
|
```tsx
|
|
413
445
|
interface OxButtonProps extends ComponentPropsWithRef<'button'> {
|
|
414
|
-
|
|
446
|
+
asSlot?: boolean; // Renders as child element (useful for Link components)
|
|
415
447
|
fullWidth?: boolean; // Expands to full container width
|
|
416
448
|
isLoading?: boolean; // Shows spinner, disables interaction
|
|
417
449
|
size?: 'sm' | 'md' | 'lg';
|
|
@@ -429,7 +461,7 @@ interface OxButtonProps extends ComponentPropsWithRef<'button'> {
|
|
|
429
461
|
{
|
|
430
462
|
/* Render as Link while keeping button styling */
|
|
431
463
|
}
|
|
432
|
-
<OxButton
|
|
464
|
+
<OxButton asSlot variant="primary">
|
|
433
465
|
<Link to="/dashboard">Dashboard</Link>
|
|
434
466
|
</OxButton>;
|
|
435
467
|
```
|
|
@@ -712,7 +744,7 @@ interface OxDrawerFooterProps extends ComponentPropsWithRef<'div'> {
|
|
|
712
744
|
Dropdown menu with extensive sub-components.
|
|
713
745
|
|
|
714
746
|
**Pattern**: Compound Component
|
|
715
|
-
**Sub-components**: `Body`, `Content`, `Footer`, `Header`, `Item`, `
|
|
747
|
+
**Sub-components**: `Body`, `CheckboxItem`, `Content`, `Footer`, `Group`, `Header`, `Item`, `RadioGroup`, `RadioItem`, `Separator`, `Shortcut`, `SubMenu`, `SubMenuContent`, `SubMenuTrigger`, `Trigger`
|
|
716
748
|
|
|
717
749
|
### Props
|
|
718
750
|
|
|
@@ -720,6 +752,7 @@ Dropdown menu with extensive sub-components.
|
|
|
720
752
|
interface OxDropdownProps {
|
|
721
753
|
align?: 'start' | 'center' | 'end';
|
|
722
754
|
children: ReactNode;
|
|
755
|
+
closeOnOutsideClick?: boolean; // Close when clicking outside
|
|
723
756
|
defaultOpen?: boolean;
|
|
724
757
|
disabled?: boolean;
|
|
725
758
|
onOpenChange?: (open: boolean) => void;
|
|
@@ -729,7 +762,7 @@ interface OxDropdownProps {
|
|
|
729
762
|
|
|
730
763
|
interface OxDropdownTriggerProps extends ComponentPropsWithRef<'button'> {
|
|
731
764
|
animateIcon?: boolean; // Animates icon on open/close
|
|
732
|
-
|
|
765
|
+
asSlot?: boolean; // Renders as child component (useful for custom triggers)
|
|
733
766
|
children: ReactNode;
|
|
734
767
|
hideIcon?: boolean;
|
|
735
768
|
icon?: LucideIcon;
|
|
@@ -754,14 +787,50 @@ interface OxDropdownItemButtonProps extends Omit<ComponentPropsWithRef<'button'>
|
|
|
754
787
|
}
|
|
755
788
|
|
|
756
789
|
interface OxDropdownItemLinkProps extends ComponentPropsWithRef<'a'> {
|
|
757
|
-
disabled?: boolean;
|
|
790
|
+
disabled?: boolean;
|
|
758
791
|
href: string; // Required for link variant
|
|
759
792
|
}
|
|
760
793
|
|
|
761
|
-
interface
|
|
794
|
+
interface OxDropdownCheckboxItemProps extends Omit<
|
|
795
|
+
ComponentPropsWithRef<'button'>,
|
|
796
|
+
'type' | 'onChange'
|
|
797
|
+
> {
|
|
798
|
+
checked?: boolean;
|
|
799
|
+
closeOnSelect?: boolean; // Close dropdown when selected
|
|
800
|
+
defaultChecked?: boolean;
|
|
801
|
+
onCheckedChange?: (checked: boolean) => void;
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
interface OxDropdownRadioGroupProps extends Omit<ComponentPropsWithRef<'div'>, 'onChange'> {
|
|
805
|
+
children: ReactNode;
|
|
806
|
+
closeOnSelect?: boolean; // Close dropdown when item selected
|
|
807
|
+
defaultValue?: string;
|
|
808
|
+
onValueChange?: (value: string) => void;
|
|
809
|
+
value?: string;
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
interface OxDropdownRadioItemProps extends Omit<ComponentPropsWithRef<'button'>, 'type' | 'value'> {
|
|
813
|
+
value: string; // Required
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
interface OxDropdownGroupProps extends ComponentPropsWithRef<'div'> {
|
|
817
|
+
children: ReactNode;
|
|
818
|
+
label?: string; // Group label
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
interface OxDropdownSubMenuProps {
|
|
762
822
|
children: ReactNode;
|
|
763
823
|
}
|
|
764
824
|
|
|
825
|
+
interface OxDropdownSubMenuTriggerProps extends Omit<ComponentPropsWithRef<'button'>, 'type'> {
|
|
826
|
+
disabled?: boolean;
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
interface OxDropdownSubMenuContentProps extends ComponentPropsWithRef<'div'> {
|
|
830
|
+
children: ReactNode;
|
|
831
|
+
className?: string;
|
|
832
|
+
}
|
|
833
|
+
|
|
765
834
|
interface OxDropdownShortcutProps extends ComponentPropsWithRef<'span'> {
|
|
766
835
|
children: ReactNode;
|
|
767
836
|
}
|
|
@@ -790,6 +859,33 @@ interface OxDropdownSeparatorProps extends Omit<OxSeparatorProps, 'orientation'
|
|
|
790
859
|
</OxDropdown.Item>
|
|
791
860
|
<OxDropdown.Item href="/settings">Settings</OxDropdown.Item>
|
|
792
861
|
<OxDropdown.Separator />
|
|
862
|
+
|
|
863
|
+
{/* Checkbox items */}
|
|
864
|
+
<OxDropdown.CheckboxItem checked={showGrid} onCheckedChange={setShowGrid}>
|
|
865
|
+
Show Grid
|
|
866
|
+
</OxDropdown.CheckboxItem>
|
|
867
|
+
|
|
868
|
+
{/* Radio group */}
|
|
869
|
+
<OxDropdown.RadioGroup value={view} onValueChange={setView}>
|
|
870
|
+
<OxDropdown.RadioItem value="list">List View</OxDropdown.RadioItem>
|
|
871
|
+
<OxDropdown.RadioItem value="grid">Grid View</OxDropdown.RadioItem>
|
|
872
|
+
</OxDropdown.RadioGroup>
|
|
873
|
+
|
|
874
|
+
{/* Grouped items */}
|
|
875
|
+
<OxDropdown.Group label="More Actions">
|
|
876
|
+
<OxDropdown.Item>Archive</OxDropdown.Item>
|
|
877
|
+
<OxDropdown.Item>Export</OxDropdown.Item>
|
|
878
|
+
</OxDropdown.Group>
|
|
879
|
+
|
|
880
|
+
{/* Submenu */}
|
|
881
|
+
<OxDropdown.SubMenu>
|
|
882
|
+
<OxDropdown.SubMenuTrigger>Share</OxDropdown.SubMenuTrigger>
|
|
883
|
+
<OxDropdown.SubMenuContent>
|
|
884
|
+
<OxDropdown.Item>Copy Link</OxDropdown.Item>
|
|
885
|
+
<OxDropdown.Item>Email</OxDropdown.Item>
|
|
886
|
+
</OxDropdown.SubMenuContent>
|
|
887
|
+
</OxDropdown.SubMenu>
|
|
888
|
+
|
|
793
889
|
<OxDropdown.Item onClick={handleDelete}>Delete</OxDropdown.Item>
|
|
794
890
|
</OxDropdown.Body>
|
|
795
891
|
</OxDropdown.Content>
|
|
@@ -900,7 +996,7 @@ interface OxFloatingProps {
|
|
|
900
996
|
}
|
|
901
997
|
|
|
902
998
|
interface OxFloatingTriggerProps extends ComponentPropsWithRef<'div'> {
|
|
903
|
-
|
|
999
|
+
asSlot?: boolean; // Renders as child component
|
|
904
1000
|
children: ReactNode;
|
|
905
1001
|
}
|
|
906
1002
|
|
|
@@ -940,7 +1036,7 @@ interface OxHoverCardProps {
|
|
|
940
1036
|
}
|
|
941
1037
|
|
|
942
1038
|
interface OxHoverCardTriggerProps extends ComponentPropsWithoutRef<'div'> {
|
|
943
|
-
|
|
1039
|
+
asSlot?: boolean;
|
|
944
1040
|
children: ReactNode;
|
|
945
1041
|
}
|
|
946
1042
|
|
|
@@ -954,7 +1050,7 @@ interface OxHoverCardContentProps extends ComponentPropsWithoutRef<'div'> {
|
|
|
954
1050
|
|
|
955
1051
|
```tsx
|
|
956
1052
|
<OxHoverCard openDelay={200} closeDelay={100}>
|
|
957
|
-
<OxHoverCard.Trigger
|
|
1053
|
+
<OxHoverCard.Trigger asSlot>
|
|
958
1054
|
<OxButton>Hover me</OxButton>
|
|
959
1055
|
</OxHoverCard.Trigger>
|
|
960
1056
|
<OxHoverCard.Content>
|
|
@@ -1006,6 +1102,40 @@ import { Check } from 'lucide-react';
|
|
|
1006
1102
|
|
|
1007
1103
|
---
|
|
1008
1104
|
|
|
1105
|
+
## OxImage
|
|
1106
|
+
|
|
1107
|
+
Image component with loading states and fallback support.
|
|
1108
|
+
|
|
1109
|
+
**Pattern**: Simple Component
|
|
1110
|
+
|
|
1111
|
+
### Props
|
|
1112
|
+
|
|
1113
|
+
```tsx
|
|
1114
|
+
interface OxImageProps extends Omit<ComponentPropsWithRef<'img'>, 'onLoad' | 'onError'> {
|
|
1115
|
+
alt: string; // Required - Alt text for accessibility
|
|
1116
|
+
fallback?: ReactNode; // Content shown when image fails to load
|
|
1117
|
+
objectFit?: 'contain' | 'cover' | 'fill' | 'none' | 'scale-down';
|
|
1118
|
+
onLoadComplete?: () => void; // Called when image loads successfully
|
|
1119
|
+
onLoadError?: () => void; // Called when image fails to load
|
|
1120
|
+
src: string; // Required - Image source URL
|
|
1121
|
+
}
|
|
1122
|
+
```
|
|
1123
|
+
|
|
1124
|
+
### Example
|
|
1125
|
+
|
|
1126
|
+
```tsx
|
|
1127
|
+
<OxImage
|
|
1128
|
+
src="/photo.jpg"
|
|
1129
|
+
alt="Profile photo"
|
|
1130
|
+
objectFit="cover"
|
|
1131
|
+
onLoadComplete={() => console.log('Loaded')}
|
|
1132
|
+
onLoadError={() => console.log('Failed')}
|
|
1133
|
+
fallback={<OxSkeleton shape="rectangle" />}
|
|
1134
|
+
/>
|
|
1135
|
+
```
|
|
1136
|
+
|
|
1137
|
+
---
|
|
1138
|
+
|
|
1009
1139
|
## OxJsonField (alpha)
|
|
1010
1140
|
|
|
1011
1141
|
JSON data display with syntax highlighting.
|
|
@@ -1122,13 +1252,13 @@ Link component for text-based navigation with hover underline.
|
|
|
1122
1252
|
|
|
1123
1253
|
**Pattern**: Simple Component
|
|
1124
1254
|
|
|
1125
|
-
> **Note:** For button-styled links (e.g., call-to-action buttons), use `OxButton` with `
|
|
1255
|
+
> **Note:** For button-styled links (e.g., call-to-action buttons), use `OxButton` with `asSlot` instead. `OxLink` is for inline and text-based links only.
|
|
1126
1256
|
|
|
1127
1257
|
### Props
|
|
1128
1258
|
|
|
1129
1259
|
```tsx
|
|
1130
1260
|
interface OxLinkProps extends ComponentPropsWithRef<'a'> {
|
|
1131
|
-
|
|
1261
|
+
asSlot?: boolean; // Renders as child element (useful for routing libraries)
|
|
1132
1262
|
disabled?: boolean; // Disables link navigation
|
|
1133
1263
|
size?: 'sm' | 'md' | 'lg';
|
|
1134
1264
|
variant?: 'primary' | 'secondary' | 'accent'; // primary = violet text, secondary = white text
|
|
@@ -1145,7 +1275,7 @@ interface OxLinkProps extends ComponentPropsWithRef<'a'> {
|
|
|
1145
1275
|
{
|
|
1146
1276
|
/* Use with React Router */
|
|
1147
1277
|
}
|
|
1148
|
-
<OxLink
|
|
1278
|
+
<OxLink asSlot>
|
|
1149
1279
|
<Link to="/dashboard">Dashboard</Link>
|
|
1150
1280
|
</OxLink>;
|
|
1151
1281
|
```
|
|
@@ -1367,7 +1497,7 @@ interface OxPaginationItemProps extends ComponentPropsWithRef<'li'> {
|
|
|
1367
1497
|
}
|
|
1368
1498
|
|
|
1369
1499
|
interface OxPaginationLinkProps extends ComponentPropsWithRef<'a'> {
|
|
1370
|
-
|
|
1500
|
+
asSlot?: boolean; // Renders as child component (for routing libraries)
|
|
1371
1501
|
children: ReactNode;
|
|
1372
1502
|
disabled?: boolean;
|
|
1373
1503
|
href?: string;
|
|
@@ -1375,14 +1505,14 @@ interface OxPaginationLinkProps extends ComponentPropsWithRef<'a'> {
|
|
|
1375
1505
|
}
|
|
1376
1506
|
|
|
1377
1507
|
interface OxPaginationPreviousProps extends ComponentPropsWithRef<'a'> {
|
|
1378
|
-
|
|
1508
|
+
asSlot?: boolean; // Renders as child component
|
|
1379
1509
|
children?: ReactNode;
|
|
1380
1510
|
disabled?: boolean;
|
|
1381
1511
|
href?: string;
|
|
1382
1512
|
}
|
|
1383
1513
|
|
|
1384
1514
|
interface OxPaginationNextProps extends ComponentPropsWithRef<'a'> {
|
|
1385
|
-
|
|
1515
|
+
asSlot?: boolean; // Renders as child component
|
|
1386
1516
|
children?: ReactNode;
|
|
1387
1517
|
disabled?: boolean;
|
|
1388
1518
|
href?: string;
|
|
@@ -1419,7 +1549,7 @@ interface OxPaginationEllipsisProps extends ComponentPropsWithRef<'span'> {}
|
|
|
1419
1549
|
|
|
1420
1550
|
## OxPopover
|
|
1421
1551
|
|
|
1422
|
-
Popover component built on
|
|
1552
|
+
Popover component built on Popper.
|
|
1423
1553
|
|
|
1424
1554
|
**Pattern**: Compound Component
|
|
1425
1555
|
**Sub-components**: `Content`, `Trigger`
|
|
@@ -1427,9 +1557,10 @@ Popover component built on Floating.
|
|
|
1427
1557
|
### Props
|
|
1428
1558
|
|
|
1429
1559
|
```tsx
|
|
1430
|
-
interface OxPopoverProps
|
|
1560
|
+
interface OxPopoverProps {
|
|
1431
1561
|
align?: 'start' | 'center' | 'end';
|
|
1432
|
-
children:
|
|
1562
|
+
children: ReactNode;
|
|
1563
|
+
closeOnOutsideClick?: boolean; // Close when clicking outside
|
|
1433
1564
|
defaultOpen?: boolean;
|
|
1434
1565
|
disabled?: boolean;
|
|
1435
1566
|
onOpenChange?: (open: boolean) => void;
|
|
@@ -1437,13 +1568,13 @@ interface OxPopoverProps extends ComponentPropsWithRef<'div'> {
|
|
|
1437
1568
|
side?: 'top' | 'bottom' | 'left' | 'right';
|
|
1438
1569
|
}
|
|
1439
1570
|
|
|
1440
|
-
interface OxPopoverTriggerProps extends
|
|
1441
|
-
|
|
1442
|
-
children:
|
|
1571
|
+
interface OxPopoverTriggerProps extends ComponentPropsWithoutRef<'button'> {
|
|
1572
|
+
asSlot?: boolean; // Renders as child component
|
|
1573
|
+
children: ReactNode;
|
|
1443
1574
|
}
|
|
1444
1575
|
|
|
1445
|
-
interface OxPopoverContentProps extends
|
|
1446
|
-
children:
|
|
1576
|
+
interface OxPopoverContentProps extends ComponentPropsWithoutRef<'div'> {
|
|
1577
|
+
children: ReactNode;
|
|
1447
1578
|
showCloseButton?: boolean;
|
|
1448
1579
|
}
|
|
1449
1580
|
```
|
|
@@ -1451,7 +1582,7 @@ interface OxPopoverContentProps extends ComponentPropsWithRef<'div'> {
|
|
|
1451
1582
|
### Example
|
|
1452
1583
|
|
|
1453
1584
|
```tsx
|
|
1454
|
-
<OxPopover side="bottom">
|
|
1585
|
+
<OxPopover side="bottom" closeOnOutsideClick>
|
|
1455
1586
|
<OxPopover.Trigger>Click me</OxPopover.Trigger>
|
|
1456
1587
|
<OxPopover.Content showCloseButton>Popover content here</OxPopover.Content>
|
|
1457
1588
|
</OxPopover>
|
|
@@ -1479,7 +1610,7 @@ interface OxPopperProps {
|
|
|
1479
1610
|
}
|
|
1480
1611
|
|
|
1481
1612
|
interface OxPopperAnchorProps extends ComponentPropsWithoutRef<'div'> {
|
|
1482
|
-
|
|
1613
|
+
asSlot?: boolean;
|
|
1483
1614
|
children?: ReactNode;
|
|
1484
1615
|
virtualRef?: RefObject<Measurable | null>; // For virtual anchor positioning
|
|
1485
1616
|
}
|
|
@@ -1503,7 +1634,7 @@ interface OxPopperContentProps extends ComponentPropsWithoutRef<'div'> {
|
|
|
1503
1634
|
|
|
1504
1635
|
```tsx
|
|
1505
1636
|
<OxPopper>
|
|
1506
|
-
<OxPopper.Anchor
|
|
1637
|
+
<OxPopper.Anchor asSlot>
|
|
1507
1638
|
<button>Anchor element</button>
|
|
1508
1639
|
</OxPopper.Anchor>
|
|
1509
1640
|
<OxPopper.Content side="bottom" align="start" sideOffset={8}>
|
|
@@ -1949,6 +2080,43 @@ interface OxTabsContentProps extends ComponentPropsWithRef<'div'> {
|
|
|
1949
2080
|
|
|
1950
2081
|
---
|
|
1951
2082
|
|
|
2083
|
+
## OxThemeSwitcher
|
|
2084
|
+
|
|
2085
|
+
Theme toggle button for switching between light, dark, and system themes.
|
|
2086
|
+
|
|
2087
|
+
**Pattern**: Simple Component
|
|
2088
|
+
|
|
2089
|
+
### Props
|
|
2090
|
+
|
|
2091
|
+
```tsx
|
|
2092
|
+
type Theme = 'light' | 'dark' | 'system';
|
|
2093
|
+
type ThemeSwitcherSize = 'sm' | 'md' | 'lg';
|
|
2094
|
+
|
|
2095
|
+
interface OxThemeSwitcherProps extends Omit<ComponentPropsWithRef<'button'>, 'onChange'> {
|
|
2096
|
+
onThemeChange?: (theme: Theme) => void; // Called when theme changes
|
|
2097
|
+
size?: ThemeSwitcherSize;
|
|
2098
|
+
theme?: Theme; // Controlled theme value
|
|
2099
|
+
}
|
|
2100
|
+
```
|
|
2101
|
+
|
|
2102
|
+
### Example
|
|
2103
|
+
|
|
2104
|
+
```tsx
|
|
2105
|
+
{
|
|
2106
|
+
/* Uncontrolled - uses useTheme hook internally */
|
|
2107
|
+
}
|
|
2108
|
+
<OxThemeSwitcher size="md" />;
|
|
2109
|
+
|
|
2110
|
+
{
|
|
2111
|
+
/* Controlled */
|
|
2112
|
+
}
|
|
2113
|
+
<OxThemeSwitcher theme={currentTheme} onThemeChange={setCurrentTheme} size="lg" />;
|
|
2114
|
+
```
|
|
2115
|
+
|
|
2116
|
+
**Note**: Works with the `useTheme` hook for theme management.
|
|
2117
|
+
|
|
2118
|
+
---
|
|
2119
|
+
|
|
1952
2120
|
## OxTimeline (alpha)
|
|
1953
2121
|
|
|
1954
2122
|
Timeline component.
|
|
@@ -1995,63 +2163,123 @@ interface OxTimelineItemProps extends ComponentPropsWithRef<'li'> {
|
|
|
1995
2163
|
|
|
1996
2164
|
---
|
|
1997
2165
|
|
|
1998
|
-
## OxToast
|
|
2166
|
+
## OxToast
|
|
1999
2167
|
|
|
2000
|
-
Toast notification system.
|
|
2168
|
+
Toast notification system built on Sonner.
|
|
2001
2169
|
|
|
2002
2170
|
**Pattern**: Context-based Component
|
|
2003
|
-
**Additional Exports**: `OxToastProvider`, `useOxToast`
|
|
2171
|
+
**Additional Exports**: `OxToastProvider`, `useOxToast`, `toast`
|
|
2004
2172
|
|
|
2005
2173
|
### Props
|
|
2006
2174
|
|
|
2007
2175
|
```tsx
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2176
|
+
type OxToastPosition =
|
|
2177
|
+
| 'top-left'
|
|
2178
|
+
| 'top-center'
|
|
2179
|
+
| 'top-right'
|
|
2180
|
+
| 'bottom-left'
|
|
2181
|
+
| 'bottom-center'
|
|
2182
|
+
| 'bottom-right';
|
|
2183
|
+
|
|
2184
|
+
interface OxToastOptions {
|
|
2185
|
+
action?: {
|
|
2186
|
+
label: string;
|
|
2187
|
+
onClick: () => void;
|
|
2188
|
+
};
|
|
2189
|
+
cancel?: {
|
|
2190
|
+
label: string;
|
|
2191
|
+
onClick?: () => void;
|
|
2192
|
+
};
|
|
2011
2193
|
description?: string;
|
|
2012
2194
|
duration?: number; // Auto-dismiss duration in ms
|
|
2013
|
-
icon?: LucideIcon;
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
path?: string; // SVG path
|
|
2017
|
-
title: string; // Required
|
|
2018
|
-
type: StatusType; // Required
|
|
2195
|
+
icon?: LucideIcon | ReactNode;
|
|
2196
|
+
onAutoClose?: () => void;
|
|
2197
|
+
onDismiss?: () => void;
|
|
2019
2198
|
}
|
|
2020
2199
|
|
|
2021
|
-
interface
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2200
|
+
interface OxToastProviderProps {
|
|
2201
|
+
children: ReactNode;
|
|
2202
|
+
closeButton?: boolean; // Show close button on toasts
|
|
2203
|
+
expand?: boolean; // Expand toasts on hover
|
|
2204
|
+
gap?: number; // Gap between toasts
|
|
2205
|
+
offset?: string | number; // Offset from viewport edge
|
|
2206
|
+
position?: OxToastPosition; // Default: 'bottom-right'
|
|
2207
|
+
richColors?: boolean; // Use rich semantic colors
|
|
2208
|
+
theme?: 'light' | 'dark' | 'system';
|
|
2209
|
+
visibleToasts?: number; // Max visible toasts
|
|
2210
|
+
}
|
|
2211
|
+
```
|
|
2212
|
+
|
|
2213
|
+
### Hook API
|
|
2214
|
+
|
|
2215
|
+
```tsx
|
|
2216
|
+
interface OxToastContextApi {
|
|
2217
|
+
(title: string, options?: OxToastOptions): string | number; // Default toast
|
|
2218
|
+
success: (title: string, options?: OxToastOptions) => string | number;
|
|
2219
|
+
error: (title: string, options?: OxToastOptions) => string | number;
|
|
2220
|
+
warning: (title: string, options?: OxToastOptions) => string | number;
|
|
2221
|
+
info: (title: string, options?: OxToastOptions) => string | number;
|
|
2222
|
+
loading: (title: string, options?: OxToastOptions) => string | number;
|
|
2223
|
+
destructive: (title: string, options?: OxToastOptions) => string | number;
|
|
2224
|
+
custom: (content: ReactNode, options?: { duration?: number }) => string | number;
|
|
2225
|
+
promise: <T>(
|
|
2226
|
+
promise: Promise<T>,
|
|
2227
|
+
messages: {
|
|
2228
|
+
loading: string;
|
|
2229
|
+
success: string | ((data: T) => string);
|
|
2230
|
+
error: string | ((error: unknown) => string);
|
|
2231
|
+
}
|
|
2232
|
+
) => Promise<T>;
|
|
2233
|
+
dismiss: (id?: string | number) => void; // Dismiss specific or all toasts
|
|
2026
2234
|
}
|
|
2027
2235
|
```
|
|
2028
2236
|
|
|
2029
|
-
### Hook
|
|
2030
|
-
|
|
2031
|
-
```tsx
|
|
2032
|
-
const { showToast } = useOxToast();
|
|
2033
|
-
|
|
2034
|
-
showToast({
|
|
2035
|
-
title: 'Success!',
|
|
2036
|
-
description: 'Your changes have been saved.',
|
|
2037
|
-
type: 'success',
|
|
2038
|
-
duration: 5000,
|
|
2039
|
-
});
|
|
2040
|
-
```
|
|
2041
|
-
|
|
2042
2237
|
### Example
|
|
2043
2238
|
|
|
2044
2239
|
```tsx
|
|
2045
|
-
// Wrap app
|
|
2046
|
-
<OxToastProvider>
|
|
2240
|
+
// Wrap app with provider
|
|
2241
|
+
<OxToastProvider position="bottom-right" richColors>
|
|
2047
2242
|
<App />
|
|
2048
2243
|
</OxToastProvider>;
|
|
2049
2244
|
|
|
2050
|
-
// Use in component
|
|
2245
|
+
// Use hook in component
|
|
2051
2246
|
function MyComponent() {
|
|
2052
|
-
const
|
|
2247
|
+
const toast = useOxToast();
|
|
2053
2248
|
|
|
2054
|
-
return
|
|
2249
|
+
return (
|
|
2250
|
+
<div>
|
|
2251
|
+
<button onClick={() => toast('Default notification')}>Default</button>
|
|
2252
|
+
<button onClick={() => toast.success('Changes saved!')}>Success</button>
|
|
2253
|
+
<button onClick={() => toast.error('Something went wrong')}>Error</button>
|
|
2254
|
+
<button onClick={() => toast.warning('Please review')}>Warning</button>
|
|
2255
|
+
<button onClick={() => toast.info('New update available')}>Info</button>
|
|
2256
|
+
|
|
2257
|
+
{/* With description and action */}
|
|
2258
|
+
<button
|
|
2259
|
+
onClick={() =>
|
|
2260
|
+
toast.success('File uploaded', {
|
|
2261
|
+
description: 'Your file has been uploaded successfully.',
|
|
2262
|
+
action: { label: 'View', onClick: () => navigate('/files') },
|
|
2263
|
+
})
|
|
2264
|
+
}
|
|
2265
|
+
>
|
|
2266
|
+
With Action
|
|
2267
|
+
</button>
|
|
2268
|
+
|
|
2269
|
+
{/* Promise toast */}
|
|
2270
|
+
<button
|
|
2271
|
+
onClick={() =>
|
|
2272
|
+
toast.promise(saveData(), {
|
|
2273
|
+
loading: 'Saving...',
|
|
2274
|
+
success: 'Data saved!',
|
|
2275
|
+
error: 'Failed to save',
|
|
2276
|
+
})
|
|
2277
|
+
}
|
|
2278
|
+
>
|
|
2279
|
+
Promise
|
|
2280
|
+
</button>
|
|
2281
|
+
</div>
|
|
2282
|
+
);
|
|
2055
2283
|
}
|
|
2056
2284
|
```
|
|
2057
2285
|
|
|
@@ -2188,12 +2416,18 @@ interface OxCheckboxProps extends Omit<
|
|
|
2188
2416
|
value?: string;
|
|
2189
2417
|
}
|
|
2190
2418
|
|
|
2191
|
-
interface OxCheckboxGroupProps extends Omit<
|
|
2419
|
+
interface OxCheckboxGroupProps extends Omit<
|
|
2420
|
+
ComponentPropsWithoutRef<'div'>,
|
|
2421
|
+
'defaultValue' | 'onChange'
|
|
2422
|
+
> {
|
|
2192
2423
|
children: ReactNode;
|
|
2424
|
+
defaultValue?: string[]; // Uncontrolled default values
|
|
2193
2425
|
disabled?: boolean; // Disables all checkboxes in group
|
|
2426
|
+
error?: boolean; // Error state styling
|
|
2194
2427
|
name: string; // Required
|
|
2195
|
-
|
|
2196
|
-
|
|
2428
|
+
onValueChange?: (value: string[]) => void; // Called when selection changes
|
|
2429
|
+
orientation?: 'horizontal' | 'vertical'; // Layout direction
|
|
2430
|
+
value?: string[]; // Controlled selected values
|
|
2197
2431
|
}
|
|
2198
2432
|
|
|
2199
2433
|
interface OxCheckboxGroupItemProps extends Omit<
|
|
@@ -2201,7 +2435,7 @@ interface OxCheckboxGroupItemProps extends Omit<
|
|
|
2201
2435
|
'type' | 'size' | 'children' | 'checked' | 'defaultChecked' | 'value'
|
|
2202
2436
|
> {
|
|
2203
2437
|
error?: boolean;
|
|
2204
|
-
value: string
|
|
2438
|
+
value: string; // Required
|
|
2205
2439
|
}
|
|
2206
2440
|
```
|
|
2207
2441
|
|
|
@@ -2221,7 +2455,12 @@ interface OxCheckboxGroupItemProps extends Omit<
|
|
|
2221
2455
|
{
|
|
2222
2456
|
/* Checkbox group */
|
|
2223
2457
|
}
|
|
2224
|
-
<OxCheckbox.Group
|
|
2458
|
+
<OxCheckbox.Group
|
|
2459
|
+
name="features"
|
|
2460
|
+
value={selected}
|
|
2461
|
+
onValueChange={setSelected}
|
|
2462
|
+
orientation="vertical"
|
|
2463
|
+
>
|
|
2225
2464
|
<OxCheckbox.GroupItem value="feature1" />
|
|
2226
2465
|
<OxCheckbox.GroupItem value="feature2" />
|
|
2227
2466
|
</OxCheckbox.Group>;
|
|
@@ -2561,8 +2800,11 @@ Numeric input with increment/decrement controls.
|
|
|
2561
2800
|
### Props
|
|
2562
2801
|
|
|
2563
2802
|
```tsx
|
|
2564
|
-
interface OxNumberInputContainerProps extends Omit<
|
|
2565
|
-
|
|
2803
|
+
interface OxNumberInputContainerProps extends Omit<
|
|
2804
|
+
ComponentPropsWithRef<'div'>,
|
|
2805
|
+
'defaultValue' | 'onChange'
|
|
2806
|
+
> {
|
|
2807
|
+
defaultValue?: number | null;
|
|
2566
2808
|
disabled?: boolean;
|
|
2567
2809
|
error?: boolean;
|
|
2568
2810
|
locale?: string; // Locale for number formatting
|
|
@@ -2570,12 +2812,12 @@ interface OxNumberInputContainerProps extends Omit<ComponentPropsWithRef<'div'>,
|
|
|
2570
2812
|
maximumFractionDigits?: number; // Max decimal places
|
|
2571
2813
|
min?: number; // Minimum value
|
|
2572
2814
|
minimumFractionDigits?: number; // Min decimal places
|
|
2573
|
-
onChange?: (value: number |
|
|
2815
|
+
onChange?: (value: number | null) => void;
|
|
2574
2816
|
required?: boolean;
|
|
2575
2817
|
steps?: number; // Increment/decrement step value
|
|
2576
2818
|
useGrouping?: boolean; // Use thousand separators
|
|
2577
2819
|
validationMessage?: string; // Custom error message shown below input
|
|
2578
|
-
value?: number; // Controlled value
|
|
2820
|
+
value?: number | null; // Controlled value
|
|
2579
2821
|
}
|
|
2580
2822
|
|
|
2581
2823
|
interface OxNumberInputProps {
|
|
@@ -2740,29 +2982,28 @@ Radio button group.
|
|
|
2740
2982
|
```tsx
|
|
2741
2983
|
interface OxRadioGroupProps extends Omit<ComponentPropsWithoutRef<'div'>, 'onChange'> {
|
|
2742
2984
|
children: ReactNode; // Required
|
|
2743
|
-
defaultValue?: string
|
|
2985
|
+
defaultValue?: string; // Uncontrolled default value
|
|
2744
2986
|
disabled?: boolean; // Disables all radio buttons
|
|
2745
2987
|
error?: boolean;
|
|
2746
2988
|
name?: string;
|
|
2747
|
-
|
|
2989
|
+
onValueChange?: (value: string) => void; // Called when selection changes
|
|
2990
|
+
orientation?: 'horizontal' | 'vertical'; // Layout direction
|
|
2748
2991
|
required?: boolean;
|
|
2749
|
-
value?: string
|
|
2992
|
+
value?: string; // Controlled selected value
|
|
2750
2993
|
}
|
|
2751
2994
|
|
|
2752
|
-
interface
|
|
2995
|
+
interface OxRadioGroupItemProps extends Omit<
|
|
2753
2996
|
ComponentPropsWithoutRef<'input'>,
|
|
2754
|
-
'type' | 'size' | 'required'
|
|
2997
|
+
'type' | 'size' | 'required' | 'value' | 'name'
|
|
2755
2998
|
> {
|
|
2756
|
-
|
|
2757
|
-
onCheckedChange?: (checked: boolean) => void; // Called when this item is checked
|
|
2758
|
-
value?: string | number;
|
|
2999
|
+
value: string; // Required - unique value for this option
|
|
2759
3000
|
}
|
|
2760
3001
|
```
|
|
2761
3002
|
|
|
2762
3003
|
### Example
|
|
2763
3004
|
|
|
2764
3005
|
```tsx
|
|
2765
|
-
<OxRadio.Group name="plan" value={plan}
|
|
3006
|
+
<OxRadio.Group name="plan" value={plan} onValueChange={setPlan} orientation="vertical">
|
|
2766
3007
|
<OxRadio.Item value="basic" />
|
|
2767
3008
|
<OxRadio.Item value="pro" />
|
|
2768
3009
|
<OxRadio.Item value="enterprise" />
|
|
@@ -2783,21 +3024,44 @@ Select dropdown with single and multi-select.
|
|
|
2783
3024
|
### Props
|
|
2784
3025
|
|
|
2785
3026
|
```tsx
|
|
2786
|
-
|
|
3027
|
+
type OxSelectValue = string | number | null;
|
|
3028
|
+
|
|
3029
|
+
// Single select
|
|
3030
|
+
interface OxSelectSingleProps extends Omit<ComponentPropsWithRef<'div'>, 'defaultValue'> {
|
|
3031
|
+
children: ReactNode;
|
|
2787
3032
|
defaultOpen?: boolean;
|
|
2788
|
-
defaultValue?:
|
|
3033
|
+
defaultValue?: OxSelectValue;
|
|
2789
3034
|
disabled?: boolean;
|
|
2790
3035
|
error?: boolean;
|
|
2791
3036
|
id?: string;
|
|
2792
3037
|
isLoading?: boolean; // Shows loading state
|
|
2793
|
-
multiple?:
|
|
2794
|
-
onChange?: (value: string | number | null | Array<string | number | null>) => void;
|
|
3038
|
+
multiple?: false; // Single select (default)
|
|
2795
3039
|
onOpenChange?: (open: boolean) => void;
|
|
3040
|
+
onValueChange?: (value: OxSelectValue) => void;
|
|
2796
3041
|
open?: boolean; // Controlled open state
|
|
2797
3042
|
required?: boolean;
|
|
2798
|
-
value?:
|
|
3043
|
+
value?: OxSelectValue; // Controlled value
|
|
2799
3044
|
}
|
|
2800
3045
|
|
|
3046
|
+
// Multi-select
|
|
3047
|
+
interface OxSelectMultipleProps extends Omit<ComponentPropsWithRef<'div'>, 'defaultValue'> {
|
|
3048
|
+
children: ReactNode;
|
|
3049
|
+
defaultOpen?: boolean;
|
|
3050
|
+
defaultValue?: OxSelectValue[];
|
|
3051
|
+
disabled?: boolean;
|
|
3052
|
+
error?: boolean;
|
|
3053
|
+
id?: string;
|
|
3054
|
+
isLoading?: boolean;
|
|
3055
|
+
multiple: true; // Required for multi-select
|
|
3056
|
+
onOpenChange?: (open: boolean) => void;
|
|
3057
|
+
onValueChange?: (value: OxSelectValue[]) => void;
|
|
3058
|
+
open?: boolean;
|
|
3059
|
+
required?: boolean;
|
|
3060
|
+
value?: OxSelectValue[];
|
|
3061
|
+
}
|
|
3062
|
+
|
|
3063
|
+
type OxSelectProps = OxSelectSingleProps | OxSelectMultipleProps;
|
|
3064
|
+
|
|
2801
3065
|
interface OxSelectTriggerProps extends ComponentPropsWithRef<'button'> {
|
|
2802
3066
|
displayAsTag?: boolean; // Display selected items as tags (multi-select)
|
|
2803
3067
|
placeholder?: string;
|
|
@@ -2811,7 +3075,7 @@ interface OxSelectGroupProps extends ComponentPropsWithRef<'div'> {
|
|
|
2811
3075
|
}
|
|
2812
3076
|
|
|
2813
3077
|
interface OxSelectItemProps extends Omit<ComponentPropsWithRef<'button'>, 'value'> {
|
|
2814
|
-
value:
|
|
3078
|
+
value: OxSelectValue; // Required
|
|
2815
3079
|
}
|
|
2816
3080
|
```
|
|
2817
3081
|
|
|
@@ -2821,7 +3085,7 @@ interface OxSelectItemProps extends Omit<ComponentPropsWithRef<'button'>, 'value
|
|
|
2821
3085
|
{
|
|
2822
3086
|
/* Single select */
|
|
2823
3087
|
}
|
|
2824
|
-
<OxSelect value={country}
|
|
3088
|
+
<OxSelect value={country} onValueChange={setCountry}>
|
|
2825
3089
|
<OxSelect.Trigger placeholder="Select country" />
|
|
2826
3090
|
<OxSelect.Content>
|
|
2827
3091
|
<OxSelect.Item value="us">United States</OxSelect.Item>
|
|
@@ -2832,7 +3096,7 @@ interface OxSelectItemProps extends Omit<ComponentPropsWithRef<'button'>, 'value
|
|
|
2832
3096
|
{
|
|
2833
3097
|
/* Multi-select with badges */
|
|
2834
3098
|
}
|
|
2835
|
-
<OxSelect multiple value={tags}
|
|
3099
|
+
<OxSelect multiple value={tags} onValueChange={setTags}>
|
|
2836
3100
|
<OxSelect.Trigger displayAsTag tagColor="blue" />
|
|
2837
3101
|
<OxSelect.Content>
|
|
2838
3102
|
<OxSelect.Group label="Categories">
|
|
@@ -3523,7 +3787,7 @@ function MyComponent() {
|
|
|
3523
3787
|
|
|
3524
3788
|
---
|
|
3525
3789
|
|
|
3526
|
-
# Hooks (
|
|
3790
|
+
# Hooks (14)
|
|
3527
3791
|
|
|
3528
3792
|
## useControllableState
|
|
3529
3793
|
|
|
@@ -4266,6 +4530,105 @@ function ResponsiveComponent() {
|
|
|
4266
4530
|
|
|
4267
4531
|
---
|
|
4268
4532
|
|
|
4533
|
+
## useSort
|
|
4534
|
+
|
|
4535
|
+
Client-side and server-side sorting with flexible API.
|
|
4536
|
+
|
|
4537
|
+
### Signature
|
|
4538
|
+
|
|
4539
|
+
```tsx
|
|
4540
|
+
// Client-side (with data)
|
|
4541
|
+
function useSort<T, K extends string = string>(
|
|
4542
|
+
data: T[],
|
|
4543
|
+
options?: UseSortOptions<K>
|
|
4544
|
+
): UseSortReturnWithData<T, K>;
|
|
4545
|
+
|
|
4546
|
+
// Server-side (state only)
|
|
4547
|
+
function useSort<K extends string = string>(options?: UseSortOptions<K>): UseSortReturnStateOnly<K>;
|
|
4548
|
+
|
|
4549
|
+
type SortDirection = 'asc' | 'desc';
|
|
4550
|
+
|
|
4551
|
+
interface SortState<K extends string = string> {
|
|
4552
|
+
direction: SortDirection;
|
|
4553
|
+
key: K;
|
|
4554
|
+
}
|
|
4555
|
+
|
|
4556
|
+
interface UseSortOptions<K extends string = string> {
|
|
4557
|
+
defaultDirection?: SortDirection;
|
|
4558
|
+
defaultKey?: K;
|
|
4559
|
+
}
|
|
4560
|
+
|
|
4561
|
+
interface UseSortReturnBase<K extends string = string> {
|
|
4562
|
+
clearSort: () => void;
|
|
4563
|
+
setSortState: (state: SortState<K> | null) => void;
|
|
4564
|
+
sortState: SortState<K> | null;
|
|
4565
|
+
toggleSort: (key: K) => void;
|
|
4566
|
+
}
|
|
4567
|
+
|
|
4568
|
+
interface UseSortReturnWithData<T, K extends string = string> extends UseSortReturnBase<K> {
|
|
4569
|
+
sortedData: T[];
|
|
4570
|
+
}
|
|
4571
|
+
|
|
4572
|
+
type UseSortReturnStateOnly<K extends string = string> = UseSortReturnBase<K>;
|
|
4573
|
+
```
|
|
4574
|
+
|
|
4575
|
+
### Example
|
|
4576
|
+
|
|
4577
|
+
```tsx
|
|
4578
|
+
// Client-side sorting
|
|
4579
|
+
function UsersTable() {
|
|
4580
|
+
const { sortedData, sortState, toggleSort, clearSort } = useSort(users, {
|
|
4581
|
+
defaultKey: 'name',
|
|
4582
|
+
defaultDirection: 'asc',
|
|
4583
|
+
});
|
|
4584
|
+
|
|
4585
|
+
return (
|
|
4586
|
+
<table>
|
|
4587
|
+
<thead>
|
|
4588
|
+
<tr>
|
|
4589
|
+
<th onClick={() => toggleSort('name')}>Name</th>
|
|
4590
|
+
<th onClick={() => toggleSort('age')}>Age</th>
|
|
4591
|
+
</tr>
|
|
4592
|
+
</thead>
|
|
4593
|
+
<tbody>
|
|
4594
|
+
{sortedData.map((user) => (
|
|
4595
|
+
<tr key={user.id}>
|
|
4596
|
+
<td>{user.name}</td>
|
|
4597
|
+
<td>{user.age}</td>
|
|
4598
|
+
</tr>
|
|
4599
|
+
))}
|
|
4600
|
+
</tbody>
|
|
4601
|
+
</table>
|
|
4602
|
+
);
|
|
4603
|
+
}
|
|
4604
|
+
|
|
4605
|
+
// Server-side sorting
|
|
4606
|
+
function ServerSideTable() {
|
|
4607
|
+
const { sortState, toggleSort, clearSort } = useSort({
|
|
4608
|
+
defaultKey: 'name',
|
|
4609
|
+
defaultDirection: 'asc',
|
|
4610
|
+
});
|
|
4611
|
+
|
|
4612
|
+
useEffect(() => {
|
|
4613
|
+
fetchUsers({
|
|
4614
|
+
sortBy: sortState?.key,
|
|
4615
|
+
sortOrder: sortState?.direction,
|
|
4616
|
+
});
|
|
4617
|
+
}, [sortState]);
|
|
4618
|
+
|
|
4619
|
+
return <table>{/* ... */}</table>;
|
|
4620
|
+
}
|
|
4621
|
+
```
|
|
4622
|
+
|
|
4623
|
+
**Notes**:
|
|
4624
|
+
|
|
4625
|
+
- Toggle cycle: none → asc → desc → none
|
|
4626
|
+
- Supports nested paths (e.g., `profile.score`)
|
|
4627
|
+
- `sortedData` is memoized for performance
|
|
4628
|
+
- Uses `es-toolkit` for sorting
|
|
4629
|
+
|
|
4630
|
+
---
|
|
4631
|
+
|
|
4269
4632
|
## useTheme
|
|
4270
4633
|
|
|
4271
4634
|
Theme management with localStorage persistence.
|
|
@@ -4697,7 +5060,7 @@ formatTimestamp(new Date(Date.now() - 5 * 60 * 1000));
|
|
|
4697
5060
|
|
|
4698
5061
|
## hasDataSlot
|
|
4699
5062
|
|
|
4700
|
-
React slot validation type guard.
|
|
5063
|
+
React slot validation type guard for slot-based component composition.
|
|
4701
5064
|
|
|
4702
5065
|
### Function
|
|
4703
5066
|
|
|
@@ -4724,6 +5087,7 @@ const headerSlot = children.find((child) => hasDataSlot(child, 'header'));
|
|
|
4724
5087
|
|
|
4725
5088
|
- Type guard for TypeScript narrowing
|
|
4726
5089
|
- Validates React element and slot attribute
|
|
5090
|
+
- Used for slot-based component composition (NOT related to `asSlot` prop)
|
|
4727
5091
|
|
|
4728
5092
|
---
|
|
4729
5093
|
|
|
@@ -4837,11 +5201,11 @@ validatePhone('+14155552671', { allowedCountries: ['US', 'CA'] });
|
|
|
4837
5201
|
|
|
4838
5202
|
# Common Patterns
|
|
4839
5203
|
|
|
4840
|
-
##
|
|
5204
|
+
## asSlot Pattern
|
|
4841
5205
|
|
|
4842
|
-
The `
|
|
5206
|
+
The `asSlot` prop enables polymorphic rendering using Radix Slot. When `asSlot={true}`, the component renders as its child element while preserving the component's styling and functionality.
|
|
4843
5207
|
|
|
4844
|
-
**Components with
|
|
5208
|
+
**Components with asSlot**:
|
|
4845
5209
|
|
|
4846
5210
|
- `OxBreadcrumb.Link`
|
|
4847
5211
|
- `OxButton`
|
|
@@ -4858,7 +5222,7 @@ The `asChild` prop enables polymorphic rendering using Radix Slot. When `asChild
|
|
|
4858
5222
|
{
|
|
4859
5223
|
/* Render as Next.js Link while keeping button styling */
|
|
4860
5224
|
}
|
|
4861
|
-
<OxButton
|
|
5225
|
+
<OxButton asSlot variant="primary">
|
|
4862
5226
|
<Link to="/dashboard">Dashboard</Link>
|
|
4863
5227
|
</OxButton>;
|
|
4864
5228
|
```
|