@veltrixsecops/app-sdk 3.2.0 → 3.5.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.
Files changed (77) hide show
  1. package/README.md +1 -1
  2. package/dist/byol/index.cjs +3802 -0
  3. package/dist/byol/index.cjs.map +1 -0
  4. package/dist/byol/index.d.cts +578 -0
  5. package/dist/byol/index.d.ts +578 -0
  6. package/dist/byol/index.js +2587 -0
  7. package/dist/byol/index.js.map +1 -0
  8. package/dist/chunk-3WK4EVQ3.js +842 -0
  9. package/dist/chunk-3WK4EVQ3.js.map +1 -0
  10. package/dist/{chunk-EOOEHZGC.js → chunk-HIL6RIDG.js} +107 -3
  11. package/dist/chunk-HIL6RIDG.js.map +1 -0
  12. package/dist/{chunk-VWFTOFTI.js → chunk-Y6XBNZGR.js} +8 -2
  13. package/dist/chunk-Y6XBNZGR.js.map +1 -0
  14. package/dist/client/index.cjs +112 -2
  15. package/dist/client/index.cjs.map +1 -1
  16. package/dist/client/index.d.cts +118 -6
  17. package/dist/client/index.d.ts +118 -6
  18. package/dist/client/index.js +13 -1
  19. package/dist/connections/index.cjs +1787 -0
  20. package/dist/connections/index.cjs.map +1 -0
  21. package/dist/connections/index.d.cts +78 -0
  22. package/dist/connections/index.d.ts +78 -0
  23. package/dist/connections/index.js +754 -0
  24. package/dist/connections/index.js.map +1 -0
  25. package/dist/hooks/index.cjs.map +1 -1
  26. package/dist/hooks/index.d.cts +2 -2
  27. package/dist/hooks/index.d.ts +2 -2
  28. package/dist/hooks/index.js +1 -1
  29. package/dist/index.cjs +7 -0
  30. package/dist/index.cjs.map +1 -1
  31. package/dist/index.d.cts +3 -3
  32. package/dist/index.d.ts +3 -3
  33. package/dist/index.js +3 -1
  34. package/dist/index.js.map +1 -1
  35. package/dist/opentofu/index.cjs +138 -0
  36. package/dist/opentofu/index.cjs.map +1 -0
  37. package/dist/opentofu/index.d.cts +131 -0
  38. package/dist/opentofu/index.d.ts +131 -0
  39. package/dist/opentofu/index.js +109 -0
  40. package/dist/opentofu/index.js.map +1 -0
  41. package/dist/pipeline/index.cjs +7 -0
  42. package/dist/pipeline/index.cjs.map +1 -1
  43. package/dist/pipeline/index.d.cts +9 -2
  44. package/dist/pipeline/index.d.ts +9 -2
  45. package/dist/pipeline/index.js +3 -1
  46. package/dist/pipeline-beeT8dje.d.cts +408 -0
  47. package/dist/pipeline-beeT8dje.d.ts +408 -0
  48. package/dist/ui/index.cjs +136 -0
  49. package/dist/ui/index.cjs.map +1 -1
  50. package/dist/ui/index.d.cts +109 -1
  51. package/dist/ui/index.d.ts +109 -1
  52. package/dist/ui/index.js +35 -677
  53. package/dist/ui/index.js.map +1 -1
  54. package/dist/{use-app-context-OQlcmq7t.d.cts → use-app-context-Byv_fam0.d.cts} +206 -4
  55. package/dist/{use-app-context-OQlcmq7t.d.ts → use-app-context-Byv_fam0.d.ts} +206 -4
  56. package/opentofu/README.md +114 -0
  57. package/opentofu/modules/aws/main.tf +1008 -0
  58. package/opentofu/modules/aws/outputs.tf +90 -0
  59. package/opentofu/modules/aws/variables.tf +437 -0
  60. package/opentofu/modules/aws/versions.tf +23 -0
  61. package/opentofu/modules/azure/main.tf +920 -0
  62. package/opentofu/modules/azure/outputs.tf +72 -0
  63. package/opentofu/modules/azure/variables.tf +498 -0
  64. package/opentofu/modules/azure/versions.tf +27 -0
  65. package/opentofu/modules/gcp/main.tf +645 -0
  66. package/opentofu/modules/gcp/outputs.tf +73 -0
  67. package/opentofu/modules/gcp/variables.tf +428 -0
  68. package/opentofu/modules/gcp/versions.tf +27 -0
  69. package/opentofu/modules/hetzner/main.tf +432 -0
  70. package/opentofu/modules/hetzner/outputs.tf +72 -0
  71. package/opentofu/modules/hetzner/variables.tf +423 -0
  72. package/opentofu/modules/hetzner/versions.tf +26 -0
  73. package/package.json +33 -1
  74. package/dist/chunk-EOOEHZGC.js.map +0 -1
  75. package/dist/chunk-VWFTOFTI.js.map +0 -1
  76. package/dist/pipeline-A-gSsPRR.d.cts +0 -189
  77. package/dist/pipeline-A-gSsPRR.d.ts +0 -189
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/ui/index.tsx","../../src/client/index.ts"],"sourcesContent":["// ========================================================================\n// @veltrixsecops/app-sdk/ui — the platform's shared component library,\n// exposed to app client bundles.\n//\n// App pages import these instead of hand-rolling raw HTML, so pages render\n// themed inside the Veltrix design system (dark/light + tenant branding via\n// `var(--vx-*)`), consistent with the rest of the portal, and externalized —\n// zero bundle bloat, one React instance. This completes the \"predictable\n// shell, flexible body\" contract: the platform owns the components; apps\n// compose their page body from them.\n//\n// RUNTIME: every export here reads its real implementation off the host at\n// render time — globalThis.__VELTRIX_APP_RUNTIME__.ui.<Name>, populated by\n// the platform from components/shared/* (see\n// client/src/appRuntime/installHostRuntime.ts). At packaging time the CLI's\n// client bundler (and the platform's on-demand esbuild bundle routes) shim\n// the '@veltrixsecops/app-sdk/ui' specifier straight to that `ui` bag, so\n// this module's own render-time lookup only actually executes in\n// non-bundled contexts: local dev, unit tests, a bare `tsc --noEmit`, or\n// Storybook.\n//\n// FALLBACK CONTRACT: outside the platform (host runtime absent, or an older\n// host that predates a given component) every export here renders a\n// minimal, accessible, unstyled fallback instead of throwing — an app page\n// under test or local dev keeps working, just without platform theming.\n// Never throw on render.\n//\n// TYPE FIDELITY: prop types are copied from the platform's real components\n// in client/src/components/shared (see the ADR at\n// _ai_tasks/ui-package/2026-07-10/02_sdk_ui_subpath.md) so app-author\n// typechecking matches what actually renders inside Veltrix. Heavy composite\n// widgets (ConfigurationCanvas, VersionControl, Pipeline) stay out of scope —\n// they carry platform coupling a later phase may expose read-only versions\n// of; see the ADR's \"Non-goals\" section.\n//\n// EXPORTS: Button, Badge, Card (+ CardHeader/CardBody/CardFooter), Input,\n// Textarea, Checkbox, Select, SearchBox, Pagination, FilterBar, SortSelect,\n// FormField, Tabs, EmptyState, Skeleton (+ SkeletonText/SkeletonCard),\n// Tooltip, Spinner, DataTable, StatsCard, FormDialog, useToast,\n// useConfirmDialog.\n//\n// useToast / useConfirmDialog are included because the platform's root\n// App.tsx mounts ToastProvider/ConfirmationDialogProvider around the ENTIRE\n// tree (including every app page, since app pages render inside the host's\n// own React instance) — so the real context-backed hooks resolve correctly\n// from app code with no extra wiring. Outside the platform they degrade to a\n// safe, non-throwing fallback (see each hook's docs below) rather than\n// crashing or silently doing nothing.\n// ========================================================================\n\nimport * as React from 'react'\nimport { getHostRuntime } from '../client'\n\n/** Read one named component off the host's `runtime.ui` bag, or undefined. */\nfunction getHostUi<T>(name: string): T | undefined {\n return getHostRuntime()?.ui?.[name] as T | undefined\n}\n\nconst fallbackNote: React.CSSProperties = { fontFamily: 'inherit' }\n\n// ---------------------------------------------------------------------------\n// Button\n// ---------------------------------------------------------------------------\n\nexport type ButtonVariant = 'primary' | 'secondary' | 'danger' | 'success' | 'warning' | 'ghost' | 'link'\nexport type ButtonSize = 'sm' | 'md' | 'lg'\n\nexport interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: ButtonVariant\n size?: ButtonSize\n isLoading?: boolean\n loadingText?: string\n fullWidth?: boolean\n leftIcon?: React.ReactNode\n rightIcon?: React.ReactNode\n}\n\ntype ButtonComponent = React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>\n\n/**\n * Button — delegates to the platform's real Button at render time.\n *\n * @example\n * <Button variant=\"primary\" leftIcon={<RefreshIcon />} onClick={refresh}>Refresh</Button>\n */\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>((props, ref) => {\n const HostButton = getHostUi<ButtonComponent>('Button')\n if (HostButton) return <HostButton ref={ref} {...props} />\n\n const {\n variant: _variant,\n size: _size,\n isLoading,\n loadingText,\n fullWidth,\n leftIcon,\n rightIcon,\n children,\n disabled,\n type,\n style,\n ...rest\n } = props\n\n return (\n <button\n ref={ref}\n type={type ?? 'button'}\n disabled={disabled || isLoading}\n aria-busy={isLoading || undefined}\n style={{\n ...fallbackNote,\n display: 'inline-flex',\n alignItems: 'center',\n gap: 6,\n padding: '6px 14px',\n borderRadius: 6,\n border: '1px solid currentColor',\n background: 'transparent',\n cursor: disabled || isLoading ? 'not-allowed' : 'pointer',\n width: fullWidth ? '100%' : undefined,\n opacity: disabled || isLoading ? 0.6 : 1,\n justifyContent: 'center',\n ...style,\n }}\n {...rest}\n >\n {leftIcon}\n {isLoading ? loadingText ?? children : children}\n {rightIcon}\n </button>\n )\n})\nButton.displayName = 'Button'\n\n// ---------------------------------------------------------------------------\n// Badge\n// ---------------------------------------------------------------------------\n\nexport type BadgeVariant = 'default' | 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info'\nexport type BadgeSize = 'sm' | 'md' | 'lg'\n\nexport interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {\n variant?: BadgeVariant\n size?: BadgeSize\n rounded?: boolean\n dot?: boolean\n}\n\nconst BADGE_FALLBACK_COLORS: Record<BadgeVariant, string> = {\n default: '#6b7280',\n primary: '#4f46e5',\n secondary: '#6b7280',\n success: '#16a34a',\n danger: '#dc2626',\n warning: '#d97706',\n info: '#0284c7',\n}\n\n/**\n * Badge — delegates to the platform's real Badge at render time.\n *\n * @example\n * <Badge variant={row.deployState === 'deployed' ? 'success' : 'warning'}>{row.deployState}</Badge>\n */\nexport const Badge: React.FC<BadgeProps> = ({ variant = 'default', size = 'md', rounded, dot, children, style, ...rest }) => {\n const HostBadge = getHostUi<React.FC<BadgeProps>>('Badge')\n if (HostBadge) return <HostBadge variant={variant} size={size} rounded={rounded} dot={dot} style={style} {...rest}>{children}</HostBadge>\n\n const color = BADGE_FALLBACK_COLORS[variant]\n const fontSize = size === 'sm' ? 11 : size === 'lg' ? 14 : 12\n return (\n <span\n style={{\n ...fallbackNote,\n display: 'inline-flex',\n alignItems: 'center',\n gap: 4,\n padding: size === 'sm' ? '1px 6px' : size === 'lg' ? '3px 10px' : '2px 8px',\n borderRadius: rounded ? 999 : 4,\n border: `1px solid ${color}`,\n color,\n fontSize,\n fontWeight: 500,\n ...style,\n }}\n {...rest}\n >\n {dot && <span aria-hidden=\"true\" style={{ width: 6, height: 6, borderRadius: '50%', background: color }} />}\n {children}\n </span>\n )\n}\nBadge.displayName = 'Badge'\n\n// ---------------------------------------------------------------------------\n// Card (+ Header/Body/Footer)\n// ---------------------------------------------------------------------------\n\nexport interface CardProps extends React.HTMLAttributes<HTMLDivElement> {\n variant?: 'default' | 'bordered' | 'elevated'\n padding?: 'none' | 'sm' | 'md' | 'lg'\n}\nexport interface CardHeaderProps extends React.HTMLAttributes<HTMLDivElement> {\n actions?: React.ReactNode\n}\nexport type CardBodyProps = React.HTMLAttributes<HTMLDivElement>\nexport interface CardFooterProps extends React.HTMLAttributes<HTMLDivElement> {\n variant?: 'default' | 'bordered'\n}\n\n/** Card — delegates to the platform's real Card at render time. */\nexport const Card: React.FC<CardProps> = ({ children, style, ...rest }) => {\n const HostCard = getHostUi<React.FC<CardProps>>('Card')\n if (HostCard) return <HostCard style={style} {...rest}>{children}</HostCard>\n return (\n <div style={{ ...fallbackNote, border: '1px solid #d1d5db', borderRadius: 8, overflow: 'hidden', ...style }} {...rest}>\n {children}\n </div>\n )\n}\nCard.displayName = 'Card'\n\n/** CardHeader — the header section of a Card, with optional trailing actions. */\nexport const CardHeader: React.FC<CardHeaderProps> = ({ actions, children, style, ...rest }) => {\n const HostCardHeader = getHostUi<React.FC<CardHeaderProps>>('CardHeader')\n if (HostCardHeader) return <HostCardHeader actions={actions} style={style} {...rest}>{children}</HostCardHeader>\n return (\n <div\n style={{\n ...fallbackNote,\n padding: '12px 16px',\n borderBottom: '1px solid #d1d5db',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 12,\n ...style,\n }}\n {...rest}\n >\n <div style={{ flex: 1, minWidth: 0 }}>{children}</div>\n {actions && <div>{actions}</div>}\n </div>\n )\n}\nCardHeader.displayName = 'CardHeader'\n\n/** CardBody — the main content area of a Card. */\nexport const CardBody: React.FC<CardBodyProps> = ({ children, style, ...rest }) => {\n const HostCardBody = getHostUi<React.FC<CardBodyProps>>('CardBody')\n if (HostCardBody) return <HostCardBody style={style} {...rest}>{children}</HostCardBody>\n return (\n <div style={{ ...fallbackNote, padding: '12px 16px', ...style }} {...rest}>\n {children}\n </div>\n )\n}\nCardBody.displayName = 'CardBody'\n\n/** CardFooter — the footer section of a Card, typically for actions. */\nexport const CardFooter: React.FC<CardFooterProps> = ({ children, style, ...rest }) => {\n const HostCardFooter = getHostUi<React.FC<CardFooterProps>>('CardFooter')\n if (HostCardFooter) return <HostCardFooter style={style} {...rest}>{children}</HostCardFooter>\n return (\n <div style={{ ...fallbackNote, padding: '12px 16px', borderTop: '1px solid #d1d5db', ...style }} {...rest}>\n {children}\n </div>\n )\n}\nCardFooter.displayName = 'CardFooter'\n\n// ---------------------------------------------------------------------------\n// Input\n// ---------------------------------------------------------------------------\n\nexport type InputSize = 'sm' | 'md' | 'lg'\nexport type InputVariant = 'default' | 'error' | 'success'\n\nexport interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'> {\n label?: string\n error?: string\n helperText?: string\n leftIcon?: React.ReactNode\n rightIcon?: React.ReactNode\n variant?: InputVariant\n inputSize?: InputSize\n isSuccess?: boolean\n fullWidth?: boolean\n}\n\ntype InputComponent = React.ForwardRefExoticComponent<InputProps & React.RefAttributes<HTMLInputElement>>\n\n/**\n * Input — delegates to the platform's real Input at render time.\n *\n * @example\n * <Input label=\"Index name\" value={name} onChange={(e) => setName(e.target.value)} error={errors.name} />\n */\nexport const Input = React.forwardRef<HTMLInputElement, InputProps>((props, ref) => {\n const HostInput = getHostUi<InputComponent>('Input')\n if (HostInput) return <HostInput ref={ref} {...props} />\n\n const { label, error, helperText, leftIcon, rightIcon, fullWidth = true, id, style, ...rest } = props\n const inputId = id ?? (label ? `vx-input-${label.toLowerCase().replace(/\\s+/g, '-')}` : undefined)\n\n return (\n <div style={{ ...fallbackNote, width: fullWidth ? '100%' : undefined }}>\n {label && (\n <label htmlFor={inputId} style={{ display: 'block', fontSize: 13, fontWeight: 500, marginBottom: 4 }}>\n {label}\n </label>\n )}\n <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>\n {leftIcon}\n <input\n ref={ref}\n id={inputId}\n aria-invalid={!!error || undefined}\n style={{ flex: 1, padding: '6px 10px', borderRadius: 6, border: '1px solid #9ca3af', ...style }}\n {...rest}\n />\n {rightIcon}\n </div>\n {error && (\n <p role=\"alert\" style={{ marginTop: 4, fontSize: 12, color: '#dc2626' }}>\n {error}\n </p>\n )}\n {helperText && !error && <p style={{ marginTop: 4, fontSize: 12, color: '#6b7280' }}>{helperText}</p>}\n </div>\n )\n})\nInput.displayName = 'Input'\n\n// ---------------------------------------------------------------------------\n// Textarea\n// ---------------------------------------------------------------------------\n\nexport interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {\n label?: string\n error?: string\n helperText?: string\n fullWidth?: boolean\n}\n\ntype TextareaComponent = React.ForwardRefExoticComponent<TextareaProps & React.RefAttributes<HTMLTextAreaElement>>\n\n/**\n * Textarea — delegates to the platform's real Textarea at render time.\n *\n * @example\n * <Textarea label=\"Description\" helperText=\"Markdown is supported.\" />\n */\nexport const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>((props, ref) => {\n const HostTextarea = getHostUi<TextareaComponent>('Textarea')\n if (HostTextarea) return <HostTextarea ref={ref} {...props} />\n\n const { label, error, helperText, fullWidth = true, id, rows = 4, style, ...rest } = props\n const textareaId = id ?? (label ? `vx-textarea-${label.toLowerCase().replace(/\\s+/g, '-')}` : undefined)\n\n return (\n <div style={{ ...fallbackNote, width: fullWidth ? '100%' : undefined }}>\n {label && (\n <label htmlFor={textareaId} style={{ display: 'block', fontSize: 13, fontWeight: 500, marginBottom: 4 }}>\n {label}\n </label>\n )}\n <textarea\n ref={ref}\n id={textareaId}\n rows={rows}\n aria-invalid={!!error || undefined}\n style={{ width: '100%', padding: '6px 10px', borderRadius: 6, border: '1px solid #9ca3af', ...style }}\n {...rest}\n />\n {error && (\n <p role=\"alert\" style={{ marginTop: 4, fontSize: 12, color: '#dc2626' }}>\n {error}\n </p>\n )}\n {helperText && !error && <p style={{ marginTop: 4, fontSize: 12, color: '#6b7280' }}>{helperText}</p>}\n </div>\n )\n})\nTextarea.displayName = 'Textarea'\n\n// ---------------------------------------------------------------------------\n// Checkbox\n// ---------------------------------------------------------------------------\n\nexport interface CheckboxProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type'> {\n label?: React.ReactNode\n error?: string\n helperText?: string\n}\n\ntype CheckboxComponent = React.ForwardRefExoticComponent<CheckboxProps & React.RefAttributes<HTMLInputElement>>\n\n/**\n * Checkbox — delegates to the platform's real Checkbox at render time.\n *\n * @example\n * <Checkbox label=\"Enable drift detection\" checked={enabled} onChange={(e) => setEnabled(e.target.checked)} />\n */\nexport const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>((props, ref) => {\n const HostCheckbox = getHostUi<CheckboxComponent>('Checkbox')\n if (HostCheckbox) return <HostCheckbox ref={ref} {...props} />\n\n const { label, error, helperText, id, disabled, ...rest } = props\n const generatedId = React.useId()\n const inputId = id ?? generatedId\n\n return (\n <div style={fallbackNote}>\n <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n <input ref={ref} id={inputId} type=\"checkbox\" disabled={disabled} aria-invalid={!!error || undefined} {...rest} />\n {label && (\n <label htmlFor={inputId} style={{ fontSize: 13, cursor: disabled ? 'not-allowed' : 'pointer', opacity: disabled ? 0.6 : 1 }}>\n {label}\n </label>\n )}\n </div>\n {error && (\n <p role=\"alert\" style={{ marginTop: 4, fontSize: 12, color: '#dc2626' }}>\n {error}\n </p>\n )}\n {helperText && !error && <p style={{ marginTop: 4, fontSize: 12, color: '#6b7280' }}>{helperText}</p>}\n </div>\n )\n})\nCheckbox.displayName = 'Checkbox'\n\n// ---------------------------------------------------------------------------\n// Select (controlled; onChange receives the new value string)\n// ---------------------------------------------------------------------------\n\nexport type SelectSize = 'sm' | 'md' | 'lg'\n\nexport interface SelectOption {\n value: string\n label: string\n disabled?: boolean\n}\n\nexport interface SelectProps {\n options: SelectOption[]\n value?: string\n onChange?: (value: string) => void\n placeholder?: string\n label?: string\n error?: string\n helperText?: string\n size?: SelectSize\n disabled?: boolean\n fullWidth?: boolean\n className?: string\n id?: string\n name?: string\n 'aria-label'?: string\n}\n\n/**\n * Select — delegates to the platform's real (WAI-ARIA listbox) Select at render time.\n * The fallback is a native `<select>` — functionally equivalent, visually plainer.\n *\n * @example\n * <Select label=\"Environment\" value={env} onChange={setEnv} options={[{ value: 'prod', label: 'Production' }]} />\n */\nexport const Select: React.FC<SelectProps> = (props) => {\n const HostSelect = getHostUi<React.FC<SelectProps>>('Select')\n if (HostSelect) return <HostSelect {...props} />\n\n const { options, value, onChange, placeholder = 'Select…', label, error, helperText, disabled, fullWidth = true, id, name, className } = props\n const selectId = id ?? (label ? `vx-select-${label.toLowerCase().replace(/\\s+/g, '-')}` : undefined)\n\n return (\n <div className={className} style={{ ...fallbackNote, width: fullWidth ? '100%' : undefined }}>\n {label && (\n <label htmlFor={selectId} style={{ display: 'block', fontSize: 13, fontWeight: 500, marginBottom: 4 }}>\n {label}\n </label>\n )}\n <select\n id={selectId}\n name={name}\n aria-label={props['aria-label']}\n aria-invalid={!!error || undefined}\n disabled={disabled}\n value={value ?? ''}\n onChange={(event) => onChange?.(event.target.value)}\n style={{ width: '100%', padding: '6px 10px', borderRadius: 6, border: '1px solid #9ca3af' }}\n >\n {placeholder && (\n <option value=\"\" disabled>\n {placeholder}\n </option>\n )}\n {options.map((option) => (\n <option key={option.value} value={option.value} disabled={option.disabled}>\n {option.label}\n </option>\n ))}\n </select>\n {error && (\n <p role=\"alert\" style={{ marginTop: 4, fontSize: 12, color: '#dc2626' }}>\n {error}\n </p>\n )}\n {helperText && !error && <p style={{ marginTop: 4, fontSize: 12, color: '#6b7280' }}>{helperText}</p>}\n </div>\n )\n}\nSelect.displayName = 'Select'\n\n// ---------------------------------------------------------------------------\n// SearchBox\n// ---------------------------------------------------------------------------\n\nexport type SearchBoxSize = 'sm' | 'md' | 'lg'\n\nexport interface SearchBoxProps {\n /** Controlled search text. */\n value: string\n /** Called with the new text — debounced by `debounceMs` when set. */\n onChange: (value: string) => void\n placeholder?: string\n disabled?: boolean\n size?: SearchBoxSize\n /** Debounces `onChange` by this many ms; omit (or `0`) to call on every keystroke. */\n debounceMs?: number\n className?: string\n 'aria-label'?: string\n}\n\n/**\n * SearchBox — delegates to the platform's real SearchBox at render time (leading search icon,\n * a clear button once there's text, optional debounce). The fallback is a bare\n * `<input type=\"search\">` wired straight to `value`/`onChange` — no icon, no debounce, no\n * clear button — but functionally sufficient for typing and clearing.\n *\n * @example\n * <SearchBox value={search} onChange={setSearch} placeholder=\"Search apps…\" debounceMs={250} />\n */\nexport const SearchBox: React.FC<SearchBoxProps> = (props) => {\n const HostSearchBox = getHostUi<React.FC<SearchBoxProps>>('SearchBox')\n if (HostSearchBox) return <HostSearchBox {...props} />\n\n const { value, onChange, placeholder, disabled, className, 'aria-label': ariaLabel } = props\n return (\n <input\n type=\"search\"\n value={value}\n onChange={(event) => onChange(event.target.value)}\n placeholder={placeholder}\n disabled={disabled}\n aria-label={ariaLabel ?? placeholder ?? 'Search'}\n className={className}\n style={{ ...fallbackNote, width: '100%', padding: '6px 10px', borderRadius: 6, border: '1px solid #9ca3af' }}\n />\n )\n}\nSearchBox.displayName = 'SearchBox'\n\n// ---------------------------------------------------------------------------\n// Pagination\n// ---------------------------------------------------------------------------\n\nexport interface PaginationProps {\n /** 1-based current page. */\n page: number\n pageSize: number\n totalItems: number\n onPageChange: (page: number) => void\n /** Renders a page-size selector when provided together with `pageSizeOptions`. */\n onPageSizeChange?: (size: number) => void\n pageSizeOptions?: number[]\n disabled?: boolean\n className?: string\n}\n\n/**\n * Pagination — delegates to the platform's real Pagination at render time: a \"Showing X–Y of\n * N\" summary, numbered pages with ellipsis for large ranges, an optional page-size Select, and\n * `aria-current=\"page\"` on the active page — visually consistent with DataTable's built-in\n * pagination footer. The fallback is a plain Prev/Next pair with \"page X of Y\" text.\n *\n * @example\n * <Pagination page={page} pageSize={20} totalItems={total} onPageChange={setPage} />\n */\nexport const Pagination: React.FC<PaginationProps> = (props) => {\n const HostPagination = getHostUi<React.FC<PaginationProps>>('Pagination')\n if (HostPagination) return <HostPagination {...props} />\n\n const { page, pageSize, totalItems, onPageChange, disabled, className } = props\n const pageCount = Math.max(1, Math.ceil(totalItems / pageSize))\n const canGoPrev = !disabled && page > 1\n const canGoNext = !disabled && page < pageCount\n\n return (\n <nav aria-label=\"Pagination\" className={className} style={{ ...fallbackNote, display: 'flex', alignItems: 'center', gap: 12 }}>\n <button type=\"button\" onClick={() => onPageChange(page - 1)} disabled={!canGoPrev} style={{ padding: '4px 10px' }}>\n Prev\n </button>\n <span>\n page {page} of {pageCount}\n </span>\n <button type=\"button\" onClick={() => onPageChange(page + 1)} disabled={!canGoNext} style={{ padding: '4px 10px' }}>\n Next\n </button>\n </nav>\n )\n}\nPagination.displayName = 'Pagination'\n\n// ---------------------------------------------------------------------------\n// FilterBar\n// ---------------------------------------------------------------------------\n\nexport interface FilterOption {\n value: string\n label: string\n}\n\nexport interface FilterDefinition {\n /** Stable identifier; also the React key for this filter's dropdown. */\n key: string\n /** Shown as the dropdown's placeholder/aria-label, and as its entry in the \"Add filter\" menu. */\n label: string\n options: FilterOption[]\n /** `null` (not `''`) represents \"no selection\" — the value FilterBar clears back to. */\n value: string | null\n onChange: (value: string | null) => void\n /** Always rendered when true. Omit/false to make this filter addable/removable via the \"Add filter\" menu. */\n alwaysVisible?: boolean\n}\n\nexport interface FilterBarSearchProps {\n value: string\n onChange: (value: string) => void\n placeholder?: string\n}\n\nexport interface FilterBarProps {\n filters: FilterDefinition[]\n /** Renders a SearchBox ahead of the filter dropdowns when provided. */\n search?: FilterBarSearchProps\n /**\n * Called by \"Clear all\" instead of FilterBar's own clearing logic. Omit it to let FilterBar\n * clear every filter with a value itself (`filter.onChange(null)` for each).\n */\n onClearAll?: () => void\n addFilterLabel?: string\n className?: string\n}\n\n/**\n * FilterBar — delegates to the platform's real FilterBar at render time: an optional\n * SearchBox, always-visible filter dropdowns, and optional filters the user can add/remove via\n * an \"Add filter\" menu (a filter with a non-null `value` is always treated as visible, even\n * before the user explicitly adds it). The fallback renders every filter as a plain,\n * always-visible native `<select>` — no add/remove menu, no styled search box — so an app page\n * under test still exposes every filter's full behavior via `onChange`.\n *\n * @example\n * <FilterBar\n * search={{ value: search, onChange: setSearch, placeholder: 'Search apps…' }}\n * filters={[\n * { key: 'vendor', label: 'Vendor', options: vendorOptions, value: vendor, onChange: setVendor, alwaysVisible: true },\n * { key: 'category', label: 'Category', options: categoryOptions, value: category, onChange: setCategory },\n * ]}\n * />\n */\nexport const FilterBar: React.FC<FilterBarProps> = (props) => {\n const HostFilterBar = getHostUi<React.FC<FilterBarProps>>('FilterBar')\n if (HostFilterBar) return <HostFilterBar {...props} />\n\n const { filters, search, className } = props\n return (\n <div className={className} style={{ ...fallbackNote, display: 'flex', flexWrap: 'wrap', gap: 8, alignItems: 'center' }}>\n {search && (\n <input\n type=\"search\"\n aria-label={search.placeholder ?? 'Search'}\n placeholder={search.placeholder}\n value={search.value}\n onChange={(event) => search.onChange(event.target.value)}\n style={{ padding: '6px 10px', borderRadius: 6, border: '1px solid #9ca3af' }}\n />\n )}\n {filters.map((filter) => (\n <label key={filter.key} style={{ display: 'flex', flexDirection: 'column', fontSize: 12 }}>\n {filter.label}\n <select\n aria-label={filter.label}\n value={filter.value ?? ''}\n onChange={(event) => filter.onChange(event.target.value === '' ? null : event.target.value)}\n style={{ padding: '6px 10px', borderRadius: 6, border: '1px solid #9ca3af' }}\n >\n <option value=\"\">{filter.label}</option>\n {filter.options.map((option) => (\n <option key={option.value} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n </label>\n ))}\n </div>\n )\n}\nFilterBar.displayName = 'FilterBar'\n\n// ---------------------------------------------------------------------------\n// SortSelect\n// ---------------------------------------------------------------------------\n\nexport type SortDirection = 'asc' | 'desc'\n\nexport interface SortOption {\n value: string\n label: string\n}\n\nexport interface SortSelectProps {\n /** Sortable fields, e.g. `[{ value: 'name', label: 'Name' }, { value: 'updatedAt', label: 'Updated' }]`. */\n options: SortOption[]\n /** Selected field key. */\n value: string\n direction: SortDirection\n /** Called with the field and direction together, whichever one the interaction changed. */\n onChange: (value: string, direction: SortDirection) => void\n disabled?: boolean\n className?: string\n}\n\n/**\n * SortSelect — delegates to the platform's real SortSelect at render time: a labeled field\n * Select paired with an asc/desc direction toggle button, styled to sit in the same toolbar\n * row as FilterBar. The standalone sort control for list/card surfaces that aren't a\n * DataTable (which has its own column-header sort). The fallback is a native `<select>` for\n * the field plus a button that flips direction.\n *\n * @example\n * <SortSelect\n * options={[{ value: 'name', label: 'Name' }, { value: 'updatedAt', label: 'Last updated' }]}\n * value={sortField}\n * direction={sortDirection}\n * onChange={(field, direction) => { setSortField(field); setSortDirection(direction) }}\n * />\n */\nexport const SortSelect: React.FC<SortSelectProps> = (props) => {\n const HostSortSelect = getHostUi<React.FC<SortSelectProps>>('SortSelect')\n if (HostSortSelect) return <HostSortSelect {...props} />\n\n const { options, value, direction, onChange, disabled, className } = props\n const directionLabel = direction === 'asc' ? 'Sort ascending' : 'Sort descending'\n\n return (\n <div className={className} style={{ ...fallbackNote, display: 'flex', alignItems: 'center', gap: 6 }}>\n <select\n aria-label=\"Sort by\"\n value={value}\n disabled={disabled}\n onChange={(event) => onChange(event.target.value, direction)}\n style={{ padding: '6px 10px', borderRadius: 6, border: '1px solid #9ca3af' }}\n >\n {options.map((option) => (\n <option key={option.value} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n <button\n type=\"button\"\n disabled={disabled}\n onClick={() => onChange(value, direction === 'asc' ? 'desc' : 'asc')}\n aria-label={directionLabel}\n style={{ padding: '4px 10px' }}\n >\n {direction === 'asc' ? '↑' : '↓'}\n </button>\n </div>\n )\n}\nSortSelect.displayName = 'SortSelect'\n\n// ---------------------------------------------------------------------------\n// FormField — generic label + control + error/hint wrapper\n// ---------------------------------------------------------------------------\n\nexport interface FormFieldProps {\n label?: string\n htmlFor?: string\n error?: string\n hint?: string\n required?: boolean\n className?: string\n children: React.ReactNode\n}\n\n/**\n * FormField — wraps a custom control (not already self-labeling like Input/Select) with\n * the platform's label + error/hint visual language.\n *\n * @example\n * <FormField label=\"Allowed IP ranges\" htmlFor=\"cidrs\" hint=\"One CIDR block per line\">\n * <textarea id=\"cidrs\" />\n * </FormField>\n */\nexport const FormField: React.FC<FormFieldProps> = (props) => {\n const HostFormField = getHostUi<React.FC<FormFieldProps>>('FormField')\n if (HostFormField) return <HostFormField {...props} />\n\n const { label, htmlFor, error, hint, required, className, children } = props\n return (\n <div className={className} style={fallbackNote}>\n {label && (\n <label htmlFor={htmlFor} style={{ display: 'block', fontSize: 13, fontWeight: 500, marginBottom: 4 }}>\n {label}\n {required && (\n <span aria-hidden=\"true\" style={{ color: '#dc2626', marginLeft: 2 }}>\n *\n </span>\n )}\n </label>\n )}\n {children}\n {error && (\n <p role=\"alert\" style={{ marginTop: 4, fontSize: 12, color: '#dc2626' }}>\n {error}\n </p>\n )}\n {hint && !error && <p style={{ marginTop: 4, fontSize: 12, color: '#6b7280' }}>{hint}</p>}\n </div>\n )\n}\nFormField.displayName = 'FormField'\n\n// ---------------------------------------------------------------------------\n// Tabs\n// ---------------------------------------------------------------------------\n\nexport interface TabItem {\n key?: string\n label: string\n content: React.ReactNode\n disabled?: boolean\n}\n\nexport interface TabsProps {\n tabs: TabItem[]\n defaultActiveIndex?: number\n activeIndex?: number\n onTabChange?: (index: number) => void\n children?: React.ReactNode\n className?: string\n}\n\n/**\n * Tabs — delegates to the platform's real (WAI-ARIA tabs pattern) Tabs at render time.\n *\n * @example\n * <Tabs tabs={[{ key: 'indexes', label: 'Indexes', content: <IndexesPanel /> }]} />\n */\nexport const Tabs: React.FC<TabsProps> = (props) => {\n const HostTabs = getHostUi<React.FC<TabsProps>>('Tabs')\n if (HostTabs) return <HostTabs {...props} />\n\n const { tabs, defaultActiveIndex = 0, activeIndex, onTabChange, children, className } = props\n const [internalIndex, setInternalIndex] = React.useState(defaultActiveIndex)\n const isControlled = activeIndex !== undefined\n const currentIndex = isControlled ? activeIndex : internalIndex\n const activeTab = tabs[currentIndex]\n\n const selectTab = (index: number) => {\n if (tabs[index]?.disabled) return\n if (!isControlled) setInternalIndex(index)\n onTabChange?.(index)\n }\n\n return (\n <div className={className} style={fallbackNote}>\n <div role=\"tablist\" style={{ display: 'flex', gap: 4, borderBottom: '1px solid #d1d5db' }}>\n {tabs.map((tab, index) => (\n <button\n key={tab.key ?? index}\n type=\"button\"\n role=\"tab\"\n aria-selected={index === currentIndex}\n disabled={tab.disabled}\n onClick={() => selectTab(index)}\n style={{\n padding: '6px 12px',\n border: 'none',\n borderBottom: index === currentIndex ? '2px solid currentColor' : '2px solid transparent',\n background: 'transparent',\n cursor: tab.disabled ? 'not-allowed' : 'pointer',\n fontWeight: index === currentIndex ? 600 : 400,\n opacity: tab.disabled ? 0.5 : 1,\n }}\n >\n {tab.label}\n </button>\n ))}\n </div>\n <div role=\"tabpanel\" style={{ padding: 12 }}>\n {children || activeTab?.content}\n </div>\n </div>\n )\n}\nTabs.displayName = 'Tabs'\n\n// ---------------------------------------------------------------------------\n// EmptyState\n// ---------------------------------------------------------------------------\n\nexport interface EmptyStateProps {\n icon?: React.ReactNode\n title: string\n description?: string\n action?: React.ReactNode\n className?: string\n}\n\n/** EmptyState — delegates to the platform's real EmptyState at render time. */\nexport const EmptyState: React.FC<EmptyStateProps> = (props) => {\n const HostEmptyState = getHostUi<React.FC<EmptyStateProps>>('EmptyState')\n if (HostEmptyState) return <HostEmptyState {...props} />\n\n const { icon, title, description, action, className } = props\n return (\n <div className={className} style={{ ...fallbackNote, textAlign: 'center', padding: '32px 16px' }}>\n {icon && <div style={{ marginBottom: 12 }}>{icon}</div>}\n <p style={{ fontWeight: 600, marginBottom: description ? 4 : 0 }}>{title}</p>\n {description && <p style={{ fontSize: 13, color: '#6b7280', marginBottom: action ? 12 : 0 }}>{description}</p>}\n {action}\n </div>\n )\n}\nEmptyState.displayName = 'EmptyState'\n\n// ---------------------------------------------------------------------------\n// Skeleton (+ Text/Card)\n// ---------------------------------------------------------------------------\n\nexport type SkeletonVariant = 'text' | 'circular' | 'rectangular'\n\nexport interface SkeletonProps extends React.HTMLAttributes<HTMLDivElement> {\n variant?: SkeletonVariant\n width?: string | number\n height?: string | number\n animation?: 'pulse' | 'wave' | 'none'\n}\n\nconst skeletonRadius: Record<SkeletonVariant, number | string> = { text: 4, circular: '50%', rectangular: 8 }\n\n/** Skeleton — delegates to the platform's real Skeleton at render time. */\nexport const Skeleton: React.FC<SkeletonProps> = (props) => {\n const HostSkeleton = getHostUi<React.FC<SkeletonProps>>('Skeleton')\n if (HostSkeleton) return <HostSkeleton {...props} />\n\n const { variant = 'text', width, height, style, ...rest } = props\n return (\n <div\n aria-hidden=\"true\"\n style={{\n background: '#e5e7eb',\n borderRadius: skeletonRadius[variant],\n width: width ?? (variant === 'text' ? '100%' : undefined),\n height: height ?? (variant === 'text' ? 14 : undefined),\n ...style,\n }}\n {...rest}\n />\n )\n}\nSkeleton.displayName = 'Skeleton'\n\nexport interface SkeletonTextProps {\n lines?: number\n width?: string | number\n lastLineWidth?: string | number\n className?: string\n}\n\n/** SkeletonText — a multi-line text skeleton, delegating to the platform's real one. */\nexport const SkeletonText: React.FC<SkeletonTextProps> = (props) => {\n const HostSkeletonText = getHostUi<React.FC<SkeletonTextProps>>('SkeletonText')\n if (HostSkeletonText) return <HostSkeletonText {...props} />\n\n const { lines = 3, width = '100%', lastLineWidth = '80%', className } = props\n return (\n <div className={className} style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>\n {Array.from({ length: lines }).map((_, index) => (\n <Skeleton key={index} variant=\"text\" width={index === lines - 1 ? lastLineWidth : width} />\n ))}\n </div>\n )\n}\nSkeletonText.displayName = 'SkeletonText'\n\nexport interface SkeletonCardProps {\n hasAvatar?: boolean\n hasActions?: boolean\n className?: string\n}\n\n/** SkeletonCard — a card-shaped skeleton, delegating to the platform's real one. */\nexport const SkeletonCard: React.FC<SkeletonCardProps> = (props) => {\n const HostSkeletonCard = getHostUi<React.FC<SkeletonCardProps>>('SkeletonCard')\n if (HostSkeletonCard) return <HostSkeletonCard {...props} />\n\n const { hasAvatar, hasActions, className } = props\n return (\n <div className={className} style={{ border: '1px solid #e5e7eb', borderRadius: 8, padding: 16 }}>\n <div style={{ display: 'flex', gap: 12 }}>\n {hasAvatar && <Skeleton variant=\"circular\" width={40} height={40} />}\n <div style={{ flex: 1 }}>\n <Skeleton variant=\"text\" width=\"60%\" />\n <div style={{ marginTop: 8 }}>\n <SkeletonText lines={2} />\n </div>\n </div>\n </div>\n {hasActions && (\n <div style={{ display: 'flex', gap: 8, marginTop: 12 }}>\n <Skeleton variant=\"rectangular\" width={72} height={30} />\n <Skeleton variant=\"rectangular\" width={72} height={30} />\n </div>\n )}\n </div>\n )\n}\nSkeletonCard.displayName = 'SkeletonCard'\n\n// ---------------------------------------------------------------------------\n// Tooltip\n// ---------------------------------------------------------------------------\n\nexport type TooltipPlacement = 'top' | 'bottom' | 'left' | 'right'\n\nexport interface TooltipProps {\n content?: React.ReactNode\n placement?: TooltipPlacement\n delayDuration?: number\n disabled?: boolean\n className?: string\n children: React.ReactNode\n}\n\n/**\n * Tooltip — delegates to the platform's real Tooltip at render time. The fallback uses the\n * browser's native `title` attribute (only works when `content` is plain text).\n */\nexport const Tooltip: React.FC<TooltipProps> = (props) => {\n const HostTooltip = getHostUi<React.FC<TooltipProps>>('Tooltip')\n if (HostTooltip) return <HostTooltip {...props} />\n\n const { content, disabled, className, children } = props\n const titleText = typeof content === 'string' ? content : undefined\n if (disabled || !titleText) return <>{children}</>\n return (\n <span className={className} title={titleText} style={{ display: 'inline-flex' }}>\n {children}\n </span>\n )\n}\nTooltip.displayName = 'Tooltip'\n\n// ---------------------------------------------------------------------------\n// Spinner\n// ---------------------------------------------------------------------------\n\nexport type SpinnerSize = 'sm' | 'md' | 'lg'\n\nexport interface SpinnerProps {\n size?: SpinnerSize\n className?: string\n label?: string\n}\n\nconst spinnerDiameter: Record<SpinnerSize, number> = { sm: 16, md: 24, lg: 32 }\n\n/** Spinner — delegates to the platform's real Spinner at render time. */\nexport const Spinner: React.FC<SpinnerProps> = (props) => {\n const HostSpinner = getHostUi<React.FC<SpinnerProps>>('Spinner')\n if (HostSpinner) return <HostSpinner {...props} />\n\n const { size = 'md', className, label } = props\n const diameter = spinnerDiameter[size]\n return (\n <div className={className} role=\"status\" aria-live=\"polite\" style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>\n <div\n aria-hidden=\"true\"\n style={{\n width: diameter,\n height: diameter,\n borderRadius: '50%',\n border: '2px solid currentColor',\n borderTopColor: 'transparent',\n animation: 'vx-sdk-spin 0.8s linear infinite',\n }}\n />\n {label && <p style={{ marginTop: 8, fontSize: 12, color: '#6b7280' }}>{label}</p>}\n <span style={{ position: 'absolute', width: 1, height: 1, overflow: 'hidden', clip: 'rect(0 0 0 0)' }}>{label || 'Loading'}</span>\n <style>{'@keyframes vx-sdk-spin { to { transform: rotate(360deg) } }'}</style>\n </div>\n )\n}\nSpinner.displayName = 'Spinner'\n\n// ---------------------------------------------------------------------------\n// DataTable (generic)\n// ---------------------------------------------------------------------------\n\nexport type DataTableAlign = 'left' | 'center' | 'right'\nexport type DataTableSortOrder = 'asc' | 'desc'\n\nexport interface DataTableSort {\n field: string\n order: DataTableSortOrder\n}\n\nexport interface DataTableColumn<T> {\n key: string\n header: React.ReactNode\n render?: (row: T) => React.ReactNode\n sortable?: boolean\n align?: DataTableAlign\n width?: string\n className?: string\n}\n\nexport interface DataTableEmptyState {\n icon?: React.ReactNode\n title: string\n description?: string\n action?: React.ReactNode\n}\n\nexport interface DataTablePaginationState {\n page: number\n pageSize: number\n total: number\n}\n\nexport interface DataTableProps<T> {\n columns: DataTableColumn<T>[]\n data: T[]\n rowKey: (row: T) => string\n isLoading?: boolean\n emptyState?: DataTableEmptyState\n sort?: DataTableSort\n onSortChange?: (sort: DataTableSort) => void\n pagination?: DataTablePaginationState\n onPageChange?: (page: number) => void\n onRowClick?: (row: T) => void\n rowActions?: (row: T) => React.ReactNode\n className?: string\n}\n\ntype DataTableComponent = (<T>(props: DataTableProps<T>) => React.ReactElement) & { displayName?: string }\n\nfunction FallbackDataTable<T>(props: DataTableProps<T>): React.ReactElement {\n const { columns, data, rowKey, isLoading, emptyState, onRowClick, rowActions, className } = props\n const showEmpty = !isLoading && data.length === 0\n\n return (\n <div className={className} style={fallbackNote}>\n <table style={{ width: '100%', borderCollapse: 'collapse' }}>\n <thead>\n <tr>\n {columns.map((column) => (\n <th key={column.key} style={{ textAlign: column.align ?? 'left', padding: '8px 10px', borderBottom: '1px solid #d1d5db' }}>\n {column.header}\n </th>\n ))}\n {rowActions && <th style={{ padding: '8px 10px', borderBottom: '1px solid #d1d5db' }} />}\n </tr>\n </thead>\n <tbody>\n {isLoading && (\n <tr>\n <td colSpan={Math.max(columns.length + (rowActions ? 1 : 0), 1)} style={{ padding: '12px 10px' }}>\n Loading…\n </td>\n </tr>\n )}\n {showEmpty && (\n <tr>\n <td colSpan={Math.max(columns.length + (rowActions ? 1 : 0), 1)}>\n <EmptyState title={emptyState?.title ?? 'No data'} description={emptyState?.description} icon={emptyState?.icon} action={emptyState?.action} />\n </td>\n </tr>\n )}\n {!isLoading &&\n !showEmpty &&\n data.map((row) => (\n <tr\n key={rowKey(row)}\n onClick={onRowClick ? () => onRowClick(row) : undefined}\n style={{ cursor: onRowClick ? 'pointer' : undefined, borderBottom: '1px solid #e5e7eb' }}\n >\n {columns.map((column) => (\n <td key={column.key} style={{ textAlign: column.align ?? 'left', padding: '8px 10px' }}>\n {column.render ? column.render(row) : String((row as Record<string, unknown>)[column.key] ?? '')}\n </td>\n ))}\n {rowActions && (\n <td style={{ padding: '8px 10px' }} onClick={(event) => event.stopPropagation()}>\n {rowActions(row)}\n </td>\n )}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )\n}\n\n/**\n * DataTable — delegates to the platform's real, server-driven DataTable at render time.\n *\n * @example\n * <DataTable\n * columns={[{ key: 'name', header: 'Name' }, { key: 'deployState', header: 'Status', render: (r) => <Badge>{r.deployState}</Badge> }]}\n * data={indexes}\n * rowKey={(row) => row.id}\n * />\n */\nexport function DataTable<T>(props: DataTableProps<T>): React.ReactElement {\n const HostDataTable = getHostUi<DataTableComponent>('DataTable')\n if (HostDataTable) return <HostDataTable {...props} />\n return <FallbackDataTable {...props} />\n}\n\n// ---------------------------------------------------------------------------\n// StatsCard\n// ---------------------------------------------------------------------------\n\nexport type StatsCardVariant = 'default' | 'primary' | 'success' | 'warning' | 'danger' | 'info'\n\nexport interface StatsCardDelta {\n value: string\n direction: 'up' | 'down' | 'neutral'\n label?: string\n}\n\nexport interface StatsCardProps {\n label: string\n value: React.ReactNode\n icon?: React.ReactNode\n delta?: StatsCardDelta\n variant?: StatsCardVariant\n isLoading?: boolean\n onClick?: () => void\n className?: string\n}\n\nconst DELTA_FALLBACK_COLOR: Record<StatsCardDelta['direction'], string> = {\n up: '#16a34a',\n down: '#dc2626',\n neutral: '#6b7280',\n}\n\n/**\n * StatsCard — delegates to the platform's real StatsCard at render time.\n *\n * @example\n * <StatsCard label=\"Indexes\" value={indexes.length} delta={{ value: '+2', direction: 'up' }} />\n */\nexport const StatsCard: React.FC<StatsCardProps> = (props) => {\n const HostStatsCard = getHostUi<React.FC<StatsCardProps>>('StatsCard')\n if (HostStatsCard) return <HostStatsCard {...props} />\n\n const { label, value, icon, delta, isLoading, onClick, className } = props\n const isClickable = Boolean(onClick)\n\n return (\n <div\n role={isClickable ? 'button' : undefined}\n tabIndex={isClickable ? 0 : undefined}\n onClick={onClick}\n onKeyDown={\n isClickable\n ? (event) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault()\n onClick?.()\n }\n }\n : undefined\n }\n className={className}\n style={{\n ...fallbackNote,\n border: '1px solid #d1d5db',\n borderRadius: 8,\n padding: 16,\n display: 'flex',\n alignItems: 'flex-start',\n justifyContent: 'space-between',\n gap: 12,\n cursor: isClickable ? 'pointer' : undefined,\n }}\n >\n <div style={{ minWidth: 0, flex: 1 }}>\n <p style={{ fontSize: 13, color: '#6b7280', margin: 0 }}>{label}</p>\n <p style={{ fontSize: 28, fontWeight: 700, margin: '4px 0 0' }}>{isLoading ? '…' : value}</p>\n {delta && !isLoading && (\n <p style={{ fontSize: 13, color: DELTA_FALLBACK_COLOR[delta.direction], margin: '4px 0 0' }}>\n {delta.value} {delta.label}\n </p>\n )}\n </div>\n {icon && <div aria-hidden=\"true\">{icon}</div>}\n </div>\n )\n}\nStatsCard.displayName = 'StatsCard'\n\n// ---------------------------------------------------------------------------\n// FormDialog\n// ---------------------------------------------------------------------------\n\nexport type FormDialogSize = 'sm' | 'md' | 'lg'\n\nexport interface FormDialogProps {\n isOpen: boolean\n onClose: () => void\n title: string\n description?: string\n children: React.ReactNode\n onSubmit: () => void | Promise<void>\n submitText?: string\n cancelText?: string\n isSubmitting?: boolean\n error?: string | null\n size?: FormDialogSize\n disableBackdropClose?: boolean\n submitDisabled?: boolean\n}\n\nconst FORM_DIALOG_MAX_WIDTH: Record<FormDialogSize, number> = { sm: 420, md: 520, lg: 680 }\n\n/**\n * FormDialog — delegates to the platform's real FormDialog at render time. The fallback is\n * a minimal, accessible modal shell (role=\"dialog\", Escape-to-close, backdrop click) without\n * the host's focus-trap polish.\n *\n * @example\n * <FormDialog isOpen={isOpen} onClose={close} title=\"Add index\" onSubmit={handleSubmit}>\n * <Input label=\"Name\" value={name} onChange={(e) => setName(e.target.value)} />\n * </FormDialog>\n */\nexport const FormDialog: React.FC<FormDialogProps> = (props) => {\n const HostFormDialog = getHostUi<React.FC<FormDialogProps>>('FormDialog')\n if (HostFormDialog) return <HostFormDialog {...props} />\n\n const {\n isOpen,\n onClose,\n title,\n description,\n children,\n onSubmit,\n submitText = 'Save',\n cancelText = 'Cancel',\n isSubmitting = false,\n error = null,\n size = 'md',\n disableBackdropClose = false,\n submitDisabled = false,\n } = props\n\n React.useEffect(() => {\n if (!isOpen) return\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape' && !isSubmitting) onClose()\n }\n document.addEventListener('keydown', handleKeyDown)\n return () => document.removeEventListener('keydown', handleKeyDown)\n }, [isOpen, isSubmitting, onClose])\n\n if (!isOpen) return null\n\n const requestClose = () => {\n if (!isSubmitting) onClose()\n }\n\n return (\n <div\n style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.5)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 50 }}\n onClick={disableBackdropClose ? undefined : requestClose}\n >\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={title}\n style={{ background: 'white', color: 'black', borderRadius: 8, width: '100%', maxWidth: FORM_DIALOG_MAX_WIDTH[size], maxHeight: '80vh', overflow: 'auto', ...fallbackNote }}\n onClick={(event) => event.stopPropagation()}\n >\n <form\n onSubmit={(event) => {\n event.preventDefault()\n void onSubmit()\n }}\n >\n <div style={{ padding: 16, borderBottom: '1px solid #d1d5db' }}>\n <h3 style={{ margin: 0, fontSize: 16, fontWeight: 600 }}>{title}</h3>\n {description && <p style={{ margin: '4px 0 0', fontSize: 13, color: '#6b7280' }}>{description}</p>}\n </div>\n <div style={{ padding: 16, display: 'flex', flexDirection: 'column', gap: 12 }}>\n {error && (\n <p role=\"alert\" style={{ margin: 0, fontSize: 13, color: '#dc2626' }}>\n {error}\n </p>\n )}\n {children}\n </div>\n <div style={{ padding: 16, borderTop: '1px solid #d1d5db', display: 'flex', justifyContent: 'flex-end', gap: 8 }}>\n <Button type=\"button\" variant=\"secondary\" onClick={requestClose} disabled={isSubmitting}>\n {cancelText}\n </Button>\n <Button type=\"submit\" variant=\"primary\" isLoading={isSubmitting} disabled={submitDisabled}>\n {submitText}\n </Button>\n </div>\n </form>\n </div>\n </div>\n )\n}\nFormDialog.displayName = 'FormDialog'\n\n// ---------------------------------------------------------------------------\n// useToast / useConfirmDialog\n//\n// Unlike the components above, these are HOOKS the host backs with real React\n// context (ToastContext / ConfirmationDialogContext), whose providers the\n// platform's root App.tsx mounts around the entire tree — including app\n// pages, since they render inside the host's own React instance. So inside\n// Veltrix these resolve to the real, working implementation with no extra\n// wiring. Outside the platform (no host, or an older host) they degrade to a\n// safe, non-throwing fallback instead of crashing: `toast()` logs to the\n// console and `confirm()` resolves to `false` (fails closed — no destructive\n// action proceeds without an explicit user confirmation the fallback cannot\n// provide).\n// ---------------------------------------------------------------------------\n\nexport type ToastVariant = 'success' | 'error' | 'warning' | 'info'\n\nexport interface ToastOptions {\n variant?: ToastVariant\n duration?: number\n action?: { label: string; onClick: () => void }\n}\n\nexport interface Toast {\n id: string\n message: string\n variant: ToastVariant\n duration?: number\n action?: { label: string; onClick: () => void }\n}\n\nexport interface ToastContextValue {\n toasts: Toast[]\n toast: (message: string, options?: ToastOptions) => string\n success: (message: string, duration?: number) => string\n error: (message: string, duration?: number) => string\n warning: (message: string, duration?: number) => string\n info: (message: string, duration?: number) => string\n promise: <T>(\n promise: Promise<T>,\n messages: { loading: string; success: string | ((data: T) => string); error: string | ((error: unknown) => string) },\n ) => Promise<T>\n dismiss: (id: string) => void\n dismissAll: () => void\n}\n\nfunction fallbackToast(message: string, options?: ToastOptions): string {\n // eslint-disable-next-line no-console -- deliberate: this IS the fallback surface.\n console.warn(`[@veltrixsecops/app-sdk/ui] Toast (${options?.variant ?? 'info'}): ${message}`)\n return 'fallback-toast'\n}\n\nconst fallbackToastContext: ToastContextValue = {\n toasts: [],\n toast: fallbackToast,\n success: (message) => fallbackToast(message, { variant: 'success' }),\n error: (message) => fallbackToast(message, { variant: 'error' }),\n warning: (message) => fallbackToast(message, { variant: 'warning' }),\n info: (message) => fallbackToast(message, { variant: 'info' }),\n promise: (promise) => promise,\n dismiss: () => {},\n dismissAll: () => {},\n}\n\n/**\n * useToast — delegates to the platform's real toast system when running inside Veltrix.\n * Outside it, `toast()`/`success()`/etc. log to the console instead of throwing.\n *\n * @example\n * const toast = useToast()\n * toast.success('Index saved')\n */\nexport function useToast(): ToastContextValue {\n const hostUseToast = getHostUi<() => ToastContextValue>('useToast')\n // eslint-disable-next-line react-hooks/rules-of-hooks -- `hostUseToast` IS the real hook;\n // its presence is fixed for the app's lifetime (the host runtime installs once at boot),\n // so this never actually violates the \"same hooks every render\" invariant in practice.\n if (hostUseToast) return hostUseToast()\n return fallbackToastContext\n}\n\nexport type ConfirmationVariant = 'danger' | 'warning' | 'info'\n\nexport interface ConfirmationOptions {\n title: string\n message: string\n confirmText?: string\n cancelText?: string\n variant?: ConfirmationVariant\n}\n\nexport interface ConfirmationDialogContextValue {\n confirm: (options: ConfirmationOptions) => Promise<boolean>\n}\n\nconst fallbackConfirmationContext: ConfirmationDialogContextValue = {\n confirm: (options) => {\n // eslint-disable-next-line no-console -- deliberate: this IS the fallback surface.\n console.warn(\n `[@veltrixsecops/app-sdk/ui] ConfirmationDialog is only available inside the Veltrix platform — ` +\n `\"${options.title}\" auto-resolved to \"not confirmed\" (fail closed).`,\n )\n return Promise.resolve(false)\n },\n}\n\n/**\n * useConfirmDialog — delegates to the platform's real confirmation dialog when running\n * inside Veltrix. Outside it, `confirm()` resolves to `false` (fails closed) rather than\n * throwing, so a guarded destructive action simply never proceeds instead of crashing.\n *\n * @example\n * const { confirm } = useConfirmDialog()\n * if (await confirm({ title: 'Delete index', message: 'This cannot be undone.', variant: 'danger' })) {\n * await deleteIndex(id)\n * }\n */\nexport function useConfirmDialog(): ConfirmationDialogContextValue {\n const hostUseConfirmDialog = getHostUi<() => ConfirmationDialogContextValue>('useConfirmDialog')\n // eslint-disable-next-line react-hooks/rules-of-hooks -- see useToast's note above.\n if (hostUseConfirmDialog) return hostUseConfirmDialog()\n return fallbackConfirmationContext\n}\n","// ========================================================================\n// Client runtime contract — how app client bundles talk to the host.\n//\n// App client code is packaged as a hermetic ESM bundle in which `react`,\n// `react-dom`, `react/jsx-runtime`, and every `@veltrixsecops/app-sdk`\n// subpath are compile-time shims that read the host-provided runtime from\n// `globalThis.__VELTRIX_APP_RUNTIME__`. The platform installs that global\n// (with ITS React instance, the shared AppContext, and an authenticated\n// fetch) before dynamically importing any app bundle, so app components\n// render inside the host React tree with working hooks and context.\n//\n// App authors: import from '@veltrixsecops/app-sdk/client' (and /hooks) —\n// never bundle your own copy of react. Use `authFetch` for calls to your\n// app's server routes (/api/apps/<app-id>/...): plain fetch() lacks the\n// platform's Authorization header and will receive 401s.\n// ========================================================================\n\nimport type { ComponentType, Context, LazyExoticComponent } from 'react'\nimport type { AppContextValue } from '../hooks/use-app-context'\nimport type { AppPermissionsApi } from '../types/platform'\n\nexport type { AppBrandingDeclaration } from '../types/manifest'\nexport type { AppPermissionsApi, PermissionEntry, PermissionCheckOptions } from '../types/platform'\n\n// Inventory — typed helpers over the platform's components API (deployment\n// targets: servers, domains, IP/CIDR ranges). Framework-free; they use the\n// `authFetch` exported below internally.\nexport {\n listInventory,\n addInventoryItem,\n updateInventoryItem,\n removeInventoryItem,\n resolveTool,\n} from './inventory'\nexport type { Tool } from './inventory'\nexport type { InventoryItem, InventoryItemInput } from '../types/platform'\n\n// Connectivity providers — reader over the customer's ZTNA providers, used to\n// populate the Access Server link picker. Framework-free; uses `authFetch`.\nexport { listConnectivityProviders } from './connectivity'\nexport type { ConnectivityProviderRef } from '../types/platform'\n\n// Environments — reader over the customer's deployment scopes, used to populate\n// the Environment picker on Connections + Access Servers. Framework-free.\nexport { listEnvironments } from './environments'\nexport type { EnvironmentRef } from '../types/pipeline'\n\n// Credentials — typed helpers over the platform's credentials API. Paired with\n// a server (component) these form a \"connection\". Secrets are write-only:\n// `listCredentials` returns redacted summaries only. Framework-free; they use\n// the `authFetch` exported below internally.\nexport {\n listCredentials,\n createCredential,\n updateCredential,\n removeCredential,\n} from './credentials'\nexport type { Credential, CredentialSummary, CredentialInput } from '../types/platform'\n\n/** Name of the global the platform installs before loading app bundles. */\nexport const HOST_RUNTIME_GLOBAL = '__VELTRIX_APP_RUNTIME__'\n\n/**\n * The runtime surface the platform exposes to app client bundles.\n * The react/reactDom/jsxRuntime members are the host's own module objects —\n * app bundles are compiled with shims that re-export them, guaranteeing a\n * single React instance per page.\n */\nexport interface VeltrixHostRuntime {\n /** The host's `react` module object. */\n react: unknown\n /** The host's `react-dom` module object. */\n reactDom: unknown\n /** The host's `react-dom/client` module object. */\n reactDomClient?: unknown\n /** The host's `react/jsx-runtime` module object. */\n jsxRuntime: unknown\n /** Shared app context — the host wraps app pages in its Provider. */\n AppContext: Context<AppContextValue | null>\n /** fetch() with the platform's Authorization header attached. */\n authFetch: (input: string, init?: RequestInit) => Promise<Response>\n /**\n * The SDK surface app bundles receive for `@veltrixsecops/app-sdk`,\n * `.../hooks`, and `.../client` imports (useAppContext, AppContext,\n * usePipelineStatus, authFetch, getHostRuntime, ...).\n */\n sdk: Record<string, unknown>\n /**\n * The platform's design-system components and hooks, host-owned so they\n * share the single host React instance. Keyed by the exact component/hook\n * names re-exported from `@veltrixsecops/app-sdk/ui` (Button, Input, Card,\n * DataTable, useToast, ...). Present only inside the platform.\n */\n ui?: Record<string, unknown>\n /**\n * Platform-scoped permission checks (RBAC/IdP hardening, Wave C4) —\n * `opts.appId` is NOT defaulted here (omit for a platform-scoped check).\n * App page code should prefer `usePermissions()`\n * (`@veltrixsecops/app-sdk/hooks`), which defaults `opts.appId` to the\n * app's own id. Optional for compatibility with a host that hasn't\n * deployed this surface yet.\n */\n permissions?: AppPermissionsApi\n}\n\n/** Read the host runtime, or null outside the platform (tests, storybook). */\nexport function getHostRuntime(): VeltrixHostRuntime | null {\n const runtime = (globalThis as Record<string, unknown>)[HOST_RUNTIME_GLOBAL]\n return (runtime as VeltrixHostRuntime) ?? null\n}\n\n/** Read the host runtime, throwing a diagnosable error when absent. */\nexport function requireHostRuntime(): VeltrixHostRuntime {\n const runtime = getHostRuntime()\n if (!runtime) {\n throw new Error(\n 'Veltrix host runtime not found — app client bundles only run inside the ' +\n `Veltrix platform (missing globalThis.${HOST_RUNTIME_GLOBAL})`,\n )\n }\n return runtime\n}\n\n/**\n * fetch() that carries the platform's Authorization header. Required for an\n * app page to call its own server routes (/api/apps/<app-id>/...), which are\n * bearer-token protected. Falls back to plain fetch outside the platform.\n */\nexport function authFetch(input: string, init?: RequestInit): Promise<Response> {\n const runtime = getHostRuntime()\n if (runtime) return runtime.authFetch(input, init)\n return fetch(input, init)\n}\n\n/** A sidebar entry contributed by the app's client entry module. */\nexport interface AppSidebarItem {\n path: string\n label: string\n icon?: string\n}\n\n/**\n * Shape of the default export of an app's `client/index.tsx`.\n * `pages` keys must match `manifest.client.pages[].component`.\n */\nexport interface AppClientModule {\n id: string\n pages: Record<string, ComponentType | LazyExoticComponent<ComponentType>>\n sidebarItems?: AppSidebarItem[]\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/ui/index.tsx","../../src/client/index.ts"],"sourcesContent":["// ========================================================================\n// @veltrixsecops/app-sdk/ui — the platform's shared component library,\n// exposed to app client bundles.\n//\n// App pages import these instead of hand-rolling raw HTML, so pages render\n// themed inside the Veltrix design system (dark/light + tenant branding via\n// `var(--vx-*)`), consistent with the rest of the portal, and externalized —\n// zero bundle bloat, one React instance. This completes the \"predictable\n// shell, flexible body\" contract: the platform owns the components; apps\n// compose their page body from them.\n//\n// RUNTIME: every export here reads its real implementation off the host at\n// render time — globalThis.__VELTRIX_APP_RUNTIME__.ui.<Name>, populated by\n// the platform from components/shared/* (see\n// client/src/appRuntime/installHostRuntime.ts). At packaging time the CLI's\n// client bundler (and the platform's on-demand esbuild bundle routes) shim\n// the '@veltrixsecops/app-sdk/ui' specifier straight to that `ui` bag, so\n// this module's own render-time lookup only actually executes in\n// non-bundled contexts: local dev, unit tests, a bare `tsc --noEmit`, or\n// Storybook.\n//\n// FALLBACK CONTRACT: outside the platform (host runtime absent, or an older\n// host that predates a given component) every export here renders a\n// minimal, accessible, unstyled fallback instead of throwing — an app page\n// under test or local dev keeps working, just without platform theming.\n// Never throw on render.\n//\n// TYPE FIDELITY: prop types are copied from the platform's real components\n// in client/src/components/shared (see the ADR at\n// _ai_tasks/ui-package/2026-07-10/02_sdk_ui_subpath.md) so app-author\n// typechecking matches what actually renders inside Veltrix. Heavy composite\n// widgets (ConfigurationCanvas, VersionControl, Pipeline) stay out of scope —\n// they carry platform coupling a later phase may expose read-only versions\n// of; see the ADR's \"Non-goals\" section.\n//\n// EXPORTS: Button, Badge, Card (+ CardHeader/CardBody/CardFooter), Input,\n// Textarea, Checkbox, Select, SearchBox, Pagination, FilterBar, SortSelect,\n// FormField, Tabs, EmptyState, Skeleton (+ SkeletonText/SkeletonCard),\n// Tooltip, Spinner, DataTable, StatsCard, FormDialog, useToast,\n// useConfirmDialog.\n//\n// useToast / useConfirmDialog are included because the platform's root\n// App.tsx mounts ToastProvider/ConfirmationDialogProvider around the ENTIRE\n// tree (including every app page, since app pages render inside the host's\n// own React instance) — so the real context-backed hooks resolve correctly\n// from app code with no extra wiring. Outside the platform they degrade to a\n// safe, non-throwing fallback (see each hook's docs below) rather than\n// crashing or silently doing nothing.\n// ========================================================================\n\nimport * as React from 'react'\nimport { getHostRuntime } from '../client'\n\n/** Read one named component off the host's `runtime.ui` bag, or undefined. */\nfunction getHostUi<T>(name: string): T | undefined {\n return getHostRuntime()?.ui?.[name] as T | undefined\n}\n\nconst fallbackNote: React.CSSProperties = { fontFamily: 'inherit' }\n\n// ---------------------------------------------------------------------------\n// Button\n// ---------------------------------------------------------------------------\n\nexport type ButtonVariant = 'primary' | 'secondary' | 'danger' | 'success' | 'warning' | 'ghost' | 'link'\nexport type ButtonSize = 'sm' | 'md' | 'lg'\n\nexport interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: ButtonVariant\n size?: ButtonSize\n isLoading?: boolean\n loadingText?: string\n fullWidth?: boolean\n leftIcon?: React.ReactNode\n rightIcon?: React.ReactNode\n}\n\ntype ButtonComponent = React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>\n\n/**\n * Button — delegates to the platform's real Button at render time.\n *\n * @example\n * <Button variant=\"primary\" leftIcon={<RefreshIcon />} onClick={refresh}>Refresh</Button>\n */\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>((props, ref) => {\n const HostButton = getHostUi<ButtonComponent>('Button')\n if (HostButton) return <HostButton ref={ref} {...props} />\n\n const {\n variant: _variant,\n size: _size,\n isLoading,\n loadingText,\n fullWidth,\n leftIcon,\n rightIcon,\n children,\n disabled,\n type,\n style,\n ...rest\n } = props\n\n return (\n <button\n ref={ref}\n type={type ?? 'button'}\n disabled={disabled || isLoading}\n aria-busy={isLoading || undefined}\n style={{\n ...fallbackNote,\n display: 'inline-flex',\n alignItems: 'center',\n gap: 6,\n padding: '6px 14px',\n borderRadius: 6,\n border: '1px solid currentColor',\n background: 'transparent',\n cursor: disabled || isLoading ? 'not-allowed' : 'pointer',\n width: fullWidth ? '100%' : undefined,\n opacity: disabled || isLoading ? 0.6 : 1,\n justifyContent: 'center',\n ...style,\n }}\n {...rest}\n >\n {leftIcon}\n {isLoading ? loadingText ?? children : children}\n {rightIcon}\n </button>\n )\n})\nButton.displayName = 'Button'\n\n// ---------------------------------------------------------------------------\n// Badge\n// ---------------------------------------------------------------------------\n\nexport type BadgeVariant = 'default' | 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info'\nexport type BadgeSize = 'sm' | 'md' | 'lg'\n\nexport interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {\n variant?: BadgeVariant\n size?: BadgeSize\n rounded?: boolean\n dot?: boolean\n}\n\nconst BADGE_FALLBACK_COLORS: Record<BadgeVariant, string> = {\n default: '#6b7280',\n primary: '#4f46e5',\n secondary: '#6b7280',\n success: '#16a34a',\n danger: '#dc2626',\n warning: '#d97706',\n info: '#0284c7',\n}\n\n/**\n * Badge — delegates to the platform's real Badge at render time.\n *\n * @example\n * <Badge variant={row.deployState === 'deployed' ? 'success' : 'warning'}>{row.deployState}</Badge>\n */\nexport const Badge: React.FC<BadgeProps> = ({ variant = 'default', size = 'md', rounded, dot, children, style, ...rest }) => {\n const HostBadge = getHostUi<React.FC<BadgeProps>>('Badge')\n if (HostBadge) return <HostBadge variant={variant} size={size} rounded={rounded} dot={dot} style={style} {...rest}>{children}</HostBadge>\n\n const color = BADGE_FALLBACK_COLORS[variant]\n const fontSize = size === 'sm' ? 11 : size === 'lg' ? 14 : 12\n return (\n <span\n style={{\n ...fallbackNote,\n display: 'inline-flex',\n alignItems: 'center',\n gap: 4,\n padding: size === 'sm' ? '1px 6px' : size === 'lg' ? '3px 10px' : '2px 8px',\n borderRadius: rounded ? 999 : 4,\n border: `1px solid ${color}`,\n color,\n fontSize,\n fontWeight: 500,\n ...style,\n }}\n {...rest}\n >\n {dot && <span aria-hidden=\"true\" style={{ width: 6, height: 6, borderRadius: '50%', background: color }} />}\n {children}\n </span>\n )\n}\nBadge.displayName = 'Badge'\n\n// ---------------------------------------------------------------------------\n// Card (+ Header/Body/Footer)\n// ---------------------------------------------------------------------------\n\nexport interface CardProps extends React.HTMLAttributes<HTMLDivElement> {\n variant?: 'default' | 'bordered' | 'elevated'\n padding?: 'none' | 'sm' | 'md' | 'lg'\n}\nexport interface CardHeaderProps extends React.HTMLAttributes<HTMLDivElement> {\n actions?: React.ReactNode\n}\nexport type CardBodyProps = React.HTMLAttributes<HTMLDivElement>\nexport interface CardFooterProps extends React.HTMLAttributes<HTMLDivElement> {\n variant?: 'default' | 'bordered'\n}\n\n/** Card — delegates to the platform's real Card at render time. */\nexport const Card: React.FC<CardProps> = ({ children, style, ...rest }) => {\n const HostCard = getHostUi<React.FC<CardProps>>('Card')\n if (HostCard) return <HostCard style={style} {...rest}>{children}</HostCard>\n return (\n <div style={{ ...fallbackNote, border: '1px solid #d1d5db', borderRadius: 8, overflow: 'hidden', ...style }} {...rest}>\n {children}\n </div>\n )\n}\nCard.displayName = 'Card'\n\n/** CardHeader — the header section of a Card, with optional trailing actions. */\nexport const CardHeader: React.FC<CardHeaderProps> = ({ actions, children, style, ...rest }) => {\n const HostCardHeader = getHostUi<React.FC<CardHeaderProps>>('CardHeader')\n if (HostCardHeader) return <HostCardHeader actions={actions} style={style} {...rest}>{children}</HostCardHeader>\n return (\n <div\n style={{\n ...fallbackNote,\n padding: '12px 16px',\n borderBottom: '1px solid #d1d5db',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 12,\n ...style,\n }}\n {...rest}\n >\n <div style={{ flex: 1, minWidth: 0 }}>{children}</div>\n {actions && <div>{actions}</div>}\n </div>\n )\n}\nCardHeader.displayName = 'CardHeader'\n\n/** CardBody — the main content area of a Card. */\nexport const CardBody: React.FC<CardBodyProps> = ({ children, style, ...rest }) => {\n const HostCardBody = getHostUi<React.FC<CardBodyProps>>('CardBody')\n if (HostCardBody) return <HostCardBody style={style} {...rest}>{children}</HostCardBody>\n return (\n <div style={{ ...fallbackNote, padding: '12px 16px', ...style }} {...rest}>\n {children}\n </div>\n )\n}\nCardBody.displayName = 'CardBody'\n\n/** CardFooter — the footer section of a Card, typically for actions. */\nexport const CardFooter: React.FC<CardFooterProps> = ({ children, style, ...rest }) => {\n const HostCardFooter = getHostUi<React.FC<CardFooterProps>>('CardFooter')\n if (HostCardFooter) return <HostCardFooter style={style} {...rest}>{children}</HostCardFooter>\n return (\n <div style={{ ...fallbackNote, padding: '12px 16px', borderTop: '1px solid #d1d5db', ...style }} {...rest}>\n {children}\n </div>\n )\n}\nCardFooter.displayName = 'CardFooter'\n\n// ---------------------------------------------------------------------------\n// Input\n// ---------------------------------------------------------------------------\n\nexport type InputSize = 'sm' | 'md' | 'lg'\nexport type InputVariant = 'default' | 'error' | 'success'\n\nexport interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'> {\n label?: string\n error?: string\n helperText?: string\n leftIcon?: React.ReactNode\n rightIcon?: React.ReactNode\n variant?: InputVariant\n inputSize?: InputSize\n isSuccess?: boolean\n fullWidth?: boolean\n}\n\ntype InputComponent = React.ForwardRefExoticComponent<InputProps & React.RefAttributes<HTMLInputElement>>\n\n/**\n * Input — delegates to the platform's real Input at render time.\n *\n * @example\n * <Input label=\"Index name\" value={name} onChange={(e) => setName(e.target.value)} error={errors.name} />\n */\nexport const Input = React.forwardRef<HTMLInputElement, InputProps>((props, ref) => {\n const HostInput = getHostUi<InputComponent>('Input')\n if (HostInput) return <HostInput ref={ref} {...props} />\n\n const { label, error, helperText, leftIcon, rightIcon, fullWidth = true, id, style, ...rest } = props\n const inputId = id ?? (label ? `vx-input-${label.toLowerCase().replace(/\\s+/g, '-')}` : undefined)\n\n return (\n <div style={{ ...fallbackNote, width: fullWidth ? '100%' : undefined }}>\n {label && (\n <label htmlFor={inputId} style={{ display: 'block', fontSize: 13, fontWeight: 500, marginBottom: 4 }}>\n {label}\n </label>\n )}\n <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>\n {leftIcon}\n <input\n ref={ref}\n id={inputId}\n aria-invalid={!!error || undefined}\n style={{ flex: 1, padding: '6px 10px', borderRadius: 6, border: '1px solid #9ca3af', ...style }}\n {...rest}\n />\n {rightIcon}\n </div>\n {error && (\n <p role=\"alert\" style={{ marginTop: 4, fontSize: 12, color: '#dc2626' }}>\n {error}\n </p>\n )}\n {helperText && !error && <p style={{ marginTop: 4, fontSize: 12, color: '#6b7280' }}>{helperText}</p>}\n </div>\n )\n})\nInput.displayName = 'Input'\n\n// ---------------------------------------------------------------------------\n// Textarea\n// ---------------------------------------------------------------------------\n\nexport interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {\n label?: string\n error?: string\n helperText?: string\n fullWidth?: boolean\n}\n\ntype TextareaComponent = React.ForwardRefExoticComponent<TextareaProps & React.RefAttributes<HTMLTextAreaElement>>\n\n/**\n * Textarea — delegates to the platform's real Textarea at render time.\n *\n * @example\n * <Textarea label=\"Description\" helperText=\"Markdown is supported.\" />\n */\nexport const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>((props, ref) => {\n const HostTextarea = getHostUi<TextareaComponent>('Textarea')\n if (HostTextarea) return <HostTextarea ref={ref} {...props} />\n\n const { label, error, helperText, fullWidth = true, id, rows = 4, style, ...rest } = props\n const textareaId = id ?? (label ? `vx-textarea-${label.toLowerCase().replace(/\\s+/g, '-')}` : undefined)\n\n return (\n <div style={{ ...fallbackNote, width: fullWidth ? '100%' : undefined }}>\n {label && (\n <label htmlFor={textareaId} style={{ display: 'block', fontSize: 13, fontWeight: 500, marginBottom: 4 }}>\n {label}\n </label>\n )}\n <textarea\n ref={ref}\n id={textareaId}\n rows={rows}\n aria-invalid={!!error || undefined}\n style={{ width: '100%', padding: '6px 10px', borderRadius: 6, border: '1px solid #9ca3af', ...style }}\n {...rest}\n />\n {error && (\n <p role=\"alert\" style={{ marginTop: 4, fontSize: 12, color: '#dc2626' }}>\n {error}\n </p>\n )}\n {helperText && !error && <p style={{ marginTop: 4, fontSize: 12, color: '#6b7280' }}>{helperText}</p>}\n </div>\n )\n})\nTextarea.displayName = 'Textarea'\n\n// ---------------------------------------------------------------------------\n// Checkbox\n// ---------------------------------------------------------------------------\n\nexport interface CheckboxProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type'> {\n label?: React.ReactNode\n error?: string\n helperText?: string\n}\n\ntype CheckboxComponent = React.ForwardRefExoticComponent<CheckboxProps & React.RefAttributes<HTMLInputElement>>\n\n/**\n * Checkbox — delegates to the platform's real Checkbox at render time.\n *\n * @example\n * <Checkbox label=\"Enable drift detection\" checked={enabled} onChange={(e) => setEnabled(e.target.checked)} />\n */\nexport const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>((props, ref) => {\n const HostCheckbox = getHostUi<CheckboxComponent>('Checkbox')\n if (HostCheckbox) return <HostCheckbox ref={ref} {...props} />\n\n const { label, error, helperText, id, disabled, ...rest } = props\n const generatedId = React.useId()\n const inputId = id ?? generatedId\n\n return (\n <div style={fallbackNote}>\n <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n <input ref={ref} id={inputId} type=\"checkbox\" disabled={disabled} aria-invalid={!!error || undefined} {...rest} />\n {label && (\n <label htmlFor={inputId} style={{ fontSize: 13, cursor: disabled ? 'not-allowed' : 'pointer', opacity: disabled ? 0.6 : 1 }}>\n {label}\n </label>\n )}\n </div>\n {error && (\n <p role=\"alert\" style={{ marginTop: 4, fontSize: 12, color: '#dc2626' }}>\n {error}\n </p>\n )}\n {helperText && !error && <p style={{ marginTop: 4, fontSize: 12, color: '#6b7280' }}>{helperText}</p>}\n </div>\n )\n})\nCheckbox.displayName = 'Checkbox'\n\n// ---------------------------------------------------------------------------\n// Select (controlled; onChange receives the new value string)\n// ---------------------------------------------------------------------------\n\nexport type SelectSize = 'sm' | 'md' | 'lg'\n\nexport interface SelectOption {\n value: string\n label: string\n disabled?: boolean\n}\n\nexport interface SelectProps {\n options: SelectOption[]\n value?: string\n onChange?: (value: string) => void\n placeholder?: string\n label?: string\n error?: string\n helperText?: string\n size?: SelectSize\n disabled?: boolean\n fullWidth?: boolean\n className?: string\n id?: string\n name?: string\n 'aria-label'?: string\n}\n\n/**\n * Select — delegates to the platform's real (WAI-ARIA listbox) Select at render time.\n * The fallback is a native `<select>` — functionally equivalent, visually plainer.\n *\n * @example\n * <Select label=\"Environment\" value={env} onChange={setEnv} options={[{ value: 'prod', label: 'Production' }]} />\n */\nexport const Select: React.FC<SelectProps> = (props) => {\n const HostSelect = getHostUi<React.FC<SelectProps>>('Select')\n if (HostSelect) return <HostSelect {...props} />\n\n const { options, value, onChange, placeholder = 'Select…', label, error, helperText, disabled, fullWidth = true, id, name, className } = props\n const selectId = id ?? (label ? `vx-select-${label.toLowerCase().replace(/\\s+/g, '-')}` : undefined)\n\n return (\n <div className={className} style={{ ...fallbackNote, width: fullWidth ? '100%' : undefined }}>\n {label && (\n <label htmlFor={selectId} style={{ display: 'block', fontSize: 13, fontWeight: 500, marginBottom: 4 }}>\n {label}\n </label>\n )}\n <select\n id={selectId}\n name={name}\n aria-label={props['aria-label']}\n aria-invalid={!!error || undefined}\n disabled={disabled}\n value={value ?? ''}\n onChange={(event) => onChange?.(event.target.value)}\n style={{ width: '100%', padding: '6px 10px', borderRadius: 6, border: '1px solid #9ca3af' }}\n >\n {placeholder && (\n <option value=\"\" disabled>\n {placeholder}\n </option>\n )}\n {options.map((option) => (\n <option key={option.value} value={option.value} disabled={option.disabled}>\n {option.label}\n </option>\n ))}\n </select>\n {error && (\n <p role=\"alert\" style={{ marginTop: 4, fontSize: 12, color: '#dc2626' }}>\n {error}\n </p>\n )}\n {helperText && !error && <p style={{ marginTop: 4, fontSize: 12, color: '#6b7280' }}>{helperText}</p>}\n </div>\n )\n}\nSelect.displayName = 'Select'\n\n// ---------------------------------------------------------------------------\n// SearchBox\n// ---------------------------------------------------------------------------\n\nexport type SearchBoxSize = 'sm' | 'md' | 'lg'\n\nexport interface SearchBoxProps {\n /** Controlled search text. */\n value: string\n /** Called with the new text — debounced by `debounceMs` when set. */\n onChange: (value: string) => void\n placeholder?: string\n disabled?: boolean\n size?: SearchBoxSize\n /** Debounces `onChange` by this many ms; omit (or `0`) to call on every keystroke. */\n debounceMs?: number\n className?: string\n 'aria-label'?: string\n}\n\n/**\n * SearchBox — delegates to the platform's real SearchBox at render time (leading search icon,\n * a clear button once there's text, optional debounce). The fallback is a bare\n * `<input type=\"search\">` wired straight to `value`/`onChange` — no icon, no debounce, no\n * clear button — but functionally sufficient for typing and clearing.\n *\n * @example\n * <SearchBox value={search} onChange={setSearch} placeholder=\"Search apps…\" debounceMs={250} />\n */\nexport const SearchBox: React.FC<SearchBoxProps> = (props) => {\n const HostSearchBox = getHostUi<React.FC<SearchBoxProps>>('SearchBox')\n if (HostSearchBox) return <HostSearchBox {...props} />\n\n const { value, onChange, placeholder, disabled, className, 'aria-label': ariaLabel } = props\n return (\n <input\n type=\"search\"\n value={value}\n onChange={(event) => onChange(event.target.value)}\n placeholder={placeholder}\n disabled={disabled}\n aria-label={ariaLabel ?? placeholder ?? 'Search'}\n className={className}\n style={{ ...fallbackNote, width: '100%', padding: '6px 10px', borderRadius: 6, border: '1px solid #9ca3af' }}\n />\n )\n}\nSearchBox.displayName = 'SearchBox'\n\n// ---------------------------------------------------------------------------\n// Pagination\n// ---------------------------------------------------------------------------\n\nexport interface PaginationProps {\n /** 1-based current page. */\n page: number\n pageSize: number\n totalItems: number\n onPageChange: (page: number) => void\n /** Renders a page-size selector when provided together with `pageSizeOptions`. */\n onPageSizeChange?: (size: number) => void\n pageSizeOptions?: number[]\n disabled?: boolean\n className?: string\n}\n\n/**\n * Pagination — delegates to the platform's real Pagination at render time: a \"Showing X–Y of\n * N\" summary, numbered pages with ellipsis for large ranges, an optional page-size Select, and\n * `aria-current=\"page\"` on the active page — visually consistent with DataTable's built-in\n * pagination footer. The fallback is a plain Prev/Next pair with \"page X of Y\" text.\n *\n * @example\n * <Pagination page={page} pageSize={20} totalItems={total} onPageChange={setPage} />\n */\nexport const Pagination: React.FC<PaginationProps> = (props) => {\n const HostPagination = getHostUi<React.FC<PaginationProps>>('Pagination')\n if (HostPagination) return <HostPagination {...props} />\n\n const { page, pageSize, totalItems, onPageChange, disabled, className } = props\n const pageCount = Math.max(1, Math.ceil(totalItems / pageSize))\n const canGoPrev = !disabled && page > 1\n const canGoNext = !disabled && page < pageCount\n\n return (\n <nav aria-label=\"Pagination\" className={className} style={{ ...fallbackNote, display: 'flex', alignItems: 'center', gap: 12 }}>\n <button type=\"button\" onClick={() => onPageChange(page - 1)} disabled={!canGoPrev} style={{ padding: '4px 10px' }}>\n Prev\n </button>\n <span>\n page {page} of {pageCount}\n </span>\n <button type=\"button\" onClick={() => onPageChange(page + 1)} disabled={!canGoNext} style={{ padding: '4px 10px' }}>\n Next\n </button>\n </nav>\n )\n}\nPagination.displayName = 'Pagination'\n\n// ---------------------------------------------------------------------------\n// FilterBar\n// ---------------------------------------------------------------------------\n\nexport interface FilterOption {\n value: string\n label: string\n}\n\nexport interface FilterDefinition {\n /** Stable identifier; also the React key for this filter's dropdown. */\n key: string\n /** Shown as the dropdown's placeholder/aria-label, and as its entry in the \"Add filter\" menu. */\n label: string\n options: FilterOption[]\n /** `null` (not `''`) represents \"no selection\" — the value FilterBar clears back to. */\n value: string | null\n onChange: (value: string | null) => void\n /** Always rendered when true. Omit/false to make this filter addable/removable via the \"Add filter\" menu. */\n alwaysVisible?: boolean\n}\n\nexport interface FilterBarSearchProps {\n value: string\n onChange: (value: string) => void\n placeholder?: string\n}\n\nexport interface FilterBarProps {\n filters: FilterDefinition[]\n /** Renders a SearchBox ahead of the filter dropdowns when provided. */\n search?: FilterBarSearchProps\n /**\n * Called by \"Clear all\" instead of FilterBar's own clearing logic. Omit it to let FilterBar\n * clear every filter with a value itself (`filter.onChange(null)` for each).\n */\n onClearAll?: () => void\n addFilterLabel?: string\n className?: string\n}\n\n/**\n * FilterBar — delegates to the platform's real FilterBar at render time: an optional\n * SearchBox, always-visible filter dropdowns, and optional filters the user can add/remove via\n * an \"Add filter\" menu (a filter with a non-null `value` is always treated as visible, even\n * before the user explicitly adds it). The fallback renders every filter as a plain,\n * always-visible native `<select>` — no add/remove menu, no styled search box — so an app page\n * under test still exposes every filter's full behavior via `onChange`.\n *\n * @example\n * <FilterBar\n * search={{ value: search, onChange: setSearch, placeholder: 'Search apps…' }}\n * filters={[\n * { key: 'vendor', label: 'Vendor', options: vendorOptions, value: vendor, onChange: setVendor, alwaysVisible: true },\n * { key: 'category', label: 'Category', options: categoryOptions, value: category, onChange: setCategory },\n * ]}\n * />\n */\nexport const FilterBar: React.FC<FilterBarProps> = (props) => {\n const HostFilterBar = getHostUi<React.FC<FilterBarProps>>('FilterBar')\n if (HostFilterBar) return <HostFilterBar {...props} />\n\n const { filters, search, className } = props\n return (\n <div className={className} style={{ ...fallbackNote, display: 'flex', flexWrap: 'wrap', gap: 8, alignItems: 'center' }}>\n {search && (\n <input\n type=\"search\"\n aria-label={search.placeholder ?? 'Search'}\n placeholder={search.placeholder}\n value={search.value}\n onChange={(event) => search.onChange(event.target.value)}\n style={{ padding: '6px 10px', borderRadius: 6, border: '1px solid #9ca3af' }}\n />\n )}\n {filters.map((filter) => (\n <label key={filter.key} style={{ display: 'flex', flexDirection: 'column', fontSize: 12 }}>\n {filter.label}\n <select\n aria-label={filter.label}\n value={filter.value ?? ''}\n onChange={(event) => filter.onChange(event.target.value === '' ? null : event.target.value)}\n style={{ padding: '6px 10px', borderRadius: 6, border: '1px solid #9ca3af' }}\n >\n <option value=\"\">{filter.label}</option>\n {filter.options.map((option) => (\n <option key={option.value} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n </label>\n ))}\n </div>\n )\n}\nFilterBar.displayName = 'FilterBar'\n\n// ---------------------------------------------------------------------------\n// SortSelect\n// ---------------------------------------------------------------------------\n\nexport type SortDirection = 'asc' | 'desc'\n\nexport interface SortOption {\n value: string\n label: string\n}\n\nexport interface SortSelectProps {\n /** Sortable fields, e.g. `[{ value: 'name', label: 'Name' }, { value: 'updatedAt', label: 'Updated' }]`. */\n options: SortOption[]\n /** Selected field key. */\n value: string\n direction: SortDirection\n /** Called with the field and direction together, whichever one the interaction changed. */\n onChange: (value: string, direction: SortDirection) => void\n disabled?: boolean\n className?: string\n}\n\n/**\n * SortSelect — delegates to the platform's real SortSelect at render time: a labeled field\n * Select paired with an asc/desc direction toggle button, styled to sit in the same toolbar\n * row as FilterBar. The standalone sort control for list/card surfaces that aren't a\n * DataTable (which has its own column-header sort). The fallback is a native `<select>` for\n * the field plus a button that flips direction.\n *\n * @example\n * <SortSelect\n * options={[{ value: 'name', label: 'Name' }, { value: 'updatedAt', label: 'Last updated' }]}\n * value={sortField}\n * direction={sortDirection}\n * onChange={(field, direction) => { setSortField(field); setSortDirection(direction) }}\n * />\n */\nexport const SortSelect: React.FC<SortSelectProps> = (props) => {\n const HostSortSelect = getHostUi<React.FC<SortSelectProps>>('SortSelect')\n if (HostSortSelect) return <HostSortSelect {...props} />\n\n const { options, value, direction, onChange, disabled, className } = props\n const directionLabel = direction === 'asc' ? 'Sort ascending' : 'Sort descending'\n\n return (\n <div className={className} style={{ ...fallbackNote, display: 'flex', alignItems: 'center', gap: 6 }}>\n <select\n aria-label=\"Sort by\"\n value={value}\n disabled={disabled}\n onChange={(event) => onChange(event.target.value, direction)}\n style={{ padding: '6px 10px', borderRadius: 6, border: '1px solid #9ca3af' }}\n >\n {options.map((option) => (\n <option key={option.value} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n <button\n type=\"button\"\n disabled={disabled}\n onClick={() => onChange(value, direction === 'asc' ? 'desc' : 'asc')}\n aria-label={directionLabel}\n style={{ padding: '4px 10px' }}\n >\n {direction === 'asc' ? '↑' : '↓'}\n </button>\n </div>\n )\n}\nSortSelect.displayName = 'SortSelect'\n\n// ---------------------------------------------------------------------------\n// FormField — generic label + control + error/hint wrapper\n// ---------------------------------------------------------------------------\n\nexport interface FormFieldProps {\n label?: string\n htmlFor?: string\n error?: string\n hint?: string\n required?: boolean\n className?: string\n children: React.ReactNode\n}\n\n/**\n * FormField — wraps a custom control (not already self-labeling like Input/Select) with\n * the platform's label + error/hint visual language.\n *\n * @example\n * <FormField label=\"Allowed IP ranges\" htmlFor=\"cidrs\" hint=\"One CIDR block per line\">\n * <textarea id=\"cidrs\" />\n * </FormField>\n */\nexport const FormField: React.FC<FormFieldProps> = (props) => {\n const HostFormField = getHostUi<React.FC<FormFieldProps>>('FormField')\n if (HostFormField) return <HostFormField {...props} />\n\n const { label, htmlFor, error, hint, required, className, children } = props\n return (\n <div className={className} style={fallbackNote}>\n {label && (\n <label htmlFor={htmlFor} style={{ display: 'block', fontSize: 13, fontWeight: 500, marginBottom: 4 }}>\n {label}\n {required && (\n <span aria-hidden=\"true\" style={{ color: '#dc2626', marginLeft: 2 }}>\n *\n </span>\n )}\n </label>\n )}\n {children}\n {error && (\n <p role=\"alert\" style={{ marginTop: 4, fontSize: 12, color: '#dc2626' }}>\n {error}\n </p>\n )}\n {hint && !error && <p style={{ marginTop: 4, fontSize: 12, color: '#6b7280' }}>{hint}</p>}\n </div>\n )\n}\nFormField.displayName = 'FormField'\n\n// ---------------------------------------------------------------------------\n// Tabs\n// ---------------------------------------------------------------------------\n\nexport interface TabItem {\n key?: string\n label: string\n content: React.ReactNode\n disabled?: boolean\n}\n\nexport interface TabsProps {\n tabs: TabItem[]\n defaultActiveIndex?: number\n activeIndex?: number\n onTabChange?: (index: number) => void\n children?: React.ReactNode\n className?: string\n}\n\n/**\n * Tabs — delegates to the platform's real (WAI-ARIA tabs pattern) Tabs at render time.\n *\n * @example\n * <Tabs tabs={[{ key: 'indexes', label: 'Indexes', content: <IndexesPanel /> }]} />\n */\nexport const Tabs: React.FC<TabsProps> = (props) => {\n const HostTabs = getHostUi<React.FC<TabsProps>>('Tabs')\n if (HostTabs) return <HostTabs {...props} />\n\n const { tabs, defaultActiveIndex = 0, activeIndex, onTabChange, children, className } = props\n const [internalIndex, setInternalIndex] = React.useState(defaultActiveIndex)\n const isControlled = activeIndex !== undefined\n const currentIndex = isControlled ? activeIndex : internalIndex\n const activeTab = tabs[currentIndex]\n\n const selectTab = (index: number) => {\n if (tabs[index]?.disabled) return\n if (!isControlled) setInternalIndex(index)\n onTabChange?.(index)\n }\n\n return (\n <div className={className} style={fallbackNote}>\n <div role=\"tablist\" style={{ display: 'flex', gap: 4, borderBottom: '1px solid #d1d5db' }}>\n {tabs.map((tab, index) => (\n <button\n key={tab.key ?? index}\n type=\"button\"\n role=\"tab\"\n aria-selected={index === currentIndex}\n disabled={tab.disabled}\n onClick={() => selectTab(index)}\n style={{\n padding: '6px 12px',\n border: 'none',\n borderBottom: index === currentIndex ? '2px solid currentColor' : '2px solid transparent',\n background: 'transparent',\n cursor: tab.disabled ? 'not-allowed' : 'pointer',\n fontWeight: index === currentIndex ? 600 : 400,\n opacity: tab.disabled ? 0.5 : 1,\n }}\n >\n {tab.label}\n </button>\n ))}\n </div>\n <div role=\"tabpanel\" style={{ padding: 12 }}>\n {children || activeTab?.content}\n </div>\n </div>\n )\n}\nTabs.displayName = 'Tabs'\n\n// ---------------------------------------------------------------------------\n// EmptyState\n// ---------------------------------------------------------------------------\n\nexport interface EmptyStateProps {\n icon?: React.ReactNode\n title: string\n description?: string\n action?: React.ReactNode\n className?: string\n}\n\n/** EmptyState — delegates to the platform's real EmptyState at render time. */\nexport const EmptyState: React.FC<EmptyStateProps> = (props) => {\n const HostEmptyState = getHostUi<React.FC<EmptyStateProps>>('EmptyState')\n if (HostEmptyState) return <HostEmptyState {...props} />\n\n const { icon, title, description, action, className } = props\n return (\n <div className={className} style={{ ...fallbackNote, textAlign: 'center', padding: '32px 16px' }}>\n {icon && <div style={{ marginBottom: 12 }}>{icon}</div>}\n <p style={{ fontWeight: 600, marginBottom: description ? 4 : 0 }}>{title}</p>\n {description && <p style={{ fontSize: 13, color: '#6b7280', marginBottom: action ? 12 : 0 }}>{description}</p>}\n {action}\n </div>\n )\n}\nEmptyState.displayName = 'EmptyState'\n\n// ---------------------------------------------------------------------------\n// Skeleton (+ Text/Card)\n// ---------------------------------------------------------------------------\n\nexport type SkeletonVariant = 'text' | 'circular' | 'rectangular'\n\nexport interface SkeletonProps extends React.HTMLAttributes<HTMLDivElement> {\n variant?: SkeletonVariant\n width?: string | number\n height?: string | number\n animation?: 'pulse' | 'wave' | 'none'\n}\n\nconst skeletonRadius: Record<SkeletonVariant, number | string> = { text: 4, circular: '50%', rectangular: 8 }\n\n/** Skeleton — delegates to the platform's real Skeleton at render time. */\nexport const Skeleton: React.FC<SkeletonProps> = (props) => {\n const HostSkeleton = getHostUi<React.FC<SkeletonProps>>('Skeleton')\n if (HostSkeleton) return <HostSkeleton {...props} />\n\n const { variant = 'text', width, height, style, ...rest } = props\n return (\n <div\n aria-hidden=\"true\"\n style={{\n background: '#e5e7eb',\n borderRadius: skeletonRadius[variant],\n width: width ?? (variant === 'text' ? '100%' : undefined),\n height: height ?? (variant === 'text' ? 14 : undefined),\n ...style,\n }}\n {...rest}\n />\n )\n}\nSkeleton.displayName = 'Skeleton'\n\nexport interface SkeletonTextProps {\n lines?: number\n width?: string | number\n lastLineWidth?: string | number\n className?: string\n}\n\n/** SkeletonText — a multi-line text skeleton, delegating to the platform's real one. */\nexport const SkeletonText: React.FC<SkeletonTextProps> = (props) => {\n const HostSkeletonText = getHostUi<React.FC<SkeletonTextProps>>('SkeletonText')\n if (HostSkeletonText) return <HostSkeletonText {...props} />\n\n const { lines = 3, width = '100%', lastLineWidth = '80%', className } = props\n return (\n <div className={className} style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>\n {Array.from({ length: lines }).map((_, index) => (\n <Skeleton key={index} variant=\"text\" width={index === lines - 1 ? lastLineWidth : width} />\n ))}\n </div>\n )\n}\nSkeletonText.displayName = 'SkeletonText'\n\nexport interface SkeletonCardProps {\n hasAvatar?: boolean\n hasActions?: boolean\n className?: string\n}\n\n/** SkeletonCard — a card-shaped skeleton, delegating to the platform's real one. */\nexport const SkeletonCard: React.FC<SkeletonCardProps> = (props) => {\n const HostSkeletonCard = getHostUi<React.FC<SkeletonCardProps>>('SkeletonCard')\n if (HostSkeletonCard) return <HostSkeletonCard {...props} />\n\n const { hasAvatar, hasActions, className } = props\n return (\n <div className={className} style={{ border: '1px solid #e5e7eb', borderRadius: 8, padding: 16 }}>\n <div style={{ display: 'flex', gap: 12 }}>\n {hasAvatar && <Skeleton variant=\"circular\" width={40} height={40} />}\n <div style={{ flex: 1 }}>\n <Skeleton variant=\"text\" width=\"60%\" />\n <div style={{ marginTop: 8 }}>\n <SkeletonText lines={2} />\n </div>\n </div>\n </div>\n {hasActions && (\n <div style={{ display: 'flex', gap: 8, marginTop: 12 }}>\n <Skeleton variant=\"rectangular\" width={72} height={30} />\n <Skeleton variant=\"rectangular\" width={72} height={30} />\n </div>\n )}\n </div>\n )\n}\nSkeletonCard.displayName = 'SkeletonCard'\n\n// ---------------------------------------------------------------------------\n// Tooltip\n// ---------------------------------------------------------------------------\n\nexport type TooltipPlacement = 'top' | 'bottom' | 'left' | 'right'\n\nexport interface TooltipProps {\n content?: React.ReactNode\n placement?: TooltipPlacement\n delayDuration?: number\n disabled?: boolean\n className?: string\n children: React.ReactNode\n}\n\n/**\n * Tooltip — delegates to the platform's real Tooltip at render time. The fallback uses the\n * browser's native `title` attribute (only works when `content` is plain text).\n */\nexport const Tooltip: React.FC<TooltipProps> = (props) => {\n const HostTooltip = getHostUi<React.FC<TooltipProps>>('Tooltip')\n if (HostTooltip) return <HostTooltip {...props} />\n\n const { content, disabled, className, children } = props\n const titleText = typeof content === 'string' ? content : undefined\n if (disabled || !titleText) return <>{children}</>\n return (\n <span className={className} title={titleText} style={{ display: 'inline-flex' }}>\n {children}\n </span>\n )\n}\nTooltip.displayName = 'Tooltip'\n\n// ---------------------------------------------------------------------------\n// Spinner\n// ---------------------------------------------------------------------------\n\nexport type SpinnerSize = 'sm' | 'md' | 'lg'\n\nexport interface SpinnerProps {\n size?: SpinnerSize\n className?: string\n label?: string\n}\n\nconst spinnerDiameter: Record<SpinnerSize, number> = { sm: 16, md: 24, lg: 32 }\n\n/** Spinner — delegates to the platform's real Spinner at render time. */\nexport const Spinner: React.FC<SpinnerProps> = (props) => {\n const HostSpinner = getHostUi<React.FC<SpinnerProps>>('Spinner')\n if (HostSpinner) return <HostSpinner {...props} />\n\n const { size = 'md', className, label } = props\n const diameter = spinnerDiameter[size]\n return (\n <div className={className} role=\"status\" aria-live=\"polite\" style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>\n <div\n aria-hidden=\"true\"\n style={{\n width: diameter,\n height: diameter,\n borderRadius: '50%',\n border: '2px solid currentColor',\n borderTopColor: 'transparent',\n animation: 'vx-sdk-spin 0.8s linear infinite',\n }}\n />\n {label && <p style={{ marginTop: 8, fontSize: 12, color: '#6b7280' }}>{label}</p>}\n <span style={{ position: 'absolute', width: 1, height: 1, overflow: 'hidden', clip: 'rect(0 0 0 0)' }}>{label || 'Loading'}</span>\n <style>{'@keyframes vx-sdk-spin { to { transform: rotate(360deg) } }'}</style>\n </div>\n )\n}\nSpinner.displayName = 'Spinner'\n\n// ---------------------------------------------------------------------------\n// DataTable (generic)\n// ---------------------------------------------------------------------------\n\nexport type DataTableAlign = 'left' | 'center' | 'right'\nexport type DataTableSortOrder = 'asc' | 'desc'\n\nexport interface DataTableSort {\n field: string\n order: DataTableSortOrder\n}\n\nexport interface DataTableColumn<T> {\n key: string\n header: React.ReactNode\n render?: (row: T) => React.ReactNode\n sortable?: boolean\n align?: DataTableAlign\n width?: string\n className?: string\n}\n\nexport interface DataTableEmptyState {\n icon?: React.ReactNode\n title: string\n description?: string\n action?: React.ReactNode\n}\n\nexport interface DataTablePaginationState {\n page: number\n pageSize: number\n total: number\n}\n\nexport interface DataTableProps<T> {\n columns: DataTableColumn<T>[]\n data: T[]\n rowKey: (row: T) => string\n isLoading?: boolean\n emptyState?: DataTableEmptyState\n sort?: DataTableSort\n onSortChange?: (sort: DataTableSort) => void\n pagination?: DataTablePaginationState\n onPageChange?: (page: number) => void\n onRowClick?: (row: T) => void\n rowActions?: (row: T) => React.ReactNode\n className?: string\n}\n\ntype DataTableComponent = (<T>(props: DataTableProps<T>) => React.ReactElement) & { displayName?: string }\n\nfunction FallbackDataTable<T>(props: DataTableProps<T>): React.ReactElement {\n const { columns, data, rowKey, isLoading, emptyState, onRowClick, rowActions, className } = props\n const showEmpty = !isLoading && data.length === 0\n\n return (\n <div className={className} style={fallbackNote}>\n <table style={{ width: '100%', borderCollapse: 'collapse' }}>\n <thead>\n <tr>\n {columns.map((column) => (\n <th key={column.key} style={{ textAlign: column.align ?? 'left', padding: '8px 10px', borderBottom: '1px solid #d1d5db' }}>\n {column.header}\n </th>\n ))}\n {rowActions && <th style={{ padding: '8px 10px', borderBottom: '1px solid #d1d5db' }} />}\n </tr>\n </thead>\n <tbody>\n {isLoading && (\n <tr>\n <td colSpan={Math.max(columns.length + (rowActions ? 1 : 0), 1)} style={{ padding: '12px 10px' }}>\n Loading…\n </td>\n </tr>\n )}\n {showEmpty && (\n <tr>\n <td colSpan={Math.max(columns.length + (rowActions ? 1 : 0), 1)}>\n <EmptyState title={emptyState?.title ?? 'No data'} description={emptyState?.description} icon={emptyState?.icon} action={emptyState?.action} />\n </td>\n </tr>\n )}\n {!isLoading &&\n !showEmpty &&\n data.map((row) => (\n <tr\n key={rowKey(row)}\n onClick={onRowClick ? () => onRowClick(row) : undefined}\n style={{ cursor: onRowClick ? 'pointer' : undefined, borderBottom: '1px solid #e5e7eb' }}\n >\n {columns.map((column) => (\n <td key={column.key} style={{ textAlign: column.align ?? 'left', padding: '8px 10px' }}>\n {column.render ? column.render(row) : String((row as Record<string, unknown>)[column.key] ?? '')}\n </td>\n ))}\n {rowActions && (\n <td style={{ padding: '8px 10px' }} onClick={(event) => event.stopPropagation()}>\n {rowActions(row)}\n </td>\n )}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )\n}\n\n/**\n * DataTable — delegates to the platform's real, server-driven DataTable at render time.\n *\n * @example\n * <DataTable\n * columns={[{ key: 'name', header: 'Name' }, { key: 'deployState', header: 'Status', render: (r) => <Badge>{r.deployState}</Badge> }]}\n * data={indexes}\n * rowKey={(row) => row.id}\n * />\n */\nexport function DataTable<T>(props: DataTableProps<T>): React.ReactElement {\n const HostDataTable = getHostUi<DataTableComponent>('DataTable')\n if (HostDataTable) return <HostDataTable {...props} />\n return <FallbackDataTable {...props} />\n}\n\n// ---------------------------------------------------------------------------\n// StatsCard\n// ---------------------------------------------------------------------------\n\nexport type StatsCardVariant = 'default' | 'primary' | 'success' | 'warning' | 'danger' | 'info'\n\nexport interface StatsCardDelta {\n value: string\n direction: 'up' | 'down' | 'neutral'\n label?: string\n}\n\nexport interface StatsCardProps {\n label: string\n value: React.ReactNode\n icon?: React.ReactNode\n delta?: StatsCardDelta\n variant?: StatsCardVariant\n isLoading?: boolean\n onClick?: () => void\n className?: string\n}\n\nconst DELTA_FALLBACK_COLOR: Record<StatsCardDelta['direction'], string> = {\n up: '#16a34a',\n down: '#dc2626',\n neutral: '#6b7280',\n}\n\n/**\n * StatsCard — delegates to the platform's real StatsCard at render time.\n *\n * @example\n * <StatsCard label=\"Indexes\" value={indexes.length} delta={{ value: '+2', direction: 'up' }} />\n */\nexport const StatsCard: React.FC<StatsCardProps> = (props) => {\n const HostStatsCard = getHostUi<React.FC<StatsCardProps>>('StatsCard')\n if (HostStatsCard) return <HostStatsCard {...props} />\n\n const { label, value, icon, delta, isLoading, onClick, className } = props\n const isClickable = Boolean(onClick)\n\n return (\n <div\n role={isClickable ? 'button' : undefined}\n tabIndex={isClickable ? 0 : undefined}\n onClick={onClick}\n onKeyDown={\n isClickable\n ? (event) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault()\n onClick?.()\n }\n }\n : undefined\n }\n className={className}\n style={{\n ...fallbackNote,\n border: '1px solid #d1d5db',\n borderRadius: 8,\n padding: 16,\n display: 'flex',\n alignItems: 'flex-start',\n justifyContent: 'space-between',\n gap: 12,\n cursor: isClickable ? 'pointer' : undefined,\n }}\n >\n <div style={{ minWidth: 0, flex: 1 }}>\n <p style={{ fontSize: 13, color: '#6b7280', margin: 0 }}>{label}</p>\n <p style={{ fontSize: 28, fontWeight: 700, margin: '4px 0 0' }}>{isLoading ? '…' : value}</p>\n {delta && !isLoading && (\n <p style={{ fontSize: 13, color: DELTA_FALLBACK_COLOR[delta.direction], margin: '4px 0 0' }}>\n {delta.value} {delta.label}\n </p>\n )}\n </div>\n {icon && <div aria-hidden=\"true\">{icon}</div>}\n </div>\n )\n}\nStatsCard.displayName = 'StatsCard'\n\n// ---------------------------------------------------------------------------\n// FormDialog\n// ---------------------------------------------------------------------------\n\nexport type FormDialogSize = 'sm' | 'md' | 'lg'\n\nexport interface FormDialogProps {\n isOpen: boolean\n onClose: () => void\n title: string\n description?: string\n children: React.ReactNode\n onSubmit: () => void | Promise<void>\n submitText?: string\n cancelText?: string\n isSubmitting?: boolean\n error?: string | null\n size?: FormDialogSize\n disableBackdropClose?: boolean\n submitDisabled?: boolean\n}\n\nconst FORM_DIALOG_MAX_WIDTH: Record<FormDialogSize, number> = { sm: 420, md: 520, lg: 680 }\n\n/**\n * FormDialog — delegates to the platform's real FormDialog at render time. The fallback is\n * a minimal, accessible modal shell (role=\"dialog\", Escape-to-close, backdrop click) without\n * the host's focus-trap polish.\n *\n * @example\n * <FormDialog isOpen={isOpen} onClose={close} title=\"Add index\" onSubmit={handleSubmit}>\n * <Input label=\"Name\" value={name} onChange={(e) => setName(e.target.value)} />\n * </FormDialog>\n */\nexport const FormDialog: React.FC<FormDialogProps> = (props) => {\n const HostFormDialog = getHostUi<React.FC<FormDialogProps>>('FormDialog')\n if (HostFormDialog) return <HostFormDialog {...props} />\n\n const {\n isOpen,\n onClose,\n title,\n description,\n children,\n onSubmit,\n submitText = 'Save',\n cancelText = 'Cancel',\n isSubmitting = false,\n error = null,\n size = 'md',\n disableBackdropClose = false,\n submitDisabled = false,\n } = props\n\n React.useEffect(() => {\n if (!isOpen) return\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape' && !isSubmitting) onClose()\n }\n document.addEventListener('keydown', handleKeyDown)\n return () => document.removeEventListener('keydown', handleKeyDown)\n }, [isOpen, isSubmitting, onClose])\n\n if (!isOpen) return null\n\n const requestClose = () => {\n if (!isSubmitting) onClose()\n }\n\n return (\n <div\n style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.5)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 50 }}\n onClick={disableBackdropClose ? undefined : requestClose}\n >\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={title}\n style={{ background: 'white', color: 'black', borderRadius: 8, width: '100%', maxWidth: FORM_DIALOG_MAX_WIDTH[size], maxHeight: '80vh', overflow: 'auto', ...fallbackNote }}\n onClick={(event) => event.stopPropagation()}\n >\n <form\n onSubmit={(event) => {\n event.preventDefault()\n void onSubmit()\n }}\n >\n <div style={{ padding: 16, borderBottom: '1px solid #d1d5db' }}>\n <h3 style={{ margin: 0, fontSize: 16, fontWeight: 600 }}>{title}</h3>\n {description && <p style={{ margin: '4px 0 0', fontSize: 13, color: '#6b7280' }}>{description}</p>}\n </div>\n <div style={{ padding: 16, display: 'flex', flexDirection: 'column', gap: 12 }}>\n {error && (\n <p role=\"alert\" style={{ margin: 0, fontSize: 13, color: '#dc2626' }}>\n {error}\n </p>\n )}\n {children}\n </div>\n <div style={{ padding: 16, borderTop: '1px solid #d1d5db', display: 'flex', justifyContent: 'flex-end', gap: 8 }}>\n <Button type=\"button\" variant=\"secondary\" onClick={requestClose} disabled={isSubmitting}>\n {cancelText}\n </Button>\n <Button type=\"submit\" variant=\"primary\" isLoading={isSubmitting} disabled={submitDisabled}>\n {submitText}\n </Button>\n </div>\n </form>\n </div>\n </div>\n )\n}\nFormDialog.displayName = 'FormDialog'\n\n// ---------------------------------------------------------------------------\n// Modal\n// ---------------------------------------------------------------------------\n\nexport type ModalSize = 'sm' | 'md' | 'lg' | 'xl'\n\nexport interface ModalProps {\n /** Controls visibility. Renders nothing when `false`. */\n isOpen: boolean\n /** Called on backdrop click (unless disabled), Escape, and the X button. */\n onClose: () => void\n /** Heading rendered at the top of the modal. */\n title?: React.ReactNode\n /** Secondary line rendered under the title. */\n subtitle?: React.ReactNode\n /** Modal body. */\n children: React.ReactNode\n /** Optional footer content (e.g. action buttons), rendered in a tinted bar. */\n footer?: React.ReactNode\n size?: ModalSize\n /** When true, clicking the backdrop no longer closes the modal. */\n disableBackdropClose?: boolean\n /** When true, Escape no longer closes the modal. */\n disableEscapeClose?: boolean\n /** Hide the top-right close (X) button. */\n hideCloseButton?: boolean\n /** Accessible label for the close button. Defaults to \"Close\". */\n closeLabel?: string\n className?: string\n}\n\nconst MODAL_MAX_WIDTH: Record<ModalSize, number> = { sm: 420, md: 520, lg: 680, xl: 896 }\n\n/**\n * Modal — delegates to the platform's real Modal at render time: a coordinated\n * overlay shell with a `title` + `subtitle` header, a scrollable body, and an\n * optional `footer` action bar. The general-purpose sibling of {@link FormDialog}\n * (form) and the confirm dialog (yes/no) — use it for detail/wizard/picker\n * overlays. Selects and other popovers rendered inside it float above the body,\n * so their menus are never clipped. The fallback is a minimal, accessible,\n * non-throwing shell for local dev / tests.\n *\n * @example\n * <Modal isOpen={open} onClose={close} title=\"Choose a region\" subtitle=\"Where should this live?\"\n * footer={<Button onClick={close}>Done</Button>}>\n * <Select label=\"Region\" options={regions} value={region} onChange={setRegion} />\n * </Modal>\n */\nexport const Modal: React.FC<ModalProps> = (props) => {\n const HostModal = getHostUi<React.FC<ModalProps>>('Modal')\n if (HostModal) return <HostModal {...props} />\n\n const {\n isOpen,\n onClose,\n title,\n subtitle,\n children,\n footer,\n size = 'md',\n disableBackdropClose = false,\n disableEscapeClose = false,\n hideCloseButton = false,\n closeLabel = 'Close',\n className,\n } = props\n\n React.useEffect(() => {\n if (!isOpen) return\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape' && !disableEscapeClose) onClose()\n }\n document.addEventListener('keydown', handleKeyDown)\n return () => document.removeEventListener('keydown', handleKeyDown)\n }, [isOpen, disableEscapeClose, onClose])\n\n if (!isOpen) return null\n\n const hasHeader = title != null || subtitle != null || !hideCloseButton\n\n return (\n <div\n style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.5)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 50 }}\n onClick={disableBackdropClose ? undefined : onClose}\n >\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n style={{ background: 'white', color: 'black', borderRadius: 8, width: '100%', maxWidth: MODAL_MAX_WIDTH[size], maxHeight: '80vh', overflow: 'auto', ...fallbackNote }}\n className={className}\n onClick={(event) => event.stopPropagation()}\n >\n {hasHeader && (\n <div style={{ padding: 16, borderBottom: '1px solid #d1d5db', display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 16 }}>\n <div style={{ minWidth: 0 }}>\n {title != null && <h3 style={{ margin: 0, fontSize: 16, fontWeight: 600 }}>{title}</h3>}\n {subtitle != null && <p style={{ margin: '4px 0 0', fontSize: 13, color: '#6b7280' }}>{subtitle}</p>}\n </div>\n {!hideCloseButton && (\n <button type=\"button\" onClick={onClose} aria-label={closeLabel} style={{ background: 'none', border: 'none', cursor: 'pointer', fontSize: 18, lineHeight: 1 }}>\n ×\n </button>\n )}\n </div>\n )}\n <div style={{ padding: 16, display: 'flex', flexDirection: 'column', gap: 12 }}>{children}</div>\n {footer != null && (\n <div style={{ padding: 16, borderTop: '1px solid #d1d5db', display: 'flex', justifyContent: 'flex-end', gap: 8 }}>{footer}</div>\n )}\n </div>\n </div>\n )\n}\nModal.displayName = 'Modal'\n\n// ---------------------------------------------------------------------------\n// Alert\n// ---------------------------------------------------------------------------\n\nexport type AlertVariant = 'info' | 'success' | 'warning' | 'danger'\n\nexport interface AlertProps {\n /** Severity — drives color and default icon. Defaults to `info`. */\n variant?: AlertVariant\n /** Optional bold heading above the message. */\n title?: React.ReactNode\n /** The message body. */\n children?: React.ReactNode\n /** Override the default icon, or pass `false` to hide it. */\n icon?: React.ReactNode | false\n /** When provided, renders a dismiss (X) button that calls this. */\n onDismiss?: () => void\n /** Optional trailing action (e.g. a link or button). */\n action?: React.ReactNode\n className?: string\n}\n\nconst ALERT_FALLBACK_COLORS: Record<AlertVariant, { bg: string; fg: string; border: string }> = {\n info: { bg: '#eff6ff', fg: '#1e40af', border: '#93c5fd' },\n success: { bg: '#ecfdf5', fg: '#065f46', border: '#6ee7b7' },\n warning: { bg: '#fffbeb', fg: '#92400e', border: '#fcd34d' },\n danger: { bg: '#fef2f2', fg: '#991b1b', border: '#fca5a5' },\n}\n\n/**\n * Alert — delegates to the platform's real Alert at render time: an inline,\n * static severity banner for warnings, errors, tips and success notices in the\n * page/form body. For transient pop-up notifications use {@link useToast}\n * instead (its `variant` supports the same `warning`/`error`/`success`/`info`).\n * The fallback is a minimal, accessible colored banner for local dev / tests.\n *\n * @example\n * <Alert variant=\"warning\" title=\"Heads up\">\n * Distributed deployments need at least 3 indexers.\n * </Alert>\n */\nexport const Alert: React.FC<AlertProps> = (props) => {\n const HostAlert = getHostUi<React.FC<AlertProps>>('Alert')\n if (HostAlert) return <HostAlert {...props} />\n\n const { variant = 'info', title, children, icon, onDismiss, action, className } = props\n const c = ALERT_FALLBACK_COLORS[variant]\n const role = variant === 'danger' || variant === 'warning' ? 'alert' : 'status'\n\n return (\n <div\n role={role}\n className={className}\n style={{\n display: 'flex',\n alignItems: 'flex-start',\n gap: 10,\n border: `1px solid ${c.border}`,\n background: c.bg,\n color: c.fg,\n borderRadius: 8,\n padding: '12px 16px',\n ...fallbackNote,\n }}\n >\n {icon !== false && icon != null && <span style={{ flexShrink: 0 }}>{icon}</span>}\n <div style={{ minWidth: 0, flex: 1 }}>\n {title != null && <p style={{ margin: 0, fontSize: 14, fontWeight: 600 }}>{title}</p>}\n {children != null && (\n <div style={{ fontSize: 14, marginTop: title != null ? 2 : 0 }}>{children}</div>\n )}\n </div>\n {action != null && <div style={{ flexShrink: 0 }}>{action}</div>}\n {onDismiss && (\n <button\n type=\"button\"\n onClick={onDismiss}\n aria-label=\"Dismiss\"\n style={{ flexShrink: 0, background: 'none', border: 'none', cursor: 'pointer', color: 'inherit', opacity: 0.7 }}\n >\n ×\n </button>\n )}\n </div>\n )\n}\nAlert.displayName = 'Alert'\n\n// ---------------------------------------------------------------------------\n// MultiSelect\n// ---------------------------------------------------------------------------\n\nexport type MultiSelectSize = 'sm' | 'md' | 'lg'\n\nexport interface MultiSelectOption {\n value: string\n label: string\n disabled?: boolean\n}\n\nexport interface MultiSelectProps {\n options: MultiSelectOption[]\n /** Currently selected values. */\n value?: string[]\n /** Called with the new list of selected values. */\n onChange?: (values: string[]) => void\n placeholder?: string\n label?: string\n error?: string\n helperText?: string\n size?: MultiSelectSize\n disabled?: boolean\n fullWidth?: boolean\n /** Show a filter box inside the dropdown. Defaults to true. */\n searchable?: boolean\n /** How many chips to show in the trigger before \"+N more\". Defaults to 3. */\n maxTagCount?: number\n className?: string\n name?: string\n 'aria-label'?: string\n}\n\n/**\n * MultiSelect — delegates to the platform's real searchable multi-selection\n * dropdown at render time (selected values as removable chips, a filter box,\n * select-all / clear). The fallback is a native `<select multiple>` for local\n * dev / tests. Use for any multi-value picker (environments, tags, targets…).\n *\n * @example\n * <MultiSelect label=\"Environments\" value={ids} onChange={setIds}\n * options={envs.map(e => ({ value: e.id, label: e.name }))} />\n */\nexport const MultiSelect: React.FC<MultiSelectProps> = (props) => {\n const HostMultiSelect = getHostUi<React.FC<MultiSelectProps>>('MultiSelect')\n if (HostMultiSelect) return <HostMultiSelect {...props} />\n\n const { options, value = [], onChange, label, disabled, fullWidth = true, name } = props\n return (\n <label style={{ ...fallbackNote, display: 'block', width: fullWidth ? '100%' : undefined }}>\n {label && <span style={{ display: 'block', marginBottom: 4, fontSize: 14, fontWeight: 500 }}>{label}</span>}\n <select\n multiple\n name={name}\n disabled={disabled}\n value={value}\n aria-label={props['aria-label']}\n onChange={(e) => onChange?.(Array.from(e.target.selectedOptions, (o) => o.value))}\n style={{ width: '100%', minHeight: 96, padding: '6px 10px', borderRadius: 6, border: '1px solid #9ca3af' }}\n >\n {options.map((option) => (\n <option key={option.value} value={option.value} disabled={option.disabled}>\n {option.label}\n </option>\n ))}\n </select>\n </label>\n )\n}\nMultiSelect.displayName = 'MultiSelect'\n\n\n//\n// Unlike the components above, these are HOOKS the host backs with real React\n// context (ToastContext / ConfirmationDialogContext), whose providers the\n// platform's root App.tsx mounts around the entire tree — including app\n// pages, since they render inside the host's own React instance. So inside\n// Veltrix these resolve to the real, working implementation with no extra\n// wiring. Outside the platform (no host, or an older host) they degrade to a\n// safe, non-throwing fallback instead of crashing: `toast()` logs to the\n// console and `confirm()` resolves to `false` (fails closed — no destructive\n// action proceeds without an explicit user confirmation the fallback cannot\n// provide).\n// ---------------------------------------------------------------------------\n\nexport type ToastVariant = 'success' | 'error' | 'warning' | 'info'\n\nexport interface ToastOptions {\n variant?: ToastVariant\n duration?: number\n action?: { label: string; onClick: () => void }\n}\n\nexport interface Toast {\n id: string\n message: string\n variant: ToastVariant\n duration?: number\n action?: { label: string; onClick: () => void }\n}\n\nexport interface ToastContextValue {\n toasts: Toast[]\n toast: (message: string, options?: ToastOptions) => string\n success: (message: string, duration?: number) => string\n error: (message: string, duration?: number) => string\n warning: (message: string, duration?: number) => string\n info: (message: string, duration?: number) => string\n promise: <T>(\n promise: Promise<T>,\n messages: { loading: string; success: string | ((data: T) => string); error: string | ((error: unknown) => string) },\n ) => Promise<T>\n dismiss: (id: string) => void\n dismissAll: () => void\n}\n\nfunction fallbackToast(message: string, options?: ToastOptions): string {\n // eslint-disable-next-line no-console -- deliberate: this IS the fallback surface.\n console.warn(`[@veltrixsecops/app-sdk/ui] Toast (${options?.variant ?? 'info'}): ${message}`)\n return 'fallback-toast'\n}\n\nconst fallbackToastContext: ToastContextValue = {\n toasts: [],\n toast: fallbackToast,\n success: (message) => fallbackToast(message, { variant: 'success' }),\n error: (message) => fallbackToast(message, { variant: 'error' }),\n warning: (message) => fallbackToast(message, { variant: 'warning' }),\n info: (message) => fallbackToast(message, { variant: 'info' }),\n promise: (promise) => promise,\n dismiss: () => {},\n dismissAll: () => {},\n}\n\n/**\n * useToast — delegates to the platform's real toast system when running inside Veltrix.\n * Outside it, `toast()`/`success()`/etc. log to the console instead of throwing.\n *\n * @example\n * const toast = useToast()\n * toast.success('Index saved')\n */\nexport function useToast(): ToastContextValue {\n const hostUseToast = getHostUi<() => ToastContextValue>('useToast')\n // eslint-disable-next-line react-hooks/rules-of-hooks -- `hostUseToast` IS the real hook;\n // its presence is fixed for the app's lifetime (the host runtime installs once at boot),\n // so this never actually violates the \"same hooks every render\" invariant in practice.\n if (hostUseToast) return hostUseToast()\n return fallbackToastContext\n}\n\nexport type ConfirmationVariant = 'danger' | 'warning' | 'info'\n\nexport interface ConfirmationOptions {\n title: string\n message: string\n confirmText?: string\n cancelText?: string\n variant?: ConfirmationVariant\n}\n\nexport interface ConfirmationDialogContextValue {\n confirm: (options: ConfirmationOptions) => Promise<boolean>\n}\n\nconst fallbackConfirmationContext: ConfirmationDialogContextValue = {\n confirm: (options) => {\n // eslint-disable-next-line no-console -- deliberate: this IS the fallback surface.\n console.warn(\n `[@veltrixsecops/app-sdk/ui] ConfirmationDialog is only available inside the Veltrix platform — ` +\n `\"${options.title}\" auto-resolved to \"not confirmed\" (fail closed).`,\n )\n return Promise.resolve(false)\n },\n}\n\n/**\n * useConfirmDialog — delegates to the platform's real confirmation dialog when running\n * inside Veltrix. Outside it, `confirm()` resolves to `false` (fails closed) rather than\n * throwing, so a guarded destructive action simply never proceeds instead of crashing.\n *\n * @example\n * const { confirm } = useConfirmDialog()\n * if (await confirm({ title: 'Delete index', message: 'This cannot be undone.', variant: 'danger' })) {\n * await deleteIndex(id)\n * }\n */\nexport function useConfirmDialog(): ConfirmationDialogContextValue {\n const hostUseConfirmDialog = getHostUi<() => ConfirmationDialogContextValue>('useConfirmDialog')\n // eslint-disable-next-line react-hooks/rules-of-hooks -- see useToast's note above.\n if (hostUseConfirmDialog) return hostUseConfirmDialog()\n return fallbackConfirmationContext\n}\n","// ========================================================================\n// Client runtime contract — how app client bundles talk to the host.\n//\n// App client code is packaged as a hermetic ESM bundle in which `react`,\n// `react-dom`, `react/jsx-runtime`, and every `@veltrixsecops/app-sdk`\n// subpath are compile-time shims that read the host-provided runtime from\n// `globalThis.__VELTRIX_APP_RUNTIME__`. The platform installs that global\n// (with ITS React instance, the shared AppContext, and an authenticated\n// fetch) before dynamically importing any app bundle, so app components\n// render inside the host React tree with working hooks and context.\n//\n// App authors: import from '@veltrixsecops/app-sdk/client' (and /hooks) —\n// never bundle your own copy of react. Use `authFetch` for calls to your\n// app's server routes (/api/apps/<app-id>/...): plain fetch() lacks the\n// platform's Authorization header and will receive 401s.\n// ========================================================================\n\nimport type { ComponentType, Context, LazyExoticComponent } from 'react'\nimport type { AppContextValue } from '../hooks/use-app-context'\nimport type { AppPermissionsApi } from '../types/platform'\n\nexport type { AppBrandingDeclaration } from '../types/manifest'\nexport type { AppPermissionsApi, PermissionEntry, PermissionCheckOptions } from '../types/platform'\n\n// Inventory — typed helpers over the platform's components API (deployment\n// targets: servers, domains, IP/CIDR ranges). Framework-free; they use the\n// `authFetch` exported below internally.\nexport {\n listInventory,\n addInventoryItem,\n updateInventoryItem,\n removeInventoryItem,\n resolveTool,\n} from './inventory'\nexport type { Tool } from './inventory'\nexport type { InventoryItem, InventoryItemInput } from '../types/platform'\n\n// Connectivity providers — reader over the customer's ZTNA providers, used to\n// populate the Access Server link picker. Framework-free; uses `authFetch`.\nexport { listConnectivityProviders } from './connectivity'\nexport type { ConnectivityProviderRef } from '../types/platform'\n\n// Environments — reader over the customer's deployment scopes, used to populate\n// the Environment picker on Connections + Access Servers. Framework-free.\nexport { listEnvironments } from './environments'\nexport type { EnvironmentRef } from '../types/pipeline'\n\n// Credentials — typed helpers over the platform's credentials API. Paired with\n// a server (component) these form a \"connection\". Secrets are write-only:\n// `listCredentials` returns redacted summaries only. Framework-free; they use\n// the `authFetch` exported below internally.\nexport {\n listCredentials,\n createCredential,\n updateCredential,\n removeCredential,\n testConnection,\n runOperation,\n} from './credentials'\nexport type { Credential, CredentialSummary, CredentialInput } from '../types/platform'\nexport type { TestConnectionResult } from '../types/pipeline'\nexport type { OperationResult } from './credentials'\n\n// Connection onboarding — the one-click \"Connect …\" flow (consent + broker).\n// Framework-free; uses `authFetch`.\nexport { startOnboarding, getOnboardingStatus, revokeOnboarding, fetchAppOnboarding } from './onboarding'\nexport type {\n StartOnboardingInput,\n StartOnboardingResult,\n OnboardingStatus,\n AppOnboardingDescriptor,\n} from './onboarding'\n\n/** Name of the global the platform installs before loading app bundles. */\nexport const HOST_RUNTIME_GLOBAL = '__VELTRIX_APP_RUNTIME__'\n\n/**\n * The runtime surface the platform exposes to app client bundles.\n * The react/reactDom/jsxRuntime members are the host's own module objects —\n * app bundles are compiled with shims that re-export them, guaranteeing a\n * single React instance per page.\n */\nexport interface VeltrixHostRuntime {\n /** The host's `react` module object. */\n react: unknown\n /** The host's `react-dom` module object. */\n reactDom: unknown\n /** The host's `react-dom/client` module object. */\n reactDomClient?: unknown\n /** The host's `react/jsx-runtime` module object. */\n jsxRuntime: unknown\n /** Shared app context — the host wraps app pages in its Provider. */\n AppContext: Context<AppContextValue | null>\n /** fetch() with the platform's Authorization header attached. */\n authFetch: (input: string, init?: RequestInit) => Promise<Response>\n /**\n * The SDK surface app bundles receive for `@veltrixsecops/app-sdk`,\n * `.../hooks`, and `.../client` imports (useAppContext, AppContext,\n * usePipelineStatus, authFetch, getHostRuntime, ...).\n */\n sdk: Record<string, unknown>\n /**\n * The platform's design-system components and hooks, host-owned so they\n * share the single host React instance. Keyed by the exact component/hook\n * names re-exported from `@veltrixsecops/app-sdk/ui` (Button, Input, Card,\n * DataTable, useToast, ...). Present only inside the platform.\n */\n ui?: Record<string, unknown>\n /**\n * Platform-scoped permission checks (RBAC/IdP hardening, Wave C4) —\n * `opts.appId` is NOT defaulted here (omit for a platform-scoped check).\n * App page code should prefer `usePermissions()`\n * (`@veltrixsecops/app-sdk/hooks`), which defaults `opts.appId` to the\n * app's own id. Optional for compatibility with a host that hasn't\n * deployed this surface yet.\n */\n permissions?: AppPermissionsApi\n}\n\n/** Read the host runtime, or null outside the platform (tests, storybook). */\nexport function getHostRuntime(): VeltrixHostRuntime | null {\n const runtime = (globalThis as Record<string, unknown>)[HOST_RUNTIME_GLOBAL]\n return (runtime as VeltrixHostRuntime) ?? null\n}\n\n/** Read the host runtime, throwing a diagnosable error when absent. */\nexport function requireHostRuntime(): VeltrixHostRuntime {\n const runtime = getHostRuntime()\n if (!runtime) {\n throw new Error(\n 'Veltrix host runtime not found — app client bundles only run inside the ' +\n `Veltrix platform (missing globalThis.${HOST_RUNTIME_GLOBAL})`,\n )\n }\n return runtime\n}\n\n/**\n * fetch() that carries the platform's Authorization header. Required for an\n * app page to call its own server routes (/api/apps/<app-id>/...), which are\n * bearer-token protected. Falls back to plain fetch outside the platform.\n */\nexport function authFetch(input: string, init?: RequestInit): Promise<Response> {\n const runtime = getHostRuntime()\n if (runtime) return runtime.authFetch(input, init)\n return fetch(input, init)\n}\n\n/** A sidebar entry contributed by the app's client entry module. */\nexport interface AppSidebarItem {\n path: string\n label: string\n icon?: string\n}\n\n/**\n * Shape of the default export of an app's `client/index.tsx`.\n * `pages` keys must match `manifest.client.pages[].component`.\n */\nexport interface AppClientModule {\n id: string\n pages: Record<string, ComponentType | LazyExoticComponent<ComponentType>>\n sidebarItems?: AppSidebarItem[]\n}\n"],"mappings":"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","names":[]}
@@ -452,6 +452,114 @@ interface FormDialogProps {
452
452
  * </FormDialog>
453
453
  */
454
454
  declare const FormDialog: React.FC<FormDialogProps>;
455
+ type ModalSize = 'sm' | 'md' | 'lg' | 'xl';
456
+ interface ModalProps {
457
+ /** Controls visibility. Renders nothing when `false`. */
458
+ isOpen: boolean;
459
+ /** Called on backdrop click (unless disabled), Escape, and the X button. */
460
+ onClose: () => void;
461
+ /** Heading rendered at the top of the modal. */
462
+ title?: React.ReactNode;
463
+ /** Secondary line rendered under the title. */
464
+ subtitle?: React.ReactNode;
465
+ /** Modal body. */
466
+ children: React.ReactNode;
467
+ /** Optional footer content (e.g. action buttons), rendered in a tinted bar. */
468
+ footer?: React.ReactNode;
469
+ size?: ModalSize;
470
+ /** When true, clicking the backdrop no longer closes the modal. */
471
+ disableBackdropClose?: boolean;
472
+ /** When true, Escape no longer closes the modal. */
473
+ disableEscapeClose?: boolean;
474
+ /** Hide the top-right close (X) button. */
475
+ hideCloseButton?: boolean;
476
+ /** Accessible label for the close button. Defaults to "Close". */
477
+ closeLabel?: string;
478
+ className?: string;
479
+ }
480
+ /**
481
+ * Modal — delegates to the platform's real Modal at render time: a coordinated
482
+ * overlay shell with a `title` + `subtitle` header, a scrollable body, and an
483
+ * optional `footer` action bar. The general-purpose sibling of {@link FormDialog}
484
+ * (form) and the confirm dialog (yes/no) — use it for detail/wizard/picker
485
+ * overlays. Selects and other popovers rendered inside it float above the body,
486
+ * so their menus are never clipped. The fallback is a minimal, accessible,
487
+ * non-throwing shell for local dev / tests.
488
+ *
489
+ * @example
490
+ * <Modal isOpen={open} onClose={close} title="Choose a region" subtitle="Where should this live?"
491
+ * footer={<Button onClick={close}>Done</Button>}>
492
+ * <Select label="Region" options={regions} value={region} onChange={setRegion} />
493
+ * </Modal>
494
+ */
495
+ declare const Modal: React.FC<ModalProps>;
496
+ type AlertVariant = 'info' | 'success' | 'warning' | 'danger';
497
+ interface AlertProps {
498
+ /** Severity — drives color and default icon. Defaults to `info`. */
499
+ variant?: AlertVariant;
500
+ /** Optional bold heading above the message. */
501
+ title?: React.ReactNode;
502
+ /** The message body. */
503
+ children?: React.ReactNode;
504
+ /** Override the default icon, or pass `false` to hide it. */
505
+ icon?: React.ReactNode | false;
506
+ /** When provided, renders a dismiss (X) button that calls this. */
507
+ onDismiss?: () => void;
508
+ /** Optional trailing action (e.g. a link or button). */
509
+ action?: React.ReactNode;
510
+ className?: string;
511
+ }
512
+ /**
513
+ * Alert — delegates to the platform's real Alert at render time: an inline,
514
+ * static severity banner for warnings, errors, tips and success notices in the
515
+ * page/form body. For transient pop-up notifications use {@link useToast}
516
+ * instead (its `variant` supports the same `warning`/`error`/`success`/`info`).
517
+ * The fallback is a minimal, accessible colored banner for local dev / tests.
518
+ *
519
+ * @example
520
+ * <Alert variant="warning" title="Heads up">
521
+ * Distributed deployments need at least 3 indexers.
522
+ * </Alert>
523
+ */
524
+ declare const Alert: React.FC<AlertProps>;
525
+ type MultiSelectSize = 'sm' | 'md' | 'lg';
526
+ interface MultiSelectOption {
527
+ value: string;
528
+ label: string;
529
+ disabled?: boolean;
530
+ }
531
+ interface MultiSelectProps {
532
+ options: MultiSelectOption[];
533
+ /** Currently selected values. */
534
+ value?: string[];
535
+ /** Called with the new list of selected values. */
536
+ onChange?: (values: string[]) => void;
537
+ placeholder?: string;
538
+ label?: string;
539
+ error?: string;
540
+ helperText?: string;
541
+ size?: MultiSelectSize;
542
+ disabled?: boolean;
543
+ fullWidth?: boolean;
544
+ /** Show a filter box inside the dropdown. Defaults to true. */
545
+ searchable?: boolean;
546
+ /** How many chips to show in the trigger before "+N more". Defaults to 3. */
547
+ maxTagCount?: number;
548
+ className?: string;
549
+ name?: string;
550
+ 'aria-label'?: string;
551
+ }
552
+ /**
553
+ * MultiSelect — delegates to the platform's real searchable multi-selection
554
+ * dropdown at render time (selected values as removable chips, a filter box,
555
+ * select-all / clear). The fallback is a native `<select multiple>` for local
556
+ * dev / tests. Use for any multi-value picker (environments, tags, targets…).
557
+ *
558
+ * @example
559
+ * <MultiSelect label="Environments" value={ids} onChange={setIds}
560
+ * options={envs.map(e => ({ value: e.id, label: e.name }))} />
561
+ */
562
+ declare const MultiSelect: React.FC<MultiSelectProps>;
455
563
  type ToastVariant = 'success' | 'error' | 'warning' | 'info';
456
564
  interface ToastOptions {
457
565
  variant?: ToastVariant;
@@ -519,4 +627,4 @@ interface ConfirmationDialogContextValue {
519
627
  */
520
628
  declare function useConfirmDialog(): ConfirmationDialogContextValue;
521
629
 
522
- export { Badge, type BadgeProps, type BadgeSize, type BadgeVariant, Button, type ButtonProps, type ButtonSize, type ButtonVariant, Card, CardBody, type CardBodyProps, CardFooter, type CardFooterProps, CardHeader, type CardHeaderProps, type CardProps, Checkbox, type CheckboxProps, type ConfirmationDialogContextValue, type ConfirmationOptions, type ConfirmationVariant, DataTable, type DataTableAlign, type DataTableColumn, type DataTableEmptyState, type DataTablePaginationState, type DataTableProps, type DataTableSort, type DataTableSortOrder, EmptyState, type EmptyStateProps, FilterBar, type FilterBarProps, type FilterBarSearchProps, type FilterDefinition, type FilterOption, FormDialog, type FormDialogProps, type FormDialogSize, FormField, type FormFieldProps, Input, type InputProps, type InputSize, type InputVariant, Pagination, type PaginationProps, SearchBox, type SearchBoxProps, type SearchBoxSize, Select, type SelectOption, type SelectProps, type SelectSize, Skeleton, SkeletonCard, type SkeletonCardProps, type SkeletonProps, SkeletonText, type SkeletonTextProps, type SkeletonVariant, type SortDirection, type SortOption, SortSelect, type SortSelectProps, Spinner, type SpinnerProps, type SpinnerSize, StatsCard, type StatsCardDelta, type StatsCardProps, type StatsCardVariant, type TabItem, Tabs, type TabsProps, Textarea, type TextareaProps, type Toast, type ToastContextValue, type ToastOptions, type ToastVariant, Tooltip, type TooltipPlacement, type TooltipProps, useConfirmDialog, useToast };
630
+ export { Alert, type AlertProps, type AlertVariant, Badge, type BadgeProps, type BadgeSize, type BadgeVariant, Button, type ButtonProps, type ButtonSize, type ButtonVariant, Card, CardBody, type CardBodyProps, CardFooter, type CardFooterProps, CardHeader, type CardHeaderProps, type CardProps, Checkbox, type CheckboxProps, type ConfirmationDialogContextValue, type ConfirmationOptions, type ConfirmationVariant, DataTable, type DataTableAlign, type DataTableColumn, type DataTableEmptyState, type DataTablePaginationState, type DataTableProps, type DataTableSort, type DataTableSortOrder, EmptyState, type EmptyStateProps, FilterBar, type FilterBarProps, type FilterBarSearchProps, type FilterDefinition, type FilterOption, FormDialog, type FormDialogProps, type FormDialogSize, FormField, type FormFieldProps, Input, type InputProps, type InputSize, type InputVariant, Modal, type ModalProps, type ModalSize, MultiSelect, type MultiSelectOption, type MultiSelectProps, type MultiSelectSize, Pagination, type PaginationProps, SearchBox, type SearchBoxProps, type SearchBoxSize, Select, type SelectOption, type SelectProps, type SelectSize, Skeleton, SkeletonCard, type SkeletonCardProps, type SkeletonProps, SkeletonText, type SkeletonTextProps, type SkeletonVariant, type SortDirection, type SortOption, SortSelect, type SortSelectProps, Spinner, type SpinnerProps, type SpinnerSize, StatsCard, type StatsCardDelta, type StatsCardProps, type StatsCardVariant, type TabItem, Tabs, type TabsProps, Textarea, type TextareaProps, type Toast, type ToastContextValue, type ToastOptions, type ToastVariant, Tooltip, type TooltipPlacement, type TooltipProps, useConfirmDialog, useToast };