@svadmin/lite 0.8.0 → 0.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -13,7 +13,7 @@ The main `@svadmin/ui` package delivers a premium SPA experience using Svelte 5,
13
13
  **What Lite is:**
14
14
  - A **Zero-JS SSR-first admin component suite** designed with an IE11-safe CSS baseline.
15
15
  - 100% interoperable with `@svadmin/core` — sharing the same `DataProvider`, `AuthProvider`, `Resource`, and `FieldDefinition` contracts.
16
- - An architectural companion to `@svadmin/ui` achieving **100% component parity (72/72 components)** through 1:1 server-rendered matches or deliberate semantic fallbacks.
16
+ - An architectural companion to `@svadmin/ui` achieving **100% component parity (103/103 components)** through 1:1 server-rendered matches, deliberate semantic fallbacks, or explicit SPA-only classification.
17
17
  - **Not** a generic Tailwind-to-IE11 compiler or a full client-side port of shadcn-svelte (which depends on modern browser JS runtimes and CSS custom properties).
18
18
 
19
19
  `@svadmin/lite` provides a server-rendered fallback that **shares the same DataProvider, AuthProvider, and Resource definitions** — only the rendering layer is different.
@@ -246,7 +246,7 @@ IE11 before the decision is made.
246
246
 
247
247
  ## Components & Parity (100% Coverage)
248
248
 
249
- `@svadmin/lite` provides **100% component parity** (72/72 components) corresponding to `@svadmin/ui`. See [PARITY.md](./PARITY.md) for the complete matrix.
249
+ `@svadmin/lite` provides **100% component parity** (103/103 components) corresponding to `@svadmin/ui`. See [PARITY.md](./PARITY.md) for the generated complete matrix and status details.
250
250
 
251
251
  ### Core Pages & Layout
252
252
 
@@ -257,6 +257,9 @@ IE11 before the decision is made.
257
257
  | `LiteListPage` | Full-featured list view with search, table, bulk actions, and pagination |
258
258
  | `LiteCreatePage` / `LiteEditPage` | Auto-generated CRUD form pages |
259
259
  | `LiteShowPage` | Key-value record view with typed field renderers |
260
+ | `LiteMasterDetailView` | URL-synchronized master/detail workspace |
261
+ | `LitePrintableBill` | Controlled A4-style printable business record |
262
+ | `LitePdfDocumentViewer` | Embedded PDF review with document stamp and annotation support |
260
263
  | `LiteProfilePage` | User profile management page with avatar and info |
261
264
  | `LiteRegisterPage` | User registration page with server-side validation |
262
265
  | `LiteForgotPasswordPage` / `LiteUpdatePasswordPage` | Password recovery and credential rotation flows |
@@ -266,14 +269,17 @@ IE11 before the decision is made.
266
269
  | `LitePagination` / `LiteSearch` | URL-driven pagination and GET search controls |
267
270
  | `LiteAlert` | Inline notification banner for success/error/warning states |
268
271
  | `LiteBreadcrumbs` / `LiteTabs` / `LiteEmptyState` | Semantic navigation and placeholder primitives |
272
+ | `LiteCanAccess` / `LiteErrorBoundary` | Server-side access gate and constrained-environment error boundary |
273
+ | `LiteSplitPaneLayout` / `LiteMultiTabKeepAlive` | Dense two-pane layouts and multi-workspace navigation |
269
274
 
270
- ### Field Components (23 Fields)
275
+ ### Field Components (33 Fields)
271
276
 
272
277
  | Category | Components |
273
278
  |----------|------------|
274
279
  | **Text & Numeric** | `LiteTextField`, `LiteNumberField`, `LiteCurrencyField`, `LitePercentField`, `LitePhoneField`, `LiteEmailField`, `LiteUrlField`, `LiteRatingField`, `LiteCopyField` |
275
280
  | **Date & Choice** | `LiteDateField`, `LiteDateRangeField`, `LiteBooleanField`, `LiteSelectField`, `LiteMultiSelectField`, `LiteTreeSelect`, `LiteCascader`, `LiteTagField`, `LiteRelationField` |
276
- | **Media & Rich & Array** | `LiteAvatarField`, `LiteImageField`, `LiteFileField`, `LiteCodeField`, `LiteMarkdownField`, `LiteRichTextField`, `LiteJsonField`, `LiteArrayField`, `LiteDynamicFormList`, `LiteTransfer` |
281
+ | **Media & Rich & Array** | `LiteAvatarField`, `LiteImageField`, `LiteFileField`, `LiteCodeField`, `LiteMarkdownField`, `LiteRichTextField`, `LiteJsonField`, `LiteArrayField`, `LiteDynamicFormList`, `LiteTransfer`, `LiteImageCropper`, `LiteJsonSchemaForm`, `LiteMentionsInput`, `LiteSignaturePad` |
282
+ | **SPA-only** | `VoiceInput` (Web Speech API; no SSR counterpart) |
277
283
 
