@opencxh/ui-kit 3.166.0 → 3.175.1

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.
@@ -1,4 +1,4 @@
1
- import { InternalSDK } from '@opencxh/domain';
1
+ import { InvokeOptions } from '@opencxh/domain';
2
2
  import { default as React } from 'react';
3
3
  export type FormFieldType = "text" | "email" | "password" | "number" | "tel" | "url" | "color" | "textarea" | "select" | "segmented" | "checkbox" | "radio" | "date" | "file" | "folder" | "custom" | "array";
4
4
  /**
@@ -148,6 +148,15 @@ export interface FormButtonProps {
148
148
  /** Additional CSS classes */
149
149
  className?: string;
150
150
  }
151
+ /**
152
+ * The sliver of an app SDK that `Form` needs: one call to the server. Nothing here knows
153
+ * about the rest of the SDK, which is the point.
154
+ */
155
+ export interface FormInvoker {
156
+ http: {
157
+ invoke<T = any>(options: InvokeOptions): Promise<T>;
158
+ };
159
+ }
151
160
  export interface FormProps<T = Record<string, any>> {
152
161
  /** Form groups */
153
162
  groups: FormGroup<T>[];
@@ -184,7 +193,16 @@ export interface FormProps<T = Record<string, any>> {
184
193
  */
185
194
  ref?: React.RefObject<HTMLFormElement | null>;
186
195
  /** SDK instance */
187
- sdk?: InternalSDK<any>;
196
+ /**
197
+ * A handle that can call the server, for the storage fields (`storage`, `folder`).
198
+ *
199
+ * Typed as the one method used rather than as the whole `InternalSDK`. That type moved
200
+ * to `@opencxh/app-sdk` — it is that package's promise, not part of the vocabulary —
201
+ * and ui-kit has no dependency on it, nor should it need one to render a form. Asking
202
+ * for what it uses also keeps the storage fields' eventual move out of here (they are
203
+ * slated to become a federated resource) from being blocked by a type import.
204
+ */
205
+ sdk?: FormInvoker;
188
206
  }
189
207
  /**
190
208
  * Generic Form component with groups, validation, and conditional rendering
@@ -23,7 +23,7 @@ export { Switch, type SwitchProps } from './input/Switch';
23
23
  export { StorageInput, type StorageInputProps } from './input/StorageInput';
24
24
  export { TextArea, type TextAreaProps } from './input/TextArea';
25
25
  export { TextField, type TextFieldProps } from './input/TextField';
26
- export { Form, FormSection, type FormButtonProps, type FormFieldType, type FormGroup, type FormGroupItem, type FormProps } from './forms/Form';
26
+ export { Form, FormSection, type FormButtonProps, type FormFieldType, type FormGroup, type FormGroupItem, type FormInvoker, type FormProps } from './forms/Form';
27
27
  export { autofillProps, type AutofillProps } from './forms/autofill';
28
28
  export { Dropdown, type DropdownOption, type DropdownProps } from './overlays/Dropdown';
29
29
  export { ConfirmDialog, type ConfirmDialogProps } from './overlays/ConfirmDialog';
@@ -1,12 +1,39 @@
1
1
  import { ReactNode } from 'react';
2
2
  export interface MeetingGridProps {
3
3
  tiles: ReactNode[];
4
+ /**
5
+ * De tegel die het vlak krijgt — de dominante spreker, of de tegenpartij in een
6
+ * 1-op-1. De rest komt als strip eronder te staan.
7
+ */
4
8
  pinned?: ReactNode;
9
+ /**
10
+ * Hoeveel striptegels er hoogstens naast elkaar mogen. Wat er overblijft wordt één
11
+ * `+N`-tegel. Zonder dit past een vergadering van twaalf mensen zich in een dock van
12
+ * 448px in twaalf onleesbare streepjes, en dat is geen weergave meer maar een rij.
13
+ */
14
+ maxStrip?: number;
5
15
  className?: string;
6
16
  }
