@checkcourt/sdk 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -0
- package/dist/iframe.d.ts +1 -1
- package/dist/iframe.js +3 -0
- package/dist/ui.d.ts +53 -6
- package/dist/ui.js +101 -11
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -193,6 +193,36 @@ ui.form({
|
|
|
193
193
|
});
|
|
194
194
|
```
|
|
195
195
|
|
|
196
|
+
Blocks can carry an `icon` from `UI_ICONS` (text, heading, stat, badge, list items), a `stat`
|
|
197
|
+
can be `size: "lg"`, badges have a soft amber `"warning"` variant, `ui.columns` lays out 2
|
|
198
|
+
to 6 children in equal widths, and `ui.row(children, { justify: "between" })` spreads a row
|
|
199
|
+
across the full width (first child left, last child right). A weather widget:
|
|
200
|
+
|
|
201
|
+
```ts
|
|
202
|
+
const days = [
|
|
203
|
+
["Heute", "sun", "24°"],
|
|
204
|
+
["Do", "cloud-sun", "21°"],
|
|
205
|
+
["Fr", "cloud-rain", "17°"],
|
|
206
|
+
["Sa", "cloud-drizzle", "18°"],
|
|
207
|
+
["So", "sun", "23°"],
|
|
208
|
+
] as const;
|
|
209
|
+
|
|
210
|
+
ui.doc([
|
|
211
|
+
ui.row(
|
|
212
|
+
[
|
|
213
|
+
ui.stat("Jetzt", "24°", { icon: "sun", size: "lg", hint: "Sonnig" }),
|
|
214
|
+
ui.badge("Regen möglich", { variant: "warning", icon: "droplets" }),
|
|
215
|
+
],
|
|
216
|
+
{ justify: "between" },
|
|
217
|
+
),
|
|
218
|
+
ui.divider(),
|
|
219
|
+
ui.columns(
|
|
220
|
+
days.map(([day, icon, temp]) => ui.stat(day, temp, { icon })),
|
|
221
|
+
{ dividers: true, align: "center" },
|
|
222
|
+
),
|
|
223
|
+
]);
|
|
224
|
+
```
|
|
225
|
+
|
|
196
226
|
Compare `context.installation_id` and `context.tenant_id` with what you stored from
|
|
197
227
|
`app.installed` before you act on a request. For the context token alone (for example in
|
|
198
228
|
the backend of an iframe extension), use `verifyExtensionContext(token, secret)`.
|
package/dist/iframe.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ export declare const MAX_TOAST_LENGTH = 200;
|
|
|
6
6
|
/** Top-level areas `navigate()` may target; anything else is dropped by CheckCourt. */
|
|
7
7
|
export declare const NAVIGABLE_SECTIONS: readonly ["dashboard", "booking", "my-bookings", "club", "team", "trainer", "fees", "arbeitsstunden", "settings", "admin"];
|
|
8
8
|
/** CSS variables CheckCourt sends with every theme message. */
|
|
9
|
-
export declare const THEME_TOKEN_NAMES: readonly ["--background", "--foreground", "--card", "--card-foreground", "--muted", "--muted-foreground", "--primary", "--primary-foreground", "--secondary", "--secondary-foreground", "--accent", "--accent-foreground", "--destructive", "--border", "--input", "--ring", "--radius"];
|
|
9
|
+
export declare const THEME_TOKEN_NAMES: readonly ["--background", "--foreground", "--card", "--card-foreground", "--muted", "--muted-foreground", "--primary", "--primary-foreground", "--secondary", "--secondary-foreground", "--accent", "--accent-foreground", "--destructive", "--warning", "--warning-foreground", "--warning-muted", "--border", "--input", "--ring", "--radius"];
|
|
10
10
|
export type ThemeTokenName = (typeof THEME_TOKEN_NAMES)[number];
|
|
11
11
|
export type FrameMessage = {
|
|
12
12
|
type: "checkcourt:resize";
|
package/dist/iframe.js
CHANGED
package/dist/ui.d.ts
CHANGED
|
@@ -2,34 +2,55 @@ export declare const UI_VERSION = "v1";
|
|
|
2
2
|
export declare const MAX_UI_BLOCKS = 50;
|
|
3
3
|
/** Top-level blocks sit at depth 1; a container's children one deeper. */
|
|
4
4
|
export declare const MAX_UI_DEPTH = 3;
|
|
5
|
-
export declare const BADGE_VARIANTS: readonly ["default", "secondary", "outline", "destructive"];
|
|
5
|
+
export declare const BADGE_VARIANTS: readonly ["default", "secondary", "outline", "destructive", "warning"];
|
|
6
6
|
export declare const BUTTON_VARIANTS: readonly ["default", "secondary", "outline", "destructive"];
|
|
7
7
|
export type BadgeVariant = (typeof BADGE_VARIANTS)[number];
|
|
8
8
|
export type ButtonVariant = (typeof BUTTON_VARIANTS)[number];
|
|
9
|
+
/** Icons a block may show, by lucide name; CheckCourt draws them in the text color at text size. */
|
|
10
|
+
export declare const UI_ICONS: readonly ["sun", "moon", "cloud", "cloud-sun", "cloud-moon", "cloud-sun-rain", "cloud-rain", "cloud-drizzle", "cloud-lightning", "cloud-snow", "cloud-fog", "snowflake", "wind", "droplet", "droplets", "umbrella", "thermometer", "sunrise", "sunset", "check", "x", "info", "alert-triangle", "triangle-alert", "alert-circle", "circle-alert", "clock", "calendar", "map-pin", "trophy", "users", "user", "lock", "unlock", "lock-open", "lightbulb", "zap", "euro", "star", "heart", "bell", "flag", "activity", "timer", "ticket", "door-open"];
|
|
11
|
+
export type UiIcon = (typeof UI_ICONS)[number];
|
|
12
|
+
/** `lg` shows the value as a large display figure, `md` (default) as a regular stat. */
|
|
13
|
+
export declare const STAT_SIZES: readonly ["md", "lg"];
|
|
14
|
+
export type StatSize = (typeof STAT_SIZES)[number];
|
|
15
|
+
export declare const COLUMNS_ALIGNMENTS: readonly ["start", "center"];
|
|
16
|
+
export type ColumnsAlignment = (typeof COLUMNS_ALIGNMENTS)[number];
|
|
17
|
+
/** `between` spreads a row's children across the full width, first at the left edge, last at the right. */
|
|
18
|
+
export declare const ROW_JUSTIFICATIONS: readonly ["start", "between"];
|
|
19
|
+
export type RowJustify = (typeof ROW_JUSTIFICATIONS)[number];
|
|
20
|
+
/** A `columns` block holds 2 to 6 children. */
|
|
21
|
+
export declare const MIN_COLUMNS = 2;
|
|
22
|
+
export declare const MAX_COLUMNS = 6;
|
|
9
23
|
export type UiTextBlock = {
|
|
10
24
|
type: "text";
|
|
11
25
|
text: string;
|
|
12
26
|
tone?: "muted";
|
|
27
|
+
icon?: UiIcon;
|
|
13
28
|
};
|
|
14
29
|
export type UiHeadingBlock = {
|
|
15
30
|
type: "heading";
|
|
16
31
|
text: string;
|
|
17
32
|
level: 2 | 3;
|
|
33
|
+
icon?: UiIcon;
|
|
18
34
|
};
|
|
35
|
+
/** With `icon`, the icon sits before the value. */
|
|
19
36
|
export type UiStatBlock = {
|
|
20
37
|
type: "stat";
|
|
21
38
|
label: string;
|
|
22
39
|
value: string;
|
|
23
40
|
hint?: string;
|
|
41
|
+
icon?: UiIcon;
|
|
42
|
+
size?: StatSize;
|
|
24
43
|
};
|
|
25
44
|
export type UiBadgeBlock = {
|
|
26
45
|
type: "badge";
|
|
27
46
|
label: string;
|
|
28
47
|
variant?: BadgeVariant;
|
|
48
|
+
icon?: UiIcon;
|
|
29
49
|
};
|
|
30
50
|
export type UiListItem = {
|
|
31
51
|
title: string;
|
|
32
52
|
description?: string;
|
|
53
|
+
icon?: UiIcon;
|
|
33
54
|
};
|
|
34
55
|
export type UiListBlock = {
|
|
35
56
|
type: "list";
|
|
@@ -136,8 +157,16 @@ export type UiStackBlock = {
|
|
|
136
157
|
export type UiRowBlock = {
|
|
137
158
|
type: "row";
|
|
138
159
|
children: UiBlock[];
|
|
160
|
+
justify?: RowJustify;
|
|
139
161
|
};
|
|
140
|
-
|
|
162
|
+
/** 2 to 6 children side by side in equal widths; on narrow cards 4 wrap to 2 per row, 5 and 6 to 3. */
|
|
163
|
+
export type UiColumnsBlock = {
|
|
164
|
+
type: "columns";
|
|
165
|
+
children: UiBlock[];
|
|
166
|
+
dividers?: boolean;
|
|
167
|
+
align?: ColumnsAlignment;
|
|
168
|
+
};
|
|
169
|
+
export type UiBlock = UiTextBlock | UiHeadingBlock | UiStatBlock | UiBadgeBlock | UiListBlock | UiKeyValueBlock | UiLinkBlock | UiButtonBlock | UiFormBlock | UiDividerBlock | UiStackBlock | UiRowBlock | UiColumnsBlock;
|
|
141
170
|
export type UiToast = {
|
|
142
171
|
kind: "success" | "error";
|
|
143
172
|
message: string;
|
|
@@ -265,12 +294,23 @@ export declare const ui: {
|
|
|
265
294
|
readonly hidden: (options?: UiDocumentOptions) => UiHiddenDocument;
|
|
266
295
|
readonly text: (text: string, options?: {
|
|
267
296
|
tone?: "muted";
|
|
297
|
+
icon?: UiIcon;
|
|
268
298
|
}) => UiTextBlock;
|
|
269
|
-
|
|
299
|
+
/** `ui.heading(text, 3)` or `ui.heading(text, { level: 3, icon: "trophy" })`; level defaults to 2. */
|
|
300
|
+
readonly heading: (text: string, levelOrOptions?: 2 | 3 | {
|
|
301
|
+
level?: 2 | 3;
|
|
302
|
+
icon?: UiIcon;
|
|
303
|
+
}) => UiHeadingBlock;
|
|
270
304
|
readonly stat: (label: string, value: string, options?: {
|
|
271
305
|
hint?: string;
|
|
306
|
+
icon?: UiIcon;
|
|
307
|
+
size?: StatSize;
|
|
272
308
|
}) => UiStatBlock;
|
|
273
|
-
|
|
309
|
+
/** `ui.badge(label, "warning")` or `ui.badge(label, { variant: "warning", icon: "droplets" })`. */
|
|
310
|
+
readonly badge: (label: string, variantOrOptions?: BadgeVariant | {
|
|
311
|
+
variant?: BadgeVariant;
|
|
312
|
+
icon?: UiIcon;
|
|
313
|
+
}) => UiBadgeBlock;
|
|
274
314
|
readonly list: (items: UiListItem[]) => UiListBlock;
|
|
275
315
|
/** Pairs keep their order; a plain object is turned into pairs in key order. */
|
|
276
316
|
readonly keyValue: (pairs: UiKeyValuePair[] | Record<string, string>) => UiKeyValueBlock;
|
|
@@ -294,8 +334,15 @@ export declare const ui: {
|
|
|
294
334
|
};
|
|
295
335
|
readonly divider: () => UiDividerBlock;
|
|
296
336
|
readonly stack: (children: UiBlock[]) => UiStackBlock;
|
|
297
|
-
/** Horizontal, wraps on narrow screens. */
|
|
298
|
-
readonly row: (children: UiBlock[]
|
|
337
|
+
/** Horizontal, wraps on narrow screens; `justify: "between"` pushes the last child to the right edge. */
|
|
338
|
+
readonly row: (children: UiBlock[], options?: {
|
|
339
|
+
justify?: RowJustify;
|
|
340
|
+
}) => UiRowBlock;
|
|
341
|
+
/** 2 to 6 equal-width columns, optionally with vertical dividers; throws on any other count. */
|
|
342
|
+
readonly columns: (children: UiBlock[], options?: {
|
|
343
|
+
dividers?: boolean;
|
|
344
|
+
align?: ColumnsAlignment;
|
|
345
|
+
}) => UiColumnsBlock;
|
|
299
346
|
};
|
|
300
347
|
/** Toasts for `ui.doc(blocks, { toast })`, at most 200 characters. */
|
|
301
348
|
export declare const toast: {
|
package/dist/ui.js
CHANGED
|
@@ -2,8 +2,65 @@ export const UI_VERSION = "v1";
|
|
|
2
2
|
export const MAX_UI_BLOCKS = 50;
|
|
3
3
|
/** Top-level blocks sit at depth 1; a container's children one deeper. */
|
|
4
4
|
export const MAX_UI_DEPTH = 3;
|
|
5
|
-
export const BADGE_VARIANTS = ["default", "secondary", "outline", "destructive"];
|
|
5
|
+
export const BADGE_VARIANTS = ["default", "secondary", "outline", "destructive", "warning"];
|
|
6
6
|
export const BUTTON_VARIANTS = ["default", "secondary", "outline", "destructive"];
|
|
7
|
+
/** Icons a block may show, by lucide name; CheckCourt draws them in the text color at text size. */
|
|
8
|
+
export const UI_ICONS = [
|
|
9
|
+
"sun",
|
|
10
|
+
"moon",
|
|
11
|
+
"cloud",
|
|
12
|
+
"cloud-sun",
|
|
13
|
+
"cloud-moon",
|
|
14
|
+
"cloud-sun-rain",
|
|
15
|
+
"cloud-rain",
|
|
16
|
+
"cloud-drizzle",
|
|
17
|
+
"cloud-lightning",
|
|
18
|
+
"cloud-snow",
|
|
19
|
+
"cloud-fog",
|
|
20
|
+
"snowflake",
|
|
21
|
+
"wind",
|
|
22
|
+
"droplet",
|
|
23
|
+
"droplets",
|
|
24
|
+
"umbrella",
|
|
25
|
+
"thermometer",
|
|
26
|
+
"sunrise",
|
|
27
|
+
"sunset",
|
|
28
|
+
"check",
|
|
29
|
+
"x",
|
|
30
|
+
"info",
|
|
31
|
+
"alert-triangle",
|
|
32
|
+
"triangle-alert",
|
|
33
|
+
"alert-circle",
|
|
34
|
+
"circle-alert",
|
|
35
|
+
"clock",
|
|
36
|
+
"calendar",
|
|
37
|
+
"map-pin",
|
|
38
|
+
"trophy",
|
|
39
|
+
"users",
|
|
40
|
+
"user",
|
|
41
|
+
"lock",
|
|
42
|
+
"unlock",
|
|
43
|
+
"lock-open",
|
|
44
|
+
"lightbulb",
|
|
45
|
+
"zap",
|
|
46
|
+
"euro",
|
|
47
|
+
"star",
|
|
48
|
+
"heart",
|
|
49
|
+
"bell",
|
|
50
|
+
"flag",
|
|
51
|
+
"activity",
|
|
52
|
+
"timer",
|
|
53
|
+
"ticket",
|
|
54
|
+
"door-open",
|
|
55
|
+
];
|
|
56
|
+
/** `lg` shows the value as a large display figure, `md` (default) as a regular stat. */
|
|
57
|
+
export const STAT_SIZES = ["md", "lg"];
|
|
58
|
+
export const COLUMNS_ALIGNMENTS = ["start", "center"];
|
|
59
|
+
/** `between` spreads a row's children across the full width, first at the left edge, last at the right. */
|
|
60
|
+
export const ROW_JUSTIFICATIONS = ["start", "between"];
|
|
61
|
+
/** A `columns` block holds 2 to 6 children. */
|
|
62
|
+
export const MIN_COLUMNS = 2;
|
|
63
|
+
export const MAX_COLUMNS = 6;
|
|
7
64
|
/** CheckCourt caps every render lifetime at this many seconds. */
|
|
8
65
|
export const UI_CACHE_MAX_AGE_LIMIT = 300;
|
|
9
66
|
/** Longest badge label of a `court.annotation`. */
|
|
@@ -75,6 +132,14 @@ function variantOf(variant, what) {
|
|
|
75
132
|
}
|
|
76
133
|
return variant;
|
|
77
134
|
}
|
|
135
|
+
function iconOf(icon) {
|
|
136
|
+
if (icon === undefined)
|
|
137
|
+
return undefined;
|
|
138
|
+
if (!UI_ICONS.includes(icon)) {
|
|
139
|
+
throw new TypeError(`Unknown icon ${String(icon)}; use one of UI_ICONS`);
|
|
140
|
+
}
|
|
141
|
+
return icon;
|
|
142
|
+
}
|
|
78
143
|
function entriesOf(list, what) {
|
|
79
144
|
if (!Array.isArray(list))
|
|
80
145
|
throw new TypeError(`${what} must be an array`);
|
|
@@ -157,19 +222,31 @@ export const ui = {
|
|
|
157
222
|
return compact({ ui: UI_VERSION, hidden: true, toast: options.toast, cache: cacheOf(options.maxAge) });
|
|
158
223
|
},
|
|
159
224
|
text(text, options = {}) {
|
|
160
|
-
return compact({ type: "text", text, tone: options.tone });
|
|
225
|
+
return compact({ type: "text", text, tone: options.tone, icon: iconOf(options.icon) });
|
|
161
226
|
},
|
|
162
|
-
heading(text, level
|
|
163
|
-
|
|
227
|
+
/** `ui.heading(text, 3)` or `ui.heading(text, { level: 3, icon: "trophy" })`; level defaults to 2. */
|
|
228
|
+
heading(text, levelOrOptions = 2) {
|
|
229
|
+
const options = typeof levelOrOptions === "object" ? levelOrOptions : { level: levelOrOptions };
|
|
230
|
+
return compact({ type: "heading", text, level: options.level ?? 2, icon: iconOf(options.icon) });
|
|
164
231
|
},
|
|
165
232
|
stat(label, value, options = {}) {
|
|
166
|
-
|
|
233
|
+
if (options.size !== undefined && !STAT_SIZES.includes(options.size)) {
|
|
234
|
+
throw new TypeError(`stat size must be one of ${STAT_SIZES.join(", ")}`);
|
|
235
|
+
}
|
|
236
|
+
return compact({ type: "stat", label, value, hint: options.hint, icon: iconOf(options.icon), size: options.size });
|
|
167
237
|
},
|
|
168
|
-
badge(label, variant)
|
|
169
|
-
|
|
238
|
+
/** `ui.badge(label, "warning")` or `ui.badge(label, { variant: "warning", icon: "droplets" })`. */
|
|
239
|
+
badge(label, variantOrOptions) {
|
|
240
|
+
const options = typeof variantOrOptions === "object" ? variantOrOptions : { variant: variantOrOptions };
|
|
241
|
+
return compact({
|
|
242
|
+
type: "badge",
|
|
243
|
+
label,
|
|
244
|
+
variant: variantOf(options.variant, "badge variant"),
|
|
245
|
+
icon: iconOf(options.icon),
|
|
246
|
+
});
|
|
170
247
|
},
|
|
171
248
|
list(items) {
|
|
172
|
-
return { type: "list", items: items.map((item) => compact({ ...item })) };
|
|
249
|
+
return { type: "list", items: items.map((item) => compact({ ...item, icon: iconOf(item.icon) })) };
|
|
173
250
|
},
|
|
174
251
|
/** Pairs keep their order; a plain object is turned into pairs in key order. */
|
|
175
252
|
keyValue(pairs) {
|
|
@@ -198,9 +275,22 @@ export const ui = {
|
|
|
198
275
|
stack(children) {
|
|
199
276
|
return { type: "stack", children };
|
|
200
277
|
},
|
|
201
|
-
/** Horizontal, wraps on narrow screens. */
|
|
202
|
-
row(children) {
|
|
203
|
-
|
|
278
|
+
/** Horizontal, wraps on narrow screens; `justify: "between"` pushes the last child to the right edge. */
|
|
279
|
+
row(children, options = {}) {
|
|
280
|
+
if (options.justify !== undefined && !ROW_JUSTIFICATIONS.includes(options.justify)) {
|
|
281
|
+
throw new TypeError(`row justify must be one of ${ROW_JUSTIFICATIONS.join(", ")}`);
|
|
282
|
+
}
|
|
283
|
+
return compact({ type: "row", children, justify: options.justify });
|
|
284
|
+
},
|
|
285
|
+
/** 2 to 6 equal-width columns, optionally with vertical dividers; throws on any other count. */
|
|
286
|
+
columns(children, options = {}) {
|
|
287
|
+
if (!Array.isArray(children) || children.length < MIN_COLUMNS || children.length > MAX_COLUMNS) {
|
|
288
|
+
throw new RangeError(`columns takes ${MIN_COLUMNS} to ${MAX_COLUMNS} children`);
|
|
289
|
+
}
|
|
290
|
+
if (options.align !== undefined && !COLUMNS_ALIGNMENTS.includes(options.align)) {
|
|
291
|
+
throw new TypeError(`columns align must be one of ${COLUMNS_ALIGNMENTS.join(", ")}`);
|
|
292
|
+
}
|
|
293
|
+
return compact({ type: "columns", children, dividers: options.dividers, align: options.align });
|
|
204
294
|
},
|
|
205
295
|
};
|
|
206
296
|
/** Toasts for `ui.doc(blocks, { toast })`, at most 200 characters. */
|