@geomak/ui 5.1.0 → 5.2.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
@@ -1384,6 +1384,16 @@ interface TableProps<T extends Record<string, any> = Record<string, any>> {
1384
1384
  hasSearch?: boolean;
1385
1385
  footer?: React$1.ReactNode;
1386
1386
  header?: React$1.ReactNode;
1387
+ /**
1388
+ * When `true`, the body renders skeleton rows (one per column with the
1389
+ * shared shimmer animation) instead of data. Use during initial data
1390
+ * fetch, server-side pagination transitions, or any time the dataset is
1391
+ * not yet ready. Combine with `pagination.serverSide` for the canonical
1392
+ * "loading next page" pattern.
1393
+ */
1394
+ loading?: boolean;
1395
+ /** Number of skeleton rows to render when `loading` is true. Default `8`. */
1396
+ loadingRowCount?: number;
1387
1397
  }
1388
1398
  /** ─────────────────── main component ─────────────────── */
1389
1399
  /**
@@ -1426,7 +1436,7 @@ interface TableProps<T extends Record<string, any> = Record<string, any>> {
1426
1436
  * />
1427
1437
  * ```
1428
1438
  */
1429
- declare function Table<T extends Record<string, any> = Record<string, any>>({ columns, rows, getRowKey, pagination, expandRow, hasSearch, footer, header, }: TableProps<T>): react_jsx_runtime.JSX.Element;
1439
+ declare function Table<T extends Record<string, any> = Record<string, any>>({ columns, rows, getRowKey, pagination, expandRow, hasSearch, footer, header, loading, loadingRowCount, }: TableProps<T>): react_jsx_runtime.JSX.Element;
1430
1440
 
