@keemakr/ui-sdk 1.6.0-dev-20261027202014 → 1.6.0-dev-20261027204717
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/negotiate.d.ts +6 -2
- package/dist/negotiate.js +40 -1
- package/dist/schema.d.ts +116 -2
- package/dist/schema.js +32 -17
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { UI_SCHEMA_VERSION, pressSchema, chatPressSchema, valuePressSchema, NAVIGATE_OPENS, buttonSchema, cellSchema, tableCellSchema, dateFormatSchema, nodeSchema, screenPresentationSchema, screenTreeSchema, actionResultSchema, screenLoadRequestSchema, screenLoadResponseSchema, screenActionRequestSchema, interfaceFamilySchema, surfaceDefinitionSchema, surfaceSchema, screenRegistrationSchema, uiManifestSchema, jobIdSchema, jobStatusSchema, screenJobRequestSchema, mediaPathSchema, seekPointSchema, seekPressSchema, BADGE_COUNT_MAX, surfaceBadgeSchema, screenBadgesRequestSchema, screenBadgesResponseSchema, TABS_MAX, } from './schema.js';
|
|
1
|
+
export { UI_SCHEMA_VERSION, pressSchema, chatPressSchema, valuePressSchema, NAVIGATE_OPENS, buttonSchema, cellSchema, factCellSchema, tableCellSchema, dateFormatSchema, nodeSchema, screenPresentationSchema, screenTreeSchema, actionResultSchema, screenLoadRequestSchema, screenLoadResponseSchema, screenActionRequestSchema, interfaceFamilySchema, surfaceDefinitionSchema, surfaceSchema, screenRegistrationSchema, uiManifestSchema, jobIdSchema, jobStatusSchema, screenJobRequestSchema, mediaPathSchema, seekPointSchema, seekPressSchema, BADGE_COUNT_MAX, surfaceBadgeSchema, screenBadgesRequestSchema, screenBadgesResponseSchema, TABS_MAX, } from './schema.js';
|
|
2
2
|
export type { Press, ChatPress, SeekPress, SeekPoint, ValuePress, NavigatePress, NavigateOpen, ScreenPresentation, ScreenNode, ScreenRootNode, ScreenTree, ActionResult, InterfaceFamily, SurfaceDefinition, Surface, ScreenRegistration, UiManifest, ScreenTreeInput, ActionResultInput, JobStatus, JobStatusInput, SurfaceBadge, SurfaceBadgeInput, ScreenBadgesRequest, ScreenBadgesResponse, } from './schema.js';
|
|
3
3
|
export { BADGE_DISPLAY_MAX, answerBadges, badgeSpokenLabel, badgeText, defineBadges, parseScreenBadges, } from './badges.js';
|
|
4
4
|
export type { BadgesHandler } from './badges.js';
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
// platform components, proxies load/action with a grant
|
|
7
7
|
//
|
|
8
8
|
// Module code never ships to the browser. UI is data, not code.
|
|
9
|
-
export { UI_SCHEMA_VERSION, pressSchema, chatPressSchema, valuePressSchema, NAVIGATE_OPENS, buttonSchema, cellSchema, tableCellSchema, dateFormatSchema, nodeSchema, screenPresentationSchema, screenTreeSchema, actionResultSchema, screenLoadRequestSchema, screenLoadResponseSchema, screenActionRequestSchema, interfaceFamilySchema, surfaceDefinitionSchema, surfaceSchema, screenRegistrationSchema, uiManifestSchema, jobIdSchema, jobStatusSchema, screenJobRequestSchema, mediaPathSchema, seekPointSchema, seekPressSchema, BADGE_COUNT_MAX, surfaceBadgeSchema, screenBadgesRequestSchema, screenBadgesResponseSchema, TABS_MAX, } from './schema.js';
|
|
9
|
+
export { UI_SCHEMA_VERSION, pressSchema, chatPressSchema, valuePressSchema, NAVIGATE_OPENS, buttonSchema, cellSchema, factCellSchema, tableCellSchema, dateFormatSchema, nodeSchema, screenPresentationSchema, screenTreeSchema, actionResultSchema, screenLoadRequestSchema, screenLoadResponseSchema, screenActionRequestSchema, interfaceFamilySchema, surfaceDefinitionSchema, surfaceSchema, screenRegistrationSchema, uiManifestSchema, jobIdSchema, jobStatusSchema, screenJobRequestSchema, mediaPathSchema, seekPointSchema, seekPressSchema, BADGE_COUNT_MAX, surfaceBadgeSchema, screenBadgesRequestSchema, screenBadgesResponseSchema, TABS_MAX, } from './schema.js';
|
|
10
10
|
export { BADGE_DISPLAY_MAX, answerBadges, badgeSpokenLabel, badgeText, defineBadges, parseScreenBadges, } from './badges.js';
|
|
11
11
|
export { CHART_POINTS_MAX, thinChart, thinnedIndices } from './chart.js';
|
|
12
12
|
export { TABS_MAX_1_4_0, foldTabs, onlyTabParamsDiffer, openingTab, tabParamsOf } from './tabs.js';
|
package/dist/negotiate.d.ts
CHANGED
|
@@ -75,8 +75,12 @@ import type { ChatPress, ScreenRootNode, ScreenTree } from './schema.js';
|
|
|
75
75
|
* (newer than any published release; core's own renderer draws it). An older parse strips it,
|
|
76
76
|
* so without it the action becomes a `button` with the same label and press, last in the
|
|
77
77
|
* section, and the reader can still go where it led. A full section drops it.
|
|
78
|
+
* - `facts.meter`: a `meter` cell as a calendar entry's `details` value or a header `meta` value
|
|
79
|
+
* (newer than any published release; core's own renderer draws it). An older parse refuses it,
|
|
80
|
+
* so without it the meter becomes a `text` cell with its value label ("Intake 3/5"). Header
|
|
81
|
+
* facts a client draws as one line (no `header.meta`) are written the same way.
|
|
78
82
|
*/
|
|
79
|
-
export type UiFeature = 'breadcrumbs' | 'button.disabled' | 'section.row' | 'form.field_kinds' | 'form.confirm' | 'press.chat' | 'form.radio' | 'table.cells' | 'header.meta' | 'tabs.many' | 'choice.action' | 'markdown.links' | 'form.disabled' | 'press.seek' | 'edit.inline' | 'timeline.time_tag' | 'stat.bar' | 'section.action';
|
|
83
|
+
export type UiFeature = 'breadcrumbs' | 'button.disabled' | 'section.row' | 'form.field_kinds' | 'form.confirm' | 'press.chat' | 'form.radio' | 'table.cells' | 'header.meta' | 'tabs.many' | 'choice.action' | 'markdown.links' | 'form.disabled' | 'press.seek' | 'edit.inline' | 'timeline.time_tag' | 'stat.bar' | 'section.action' | 'facts.meter';
|
|
80
84
|
/** The node types and features one ui-sdk release, or one client, draws. */
|
|
81
85
|
export interface NodeSet {
|
|
82
86
|
/** For messages: "ui-sdk 1.4.0", "mobile 0.2.5". */
|
|
@@ -113,7 +117,7 @@ export declare const UI_SDK_SNAPSHOTS: {
|
|
|
113
117
|
readonly current: {
|
|
114
118
|
readonly name: "ui-sdk (this package)";
|
|
115
119
|
readonly nodes: readonly ["heading", "text", "markdown", "stat", "button", "form", "table", "timeline", "pending_request", "pending_requests", "choice_cards", "progress", "chart", "section", "tabs", "pagination", "select", "alert", "details", "timestamp", "divider", "board", "link", "tags", "toggle", "segmented", "progress_bar", "conversation", "composer", "calendar", "image", "video", "stacked_bar", "heatmap", "audio"];
|
|
116
|
-
readonly features: readonly ["breadcrumbs", "button.disabled", "section.row", "form.field_kinds", "form.confirm", "press.chat", "form.radio", "table.cells", "header.meta", "tabs.many", "choice.action", "markdown.links", "form.disabled", "press.seek", "edit.inline", "timeline.time_tag", "stat.bar", "section.action"];
|
|
120
|
+
readonly features: readonly ["breadcrumbs", "button.disabled", "section.row", "form.field_kinds", "form.confirm", "press.chat", "form.radio", "table.cells", "header.meta", "tabs.many", "choice.action", "markdown.links", "form.disabled", "press.seek", "edit.inline", "timeline.time_tag", "stat.bar", "section.action", "facts.meter"];
|
|
117
121
|
};
|
|
118
122
|
};
|
|
119
123
|
export type UiSdkSnapshot = keyof typeof UI_SDK_SNAPSHOTS;
|
package/dist/negotiate.js
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
// (tests/sdk/ui-negotiation.test.ts) fails until the current snapshot matches KNOWN_NODE_TYPES,
|
|
21
21
|
// until every node type has a fallback, and until every sample tree, negotiated for every row,
|
|
22
22
|
// parses with that row's published schema with no safety field lost.
|
|
23
|
-
import { foldTableCell, isNewerTableCell } from './cells.js';
|
|
23
|
+
import { foldTableCell, isNewerTableCell, meterLabel } from './cells.js';
|
|
24
24
|
import { conformTree } from './conform.js';
|
|
25
25
|
import { withoutScreenLinks } from './markdown-links.js';
|
|
26
26
|
import { pageRangeLabel } from './pager.js';
|
|
@@ -52,6 +52,7 @@ const ALL_FEATURES = [
|
|
|
52
52
|
'timeline.time_tag',
|
|
53
53
|
'stat.bar',
|
|
54
54
|
'section.action',
|
|
55
|
+
'facts.meter',
|
|
55
56
|
];
|
|
56
57
|
/** The nodes of ui-sdk 1.1.0 and 1.2.0 (one schema). */
|
|
57
58
|
const NODES_1_1_0 = [
|
|
@@ -400,6 +401,22 @@ export function negotiateTree(tree, set) {
|
|
|
400
401
|
return features.has('choice.action') ? node : foldChoiceActions(node, path, fallbacks);
|
|
401
402
|
case 'timeline':
|
|
402
403
|
return features.has('timeline.time_tag') ? node : foldTimeAndTag(node, path, fallbacks);
|
|
404
|
+
case 'calendar': {
|
|
405
|
+
if (features.has('facts.meter'))
|
|
406
|
+
return node;
|
|
407
|
+
let changed = false;
|
|
408
|
+
const events = node.events.map((event, i) => {
|
|
409
|
+
if (!event.details)
|
|
410
|
+
return event;
|
|
411
|
+
const at = `${path}.events[${i}].details`;
|
|
412
|
+
const details = foldFactMeters(event.details, at, 'calendar', fallbacks);
|
|
413
|
+
if (details === event.details)
|
|
414
|
+
return event;
|
|
415
|
+
changed = true;
|
|
416
|
+
return { ...event, details };
|
|
417
|
+
});
|
|
418
|
+
return changed ? { ...node, events } : node;
|
|
419
|
+
}
|
|
403
420
|
case 'markdown': {
|
|
404
421
|
if (features.has('markdown.links'))
|
|
405
422
|
return node;
|
|
@@ -501,6 +518,11 @@ export function negotiateTree(tree, set) {
|
|
|
501
518
|
delete next.actions;
|
|
502
519
|
}
|
|
503
520
|
}
|
|
521
|
+
if (tree.meta && features.has('header.meta') && !features.has('facts.meter')) {
|
|
522
|
+
const meta = foldFactMeters(tree.meta, 'meta', 'header', fallbacks);
|
|
523
|
+
if (meta !== tree.meta)
|
|
524
|
+
next = { ...next, meta };
|
|
525
|
+
}
|
|
504
526
|
// Before the breadcrumbs fold, so a trail line (which says where the screen sits) lands above it.
|
|
505
527
|
if ((tree.badges || tree.meta) && !features.has('header.meta')) {
|
|
506
528
|
const line = headerFactsLine(tree, zone);
|
|
@@ -621,6 +643,21 @@ export function foldChoiceActions(node, path, fallbacks) {
|
|
|
621
643
|
});
|
|
622
644
|
return { ...node, choices };
|
|
623
645
|
}
|
|
646
|
+
/**
|
|
647
|
+
* Facts with each `meter` value as a `text` cell of its value label, for a client that draws no
|
|
648
|
+
* meter outside a table (`facts.meter`). The same array when there is none.
|
|
649
|
+
*/
|
|
650
|
+
function foldFactMeters(facts, path, type, fallbacks) {
|
|
651
|
+
let changed = false;
|
|
652
|
+
const folded = facts.map((fact, i) => {
|
|
653
|
+
if (fact.value.kind !== 'meter')
|
|
654
|
+
return fact;
|
|
655
|
+
changed = true;
|
|
656
|
+
fallbacks.push({ path: `${path}[${i}].value`, type, reason: 'facts.meter', as: 'folded' });
|
|
657
|
+
return { ...fact, value: { kind: 'text', value: meterLabel(fact.value) } };
|
|
658
|
+
});
|
|
659
|
+
return changed ? folded : facts;
|
|
660
|
+
}
|
|
624
661
|
/**
|
|
625
662
|
* A section with its `action` moved into its body as a last `button`, for a client that does not
|
|
626
663
|
* draw the action on the title line (`section.action`). Dropped when the section is full.
|
|
@@ -1091,6 +1128,8 @@ const TONE_WORD = {
|
|
|
1091
1128
|
destructive: 'Error',
|
|
1092
1129
|
};
|
|
1093
1130
|
function cellText(cell, timeZone) {
|
|
1131
|
+
if (cell.kind === 'meter')
|
|
1132
|
+
return meterLabel(cell);
|
|
1094
1133
|
return cell.kind === 'date' ? formatMoment(cell.value, 'datetime', timeZone) : cell.value;
|
|
1095
1134
|
}
|
|
1096
1135
|
/**
|
package/dist/schema.d.ts
CHANGED
|
@@ -250,8 +250,8 @@ export declare const cellSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
250
250
|
}, z.core.$strip>], "kind">;
|
|
251
251
|
/**
|
|
252
252
|
* A table cell: every value cell kind, plus `sparkline` and `meter`, and a
|
|
253
|
-
* `secondary` line on `text` and `badge`. Table cells only: a `details` row
|
|
254
|
-
*
|
|
253
|
+
* `secondary` line on `text` and `badge`. Table cells only: a `details` row and a board card
|
|
254
|
+
* keep `cellSchema`; a calendar entry's details and the header's meta take `factCellSchema`.
|
|
255
255
|
*
|
|
256
256
|
* Neither a sparkline nor a meter is sortable by itself: the renderer never
|
|
257
257
|
* reorders rows, so a sortable column of them sorts by whatever the module
|
|
@@ -320,6 +320,55 @@ export declare const tableCellSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
320
320
|
}>>;
|
|
321
321
|
valueLabel: z.ZodOptional<z.ZodString>;
|
|
322
322
|
}, z.core.$strip>], "kind">;
|
|
323
|
+
/**
|
|
324
|
+
* A fact's value: a value cell, or a meter ("Intake 3/5"). A calendar entry's `details` and the
|
|
325
|
+
* screen header's `meta` take it. A client that draws no meter there gets a `text` cell with the
|
|
326
|
+
* meter's value label (negotiate.ts, `facts.meter`).
|
|
327
|
+
*/
|
|
328
|
+
export declare const factCellSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
329
|
+
kind: z.ZodLiteral<"text">;
|
|
330
|
+
value: z.ZodString;
|
|
331
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
332
|
+
kind: z.ZodLiteral<"badge">;
|
|
333
|
+
value: z.ZodString;
|
|
334
|
+
tone: z.ZodDefault<z.ZodEnum<{
|
|
335
|
+
default: "default";
|
|
336
|
+
success: "success";
|
|
337
|
+
warning: "warning";
|
|
338
|
+
destructive: "destructive";
|
|
339
|
+
info: "info";
|
|
340
|
+
accent: "accent";
|
|
341
|
+
}>>;
|
|
342
|
+
outline: z.ZodOptional<z.ZodBoolean>;
|
|
343
|
+
dot: z.ZodOptional<z.ZodBoolean>;
|
|
344
|
+
hint: z.ZodOptional<z.ZodString>;
|
|
345
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
346
|
+
kind: z.ZodLiteral<"date">;
|
|
347
|
+
value: z.ZodISODateTime;
|
|
348
|
+
dateFormat: z.ZodOptional<z.ZodObject<{
|
|
349
|
+
weekday: z.ZodOptional<z.ZodBoolean>;
|
|
350
|
+
year: z.ZodOptional<z.ZodEnum<{
|
|
351
|
+
auto: "auto";
|
|
352
|
+
always: "always";
|
|
353
|
+
never: "never";
|
|
354
|
+
}>>;
|
|
355
|
+
hour12: z.ZodOptional<z.ZodBoolean>;
|
|
356
|
+
locale: z.ZodOptional<z.ZodString>;
|
|
357
|
+
}, z.core.$strip>>;
|
|
358
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
359
|
+
kind: z.ZodLiteral<"meter">;
|
|
360
|
+
value: z.ZodNumber;
|
|
361
|
+
max: z.ZodDefault<z.ZodNumber>;
|
|
362
|
+
tone: z.ZodDefault<z.ZodEnum<{
|
|
363
|
+
default: "default";
|
|
364
|
+
success: "success";
|
|
365
|
+
warning: "warning";
|
|
366
|
+
destructive: "destructive";
|
|
367
|
+
info: "info";
|
|
368
|
+
accent: "accent";
|
|
369
|
+
}>>;
|
|
370
|
+
valueLabel: z.ZodOptional<z.ZodString>;
|
|
371
|
+
}, z.core.$strip>], "kind">;
|
|
323
372
|
/**
|
|
324
373
|
* A file inside the module's own runtime: "patients/p-17/scan.jpg". Never a
|
|
325
374
|
* URL. Core fetches it from the runtime's GET /screens/media/<path> with the
|
|
@@ -1698,6 +1747,19 @@ declare const leafNodeSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
1698
1747
|
hour12: z.ZodOptional<z.ZodBoolean>;
|
|
1699
1748
|
locale: z.ZodOptional<z.ZodString>;
|
|
1700
1749
|
}, z.core.$strip>>;
|
|
1750
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
1751
|
+
kind: z.ZodLiteral<"meter">;
|
|
1752
|
+
value: z.ZodNumber;
|
|
1753
|
+
max: z.ZodDefault<z.ZodNumber>;
|
|
1754
|
+
tone: z.ZodDefault<z.ZodEnum<{
|
|
1755
|
+
default: "default";
|
|
1756
|
+
success: "success";
|
|
1757
|
+
warning: "warning";
|
|
1758
|
+
destructive: "destructive";
|
|
1759
|
+
info: "info";
|
|
1760
|
+
accent: "accent";
|
|
1761
|
+
}>>;
|
|
1762
|
+
valueLabel: z.ZodOptional<z.ZodString>;
|
|
1701
1763
|
}, z.core.$strip>], "kind">;
|
|
1702
1764
|
}, z.core.$strip>>>;
|
|
1703
1765
|
actions: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
@@ -2090,6 +2152,19 @@ export declare const screenTreeSchema: z.ZodObject<{
|
|
|
2090
2152
|
hour12: z.ZodOptional<z.ZodBoolean>;
|
|
2091
2153
|
locale: z.ZodOptional<z.ZodString>;
|
|
2092
2154
|
}, z.core.$strip>>;
|
|
2155
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
2156
|
+
kind: z.ZodLiteral<"meter">;
|
|
2157
|
+
value: z.ZodNumber;
|
|
2158
|
+
max: z.ZodDefault<z.ZodNumber>;
|
|
2159
|
+
tone: z.ZodDefault<z.ZodEnum<{
|
|
2160
|
+
default: "default";
|
|
2161
|
+
success: "success";
|
|
2162
|
+
warning: "warning";
|
|
2163
|
+
destructive: "destructive";
|
|
2164
|
+
info: "info";
|
|
2165
|
+
accent: "accent";
|
|
2166
|
+
}>>;
|
|
2167
|
+
valueLabel: z.ZodOptional<z.ZodString>;
|
|
2093
2168
|
}, z.core.$strip>], "kind">;
|
|
2094
2169
|
}, z.core.$strip>>>;
|
|
2095
2170
|
breadcrumbs: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
@@ -2318,6 +2393,19 @@ export declare const actionResultSchema: z.ZodObject<{
|
|
|
2318
2393
|
hour12: z.ZodOptional<z.ZodBoolean>;
|
|
2319
2394
|
locale: z.ZodOptional<z.ZodString>;
|
|
2320
2395
|
}, z.core.$strip>>;
|
|
2396
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
2397
|
+
kind: z.ZodLiteral<"meter">;
|
|
2398
|
+
value: z.ZodNumber;
|
|
2399
|
+
max: z.ZodDefault<z.ZodNumber>;
|
|
2400
|
+
tone: z.ZodDefault<z.ZodEnum<{
|
|
2401
|
+
default: "default";
|
|
2402
|
+
success: "success";
|
|
2403
|
+
warning: "warning";
|
|
2404
|
+
destructive: "destructive";
|
|
2405
|
+
info: "info";
|
|
2406
|
+
accent: "accent";
|
|
2407
|
+
}>>;
|
|
2408
|
+
valueLabel: z.ZodOptional<z.ZodString>;
|
|
2321
2409
|
}, z.core.$strip>], "kind">;
|
|
2322
2410
|
}, z.core.$strip>>>;
|
|
2323
2411
|
breadcrumbs: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
@@ -2539,6 +2627,19 @@ export declare const jobStatusSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
2539
2627
|
hour12: z.ZodOptional<z.ZodBoolean>;
|
|
2540
2628
|
locale: z.ZodOptional<z.ZodString>;
|
|
2541
2629
|
}, z.core.$strip>>;
|
|
2630
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
2631
|
+
kind: z.ZodLiteral<"meter">;
|
|
2632
|
+
value: z.ZodNumber;
|
|
2633
|
+
max: z.ZodDefault<z.ZodNumber>;
|
|
2634
|
+
tone: z.ZodDefault<z.ZodEnum<{
|
|
2635
|
+
default: "default";
|
|
2636
|
+
success: "success";
|
|
2637
|
+
warning: "warning";
|
|
2638
|
+
destructive: "destructive";
|
|
2639
|
+
info: "info";
|
|
2640
|
+
accent: "accent";
|
|
2641
|
+
}>>;
|
|
2642
|
+
valueLabel: z.ZodOptional<z.ZodString>;
|
|
2542
2643
|
}, z.core.$strip>], "kind">;
|
|
2543
2644
|
}, z.core.$strip>>>;
|
|
2544
2645
|
breadcrumbs: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
@@ -2750,6 +2851,19 @@ export declare const screenLoadResponseSchema: z.ZodObject<{
|
|
|
2750
2851
|
hour12: z.ZodOptional<z.ZodBoolean>;
|
|
2751
2852
|
locale: z.ZodOptional<z.ZodString>;
|
|
2752
2853
|
}, z.core.$strip>>;
|
|
2854
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
2855
|
+
kind: z.ZodLiteral<"meter">;
|
|
2856
|
+
value: z.ZodNumber;
|
|
2857
|
+
max: z.ZodDefault<z.ZodNumber>;
|
|
2858
|
+
tone: z.ZodDefault<z.ZodEnum<{
|
|
2859
|
+
default: "default";
|
|
2860
|
+
success: "success";
|
|
2861
|
+
warning: "warning";
|
|
2862
|
+
destructive: "destructive";
|
|
2863
|
+
info: "info";
|
|
2864
|
+
accent: "accent";
|
|
2865
|
+
}>>;
|
|
2866
|
+
valueLabel: z.ZodOptional<z.ZodString>;
|
|
2753
2867
|
}, z.core.$strip>], "kind">;
|
|
2754
2868
|
}, z.core.$strip>>>;
|
|
2755
2869
|
breadcrumbs: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
package/dist/schema.js
CHANGED
|
@@ -297,6 +297,17 @@ export const cellSchema = z.discriminatedUnion('kind', [
|
|
|
297
297
|
badgeCellSchema,
|
|
298
298
|
dateCellSchema,
|
|
299
299
|
]);
|
|
300
|
+
/** A bar of `value` out of `max`, its value always written beside it. */
|
|
301
|
+
const meterCellSchema = z.object({
|
|
302
|
+
kind: z.literal('meter'),
|
|
303
|
+
/** A value past `max` draws a full bar; say so in `valueLabel`. */
|
|
304
|
+
value: z.number().min(0),
|
|
305
|
+
max: z.number().positive().default(100),
|
|
306
|
+
/** The bar's colour. */
|
|
307
|
+
tone: tone.default('default'),
|
|
308
|
+
/** Drawn beside the bar: "72%", "36 of 50". Without it, the percent of `max`. */
|
|
309
|
+
valueLabel: z.string().min(1).max(40).optional(),
|
|
310
|
+
});
|
|
300
311
|
/**
|
|
301
312
|
* A muted second line under a table cell's value, one line, cut short with an
|
|
302
313
|
* ellipsis when it does not fit: an account's city and tier under its name, the
|
|
@@ -305,8 +316,8 @@ export const cellSchema = z.discriminatedUnion('kind', [
|
|
|
305
316
|
const cellSecondary = z.string().min(1).max(200).optional();
|
|
306
317
|
/**
|
|
307
318
|
* A table cell: every value cell kind, plus `sparkline` and `meter`, and a
|
|
308
|
-
* `secondary` line on `text` and `badge`. Table cells only: a `details` row
|
|
309
|
-
*
|
|
319
|
+
* `secondary` line on `text` and `badge`. Table cells only: a `details` row and a board card
|
|
320
|
+
* keep `cellSchema`; a calendar entry's details and the header's meta take `factCellSchema`.
|
|
310
321
|
*
|
|
311
322
|
* Neither a sparkline nor a meter is sortable by itself: the renderer never
|
|
312
323
|
* reorders rows, so a sortable column of them sorts by whatever the module
|
|
@@ -330,16 +341,18 @@ export const tableCellSchema = z.discriminatedUnion('kind', [
|
|
|
330
341
|
/** What the line says, in words: "Usage down 18% in 30 days". Required. */
|
|
331
342
|
label: z.string().min(1).max(120),
|
|
332
343
|
}),
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
344
|
+
meterCellSchema,
|
|
345
|
+
]);
|
|
346
|
+
/**
|
|
347
|
+
* A fact's value: a value cell, or a meter ("Intake 3/5"). A calendar entry's `details` and the
|
|
348
|
+
* screen header's `meta` take it. A client that draws no meter there gets a `text` cell with the
|
|
349
|
+
* meter's value label (negotiate.ts, `facts.meter`).
|
|
350
|
+
*/
|
|
351
|
+
export const factCellSchema = z.discriminatedUnion('kind', [
|
|
352
|
+
textCellSchema,
|
|
353
|
+
badgeCellSchema,
|
|
354
|
+
dateCellSchema,
|
|
355
|
+
meterCellSchema,
|
|
343
356
|
]);
|
|
344
357
|
/**
|
|
345
358
|
* Cards to choose from, or a list of things to act on (a My Day action list). Each card is a
|
|
@@ -855,8 +868,9 @@ const calendarSchema = z
|
|
|
855
868
|
/** Colours the entry: a confirmed visit, an unconfirmed one, a no-show. */
|
|
856
869
|
tone: tone.default('default'),
|
|
857
870
|
subtitle: z.string().max(200).optional(),
|
|
871
|
+
/** Drawn in the entry's panel. A `meter` value shows progress: "Intake 3/5". */
|
|
858
872
|
details: z
|
|
859
|
-
.array(z.object({ label: z.string().min(1).max(80), value:
|
|
873
|
+
.array(z.object({ label: z.string().min(1).max(80), value: factCellSchema }))
|
|
860
874
|
.max(12)
|
|
861
875
|
.optional(),
|
|
862
876
|
actions: z.array(buttonSchema).max(4).optional(),
|
|
@@ -2496,12 +2510,13 @@ export const screenTreeSchema = z
|
|
|
2496
2510
|
/**
|
|
2497
2511
|
* Up to eight facts drawn as a compact row under the title (and its
|
|
2498
2512
|
* description): ARR, renewal date, reps, NPS. Each value is a cell, so a
|
|
2499
|
-
* `date` follows the screen's `timeZone` and `dateFormat
|
|
2500
|
-
* keeps its tone
|
|
2501
|
-
* value) that wraps on a narrow
|
|
2513
|
+
* `date` follows the screen's `timeZone` and `dateFormat`, a `badge`
|
|
2514
|
+
* keeps its tone and a `meter` draws its bar ("Onboarding 3/5"). A renderer
|
|
2515
|
+
* draws them as a description list (term and value) that wraps on a narrow
|
|
2516
|
+
* screen.
|
|
2502
2517
|
*/
|
|
2503
2518
|
meta: z
|
|
2504
|
-
.array(z.object({ label: z.string().min(1).max(40), value:
|
|
2519
|
+
.array(z.object({ label: z.string().min(1).max(40), value: factCellSchema }))
|
|
2505
2520
|
.min(1)
|
|
2506
2521
|
.max(8)
|
|
2507
2522
|
.optional(),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@keemakr/ui-sdk",
|
|
3
|
-
"version": "1.6.0-dev-
|
|
3
|
+
"version": "1.6.0-dev-20261027204717",
|
|
4
4
|
"description": "Product screens for keemakr marketplace modules: a versioned, server-driven UI tree schema plus defineScreen() handlers. Module code never ships to the browser — keemakr-core validates the tree and renders it with platform components.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|