@geomak/ui 1.8.0 → 2.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/dist/index.d.cts CHANGED
@@ -853,42 +853,79 @@ interface MenuBarProps {
853
853
  */
854
854
  declare function MenuBar({ items }: MenuBarProps): react_jsx_runtime.JSX.Element;
855
855
 
856
+ /**
857
+ * A single action in the context menu.
858
+ *
859
+ * - Leaf items (no `children`) call `onClick` when activated.
860
+ * - Parent items (with `children`) open a sub-menu on hover / arrow-right.
861
+ * - `disabled` items render but cannot be activated; screen readers
862
+ * announce them as disabled.
863
+ */
856
864
  interface ContextMenuActionItem {
857
- key: string | number;
865
+ key: React$1.Key;
866
+ /** Label shown for the item. May be plain text or a node. */
858
867
  value: React$1.ReactNode;
859
868
  icon?: React$1.ReactNode;
860
- onClick?: (path?: string, reportType?: string) => void;
861
- path?: string;
862
- reportType?: string;
869
+ /** Fires when the item is activated. Ignored when `children` is set. */
870
+ onClick?: () => void;
871
+ /** Optional sub-menu items. */
863
872
  children?: ContextMenuActionItem[];
864
- }
865
- interface ContextMenuPosition {
866
- x: number;
867
- y: number;
873
+ /** Render as disabled — still visible but not activatable. */
874
+ disabled?: boolean;
868
875
  }
869
876
  interface ContextMenuProps {
877
+ /** Top-level items. Each may carry nested `children` for sub-menus. */
870
878
  items: ContextMenuActionItem[];
871
- position: ContextMenuPosition;
872
- visible: boolean;
873
- onClose: () => void;
879
+ /**
880
+ * The element that should respond to right-click. The entire React
881
+ * subtree underneath becomes the trigger area. Wrap an existing
882
+ * component / div / image — anything you can right-click on.
883
+ */
884
+ children: React$1.ReactNode;
874
885
  }
875
886
  /**
876
- * Right-click context menu positioned at arbitrary screen coordinates.
877
- *
878
- * Decoupled from `useData()` — the app manages `visible`, `position`, and
879
- * `items` in its own state and passes them here.
887
+ * Right-click context menu, built on `@radix-ui/react-context-menu`.
880
888
  *
881
- * @example
882
- * const [ctx, setCtx] = useState({ visible: false, items: [], position: { x: 0, y: 0 } })
889
+ * **Idiomatic usage**: wrap the element that should respond to right-click.
890
+ * Radix handles positioning (avoids viewport edges automatically), keyboard
891
+ * navigation (↑↓ to move, → to open sub-menu, ← to close, Enter to activate,
892
+ * Esc to dismiss), focus management, and portal-based stacking.
883
893
  *
884
- * <div onContextMenu={(e) => {
885
- * e.preventDefault()
886
- * setCtx({ visible: true, items: menuItems, position: { x: e.clientX, y: e.clientY } })
887
- * }}>...</div>
894
+ * @example Basic flat menu
895
+ * ```tsx
896
+ * <ContextMenu
897
+ * items={[
898
+ * { key: 'edit', value: 'Edit', onClick: () => openEditor() },
899
+ * { key: 'delete', value: 'Delete', onClick: () => askDelete() },
900
+ * ]}
901
+ * >
902
+ * <Card vessel={vessel} />
903
+ * </ContextMenu>
904
+ * ```
888
905
  *
889
- * <ContextMenu {...ctx} onClose={() => setCtx(c => ({ ...c, visible: false }))} />
906
+ * @example With sub-menu
907
+ * ```tsx
908
+ * <ContextMenu
909
+ * items={[
910
+ * {
911
+ * key: 'export', value: 'Export',
912
+ * children: [
913
+ * { key: 'csv', value: 'as CSV', onClick: () => exportCsv() },
914
+ * { key: 'xlsx', value: 'as Excel', onClick: () => exportXlsx() },
915
+ * ],
916
+ * },
917
+ * ]}
918
+ * >
919
+ * <Table rows={rows} />
920
+ * </ContextMenu>
921
+ * ```
890
922
  */
891
- declare function ContextMenu({ items, position, visible, onClose }: ContextMenuProps): react_jsx_runtime.JSX.Element;
923
+ declare function ContextMenu({ items, children }: ContextMenuProps): react_jsx_runtime.JSX.Element;
924
+ /** @deprecated The Radix rewrite positions the menu automatically — no coordinates needed. */
925
+ interface ContextMenuPosition {
926
+ x: number;
927
+ y: number;
928
+ }
892
929
 
893
930
  interface WizardStep {
894
931
  /** Ref to the DOM element to highlight */
@@ -1457,11 +1494,14 @@ interface TextInputProps {
1457
1494
  declare function TextInput({ value, onChange, disabled, label, htmlFor, placeholder, name, inputStyle, style, layout, onBlur, errorMessage, labelColor, }: TextInputProps): react_jsx_runtime.JSX.Element;
1458
1495
 
1459
1496
  interface NumberInputProps {
1497
+ /** Step size for the up/down buttons and native arrow-key handling. Default `1`. */
1460
1498
  step?: number;
1461
- value?: any;
1499
+ /** Current value. `undefined` renders an empty field; a number renders that value. */
1500
+ value?: number | '';
1501
+ /** Fires with the next number. Empty input resolves to `undefined`. */
1462
1502
  onChange?: (e: {
1463
1503
  target: {
1464
- value: number;
1504
+ value: number | undefined;
1465
1505
  id?: string;
1466
1506
  name?: string;
1467
1507
  };
@@ -1470,8 +1510,8 @@ interface NumberInputProps {
1470
1510
  htmlFor?: string;
1471
1511
  name?: string;
1472
1512
  disabled?: boolean;
1473
- /** 'horizontal' | 'vertical' */
1474
- layout?: string;
1513
+ /** Label/input orientation. Defaults to `'horizontal'`. */
1514
+ layout?: 'horizontal' | 'vertical';
1475
1515
  errorMessage?: React$1.ReactNode;
1476
1516
  inputStyle?: React$1.CSSProperties;
1477
1517
  labelStyle?: React$1.CSSProperties;
@@ -1480,12 +1520,42 @@ interface NumberInputProps {
1480
1520
  min?: number;
1481
1521
  max?: number;
1482
1522
  readOnly?: boolean;
1483
- [key: string]: any;
1523
+ /** Optional precision for floating-point steps (number of decimal places to round to). */
1524
+ precision?: number;
1484
1525
  }
1485
1526
  /**
1486
- * Number input with increment / decrement controls.
1527
+ * Numeric input with keyboard-accessible increment / decrement buttons.
1528
+ *
1529
+ * **What's improved over the previous version**
1530
+ * - Step buttons are real `<button>` elements with `aria-label`, focus rings,
1531
+ * and proper keyboard activation (Enter / Space). The previous version used
1532
+ * `<span onClick>` which keyboard-only users could not reach.
1533
+ * - Floating-point drift on decimal steps (`0.1 + 0.2 = 0.30000000000000004`)
1534
+ * is rounded out via a `precision` prop or auto-inferred from the step.
1535
+ * - Empty input resolves to `undefined` instead of `NaN` — works with form
1536
+ * libraries (RHF, Formik) that treat empty as "no value".
1537
+ * - The decrement chevron actually points down (the previous SVG was the up
1538
+ * chevron rotated, with the up chevron itself wrongly using the same path).
1539
+ * - Width is a prop, not hardcoded `w-60`. Default is `w-full` so the input
1540
+ * flows with its parent.
1541
+ *
1542
+ * @example
1543
+ * ```tsx
1544
+ * const [qty, setQty] = useState<number | undefined>(1)
1545
+ * <NumberInput
1546
+ * label="Quantity"
1547
+ * value={qty ?? ''}
1548
+ * onChange={({ target }) => setQty(target.value)}
1549
+ * min={0} max={99}
1550
+ * />
1551
+ * ```
1552
+ *
1553
+ * @example Decimal step
1554
+ * ```tsx
1555
+ * <NumberInput label="Tonnage" step={0.25} precision={2} />
1556
+ * ```
1487
1557
  */
1488
- declare function NumberInput({ step, value, onChange, label, htmlFor, name, disabled, layout, errorMessage, inputStyle, labelStyle, placeholder, style, min, max, readOnly, }: NumberInputProps): react_jsx_runtime.JSX.Element;
1558
+ declare function NumberInput({ step, value, onChange, label, htmlFor, name, disabled, layout, errorMessage, inputStyle, labelStyle, placeholder, style, min, max, readOnly, precision, }: NumberInputProps): react_jsx_runtime.JSX.Element;
1489
1559
 
1490
1560
  interface PasswordProps {
1491
1561
  value?: string;
package/dist/index.d.ts CHANGED
@@ -853,42 +853,79 @@ interface MenuBarProps {
853
853
  */
854
854
  declare function MenuBar({ items }: MenuBarProps): react_jsx_runtime.JSX.Element;
855
855
 
856
+ /**
857
+ * A single action in the context menu.
858
+ *
859
+ * - Leaf items (no `children`) call `onClick` when activated.
860
+ * - Parent items (with `children`) open a sub-menu on hover / arrow-right.
861
+ * - `disabled` items render but cannot be activated; screen readers
862
+ * announce them as disabled.
863
+ */
856
864
  interface ContextMenuActionItem {
857
- key: string | number;
865
+ key: React$1.Key;
866
+ /** Label shown for the item. May be plain text or a node. */
858
867
  value: React$1.ReactNode;
859
868
  icon?: React$1.ReactNode;
860
- onClick?: (path?: string, reportType?: string) => void;
861
- path?: string;
862
- reportType?: string;
869
+ /** Fires when the item is activated. Ignored when `children` is set. */
870
+ onClick?: () => void;
871
+ /** Optional sub-menu items. */
863
872
  children?: ContextMenuActionItem[];
864
- }
865
- interface ContextMenuPosition {
866
- x: number;
867
- y: number;
873
+ /** Render as disabled — still visible but not activatable. */
874
+ disabled?: boolean;
868
875
  }
869
876
  interface ContextMenuProps {
877
+ /** Top-level items. Each may carry nested `children` for sub-menus. */
870
878
  items: ContextMenuActionItem[];
871
- position: ContextMenuPosition;
872
- visible: boolean;
873
- onClose: () => void;
879
+ /**
880
+ * The element that should respond to right-click. The entire React
881
+ * subtree underneath becomes the trigger area. Wrap an existing
882
+ * component / div / image — anything you can right-click on.
883
+ */
884
+ children: React$1.ReactNode;
874
885
  }
875
886
  /**
876
- * Right-click context menu positioned at arbitrary screen coordinates.
877
- *
878
- * Decoupled from `useData()` — the app manages `visible`, `position`, and
879
- * `items` in its own state and passes them here.
887
+ * Right-click context menu, built on `@radix-ui/react-context-menu`.
880
888
  *
881
- * @example
882
- * const [ctx, setCtx] = useState({ visible: false, items: [], position: { x: 0, y: 0 } })
889
+ * **Idiomatic usage**: wrap the element that should respond to right-click.
890
+ * Radix handles positioning (avoids viewport edges automatically), keyboard
891
+ * navigation (↑↓ to move, → to open sub-menu, ← to close, Enter to activate,
892
+ * Esc to dismiss), focus management, and portal-based stacking.
883
893
  *
884
- * <div onContextMenu={(e) => {
885
- * e.preventDefault()
886
- * setCtx({ visible: true, items: menuItems, position: { x: e.clientX, y: e.clientY } })
887
- * }}>...</div>
894
+ * @example Basic flat menu
895
+ * ```tsx
896
+ * <ContextMenu
897
+ * items={[
898
+ * { key: 'edit', value: 'Edit', onClick: () => openEditor() },
899
+ * { key: 'delete', value: 'Delete', onClick: () => askDelete() },
900
+ * ]}
901
+ * >
902
+ * <Card vessel={vessel} />
903
+ * </ContextMenu>
904
+ * ```
888
905
  *
889
- * <ContextMenu {...ctx} onClose={() => setCtx(c => ({ ...c, visible: false }))} />
906
+ * @example With sub-menu
907
+ * ```tsx
908
+ * <ContextMenu
909
+ * items={[
910
+ * {
911
+ * key: 'export', value: 'Export',
912
+ * children: [
913
+ * { key: 'csv', value: 'as CSV', onClick: () => exportCsv() },
914
+ * { key: 'xlsx', value: 'as Excel', onClick: () => exportXlsx() },
915
+ * ],
916
+ * },
917
+ * ]}
918
+ * >
919
+ * <Table rows={rows} />
920
+ * </ContextMenu>
921
+ * ```
890
922
  */
891
- declare function ContextMenu({ items, position, visible, onClose }: ContextMenuProps): react_jsx_runtime.JSX.Element;
923
+ declare function ContextMenu({ items, children }: ContextMenuProps): react_jsx_runtime.JSX.Element;
924
+ /** @deprecated The Radix rewrite positions the menu automatically — no coordinates needed. */
925
+ interface ContextMenuPosition {
926
+ x: number;
927
+ y: number;
928
+ }
892
929
 
893
930
  interface WizardStep {
894
931
  /** Ref to the DOM element to highlight */
@@ -1457,11 +1494,14 @@ interface TextInputProps {
1457
1494
  declare function TextInput({ value, onChange, disabled, label, htmlFor, placeholder, name, inputStyle, style, layout, onBlur, errorMessage, labelColor, }: TextInputProps): react_jsx_runtime.JSX.Element;
1458
1495
 
1459
1496
  interface NumberInputProps {
1497
+ /** Step size for the up/down buttons and native arrow-key handling. Default `1`. */
1460
1498
  step?: number;
1461
- value?: any;
1499
+ /** Current value. `undefined` renders an empty field; a number renders that value. */
1500
+ value?: number | '';
1501
+ /** Fires with the next number. Empty input resolves to `undefined`. */
1462
1502
  onChange?: (e: {
1463
1503
  target: {
1464
- value: number;
1504
+ value: number | undefined;
1465
1505
  id?: string;
1466
1506
  name?: string;
1467
1507
  };
@@ -1470,8 +1510,8 @@ interface NumberInputProps {
1470
1510
  htmlFor?: string;
1471
1511
  name?: string;
1472
1512
  disabled?: boolean;
1473
- /** 'horizontal' | 'vertical' */
1474
- layout?: string;
1513
+ /** Label/input orientation. Defaults to `'horizontal'`. */
1514
+ layout?: 'horizontal' | 'vertical';
1475
1515
  errorMessage?: React$1.ReactNode;
1476
1516
  inputStyle?: React$1.CSSProperties;
1477
1517
  labelStyle?: React$1.CSSProperties;
@@ -1480,12 +1520,42 @@ interface NumberInputProps {
1480
1520
  min?: number;
1481
1521
  max?: number;
1482
1522
  readOnly?: boolean;
1483
- [key: string]: any;
1523
+ /** Optional precision for floating-point steps (number of decimal places to round to). */
1524
+ precision?: number;
1484
1525
  }
1485
1526
  /**
1486
- * Number input with increment / decrement controls.
1527
+ * Numeric input with keyboard-accessible increment / decrement buttons.
1528
+ *
1529
+ * **What's improved over the previous version**
1530
+ * - Step buttons are real `<button>` elements with `aria-label`, focus rings,
1531
+ * and proper keyboard activation (Enter / Space). The previous version used
1532
+ * `<span onClick>` which keyboard-only users could not reach.
1533
+ * - Floating-point drift on decimal steps (`0.1 + 0.2 = 0.30000000000000004`)
1534
+ * is rounded out via a `precision` prop or auto-inferred from the step.
1535
+ * - Empty input resolves to `undefined` instead of `NaN` — works with form
1536
+ * libraries (RHF, Formik) that treat empty as "no value".
1537
+ * - The decrement chevron actually points down (the previous SVG was the up
1538
+ * chevron rotated, with the up chevron itself wrongly using the same path).
1539
+ * - Width is a prop, not hardcoded `w-60`. Default is `w-full` so the input
1540
+ * flows with its parent.
1541
+ *
1542
+ * @example
1543
+ * ```tsx
1544
+ * const [qty, setQty] = useState<number | undefined>(1)
1545
+ * <NumberInput
1546
+ * label="Quantity"
1547
+ * value={qty ?? ''}
1548
+ * onChange={({ target }) => setQty(target.value)}
1549
+ * min={0} max={99}
1550
+ * />
1551
+ * ```
1552
+ *
1553
+ * @example Decimal step
1554
+ * ```tsx
1555
+ * <NumberInput label="Tonnage" step={0.25} precision={2} />
1556
+ * ```
1487
1557
  */
1488
- declare function NumberInput({ step, value, onChange, label, htmlFor, name, disabled, layout, errorMessage, inputStyle, labelStyle, placeholder, style, min, max, readOnly, }: NumberInputProps): react_jsx_runtime.JSX.Element;
1558
+ declare function NumberInput({ step, value, onChange, label, htmlFor, name, disabled, layout, errorMessage, inputStyle, labelStyle, placeholder, style, min, max, readOnly, precision, }: NumberInputProps): react_jsx_runtime.JSX.Element;
1489
1559
 
1490
1560
  interface PasswordProps {
1491
1561
  value?: string;