1431
1441
  interface ThemeSwitchProps {
1432
1442
  checked: boolean;
@@ -2094,25 +2104,67 @@ interface AutoCompleteProps {
2094
2104
  style?: React$1.CSSProperties;
2095
2105
  /** Label/input orientation. Defaults to `'vertical'`. */
2096
2106
  layout?: 'horizontal' | 'vertical';
2107
+ /**
2108
+ * Static list — when provided, the component does its own substring
2109
+ * filtering on `label` and `key`. Mutually exclusive with `onSearch`.
2110
+ */
2097
2111
  items?: AutoCompleteItem[];
2112
+ /**
2113
+ * Async resolver — when provided, `items` is ignored and `onSearch(term)`
2114
+ * is called (debounced) every time the user pauses typing. Its returned
2115
+ * promise drives the option list. The component manages an internal
2116
+ * `loading` state and shows an `xs` LoadingSpinner where the search icon
2117
+ * normally lives while a query is in flight.
2118
+ */
2119
+ onSearch?: (term: string) => Promise<AutoCompleteItem[]>;
2120
+ /**
2121
+ * Debounce delay (ms) before `onSearch` fires after the user stops
2122
+ * typing. Default `250`. Ignored when `items` is used.
2123
+ */
2124
+ debounce?: number;
2098
2125
  onItemClick?: (value: string) => void;
2099
2126
  /** Custom "empty" message */
2100
2127
  emptyText?: string;
2128
+ /** Custom "loading" message — shown in async mode while a query is in flight. */
2129
+ loadingText?: string;
2101
2130
  }
2102
2131
  /**
2103
- * Search-as-you-type autocomplete powered by Radix Popover.
2132
+ * Search-as-you-type autocomplete powered by Radix Popover. Supports two
2133
+ * modes:
2134
+ *
2135
+ * - **Static**: pass `items` — the component substring-filters locally.
2136
+ * Best for small fixed lists (≤ 200 entries).
2137
+ * - **Async**: pass `onSearch(term) => Promise<Item[]>` — the component
2138
+ * debounces input and drives the option list from the resolver. Shows
2139
+ * an `xs` LoadingSpinner while the query is in flight.
2104
2140
  *
2105
2141
  * The popover opens when the input is focused and closes when an item is
2106
- * selected or the user clicks away. Radix handles portal-based z-stacking.
2142
+ * selected or the user clicks away.
2107
2143
  *
2108
- * @example
2144
+ * @example Static (small fixed list)
2145
+ * ```tsx
2109
2146
  * <AutoComplete
2110
2147
  * label="Vessel"
2111
- * items={vessels.map(v => ({ key: v.imo, value: v.imo, label: v.name }))}
2148
+ * items={vessels.map((v) => ({ key: v.imo, value: v.imo, label: v.name }))}
2112
2149
  * onItemClick={(imo) => setVessel(imo)}
2113
2150
  * />
2151
+ * ```
2152
+ *
2153
+ * @example Async (server-backed)
2154
+ * ```tsx
2155
+ * <AutoComplete
2156
+ * label="Port"
2157
+ * debounce={300}
2158
+ * onSearch={async (term) => {
2159
+ * const res = await fetch(`/api/ports?q=${encodeURIComponent(term)}`)
2160
+ * const data = await res.json()
2161
+ * return data.map((p) => ({ key: p.unlocode, value: p.unlocode, label: p.name }))
2162
+ * }}
2163
+ * onItemClick={(unlocode) => setPort(unlocode)}
2164
+ * />
2165
+ * ```
2114
2166
  */
2115
- declare function AutoComplete({ disabled, label, placeholder, name, inputStyle, style, layout, items, onItemClick, emptyText, }: AutoCompleteProps): react_jsx_runtime.JSX.Element;
2167
+ declare function AutoComplete({ disabled, label, placeholder, name, inputStyle, style, layout, items, onSearch, debounce, onItemClick, emptyText, loadingText, }: AutoCompleteProps): react_jsx_runtime.JSX.Element;
2116
2168
 
2117
2169
  interface TreeSelectNode {
2118
2170
  key: string | number;
package/dist/index.d.ts CHANGED
@@ -1384,6 +1384,16 @@ interface TableProps<T extends Record<string, any> = Record<string, any>> {
1384
1384
  hasSearch?: boolean;
1385
1385
  footer?: React$1.ReactNode;
1386
1386
  header?: React$1.ReactNode;
1387
+ /**
1388
+ * When `true`, the body renders skeleton rows (one per column with the
1389
+ * shared shimmer animation) instead of data. Use during initial data
1390
+ * fetch, server-side pagination transitions, or any time the dataset is
1391
+ * not yet ready. Combine with `pagination.serverSide` for the canonical
1392
+ * "loading next page" pattern.
1393
+ */
1394
+ loading?: boolean;
1395
+ /** Number of skeleton rows to render when `loading` is true. Default `8`. */
1396
+ loadingRowCount?: number;
1387
1397
  }
1388
1398
  /** ─────────────────── main component ─────────────────── */
1389
1399
  /**
@@ -1426,7 +1436,7 @@ interface TableProps<T extends Record<string, any> = Record<string, any>> {
1426
1436
  * />
1427
1437
  * ```
1428
1438
  */
1429
- declare function Table<T extends Record<string, any> = Record<string, any>>({ columns, rows, getRowKey, pagination, expandRow, hasSearch, footer, header, }: TableProps<T>): react_jsx_runtime.JSX.Element;
1439
+ declare function Table<T extends Record<string, any> = Record<string, any>>({ columns, rows, getRowKey, pagination, expandRow, hasSearch, footer, header, loading, loadingRowCount, }: TableProps<T>): react_jsx_runtime.JSX.Element;
1430
1440
 
1431
1441
  interface ThemeSwitchProps {
1432
1442
  checked: boolean;
@@ -2094,25 +2104,67 @@ interface AutoCompleteProps {
2094
2104
  style?: React$1.CSSProperties;
2095
2105
  /** Label/input orientation. Defaults to `'vertical'`. */
2096
2106
  layout?: 'horizontal' | 'vertical';
2107
+ /**
2108
+ * Static list — when provided, the component does its own substring
2109
+ * filtering on `label` and `key`. Mutually exclusive with `onSearch`.
2110
+ */
2097
2111
  items?: AutoCompleteItem[];
2112
+ /**
2113
+ * Async resolver — when provided, `items` is ignored and `onSearch(term)`
2114
+ * is called (debounced) every time the user pauses typing. Its returned
2115
+ * promise drives the option list. The component manages an internal
2116
+ * `loading` state and shows an `xs` LoadingSpinner where the search icon
2117
+ * normally lives while a query is in flight.
2118
+ */
2119
+ onSearch?: (term: string) => Promise<AutoCompleteItem[]>;
2120
+ /**
2121
+ * Debounce delay (ms) before `onSearch` fires after the user stops
2122
+ * typing. Default `250`. Ignored when `items` is used.
2123
+ */
2124
+ debounce?: number;
2098
2125
  onItemClick?: (value: string) => void;
2099
2126
  /** Custom "empty" message */
2100
2127
  emptyText?: string;
2128
+ /** Custom "loading" message — shown in async mode while a query is in flight. */
2129
+ loadingText?: string;
2101
2130
  }
2102
2131
  /**
2103
- * Search-as-you-type autocomplete powered by Radix Popover.
2132
+ * Search-as-you-type autocomplete powered by Radix Popover. Supports two
2133
+ * modes:
2134
+ *
2135
+ * - **Static**: pass `items` — the component substring-filters locally.
2136
+ * Best for small fixed lists (≤ 200 entries).
2137
+ * - **Async**: pass `onSearch(term) => Promise<Item[]>` — the component
2138
+ * debounces input and drives the option list from the resolver. Shows
2139
+ * an `xs` LoadingSpinner while the query is in flight.
2104
2140
  *
2105
2141
  * The popover opens when the input is focused and closes when an item is
2106
- * selected or the user clicks away. Radix handles portal-based z-stacking.
2142
+ * selected or the user clicks away.
2107
2143
  *
2108
- * @example
2144
+ * @example Static (small fixed list)
2145
+ * ```tsx
2109
2146
  * <AutoComplete
2110
2147
  * label="Vessel"
2111
- * items={vessels.map(v => ({ key: v.imo, value: v.imo, label: v.name }))}
2148
+ * items={vessels.map((v) => ({ key: v.imo, value: v.imo, label: v.name }))}
2112
2149
  * onItemClick={(imo) => setVessel(imo)}
2113
2150
  * />
2151
+ * ```
2152
+ *
2153
+ * @example Async (server-backed)
2154
+ * ```tsx
2155
+ * <AutoComplete
2156
+ * label="Port"
2157
+ * debounce={300}
2158
+ * onSearch={async (term) => {
2159
+ * const res = await fetch(`/api/ports?q=${encodeURIComponent(term)}`)
2160
+ * const data = await res.json()
2161
+ * return data.map((p) => ({ key: p.unlocode, value: p.unlocode, label: p.name }))
2162
+ * }}
2163
+ * onItemClick={(unlocode) => setPort(unlocode)}
2164
+ * />
2165
+ * ```
2114
2166
  */
2115
- declare function AutoComplete({ disabled, label, placeholder, name, inputStyle, style, layout, items, onItemClick, emptyText, }: AutoCompleteProps): react_jsx_runtime.JSX.Element;
2167
+ declare function AutoComplete({ disabled, label, placeholder, name, inputStyle, style, layout, items, onSearch, debounce, onItemClick, emptyText, loadingText, }: AutoCompleteProps): react_jsx_runtime.JSX.Element;
2116
2168
 
2117
2169
  interface TreeSelectNode {
2118
2170
  key: string | number;