@geomak/ui 1.2.0 → 1.4.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/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { C as COLORS, S as SemanticColorKey, a as SemanticRadiusKey, V as VarColorKey, b as VarRadiusKey, c as VarShadowKey, P as palette, s as semanticTokens, v as vars } from './index-CPCiQllz.js';
1
+ export { C as COLORS, S as SemanticColorKey, a as SemanticRadiusKey, V as VarColorKey, b as VarRadiusKey, c as VarShadowKey, P as palette, s as semanticTokens, v as vars } from './index-DLGzTj3K.js';
2
2
  import * as react_jsx_runtime from 'react/jsx-runtime';
3
3
  import React$1 from 'react';
4
4
  import * as TooltipPrimitive from '@radix-ui/react-tooltip';
@@ -329,26 +329,31 @@ declare function Drawer({ isOpen, onClose, hasFooter, placement, width, okText,
329
329
 
330
330
  interface TooltipProps {
331
331
  children: React$1.ReactNode;
332
+ /** The text or node shown inside the tooltip */
332
333
  title: React$1.ReactNode;
333
- /** 'top' | 'right' | 'bottom' | 'left' */
334
+ /** Which side of the trigger the tooltip appears on */
334
335
  placement?: 'top' | 'right' | 'bottom' | 'left';
335
- /** Delay in ms before showing the tooltip */
336
+ /** Delay before showing, ms (default 300) */
336
337
  delayDuration?: number;
338
+ /** Offset from trigger in px (default 8) */
339
+ sideOffset?: number;
337
340
  }
338
341
  /**
339
342
  * Tooltip powered by Radix Tooltip.
340
343
  *
341
- * Radix handles keyboard navigation (escape), pointer events, and ARIA.
342
- * The VesOPS prussian-blue style is preserved.
343
- *
344
- * Wrap your app in `<TooltipProvider>` (re-exported below) to batch providers.
344
+ * Radix handles keyboard navigation (Escape), pointer events, and ARIA.
345
+ * Each placement animates in from the correct direction.
346
+ * Wrap your app in `<TooltipProvider>` (re-exported below) to share a
347
+ * single provider instead of nesting one per tooltip.
345
348
  *
346
349
  * @example
347
- * <Tooltip title="Delete record" placement="right">
348
- * <IconButton icon={<Icon.Trash />} />
349
- * </Tooltip>
350
+ * <TooltipProvider>
351
+ * <Tooltip title="Delete record" placement="top">
352
+ * <IconButton icon={<TrashIcon />} />
353
+ * </Tooltip>
354
+ * </TooltipProvider>
350
355
  */
351
- declare function Tooltip({ children, title, placement, delayDuration, }: TooltipProps): react_jsx_runtime.JSX.Element;
356
+ declare function Tooltip({ children, title, placement, delayDuration, sideOffset, }: TooltipProps): react_jsx_runtime.JSX.Element;
352
357
 
353
358
  declare const TooltipProvider: React$1.FC<TooltipPrimitive.TooltipProviderProps>;
354
359
 
@@ -452,6 +457,7 @@ declare function ToggleButton({ items, onChange, activeKey }: ToggleButtonProps)
452
457
 
453
458
  /** ─────────────────── types ─────────────────── */
454
459
  type NotificationType = 'info' | 'success' | 'warning' | 'danger';
460
+ type NotificationPosition = 'top-right' | 'top-left' | 'top-center' | 'bottom-right' | 'bottom-left' | 'bottom-center';
455
461
  interface NotificationPayload {
456
462
  title: React$1.ReactNode;
457
463
  description?: React$1.ReactNode;
@@ -461,32 +467,20 @@ interface NotificationPayload {
461
467
  }
462
468
  /** ─────────────────── provider ─────────────────── */
463
469
  /**
464
- * Wrap your application (or a subtree) in `NotificationProvider` to enable
465
- * toast notifications. Then call `useNotification()` anywhere inside to
466
- * trigger them.
470
+ * Wrap your app in `NotificationProvider`, then call `useNotification()` anywhere inside.
471
+ *
472
+ * @param position One of 6 viewport positions (default: `top-right`)
467
473
  *
468
474
  * @example
469
- * // _app.tsx / main.tsx
470
- * <NotificationProvider>
475
+ * <NotificationProvider position="bottom-right">
471
476
  * <App />
472
477
  * </NotificationProvider>
473
- *
474
- * // Inside a component
475
- * const notify = useNotification()
476
- * notify.success({ title: 'Saved!', description: 'Your changes were saved.', duration: 3000 })
477
478
  */
478
- declare function NotificationProvider({ children }: {
479
+ declare function NotificationProvider({ children, position, }: {
479
480
  children: React$1.ReactNode;
481
+ position?: NotificationPosition;
480
482
  }): react_jsx_runtime.JSX.Element;
481
483
  /** ─────────────────── hook ─────────────────── */
482
- /**
483
- * Imperative notification API.
484
- *
485
- * @example
486
- * const notify = useNotification()
487
- * notify.success({ title: 'Done', description: 'Record saved.', duration: 3000 })
488
- * notify.danger({ title: 'Error', description: err.message })
489
- */
490
484
  declare function useNotification(): {
491
485
  info: (props: Omit<NotificationPayload, "type">) => void;
492
486
  success: (props: Omit<NotificationPayload, "type">) => void;
@@ -827,38 +821,254 @@ interface ThemeSwitchProps {
827
821
  checked: boolean;
828
822
  };
829
823
  }) => void;
824
+ /** Optional accessible label (defaults to "Toggle dark mode") */
825
+ label?: string;
830
826
  }
831
827
  /**
832
828
  * Theme (dark-mode) toggle switch powered by Radix Switch.
833
829
  *
834
- * Displays a red/green dot to indicate the checked state.
835
- * Used as the dark-mode toggle in the TopBar.
830
+ * The thumb color indicates mode: green = light, slate = dark.
831
+ * Layout (position, margin) is the parent's responsibility this component
832
+ * renders inline with no external margins.
836
833
  *
837
834
  * @example
838
- * <Switch checked={isDarkMode} onChange={({ target }) => setDarkMode(target.checked)} />
835
+ * <ThemeSwitch checked={isDark} onChange={({ target }) => setDark(target.checked)} />
839
836
  */
840
- declare function Switch$1({ checked, onChange }: ThemeSwitchProps): react_jsx_runtime.JSX.Element;
837
+ declare function ThemeSwitch({ checked, onChange, label }: ThemeSwitchProps): react_jsx_runtime.JSX.Element;
838
+
839
+ interface TopBarProps {
840
+ /** Brand area — logo, wordmark, or app name. Rendered on the leading edge. */
841
+ brand?: React$1.ReactNode;
842
+ /**
843
+ * Centre content — primary navigation links, breadcrumb, or page title.
844
+ * On mobile (< md breakpoint) this moves below the brand row.
845
+ */
846
+ center?: React$1.ReactNode;
847
+ /**
848
+ * Trailing actions — theme toggle, user avatar, notification bell, etc.
849
+ * Rendered on the trailing edge.
850
+ */
851
+ actions?: React$1.ReactNode;
852
+ /**
853
+ * Height in pixels (default 56). Controls the `h-*` style directly so
854
+ * child scroll-offset calculations can consume it as a CSS var.
855
+ */
856
+ height?: number;
857
+ /** Additional className on the root element */
858
+ className?: string;
859
+ }
860
+ /**
861
+ * App-shell top navigation bar.
862
+ *
863
+ * Three named slots: brand (leading), center, actions (trailing).
864
+ * All slots are optional — omit what you don't need.
865
+ *
866
+ * The component is sticky by default (`sticky top-0`) with `z-[100]`.
867
+ * Height is exposed as `--topbar-height` CSS variable on the element so
868
+ * layout children can reference it for scroll-offset or sticky positioning.
869
+ *
870
+ * Light/dark aware via Phase B semantic tokens.
871
+ *
872
+ * @example
873
+ * <TopBar
874
+ * brand={<Logo />}
875
+ * center={<NavLinks />}
876
+ * actions={
877
+ * <>
878
+ * <ThemeSwitch checked={isDark} onChange={toggleDark} />
879
+ * <UserAvatar />
880
+ * </>
881
+ * }
882
+ * />
883
+ */
884
+ declare function TopBar({ brand, center, actions, height, className, }: TopBarProps): react_jsx_runtime.JSX.Element;
885
+
886
+ /** ─────────────────── types ─────────────────── */
887
+ interface SidebarItem {
888
+ key: string;
889
+ icon: React$1.ReactNode;
890
+ label: string;
891
+ isActive?: boolean;
892
+ onClick?: () => void;
893
+ /** Numeric badge shown on the icon */
894
+ badge?: number;
895
+ }
896
+ interface SidebarSection {
897
+ key: string;
898
+ /** Section title — visible only when expanded */
899
+ title?: string;
900
+ items: SidebarItem[];
901
+ }
902
+ interface SidebarProps {
903
+ sections: SidebarSection[];
904
+ isExpanded: boolean;
905
+ onToggle?: () => void;
906
+ /** Expanded sidebar width in px (default 220) */
907
+ expandedWidth?: number;
908
+ /** Collapsed sidebar width in px (default 52) */
909
+ collapsedWidth?: number;
910
+ /** Slot rendered at the bottom of the sidebar (theme switch, user avatar…) */
911
+ footer?: React$1.ReactNode;
912
+ }
913
+ /** ─────────────────── main component ─────────────────── */
914
+ /**
915
+ * Collapsible application sidebar.
916
+ *
917
+ * When collapsed: icon-only with tooltips. When expanded: icon + label.
918
+ * Width animates with an ease-out-expo curve. The parent (AppShell) is
919
+ * responsible for shifting the main content by the sidebar width.
920
+ *
921
+ * @example
922
+ * const [open, setOpen] = useState(true)
923
+ * <Sidebar
924
+ * sections={NAV_SECTIONS}
925
+ * isExpanded={open}
926
+ * onToggle={() => setOpen(o => !o)}
927
+ * />
928
+ */
929
+ declare function Sidebar({ sections, isExpanded, onToggle, expandedWidth, collapsedWidth, footer, }: SidebarProps): react_jsx_runtime.JSX.Element;
930
+
931
+ interface AppShellProps {
932
+ /**
933
+ * Top navigation bar.
934
+ * Typically `<TopBar brand={...} actions={...} />`.
935
+ */
936
+ topBar?: React$1.ReactNode;
937
+ /** Sidebar navigation sections */
938
+ sidebarSections?: SidebarSection[];
939
+ /** Expanded width of the sidebar in px (default 220) */
940
+ sidebarExpandedWidth?: SidebarProps['expandedWidth'];
941
+ /** Collapsed width of the sidebar in px (default 52) */
942
+ sidebarCollapsedWidth?: SidebarProps['collapsedWidth'];
943
+ /** Start expanded (default false) */
944
+ sidebarDefaultExpanded?: boolean;
945
+ /** Slot rendered at the bottom of the sidebar */
946
+ sidebarFooter?: SidebarProps['footer'];
947
+ /** Main page content */
948
+ children?: React$1.ReactNode;
949
+ /** Root element className */
950
+ className?: string;
951
+ }
952
+ /**
953
+ * Full-page application layout skeleton.
954
+ *
955
+ * Composes a sticky TopBar + collapsible Sidebar + scrollable content area.
956
+ * The main area shifts with the sidebar width via a Framer Motion margin animation.
957
+ *
958
+ * @example
959
+ * <AppShell
960
+ * topBar={<TopBar brand={<Logo />} actions={<ThemeSwitch ... />} />}
961
+ * sidebarSections={NAV_SECTIONS}
962
+ * >
963
+ * <PageContent />
964
+ * </AppShell>
965
+ */
966
+ declare function AppShell({ topBar, sidebarSections, sidebarExpandedWidth, sidebarCollapsedWidth, sidebarDefaultExpanded, sidebarFooter, children, className, }: AppShellProps): react_jsx_runtime.JSX.Element;
967
+
968
+ /** ─────────────────── base ─────────────────── */
969
+ interface SkeletonBaseProps {
970
+ className?: string;
971
+ /** Override inline styles */
972
+ style?: React$1.CSSProperties;
973
+ }
974
+ /** ─────────────────── SkeletonBox ─────────────────── */
975
+ interface SkeletonBoxProps extends SkeletonBaseProps {
976
+ width?: number | string;
977
+ height?: number | string;
978
+ /** Override border-radius (defaults to token --radius-md) */
979
+ radius?: number | string;
980
+ }
981
+ /**
982
+ * Generic rectangular loading placeholder.
983
+ * Use for images, cards, headers, or any block element.
984
+ *
985
+ * @example
986
+ * <SkeletonBox width={240} height={160} />
987
+ * <SkeletonBox width="100%" height={48} radius="var(--radius-lg)" />
988
+ */
989
+ declare function SkeletonBox({ width, height, radius, className, style }: SkeletonBoxProps): react_jsx_runtime.JSX.Element;
990
+ /** ─────────────────── SkeletonText ─────────────────── */
991
+ interface SkeletonTextProps extends SkeletonBaseProps {
992
+ /** Number of lines (default 3) */
993
+ lines?: number;
994
+ /** Width of the last (shortest) line as a percentage (default 60) */
995
+ lastLineWidth?: number;
996
+ /** Line height in px (default 14) */
997
+ lineHeight?: number;
998
+ /** Gap between lines in px (default 8) */
999
+ gap?: number;
1000
+ }
1001
+ /**
1002
+ * Multi-line text loading placeholder.
1003
+ * Last line is shorter to mimic real paragraph layout.
1004
+ *
1005
+ * @example
1006
+ * <SkeletonText lines={4} lastLineWidth={45} />
1007
+ */
1008
+ declare function SkeletonText({ lines, lastLineWidth, lineHeight, gap, className, style, }: SkeletonTextProps): react_jsx_runtime.JSX.Element;
1009
+ /** ─────────────────── SkeletonCircle ─────────────────── */
1010
+ interface SkeletonCircleProps extends SkeletonBaseProps {
1011
+ /** Diameter in px (default 40) */
1012
+ size?: number;
1013
+ }
1014
+ /**
1015
+ * Circular loading placeholder — avatars, icons, status indicators.
1016
+ *
1017
+ * @example
1018
+ * <SkeletonCircle size={48} />
1019
+ */
1020
+ declare function SkeletonCircle({ size, className, style }: SkeletonCircleProps): react_jsx_runtime.JSX.Element;
1021
+ /** ─────────────────── SkeletonCard ─────────────────── */
1022
+ interface SkeletonCardProps extends SkeletonBaseProps {
1023
+ /** Include a circular avatar in the header (default true) */
1024
+ hasAvatar?: boolean;
1025
+ /** Number of text lines in the body (default 3) */
1026
+ lines?: number;
1027
+ }
1028
+ /**
1029
+ * Composite card skeleton — avatar + heading + body text + action strip.
1030
+ * Use as a drop-in while real card data loads.
1031
+ *
1032
+ * @example
1033
+ * <div className="grid grid-cols-3 gap-4">
1034
+ * {loading && Array.from({ length: 3 }).map((_, i) => <SkeletonCard key={i} />)}
1035
+ * </div>
1036
+ */
1037
+ declare function SkeletonCard({ hasAvatar, lines, className, style }: SkeletonCardProps): react_jsx_runtime.JSX.Element;
841
1038
 
842
1039
  interface ButtonProps {
843
1040
  content?: React$1.ReactNode;
844
- /** HTML button type attribute */
1041
+ /** Visual style variant */
1042
+ variant?: 'primary' | 'secondary' | 'ghost' | 'danger';
1043
+ /** Size — controls height, padding, and font size */
1044
+ size?: 'sm' | 'md' | 'lg';
1045
+ /** HTML button type */
845
1046
  buttonType?: 'button' | 'submit' | 'reset';
846
- /** Visual variant */
847
- type?: string;
848
1047
  loading?: boolean;
849
1048
  disabled?: boolean;
1049
+ /** Inline style overrides (width, etc.). Margins/layout belong in the parent. */
850
1050
  style?: React$1.CSSProperties;
1051
+ /** Leading icon — rendered before content */
851
1052
  icon?: React$1.ReactNode;
852
1053
  onClick?: React$1.MouseEventHandler<HTMLButtonElement>;
1054
+ /**
1055
+ * @deprecated Pass `variant` instead. Kept for API compat — currently no-op.
1056
+ * Will be removed in the next major version.
1057
+ */
1058
+ type?: string;
853
1059
  }
854
1060
  /**
855
- * Primary action button.
1061
+ * Primary action button with variant + size system.
1062
+ *
1063
+ * Width is never hardcoded — set `style={{ width }}` or let the parent grid/flex control it.
856
1064
  *
857
1065
  * @example
858
1066
  * <Button content="Save" onClick={handleSave} />
859
- * <Button content="Submit" buttonType="submit" loading={isPending} />
1067
+ * <Button content="Delete" variant="danger" size="sm" />
1068
+ * <Button content="Cancel" variant="secondary" />
1069
+ * <Button content="Loading…" loading buttonType="submit" />
860
1070
  */
861
- declare function Button({ content, buttonType, loading, disabled, style, icon, onClick, }: ButtonProps): react_jsx_runtime.JSX.Element;
1071
+ declare function Button({ content, variant, size, buttonType, loading, disabled, style, icon, onClick, }: ButtonProps): react_jsx_runtime.JSX.Element;
862
1072
 
863
1073
  interface TextInputProps {
864
1074
  value?: any;
@@ -964,40 +1174,40 @@ interface DropdownPillProps {
964
1174
  declare function DropdownPill({ value, hasSiblings }: DropdownPillProps): react_jsx_runtime.JSX.Element;
965
1175
 
966
1176
  interface CheckboxProps {
967
- /** 'vertical' | 'horizontal' */
968
- layout?: string;
969
- /** 'left' | 'right' (label side when horizontal) */
970
- labelPosition?: string;
971
- label?: React$1.ReactNode;
972
- name?: string;
973
- htmlFor?: string;
974
- errorMessage?: React$1.ReactNode;
975
- value?: boolean;
1177
+ /** Controlled checked state */
1178
+ checked?: boolean;
976
1179
  onChange?: (e: {
977
1180
  target: {
978
- value: boolean;
1181
+ checked: boolean;
979
1182
  id?: string;
980
1183
  name?: string;
981
1184
  };
982
1185
  }) => void;
983
- [key: string]: any;
1186
+ label?: React$1.ReactNode;
1187
+ name?: string;
1188
+ /** `id` for the hidden input and the `<label htmlFor>` link */
1189
+ htmlFor?: string;
1190
+ errorMessage?: React$1.ReactNode;
1191
+ disabled?: boolean;
1192
+ /** @deprecated Use `checked` */
1193
+ value?: boolean;
984
1194
  }
985
1195
  /**
986
1196
  * Accessible checkbox powered by Radix Checkbox.
987
1197
  *
988
- * Radix handles keyboard activation, focus ring, and ARIA checked state.
989
- * Emits a synthetic `{ target: { value, id, name } }` event to stay
990
- * compatible with existing form-change handlers.
1198
+ * Radix handles keyboard activation, focus ring, and `role="checkbox"` ARIA.
1199
+ * The check mark pops in with a spring animation on first check.
991
1200
  *
992
1201
  * @example
993
1202
  * <Checkbox
994
1203
  * htmlFor="agree"
995
1204
  * label="I agree to the terms"
996
- * value={form.agree}
997
- * onChange={({ target }) => setField('agree', target.value)}
1205
+ * checked={form.agree}
1206
+ * onChange={({ target }) => setField('agree', target.checked)}
998
1207
  * />
999
1208
  */
1000
- declare function Checkbox({ layout, labelPosition, label, name, htmlFor, errorMessage, value, onChange, }: CheckboxProps): react_jsx_runtime.JSX.Element;
1209
+ declare function Checkbox({ checked, value, // legacy alias
1210
+ onChange, label, name, htmlFor, errorMessage, disabled, }: CheckboxProps): react_jsx_runtime.JSX.Element;
1001
1211
 
1002
1212
  interface SwitchInputProps {
1003
1213
  checked?: boolean;
@@ -1237,4 +1447,4 @@ declare const Temporal: {
1237
1447
  TemporalPicker: typeof TemporalPickerBase;
1238
1448
  };
1239
1449
 
1240
- export { AutoComplete, type AutoCompleteProps, Button, type ButtonProps, Catalog, CatalogCarousel, type CatalogCarouselProps, CatalogGrid, type CatalogGridProps, type CatalogProps, Checkbox, type CheckboxProps, ContextMenu, type ContextMenuActionItem, type ContextMenuPosition, type ContextMenuProps, type DatePickerProps, Drawer, type DrawerProps, Dropdown, type DropdownItem, DropdownPill, type DropdownPillProps, type DropdownProps, type ExpandRowOptions, FadingBase, type FadingBaseProps, FileInput, type FileInputProps, GridCard, type GridCardItem, type GridCardProps, Icon, IconButton, type IconButtonProps, List, type ListItem, type ListProps, LoadingSpinner, type LoadingSpinnerProps, MenuBar, MenuBarItem, type MenuBarItemConfig, type MenuBarItemProps, type MenuBarProps, Modal, type ModalProps, type NotificationPayload, NotificationProvider, NumberInput, type NumberInputProps, OpaqueGridCard, type OpaqueGridCardProps, type PaginationOptions, Password, type PasswordProps, ScalableContainer, type ScalableContainerProps, SearchInput, type SearchInputProps, Switch, type SwitchInputProps, type TabItem, Table, type TableColumn, type TableProps, Tabs, type TabsProps, Temporal, type TemporalPickerProps, TextInput, type TextInputProps, Switch$1 as ThemeSwitch, type ThemeSwitchProps, ToggleButton, type ToggleButtonProps, type ToggleItem, Tooltip, type TooltipProps, TooltipProvider, Tree, type TreeItemClickPayload, type TreeNode, type TreeProps, TreeSelect, type TreeSelectProps, Wizard, type WizardProps, type WizardStep, useNotification };
1450
+ export { AppShell, type AppShellProps, AutoComplete, type AutoCompleteProps, Button, type ButtonProps, Catalog, CatalogCarousel, type CatalogCarouselProps, CatalogGrid, type CatalogGridProps, type CatalogProps, Checkbox, type CheckboxProps, ContextMenu, type ContextMenuActionItem, type ContextMenuPosition, type ContextMenuProps, type DatePickerProps, Drawer, type DrawerProps, Dropdown, type DropdownItem, DropdownPill, type DropdownPillProps, type DropdownProps, type ExpandRowOptions, FadingBase, type FadingBaseProps, FileInput, type FileInputProps, GridCard, type GridCardItem, type GridCardProps, Icon, IconButton, type IconButtonProps, List, type ListItem, type ListProps, LoadingSpinner, type LoadingSpinnerProps, MenuBar, MenuBarItem, type MenuBarItemConfig, type MenuBarItemProps, type MenuBarProps, Modal, type ModalProps, type NotificationPayload, NotificationProvider, NumberInput, type NumberInputProps, OpaqueGridCard, type OpaqueGridCardProps, type PaginationOptions, Password, type PasswordProps, ScalableContainer, type ScalableContainerProps, SearchInput, type SearchInputProps, Sidebar, type SidebarItem, type SidebarProps, type SidebarSection, SkeletonBox, type SkeletonBoxProps, SkeletonCard, type SkeletonCardProps, SkeletonCircle, type SkeletonCircleProps, SkeletonText, type SkeletonTextProps, Switch, type SwitchInputProps, type TabItem, Table, type TableColumn, type TableProps, Tabs, type TabsProps, Temporal, type TemporalPickerProps, TextInput, type TextInputProps, ThemeSwitch, type ThemeSwitchProps, ToggleButton, type ToggleButtonProps, type ToggleItem, Tooltip, type TooltipProps, TooltipProvider, TopBar, type TopBarProps, Tree, type TreeItemClickPayload, type TreeNode, type TreeProps, TreeSelect, type TreeSelectProps, Wizard, type WizardProps, type WizardStep, useNotification };