17
+ export declare function columnsFor(count: number): string;
7
18
  /**
8
19
  * Layout primitive for meeting views. When `pinned` is provided it gets the
9
- * dominant area and remaining tiles render in a sidebar/strip. Otherwise tiles
20
+ * dominant area and remaining tiles render in a strip underneath. Otherwise tiles
10
21
  * flow in an auto-sized grid.
22
+ *
23
+ * **Het vlak bepaalt de tegels, niet andersom.** Elke cel is `min-w-0 min-h-0` en de rijen
24
+ * delen de hoogte (`auto-rows-fr`), zodat het raster past in de doos die het krijgt. Geef de
25
+ * tegels daarom `fill` mee: een tegel die zijn hoogte uit zijn eigen breedte haalt
26
+ * (`aspect-video`, de standaard) duwt het raster buiten zijn oevers zodra het vlak lager is
27
+ * dan die verhouding — precies wat er in de dock gebeurde.
11
28
  */
12
- export declare function MeetingGrid({ tiles, pinned, className }: MeetingGridProps): import("react").JSX.Element;
29
+ /**
30
+ * Hoeveel striptegels er getoond worden, en hoeveel er als `+N` overblijven.
31
+ *
32
+ * De teller neemt zelf een plek in — anders vervangt hij één tegel door de mededeling dat er
33
+ * één tegel weg is, en dat is geen winst. Bij precies genoeg ruimte blijft hij dus weg.
34
+ */
35
+ export declare function splitStrip(count: number, maxStrip?: number): {
36
+ shown: number;
37
+ hidden: number;
38
+ };
39
+ export declare function MeetingGrid({ tiles, pinned, maxStrip, className }: MeetingGridProps): import("react").JSX.Element;
@@ -19,5 +19,15 @@ export interface ParticipantTileProps {
19
19
  * Provider-agnostic participant tile. Shows avatar + name when no video is
20
20
  * available; otherwise renders the `videoSlot` passed by the caller (typically
21
21
  * a <VideoSurface /> wired to a provider-specific stream renderer).
22
+ *
23
+ * **Alles binnenin schaalt met de tegel, niet met het venster.** De tegel is zelf een
24
+ * container (`@container`), zodat de avatar een percentage van zijn eigen breedte kan zijn en
25
+ * de naam pas verschijnt als er plek voor is. Dat is het verschil tussen een gesprek in de
26
+ * hoek-dock en hetzelfde gesprek in theater-modus: dezelfde component, twee maten, en de
27
+ * viewport-breakpoints van Tailwind (`md:`) zeggen daar niets zinnigs over — die kijken naar
28
+ * het scherm, terwijl de tegel 120px breed kan zijn op een 4K-monitor.
29
+ *
30
+ * Vaste maten stonden hier eerder wél: een avatar van 64px en een naamlabel met `max-w-35`.
31
+ * In een striptegel van 90px was de avatar breder dan de tegel en dekte het label hem af.
22
32
  */
23
33
  export declare function ParticipantTile({ name, avatarUrl, muted, speaking, hasVideo, videoSlot, className, fill, }: ParticipantTileProps): import("react").JSX.Element;
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opencxh/ui-kit",
3
- "version": "3.166.0",
3
+ "version": "3.175.1",
4
4
  "description": "Theme-aware UI component library for OpenCXH platform",
5
5
  "type": "module",
6
6
  "exports": {
@@ -37,6 +37,9 @@
37
37
  "remark-gfm": "^4.0.1"
38
38
  },
39
39
  "devDependencies": {
40
+ "@testing-library/jest-dom": "^6.6.3",
41
+ "@testing-library/react": "^16.3.0",
42
+ "@testing-library/user-event": "^14.6.1",
40
43
  "@types/react": "^19.1.8",
41
44
  "@types/react-dom": "^19.2.3",
42
45
  "@typescript-eslint/eslint-plugin": "^8.15.0",
@@ -45,10 +48,11 @@
45
48
  "eslint": "^9.15.0",
46
49
  "eslint-plugin-react": "^7.37.2",
47
50
  "eslint-plugin-react-hooks": "^5.0.0",
51
+ "jsdom": "^26.1.0",
48
52
  "typescript": "6.0.3",
49
53
  "vite": "7.1.7",
50
54
  "vite-plugin-dts": "^5.0.3",
51
- "vitest": "^2.1.8"
55
+ "vitest": "^4.0.18"
52
56
  },
53
57
  "peerDependencies": {
54
58
  "react": ">=19.2.4",