@dimaan/ui 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as react from 'react';
3
- import { HTMLAttributes, ReactNode, ReactElement, ButtonHTMLAttributes, InputHTMLAttributes, ChangeEvent, AnchorHTMLAttributes, Ref } from 'react';
3
+ import { HTMLAttributes, ReactNode, ReactElement, ButtonHTMLAttributes, InputHTMLAttributes, ChangeEvent, FieldsetHTMLAttributes, AnchorHTMLAttributes, Ref } from 'react';
4
4
  import { ClassValue } from 'clsx';
5
5
 
6
6
  interface DashboardLayoutContextValue {
@@ -34,7 +34,8 @@ type RenderLink = (props: {
34
34
  'aria-current'?: 'page';
35
35
  }) => ReactElement;
36
36
  interface AppShellNavItem {
37
- key: string;
37
+ /** Optional stable key. Falls back to array index if omitted — only safe for static nav. */
38
+ key?: string;
38
39
  label: ReactNode;
39
40
  href?: string;
40
41
  icon?: ReactNode;
@@ -44,18 +45,14 @@ interface AppShellNavItem {
44
45
  render?: RenderLink;
45
46
  }
46
47
  interface AppShellNavGroup {
47
- key: string;
48
+ /** Optional stable key. Falls back to array index if omitted — only safe for static nav. */
49
+ key?: string;
48
50
  label: ReactNode;
49
51
  icon?: ReactNode;
50
52
  active?: boolean;
51
53
  defaultOpen?: boolean;
52
54
  items: AppShellNavItem[];
53
55
  }
54
- interface AppShellNavSection {
55
- key: string;
56
- label?: ReactNode;
57
- items: Array<AppShellNavItem | AppShellNavGroup>;
58
- }
59
56
  interface AppShellBrand {
60
57
  logo?: ReactNode;
61
58
  name?: ReactNode;
@@ -63,8 +60,12 @@ interface AppShellBrand {
63
60
  }
64
61
  interface AppShellProps extends Pick<DashboardLayoutProps, 'defaultCollapsed' | 'collapsed' | 'onCollapsedChange'> {
65
62
  brand?: AppShellBrand;
66
- /** Either a flat list of items, or grouped sections. */
67
- nav: AppShellNavSection[] | Array<AppShellNavItem | AppShellNavGroup>;
63
+ /**
64
+ * Flat list of nav entries: leaf items (with `href` or `render`) and/or
65
+ * collapsible groups (with `items`). For more advanced layouts (sections,
66
+ * dividers, custom structure), compose `Sidebar` + `SidebarNav` directly.
67
+ */
68
+ nav: Array<AppShellNavItem | AppShellNavGroup>;
68
69
  title?: ReactNode;
69
70
  searchPlaceholder?: string;
70
71
  onSearch?: (value: string) => void;
@@ -178,6 +179,19 @@ interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size'
178
179
  }
179
180
  declare const Input: react.ForwardRefExoticComponent<InputProps & react.RefAttributes<HTMLInputElement>>;
180
181
 
182
+ interface LanguageOption<TCode extends string = string> {
183
+ code: TCode;
184
+ label?: string;
185
+ }
186
+ interface LanguageSwitcherProps<TCode extends string = string> extends Omit<FieldsetHTMLAttributes<HTMLFieldSetElement>, 'onChange'> {
187
+ languages: ReadonlyArray<LanguageOption<TCode>>;
188
+ value: TCode;
189
+ onChange: (next: TCode) => void;
190
+ /** Accessible label for the group. Defaults to "Language". */
191
+ ariaLabel?: string;
192
+ }
193
+ declare function LanguageSwitcher<TCode extends string = string>({ languages, value, onChange, ariaLabel, className, ...props }: LanguageSwitcherProps<TCode>): react_jsx_runtime.JSX.Element;
194
+
181
195
  type SidebarProps = HTMLAttributes<HTMLElement>;
182
196
  declare function Sidebar({ className, children, ...props }: SidebarProps): react_jsx_runtime.JSX.Element;
183
197
 
@@ -346,4 +360,4 @@ declare function useDirection(): Direction;
346
360
 
347
361
  declare function cn(...inputs: ClassValue[]): string;
348
362
 
349
- export { AppShell, type AppShellBrand, type AppShellNavGroup, type AppShellNavItem, type AppShellNavSection, type AppShellProps, Avatar, type AvatarProps, Button, type ButtonProps, type ButtonSize, type ButtonVariant, Checkbox, type CheckboxProps, type CheckboxSize, type Column, type ColumnAlign, DashboardContent, type DashboardContentProps, DashboardHeader, type DashboardHeaderProps, DashboardLayout, type DashboardLayoutContextValue, type DashboardLayoutProps, DashboardMain, type DashboardMainProps, type Direction, HeaderActions, type HeaderActionsProps, HeaderCollapseTrigger, type HeaderCollapseTriggerProps, HeaderMobileTrigger, type HeaderMobileTriggerProps, HeaderSearch, type HeaderSearchProps, HeaderTitle, type HeaderTitleProps, Input, type InputProps, type InputSize, type InputVariant, type PaginationState, type RowSelectionState, Sidebar, SidebarFooter, type SidebarFooterProps, SidebarGroup, type SidebarGroupProps, SidebarHeader, type SidebarHeaderProps, SidebarNav, SidebarNavGroup, type SidebarNavGroupProps, SidebarNavItem, type SidebarNavItemProps, type SidebarNavItemRenderProps, type SidebarNavProps, type SidebarProps, type SortDirection, type SortState, type SortableValue, Table, type TableProps, type TableSize, type TableSizeClasses, buttonBaseClass, buttonSizeClass, buttonVariantClass, cn, inputBaseClass, inputSizeClass, inputVariantClass, alignClass as tableAlignClass, tableBaseClass, selectedRowClass as tableSelectedRowClass, tableSizeClass, sortIconClass as tableSortIconClass, useDashboardLayout, useDirection };
363
+ export { AppShell, type AppShellBrand, type AppShellNavGroup, type AppShellNavItem, type AppShellProps, Avatar, type AvatarProps, Button, type ButtonProps, type ButtonSize, type ButtonVariant, Checkbox, type CheckboxProps, type CheckboxSize, type Column, type ColumnAlign, DashboardContent, type DashboardContentProps, DashboardHeader, type DashboardHeaderProps, DashboardLayout, type DashboardLayoutContextValue, type DashboardLayoutProps, DashboardMain, type DashboardMainProps, type Direction, HeaderActions, type HeaderActionsProps, HeaderCollapseTrigger, type HeaderCollapseTriggerProps, HeaderMobileTrigger, type HeaderMobileTriggerProps, HeaderSearch, type HeaderSearchProps, HeaderTitle, type HeaderTitleProps, Input, type InputProps, type InputSize, type InputVariant, type LanguageOption, LanguageSwitcher, type LanguageSwitcherProps, type PaginationState, type RowSelectionState, Sidebar, SidebarFooter, type SidebarFooterProps, SidebarGroup, type SidebarGroupProps, SidebarHeader, type SidebarHeaderProps, SidebarNav, SidebarNavGroup, type SidebarNavGroupProps, SidebarNavItem, type SidebarNavItemProps, type SidebarNavItemRenderProps, type SidebarNavProps, type SidebarProps, type SortDirection, type SortState, type SortableValue, Table, type TableProps, type TableSize, type TableSizeClasses, buttonBaseClass, buttonSizeClass, buttonVariantClass, cn, inputBaseClass, inputSizeClass, inputVariantClass, alignClass as tableAlignClass, tableBaseClass, selectedRowClass as tableSelectedRowClass, tableSizeClass, sortIconClass as tableSortIconClass, useDashboardLayout, useDirection };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as react from 'react';
3
- import { HTMLAttributes, ReactNode, ReactElement, ButtonHTMLAttributes, InputHTMLAttributes, ChangeEvent, AnchorHTMLAttributes, Ref } from 'react';
3
+ import { HTMLAttributes, ReactNode, ReactElement, ButtonHTMLAttributes, InputHTMLAttributes, ChangeEvent, FieldsetHTMLAttributes, AnchorHTMLAttributes, Ref } from 'react';
4
4
  import { ClassValue } from 'clsx';
5
5
 
6
6
  interface DashboardLayoutContextValue {
@@ -34,7 +34,8 @@ type RenderLink = (props: {
34
34
  'aria-current'?: 'page';
35
35
  }) => ReactElement;
36
36
  interface AppShellNavItem {
37
- key: string;
37
+ /** Optional stable key. Falls back to array index if omitted — only safe for static nav. */
38
+ key?: string;
38
39
  label: ReactNode;
39
40
  href?: string;
40
41
  icon?: ReactNode;
@@ -44,18 +45,14 @@ interface AppShellNavItem {
44
45
  render?: RenderLink;
45
46
  }
46
47
  interface AppShellNavGroup {
47
- key: string;
48
+ /** Optional stable key. Falls back to array index if omitted — only safe for static nav. */
49
+ key?: string;
48
50
  label: ReactNode;
49
51
  icon?: ReactNode;
50
52
  active?: boolean;
51
53
  defaultOpen?: boolean;
52
54
  items: AppShellNavItem[];
53
55
  }
54
- interface AppShellNavSection {
55
- key: string;
56
- label?: ReactNode;
57
- items: Array<AppShellNavItem | AppShellNavGroup>;
58
- }
59
56
  interface AppShellBrand {
60
57
  logo?: ReactNode;
61
58
  name?: ReactNode;
@@ -63,8 +60,12 @@ interface AppShellBrand {
63
60
  }
64
61
  interface AppShellProps extends Pick<DashboardLayoutProps, 'defaultCollapsed' | 'collapsed' | 'onCollapsedChange'> {
65
62
  brand?: AppShellBrand;
66
- /** Either a flat list of items, or grouped sections. */
67
- nav: AppShellNavSection[] | Array<AppShellNavItem | AppShellNavGroup>;
63
+ /**
64
+ * Flat list of nav entries: leaf items (with `href` or `render`) and/or
65
+ * collapsible groups (with `items`). For more advanced layouts (sections,
66
+ * dividers, custom structure), compose `Sidebar` + `SidebarNav` directly.
67
+ */
68
+ nav: Array<AppShellNavItem | AppShellNavGroup>;
68
69
  title?: ReactNode;
69
70
  searchPlaceholder?: string;
70
71
  onSearch?: (value: string) => void;
@@ -178,6 +179,19 @@ interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size'
178
179
  }
179
180
  declare const Input: react.ForwardRefExoticComponent<InputProps & react.RefAttributes<HTMLInputElement>>;
180
181
 
182
+ interface LanguageOption<TCode extends string = string> {
183
+ code: TCode;
184
+ label?: string;
185
+ }
186
+ interface LanguageSwitcherProps<TCode extends string = string> extends Omit<FieldsetHTMLAttributes<HTMLFieldSetElement>, 'onChange'> {
187
+ languages: ReadonlyArray<LanguageOption<TCode>>;
188
+ value: TCode;
189
+ onChange: (next: TCode) => void;
190
+ /** Accessible label for the group. Defaults to "Language". */
191
+ ariaLabel?: string;
192
+ }
193
+ declare function LanguageSwitcher<TCode extends string = string>({ languages, value, onChange, ariaLabel, className, ...props }: LanguageSwitcherProps<TCode>): react_jsx_runtime.JSX.Element;
194
+
181
195
  type SidebarProps = HTMLAttributes<HTMLElement>;
182
196
  declare function Sidebar({ className, children, ...props }: SidebarProps): react_jsx_runtime.JSX.Element;
183
197
 
@@ -346,4 +360,4 @@ declare function useDirection(): Direction;
346
360
 
347
361
  declare function cn(...inputs: ClassValue[]): string;
348
362
 
349
- export { AppShell, type AppShellBrand, type AppShellNavGroup, type AppShellNavItem, type AppShellNavSection, type AppShellProps, Avatar, type AvatarProps, Button, type ButtonProps, type ButtonSize, type ButtonVariant, Checkbox, type CheckboxProps, type CheckboxSize, type Column, type ColumnAlign, DashboardContent, type DashboardContentProps, DashboardHeader, type DashboardHeaderProps, DashboardLayout, type DashboardLayoutContextValue, type DashboardLayoutProps, DashboardMain, type DashboardMainProps, type Direction, HeaderActions, type HeaderActionsProps, HeaderCollapseTrigger, type HeaderCollapseTriggerProps, HeaderMobileTrigger, type HeaderMobileTriggerProps, HeaderSearch, type HeaderSearchProps, HeaderTitle, type HeaderTitleProps, Input, type InputProps, type InputSize, type InputVariant, type PaginationState, type RowSelectionState, Sidebar, SidebarFooter, type SidebarFooterProps, SidebarGroup, type SidebarGroupProps, SidebarHeader, type SidebarHeaderProps, SidebarNav, SidebarNavGroup, type SidebarNavGroupProps, SidebarNavItem, type SidebarNavItemProps, type SidebarNavItemRenderProps, type SidebarNavProps, type SidebarProps, type SortDirection, type SortState, type SortableValue, Table, type TableProps, type TableSize, type TableSizeClasses, buttonBaseClass, buttonSizeClass, buttonVariantClass, cn, inputBaseClass, inputSizeClass, inputVariantClass, alignClass as tableAlignClass, tableBaseClass, selectedRowClass as tableSelectedRowClass, tableSizeClass, sortIconClass as tableSortIconClass, useDashboardLayout, useDirection };
363
+ export { AppShell, type AppShellBrand, type AppShellNavGroup, type AppShellNavItem, type AppShellProps, Avatar, type AvatarProps, Button, type ButtonProps, type ButtonSize, type ButtonVariant, Checkbox, type CheckboxProps, type CheckboxSize, type Column, type ColumnAlign, DashboardContent, type DashboardContentProps, DashboardHeader, type DashboardHeaderProps, DashboardLayout, type DashboardLayoutContextValue, type DashboardLayoutProps, DashboardMain, type DashboardMainProps, type Direction, HeaderActions, type HeaderActionsProps, HeaderCollapseTrigger, type HeaderCollapseTriggerProps, HeaderMobileTrigger, type HeaderMobileTriggerProps, HeaderSearch, type HeaderSearchProps, HeaderTitle, type HeaderTitleProps, Input, type InputProps, type InputSize, type InputVariant, type LanguageOption, LanguageSwitcher, type LanguageSwitcherProps, type PaginationState, type RowSelectionState, Sidebar, SidebarFooter, type SidebarFooterProps, SidebarGroup, type SidebarGroupProps, SidebarHeader, type SidebarHeaderProps, SidebarNav, SidebarNavGroup, type SidebarNavGroupProps, SidebarNavItem, type SidebarNavItemProps, type SidebarNavItemRenderProps, type SidebarNavProps, type SidebarProps, type SortDirection, type SortState, type SortableValue, Table, type TableProps, type TableSize, type TableSizeClasses, buttonBaseClass, buttonSizeClass, buttonVariantClass, cn, inputBaseClass, inputSizeClass, inputVariantClass, alignClass as tableAlignClass, tableBaseClass, selectedRowClass as tableSelectedRowClass, tableSizeClass, sortIconClass as tableSortIconClass, useDashboardLayout, useDirection };
package/dist/index.js CHANGED
@@ -555,18 +555,11 @@ function SidebarNavItem({
555
555
  }
556
556
  );
557
557
  }
558
- function isSection(entry) {
559
- return "items" in entry && !("label" in entry && "href" in entry) && Array.isArray(entry.items);
560
- }
561
558
  function isGroup(entry) {
562
- return "items" in entry;
563
- }
564
- function normalize(nav) {
565
- if (nav.length === 0) return [];
566
- if (isSection(nav[0])) return nav;
567
- return [{ key: "__root", items: nav }];
559
+ return "items" in entry && Array.isArray(entry.items);
568
560
  }
569
- function renderItem(item) {
561
+ function renderItem(item, fallbackKey) {
562
+ const key = item.key ?? fallbackKey;
570
563
  if (item.render) {
571
564
  return /* @__PURE__ */ jsx(
572
565
  SidebarNavItem,
@@ -577,7 +570,7 @@ function renderItem(item) {
577
570
  render: item.render,
578
571
  children: item.label
579
572
  },
580
- item.key
573
+ key
581
574
  );
582
575
  }
583
576
  return /* @__PURE__ */ jsx(
@@ -589,7 +582,7 @@ function renderItem(item) {
589
582
  endSlot: item.endSlot,
590
583
  children: item.label
591
584
  },
592
- item.key
585
+ key
593
586
  );
594
587
  }
595
588
  function AppShell({
@@ -605,7 +598,6 @@ function AppShell({
605
598
  onCollapsedChange,
606
599
  children
607
600
  }) {
608
- const sections = normalize(nav);
609
601
  return /* @__PURE__ */ jsxs(
610
602
  DashboardLayout,
611
603
  {
@@ -618,19 +610,19 @@ function AppShell({
618
610
  brand.logo,
619
611
  brand.name ? /* @__PURE__ */ jsx("span", { className: "truncate text-sm font-semibold", children: brand.name }) : null
620
612
  ] }),
621
- /* @__PURE__ */ jsx(SidebarNav, { children: sections.map((section) => /* @__PURE__ */ jsx(SidebarGroup, { label: section.label, children: section.items.map(
622
- (entry) => isGroup(entry) ? /* @__PURE__ */ jsx(
613
+ /* @__PURE__ */ jsx(SidebarNav, { children: nav.map(
614
+ (entry, index) => isGroup(entry) ? /* @__PURE__ */ jsx(
623
615
  SidebarNavGroup,
624
616
  {
625
617
  label: entry.label,
626
618
  icon: entry.icon,
627
619
  active: entry.active,
628
620
  defaultOpen: entry.defaultOpen ?? entry.items.some((i) => i.active),
629
- children: entry.items.map(renderItem)
621
+ children: entry.items.map((item, itemIndex) => renderItem(item, itemIndex))
630
622
  },
631
- entry.key
632
- ) : renderItem(entry)
633
- ) }, section.key)) }),
623
+ entry.key ?? index
624
+ ) : renderItem(entry, index)
625
+ ) }),
634
626
  sidebarFooter ? /* @__PURE__ */ jsx(SidebarFooter, { children: sidebarFooter }) : null
635
627
  ] }),
636
628
  /* @__PURE__ */ jsxs(DashboardMain, { children: [
@@ -847,6 +839,43 @@ var Input = forwardRef(function Input2({
847
839
  hasError ? /* @__PURE__ */ jsx("p", { id: errorId, className: "text-xs text-destructive", children: error }) : helperText ? /* @__PURE__ */ jsx("p", { id: helperId, className: "text-xs text-muted-foreground", children: helperText }) : null
848
840
  ] });
849
841
  });
842
+ function LanguageSwitcher({
843
+ languages,
844
+ value,
845
+ onChange,
846
+ ariaLabel = "Language",
847
+ className,
848
+ ...props
849
+ }) {
850
+ return /* @__PURE__ */ jsx(
851
+ "fieldset",
852
+ {
853
+ "aria-label": ariaLabel,
854
+ className: cn(
855
+ "inline-flex items-center rounded-md border border-border bg-background p-0.5 text-xs",
856
+ className
857
+ ),
858
+ ...props,
859
+ children: languages.map((lang) => {
860
+ const isActive = lang.code === value;
861
+ return /* @__PURE__ */ jsx(
862
+ "button",
863
+ {
864
+ type: "button",
865
+ onClick: () => onChange(lang.code),
866
+ "aria-pressed": isActive,
867
+ className: cn(
868
+ "rounded px-2 py-1 font-medium transition-colors",
869
+ isActive ? "bg-primary text-primary-foreground" : "text-muted-foreground hover:text-foreground"
870
+ ),
871
+ children: lang.label ?? lang.code.toUpperCase()
872
+ },
873
+ lang.code
874
+ );
875
+ })
876
+ }
877
+ );
878
+ }
850
879
  function readDocumentDirection() {
851
880
  if (typeof document === "undefined") return "ltr";
852
881
  const dir = document.documentElement.getAttribute("dir");
@@ -1355,6 +1384,6 @@ function SortIndicator({ active, direction }) {
1355
1384
  return direction === "asc" ? /* @__PURE__ */ jsx(ChevronUp, { "aria-hidden": "true", className }) : /* @__PURE__ */ jsx(ChevronDown, { "aria-hidden": "true", className });
1356
1385
  }
1357
1386
 
1358
- export { AppShell, Avatar, Button, Checkbox, DashboardContent, DashboardHeader, DashboardLayout, DashboardMain, HeaderActions, HeaderCollapseTrigger, HeaderMobileTrigger, HeaderSearch, HeaderTitle, Input, Sidebar, SidebarFooter, SidebarGroup, SidebarHeader, SidebarNav, SidebarNavGroup, SidebarNavItem, Table, buttonBaseClass, buttonSizeClass, buttonVariantClass, cn, inputBaseClass, inputSizeClass, inputVariantClass, alignClass as tableAlignClass, tableBaseClass, selectedRowClass as tableSelectedRowClass, tableSizeClass, sortIconClass as tableSortIconClass, useDashboardLayout, useDirection };
1387
+ export { AppShell, Avatar, Button, Checkbox, DashboardContent, DashboardHeader, DashboardLayout, DashboardMain, HeaderActions, HeaderCollapseTrigger, HeaderMobileTrigger, HeaderSearch, HeaderTitle, Input, LanguageSwitcher, Sidebar, SidebarFooter, SidebarGroup, SidebarHeader, SidebarNav, SidebarNavGroup, SidebarNavItem, Table, buttonBaseClass, buttonSizeClass, buttonVariantClass, cn, inputBaseClass, inputSizeClass, inputVariantClass, alignClass as tableAlignClass, tableBaseClass, selectedRowClass as tableSelectedRowClass, tableSizeClass, sortIconClass as tableSortIconClass, useDashboardLayout, useDirection };
1359
1388
  //# sourceMappingURL=index.js.map
1360
1389
  //# sourceMappingURL=index.js.map