278
284
  ### Action Buttons (10 Buttons)
279
285
 
@@ -289,6 +295,7 @@ IE11 before the decision is made.
289
295
  |-----------|-------------|
290
296
  | `LiteStatsCard`, `LiteInsightCard`, `LiteAnomalyBadge` | Metric KPI cards and status badges |
291
297
  | `LiteBarChart`, `LiteLineChart`, `LitePieChart` | Server-rendered SVG/HTML charts with fallback data tables |
298
+ | `LitePresenceAvatarGroup`, `LiteGanttChart`, `LiteOfflineSyncBanner` | Presence, schedule, and offline mutation status rendered without client hydration |
292
299
 
293
300
  ### Compatibility & Degradation Primitives
294
301
 
@@ -308,6 +315,12 @@ IE11 before the decision is made.
308
315
  | `LiteDraggableHeader` | Static column header with URL sorter links |
309
316
  | `LiteToast` / `LiteUndoableNotification` | Server-driven flash messages and undo actions |
310
317
  | `LiteFilterBuilder` | Native multi-rule CRUD filter builder with AND/OR logical operators |
318
+ | `LiteConfirmDialog`, `LiteWatermark`, `LiteColumnSettings`, `LiteImportWizard` | Server-safe confirmation, watermark, column, and import workflows |
319
+ | `LiteColumnHeaderFilter`, `LiteTreeTable`, `LiteSensitiveDataMask`, `LiteApprovalActionCard` | Query, hierarchy, masking, and approval fallbacks |
320
+ | `LiteStepForm`, `LiteTableSummary`, `LiteVersionDiffViewer`, `LiteEditableTable`, `LiteDraggableRowTable` | Server-driven enterprise data interaction components |
321
+ | `LiteMediaLibraryModal`, `LiteActivityFeed`, `LiteKanbanBoard`, `LitePivotTable` | Media, activity, workflow, and analysis views |
322
+ | `LiteCanvasAnnotation`, `LiteSpreadsheetView`, `LiteDecisionTable` | SSR-compatible annotation, spreadsheet, and rules views |
323
+ | `DevTools`, `CopilotPanel` | SPA-only components with no Lite counterpart |
311
324
 
312
325
  ## Parity Tracking & Visualization
313
326
 
@@ -316,7 +329,7 @@ To monitor and maintain 100% component parity between `@svadmin/ui` and `@svadmi
316
329
  - **CLI Dashboard**: Run `bun run check:parity` to inspect the live coverage matrix in terminal.
317
330
  - **Parity Matrix Document**: [PARITY.md](./PARITY.md) is auto-generated with exhaustive module-by-module tables.
318
331
  - **Machine-Readable JSON**: `packages/lite/parity.json` provides structured data for automation.
319
- - **Interactive Showroom**: Visit `/lite/parity` in the example app to interactively preview all 72 components and live metrics.
332
+ - **Interactive Showroom**: Visit `/lite/parity` in the example app to interactively preview all 103 components and live metrics.
320
333
  - **CI Contract Test**: `scripts/parity-contract.test.ts` runs in CI to prevent regression and ensure every new UI component has a documented Lite counterpart.
321
334
 
322
335
  ## Server Utilities
@@ -329,7 +342,9 @@ To monitor and maintain 100% component parity between `@svadmin/ui` and `@svadmi
329
342
  | `createAuthGuard(authProvider)` | Server hook for authentication |
330
343
  | `createAuthActions(authProvider)` | Login/logout actions plus optional provider-delegating account actions |
331
344
  | `createLegacyRedirectHook()` | Auto-redirect IE11 to `/lite/` |
332
- | `fieldsToTypeBoxSchema(fields)` | Generate the TypeBox schema used by Lite actions or other consumers (with `fieldsToZodSchema` alias) |
345
+ | `fieldsToTypeBoxSchema(fields)` | Generate the TypeBox schema used by Lite actions or other consumers |
346
+
347
+ Schema generation is TypeBox-only. The former Zod-named exports and parser-compatible methods were removed; use `Check`, `Errors`, and `Decode` on the returned schema.
333
348
 
334
349
  ## CSS
335
350
 
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@ export { createListLoader, createDetailLoader, createCrudActions, createAuthGuar
2
2
  export type { LegacyRedirectOptions, ListLoaderResult } from './server-adapter';
3
3
  export { LITE_COMPATIBILITY_CATALOG, detectLiteCapabilities, resolveLiteCompatibility, } from './compatibility';
4
4
  export type { LiteCapability, LiteCapabilitySupport, LiteCompatibilityDescriptor, LiteCompatibilityResolution, LiteFallbackKind, } from './compatibility';
5
- export { fieldsToTypeBoxSchema, resourceToTypeBoxSchema, fieldsToZodSchema, resourceToZodSchema, fieldToInputType, fieldToPlaceholder, } from './schema-generator';
5
+ export { fieldsToTypeBoxSchema, resourceToTypeBoxSchema, fieldToInputType, fieldToPlaceholder, } from './schema-generator';
6
6
  export { getStatusBadgeClass, parseExplicitBoolean, isExplicitBooleanTrue } from './value-normalization';
7
7
  export { default as LiteLayout } from './components/LiteLayout.svelte';
8
8
  export { default as LiteTable } from './components/LiteTable.svelte';
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ export { createListLoader, createDetailLoader, createCrudActions, createAuthGuar
5
5
  // Optional browser capabilities. The SSR baseline does not import browser globals.
6
6
  export { LITE_COMPATIBILITY_CATALOG, detectLiteCapabilities, resolveLiteCompatibility, } from './compatibility';
7
7
  // Schema generator (TypeBox schemas used by Lite actions and client forms)
8
- export { fieldsToTypeBoxSchema, resourceToTypeBoxSchema, fieldsToZodSchema, resourceToZodSchema, fieldToInputType, fieldToPlaceholder, } from './schema-generator';
8
+ export { fieldsToTypeBoxSchema, resourceToTypeBoxSchema, fieldToInputType, fieldToPlaceholder, } from './schema-generator';
9
9
  // UI Components (use in +page.svelte with csr = false)
10
10
  export { getStatusBadgeClass, parseExplicitBoolean, isExplicitBooleanTrue } from './value-normalization';
11
11
  export { default as LiteLayout } from './components/LiteLayout.svelte';
@@ -10,33 +10,14 @@ export interface SchemaValidationIssue {
10
10
  path: (string | number)[];
11
11
  message: string;
12
12
  }
13
- export type SchemaValidationResult<T = Record<string, unknown>> = {
14
- success: true;
15
- data: T;
16
- error?: never;
17
- } | {
18
- success: false;
19
- error: {
20
- issues: SchemaValidationIssue[];
21
- };
22
- data?: never;
23
- };
13
+ export interface TypeBoxValidationError {
14
+ path: string;
15
+ message: string;
16
+ }
24
17
  export type TypeBoxEnhancedSchema<T = Record<string, unknown>> = TObject & {
25
- parse: (values: unknown) => T;
26
- safeParse: (values: unknown) => SchemaValidationResult<T>;
27
18
  Check: (values: unknown) => boolean;
28
- "~standard": {
29
- version: 1;
30
- vendor: "svadmin";
31
- validate: (values: unknown) => {
32
- value: T;
33
- } | {
34
- issues: Array<{
35
- message: string;
36
- path?: (string | number)[];
37
- }>;
38
- };
39
- };
19
+ Errors: (values: unknown) => Iterable<TypeBoxValidationError>;
20
+ Decode: (values: unknown) => T;
40
21
  };
41
22
  /**
42
23
  * Generate a TypeBox object schema from a list of FieldDefinitions.
@@ -47,14 +28,6 @@ export declare function fieldsToTypeBoxSchema(fields: FieldDefinition[], mode?:
47
28
  * Convenience wrapper around fieldsToTypeBoxSchema.
48
29
  */
49
30
  export declare function resourceToTypeBoxSchema(resource: ResourceDefinition, mode?: "create" | "edit"): TypeBoxEnhancedSchema;
50
- /**
51
- * Backward compatibility alias for fieldsToTypeBoxSchema
52
- */
53
- export declare const fieldsToZodSchema: typeof fieldsToTypeBoxSchema;
54
- /**
55
- * Backward compatibility alias for resourceToTypeBoxSchema
56
- */
57
- export declare const resourceToZodSchema: typeof resourceToTypeBoxSchema;
58
31
  /**
59
32
  * Determine a conservative HTML input type for server-rendered forms.
60
33
  */
@@ -361,11 +361,10 @@ export function fieldsToTypeBoxSchema(fields, mode = "create") {
361
361
  }
362
362
  }
363
363
  const baseSchema = Type.Object(shape, { additionalProperties: true });
364
- const safeParse = (values) => {
364
+ const validateAndNormalize = (values) => {
365
365
  if (typeof values !== "object" || values === null) {
366
366
  return {
367
- success: false,
368
- error: { issues: [{ path: ["_root"], message: "Values must be an object" }] },
367
+ issues: [{ path: ["_root"], message: "Values must be an object" }],
369
368
  };
370
369
  }
371
370
  const input = values;
@@ -380,45 +379,26 @@ export function fieldsToTypeBoxSchema(fields, mode = "create") {
380
379
  }
381
380
  }
382
381
  if (allIssues.length > 0) {
383
- return {
384
- success: false,
385
- error: { issues: allIssues },
386
- };
382
+ return { issues: allIssues };
387
383
  }
388
- return {
389
- success: true,
390
- data: resultData,
391
- };
384
+ return { data: resultData, issues: [] };
392
385
  };
393
- const parse = (values) => {
394
- const res = safeParse(values);
395
- if (!res.success) {
396
- const err = new Error(res.error?.issues[0]?.message || "Validation failed");
397
- err.issues = res.error?.issues ?? [];
386
+ const decode = (values) => {
387
+ const validation = validateAndNormalize(values);
388
+ if (validation.issues.length > 0) {
389
+ const err = new Error(validation.issues[0]?.message || "Validation failed");
390
+ err.errors = validation.issues;
398
391
  throw err;
399
392
  }
400
- return res.data ?? {};
393
+ return validation.data ?? {};
401
394
  };
402
395
  return Object.assign(baseSchema, {
403
- parse,
404
- safeParse,
405
- Check: (val) => safeParse(val).success,
406
- "~standard": {
407
- version: 1,
408
- vendor: "svadmin",
409
- validate: (val) => {
410
- const res = safeParse(val);
411
- if (res.success) {
412
- return { value: res.data ?? {} };
413
- }
414
- return {
415
- issues: (res.error?.issues ?? []).map((iss) => ({
416
- message: iss.message,
417
- path: iss.path,
418
- })),
419
- };
420
- },
421
- },
396
+ Check: (val) => validateAndNormalize(val).issues.length === 0,
397
+ Errors: (val) => validateAndNormalize(val).issues.map((issue) => ({
398
+ path: issue.path.length > 0 ? `/${issue.path.map(String).join("/")}` : "",
399
+ message: issue.message,
400
+ })),
401
+ Decode: decode,
422
402
  });
423
403
  }
424
404
  /**
@@ -429,14 +409,6 @@ export function resourceToTypeBoxSchema(resource, mode = "create") {
429
409
  const primaryKey = resource.primaryKey ?? "id";
430
410
  return fieldsToTypeBoxSchema(resource.fields.filter((field) => field.key !== primaryKey), mode);
431
411
  }
432
- /**
433
- * Backward compatibility alias for fieldsToTypeBoxSchema
434
- */
435
- export const fieldsToZodSchema = fieldsToTypeBoxSchema;
436
- /**
437
- * Backward compatibility alias for resourceToTypeBoxSchema
438
- */
439
- export const resourceToZodSchema = resourceToTypeBoxSchema;
440
412
  /**
441
413
  * Determine a conservative HTML input type for server-rendered forms.
442
414
  */
@@ -473,16 +473,19 @@ function formatValidationErrors(issues) {
473
473
  return errors;
474
474
  }
475
475
  function validateFormVariables(resource, mode, values) {
476
- const result = resourceToTypeBoxSchema(resource, mode).safeParse(values);
477
- if (result.success)
478
- return { success: true, data: result.data };
476
+ const schema = resourceToTypeBoxSchema(resource, mode);
477
+ if (schema.Check(values))
478
+ return { success: true, data: schema.Decode(values) };
479
479
  return {
480
480
  success: false,
481
481
  failure: {
482
482
  success: false,
483
483
  error: 'Validation failed',
484
484
  values: formValuesForResponse(resource.fields, values),
485
- errors: formatValidationErrors(result.error.issues),
485
+ errors: formatValidationErrors([...schema.Errors(values)].map((issue) => ({
486
+ path: issue.path.split('/').filter(Boolean),
487
+ message: issue.message,
488
+ }))),
486
489
  },
487
490
  };
488
491
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@svadmin/lite",
3
- "version": "0.8.0",
3
+ "version": "0.8.2",
4
4
  "description": "SSR-first lightweight admin UI for @svadmin with optional progressive enhancement",
5
5
  "type": "module",
6
6
  "sideEffects": [