k3-plugin-api 1.4.5 → 1.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.
- package/dist/index.cjs +73 -0
- package/{index.ts → dist/index.d.cts} +164 -202
- package/dist/index.d.ts +674 -656
- package/dist/index.js +69 -0
- package/package.json +17 -8
- package/dist/index.d.ts.map +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
//#region index.d.ts
|
|
4
|
+
|
|
2
5
|
/**
|
|
3
6
|
* Get plugin-specific settings from the K3 store.
|
|
4
7
|
* Returns a snapshot of the current settings - not reactive.
|
|
@@ -15,268 +18,283 @@ import type React from "react";
|
|
|
15
18
|
* }
|
|
16
19
|
* ```
|
|
17
20
|
*/
|
|
18
|
-
|
|
21
|
+
declare function getSettings(pluginId: string): unknown;
|
|
22
|
+
/**
|
|
23
|
+
* Get plugin-specific settings from the K3 store as a reactive hook.
|
|
24
|
+
* Re-renders the component whenever the settings change.
|
|
25
|
+
* Use this in plugin React components.
|
|
26
|
+
*
|
|
27
|
+
* @param pluginId - The unique plugin ID (e.g. "acme.my-plugin")
|
|
28
|
+
* @returns The settings object for this plugin, or `{}` if none are configured
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* const settings = useK3PluginSettings("acme.my-plugin") as { apiKey?: string };
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
declare function useK3PluginSettings(pluginId: string): unknown;
|
|
19
36
|
/**
|
|
20
37
|
* Called by K3 when the plugin is loaded to inject runtime API functions.
|
|
21
38
|
* @internal This function is called by K3 automatically - plugins should not call it directly.
|
|
22
39
|
*/
|
|
23
|
-
|
|
24
|
-
|
|
40
|
+
declare function init(api: {
|
|
41
|
+
getSettings: (pluginId: string) => unknown;
|
|
42
|
+
usePluginSettings: (pluginId: string) => unknown;
|
|
25
43
|
}): void;
|
|
26
44
|
/** A Higher-Order Component: takes the default component, returns a new one. */
|
|
27
|
-
|
|
45
|
+
type HOC<P = Record<string, unknown>> = (comp: React.FC<P>) => React.FC<P>;
|
|
28
46
|
/** Four editor languages supported by K3. */
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
47
|
+
type LocalizedString = {
|
|
48
|
+
de?: string;
|
|
49
|
+
en?: string;
|
|
50
|
+
nl?: string;
|
|
51
|
+
fr?: string;
|
|
34
52
|
};
|
|
35
53
|
/** An HOC slot with a required description for the admin UI. */
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
54
|
+
interface HOCWithDescription<P = Record<string, unknown>> {
|
|
55
|
+
hoc: HOC<P>;
|
|
56
|
+
/** Describe what this extension point does. Shown in the plugin extensions dialog. */
|
|
57
|
+
description: string | LocalizedString;
|
|
40
58
|
}
|
|
41
59
|
/** A logic callback with a required description for the admin UI. */
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
60
|
+
interface CallbackWithDescription<T> {
|
|
61
|
+
fn: T;
|
|
62
|
+
/** Describe what this callback does. Shown in the plugin extensions dialog. */
|
|
63
|
+
description: string | LocalizedString;
|
|
64
|
+
}
|
|
65
|
+
interface K3PluginDescriptor {
|
|
66
|
+
/** Unique stable identifier, e.g. "vendor.myplugin". Required for collision detection. */
|
|
67
|
+
id: string;
|
|
68
|
+
/** Semver string, e.g. "1.0.0". */
|
|
69
|
+
version: string;
|
|
70
|
+
/** UI extension points: layout HOCs, input HOCs, dialog HOCs. */
|
|
71
|
+
ui?: K3UIExtensions;
|
|
72
|
+
/** Viewer / 3D extension points: canvas, scene components, layout components, dynamic models. */
|
|
73
|
+
viewer?: K3ViewerExtensions;
|
|
74
|
+
/** Logic/callback hooks: config, camera, core. */
|
|
75
|
+
logic?: K3LogicExtensions;
|
|
76
|
+
settings?: React.ComponentType<{
|
|
77
|
+
settings: unknown;
|
|
78
|
+
onSave: (settings: unknown) => void;
|
|
79
|
+
}>;
|
|
80
|
+
/** @deprecated Use viewer.models instead. */
|
|
81
|
+
dynamicModels?: DynamicModel[];
|
|
82
|
+
}
|
|
83
|
+
interface K3UIExtensions {
|
|
84
|
+
/** Override layout shell components. */
|
|
85
|
+
layout?: K3LayoutExtensions;
|
|
86
|
+
/** Register new variable visualisations (renderers) per variable data type. */
|
|
87
|
+
inputs?: K3InputExtensions;
|
|
88
|
+
/** Override dialog components. */
|
|
89
|
+
dialogs?: K3DialogExtensions;
|
|
90
|
+
}
|
|
91
|
+
interface K3LayoutExtensions {
|
|
92
|
+
/** Wraps the outermost app shell component. */
|
|
93
|
+
root?: HOCWithDescription;
|
|
94
|
+
/** Wraps the top header bar containing branding, navigation buttons, and scene controls. */
|
|
95
|
+
header?: HOCWithDescription;
|
|
96
|
+
/** Wraps the sidebar container that lists groups and variables. */
|
|
97
|
+
sidebar?: HOCWithDescription;
|
|
98
|
+
/** Wraps the header section inside the sidebar (above the groups list). */
|
|
99
|
+
sidebarHeader?: HOCWithDescription;
|
|
100
|
+
/** Wraps the footer section inside the sidebar (below the groups list). */
|
|
101
|
+
sidebarFooter?: HOCWithDescription;
|
|
102
|
+
/** Wraps the bottom footer bar of the app shell. */
|
|
103
|
+
footer?: HOCWithDescription;
|
|
104
|
+
/** Wraps the main content / viewer area of the configurator page. */
|
|
105
|
+
contentView?: HOCWithDescription;
|
|
106
|
+
/** Wraps the gallery / image viewer page layout. */
|
|
107
|
+
gallery?: HOCWithDescription;
|
|
108
|
+
/** Wraps the branding slot in the header (typically a logo + brand name). */
|
|
109
|
+
branding?: HOCWithDescription;
|
|
110
|
+
/** Wraps the logo image component inside the branding area. */
|
|
111
|
+
logo?: HOCWithDescription;
|
|
112
|
+
/** Wraps the previous/next group navigation button bar. */
|
|
113
|
+
navigationButtons?: HOCWithDescription;
|
|
114
|
+
/** Wraps the exit / close configurator button(s). */
|
|
115
|
+
exitButtons?: HOCWithDescription;
|
|
116
|
+
/** Wraps the 3D scene action buttons (e.g. AR, fullscreen, screenshot). */
|
|
117
|
+
sceneButtons?: HOCWithDescription;
|
|
118
|
+
/** Wraps the price display component shown in the header or footer. */
|
|
119
|
+
price?: HOCWithDescription;
|
|
120
|
+
/** Wraps the label/hotspot action display overlay rendered on the desktop 3D canvas. */
|
|
121
|
+
labelActionDisplay?: HOCWithDescription;
|
|
122
|
+
/** Wraps the label/hotspot action display overlay rendered on mobile. */
|
|
123
|
+
mobileLabelActionDisplay?: HOCWithDescription;
|
|
124
|
+
/** Wraps the modal shown when a selection violates a mandatory rule. */
|
|
125
|
+
invalidRuleModal?: HOCWithDescription;
|
|
126
|
+
/** Wraps a component that is only mounted after the app has fully loaded. */
|
|
127
|
+
mountedWhenLoaded?: HOCWithDescription;
|
|
128
|
+
/** Wraps the top-level configurator page layout (groups navigation + variable panel). */
|
|
129
|
+
configurator?: HOCWithDescription;
|
|
130
|
+
/** Wraps each group label in the sidebar navigation list. */
|
|
131
|
+
groupLabel?: HOCWithDescription;
|
|
132
|
+
/** Wraps the expandable group panel that contains its variables. */
|
|
133
|
+
groupPanel?: HOCWithDescription;
|
|
134
|
+
/** Wraps the additional-groups slot appended below the main groups list. */
|
|
135
|
+
additionalGroups?: HOCWithDescription;
|
|
136
|
+
/** Wraps the additional-variables slot appended at the end of a group's variable list. */
|
|
137
|
+
additionalVars?: HOCWithDescription;
|
|
138
|
+
/** Wraps each individual variable label inside a group panel. */
|
|
139
|
+
variableLabel?: HOCWithDescription;
|
|
122
140
|
}
|
|
123
141
|
/**
|
|
124
142
|
* Props passed to a plugin variable component (VariableVisualisation.component) at runtime.
|
|
125
143
|
* Use these to render a fully custom variable input UI.
|
|
126
144
|
*/
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
[key: string]: unknown;
|
|
144
|
-
};
|
|
145
|
-
[key: string]: unknown;
|
|
146
|
-
};
|
|
145
|
+
interface K3VariableComponentProps {
|
|
146
|
+
/** The variable definition for which this component is rendered. */
|
|
147
|
+
variable: {
|
|
148
|
+
/** Database ID of the variable. */
|
|
149
|
+
id: string | number;
|
|
150
|
+
/** Translated display label of the variable. */
|
|
151
|
+
label: string;
|
|
152
|
+
/** Data type of the variable (list, color, number, …). */
|
|
153
|
+
type: VariableTypes;
|
|
154
|
+
settings?: {
|
|
155
|
+
/** Key of the VariableVisualisation that should be used to render this variable. */
|
|
156
|
+
template?: string;
|
|
157
|
+
templateOptions?: {
|
|
158
|
+
min?: number;
|
|
159
|
+
max?: number;
|
|
160
|
+
digits?: number;
|
|
147
161
|
[key: string]: unknown;
|
|
162
|
+
};
|
|
163
|
+
[key: string]: unknown;
|
|
148
164
|
};
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
165
|
+
[key: string]: unknown;
|
|
166
|
+
};
|
|
167
|
+
/** The currently active selection for this variable, if any. */
|
|
168
|
+
selection?: {
|
|
169
|
+
/** ID of the currently selected value. */
|
|
170
|
+
id: string | number;
|
|
171
|
+
data?: {
|
|
172
|
+
inputValue?: number;
|
|
173
|
+
[key: string]: unknown;
|
|
158
174
|
};
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
175
|
+
[key: string]: unknown;
|
|
176
|
+
};
|
|
177
|
+
/** All available value options for this variable. */
|
|
178
|
+
values?: Array<{
|
|
179
|
+
/** Database ID of the value. */
|
|
180
|
+
id: string | number;
|
|
181
|
+
/** Translated display label of the value. */
|
|
182
|
+
label: string;
|
|
183
|
+
/** Raw value payload (hex color, boolean, etc.). */
|
|
184
|
+
value?: string | boolean | null;
|
|
185
|
+
[key: string]: unknown;
|
|
186
|
+
}>;
|
|
187
|
+
/**
|
|
188
|
+
* Commit a selection.
|
|
189
|
+
* Number variables: onChange(values[0].id, { inputValue: numericValue })
|
|
190
|
+
* List/color/boolean: onChange(value.id)
|
|
191
|
+
*/
|
|
192
|
+
onChange: (valueId: string | number, metadata?: {
|
|
193
|
+
inputValue?: number;
|
|
194
|
+
}) => void;
|
|
195
|
+
/** When `true`, the variable is locked and user interaction should be blocked. */
|
|
196
|
+
disabled?: boolean;
|
|
179
197
|
}
|
|
180
198
|
/**
|
|
181
199
|
* A plugin-registered variable renderer (VariableVisualisation).
|
|
182
200
|
* Displayed as a selectable option in the admin visualisation chooser.
|
|
183
201
|
* The component owns its full UI — label, input, chrome.
|
|
184
202
|
*/
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
203
|
+
interface VariableVisualisation {
|
|
204
|
+
/**
|
|
205
|
+
* Globally unique template key, e.g. "acme.mySlider".
|
|
206
|
+
* Set variable.settings.template = this key to use this visualisation.
|
|
207
|
+
* Must be namespaced to avoid collisions.
|
|
208
|
+
*/
|
|
209
|
+
key: string;
|
|
210
|
+
/** Label shown in the admin visualisation chooser. */
|
|
211
|
+
label: string;
|
|
212
|
+
/** Describe what this visualisation does. Shown in the plugin extensions dialog. */
|
|
213
|
+
description: string | LocalizedString;
|
|
214
|
+
/** Full variable renderer component. Receives K3VariableComponentProps. */
|
|
215
|
+
component: React.ComponentType<K3VariableComponentProps>;
|
|
216
|
+
}
|
|
217
|
+
interface K3InputExtensions {
|
|
218
|
+
/** Register new visualisations for list-type variables. */
|
|
219
|
+
list?: VariableVisualisation[];
|
|
220
|
+
/** Register new visualisations for color-type variables. */
|
|
221
|
+
color?: VariableVisualisation[];
|
|
222
|
+
/** Register new visualisations for number-type variables (e.g. custom slider). */
|
|
223
|
+
number?: VariableVisualisation[];
|
|
224
|
+
/** Register new visualisations for text-type variables. */
|
|
225
|
+
text?: VariableVisualisation[];
|
|
226
|
+
/** Register new visualisations for boolean-type variables. */
|
|
227
|
+
boolean?: VariableVisualisation[];
|
|
228
|
+
/** Register new visualisations for image-type variables. */
|
|
229
|
+
image?: VariableVisualisation[];
|
|
230
|
+
/** Register new visualisations for upload-type variables. */
|
|
231
|
+
upload?: VariableVisualisation[];
|
|
232
|
+
/** Register new visualisations for components-type variables. */
|
|
233
|
+
components?: VariableVisualisation[];
|
|
234
|
+
/** Register new visualisations for information-type variables. */
|
|
235
|
+
information?: VariableVisualisation[];
|
|
236
|
+
}
|
|
237
|
+
interface K3DialogExtensions {
|
|
238
|
+
/** Extension points for the order / summary dialog (contact form, price table, confirmation). */
|
|
239
|
+
order?: K3OrderDialogExtensions;
|
|
240
|
+
/** Extension points for inline selection-warning components shown in the sidebar. */
|
|
241
|
+
warnings?: K3WarningExtensions;
|
|
242
|
+
}
|
|
243
|
+
interface K3OrderDialogExtensions {
|
|
244
|
+
/** Wraps the entire order dialog modal. */
|
|
245
|
+
root?: HOCWithDescription;
|
|
246
|
+
/** Wraps the dialog headline / title element. */
|
|
247
|
+
headline?: HOCWithDescription;
|
|
248
|
+
/** Wraps the customer contact form fields (name, email, …). */
|
|
249
|
+
contactFields?: HOCWithDescription;
|
|
250
|
+
/** Wraps the price table container in the order summary. */
|
|
251
|
+
priceTable?: HOCWithDescription;
|
|
252
|
+
/** Wraps the list of selected option rows inside the price table. */
|
|
253
|
+
priceTableSelectionList?: HOCWithDescription;
|
|
254
|
+
/** Wraps the list of article/BOM rows inside the price table. */
|
|
255
|
+
priceTableArticleList?: HOCWithDescription;
|
|
256
|
+
/** Wraps the totals row at the bottom of the price table. */
|
|
257
|
+
priceTableTotal?: HOCWithDescription;
|
|
258
|
+
/** Wraps the success confirmation screen shown after a successful order submission. */
|
|
259
|
+
confirmationSuccess?: HOCWithDescription;
|
|
260
|
+
/** Wraps the error confirmation screen shown after a failed order submission. */
|
|
261
|
+
confirmationError?: HOCWithDescription;
|
|
262
|
+
}
|
|
263
|
+
interface K3WarningExtensions {
|
|
264
|
+
/** Wraps the full invalid-selection warning component (red badge next to a variable value). */
|
|
265
|
+
invalidSelection?: HOCWithDescription;
|
|
266
|
+
/** Wraps the icon inside the invalid-selection warning. */
|
|
267
|
+
invalidSelectionIcon?: HOCWithDescription;
|
|
268
|
+
/** Wraps the tooltip content shown when hovering the invalid-selection warning. */
|
|
269
|
+
invalidSelectionTooltip?: HOCWithDescription;
|
|
270
|
+
/** Wraps the tooltip content shown when a number variable value is out of bounds. */
|
|
271
|
+
numberWarningTooltip?: HOCWithDescription;
|
|
254
272
|
}
|
|
255
273
|
/**
|
|
256
274
|
* A single Bill-of-Materials entry exposed to plugin components.
|
|
257
275
|
* Mirrors the internal BOMEntry shape using only primitive/simple types.
|
|
258
276
|
*/
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
277
|
+
interface K3BomEntry {
|
|
278
|
+
article: {
|
|
279
|
+
id: number;
|
|
280
|
+
/** Article number as defined in the K3 admin. */
|
|
281
|
+
no: string;
|
|
282
|
+
name: string;
|
|
283
|
+
description?: string | null;
|
|
284
|
+
thumbnail?: string | null;
|
|
285
|
+
category?: string | null;
|
|
286
|
+
};
|
|
287
|
+
/** Quantity of this article for the current selection. */
|
|
288
|
+
qty: number;
|
|
289
|
+
/** Optional override quantity from the article amount modal. */
|
|
290
|
+
amount?: number | null;
|
|
291
|
+
/** Price of a single unit of this article. */
|
|
292
|
+
price: {
|
|
293
|
+
price: number;
|
|
294
|
+
unit?: string;
|
|
295
|
+
};
|
|
296
|
+
/** Whether this is a main article (`true`) or an accessory/surcharge (`false`). */
|
|
297
|
+
main?: boolean;
|
|
280
298
|
}
|
|
281
299
|
/**
|
|
282
300
|
* Props automatically injected into every `customLayoutComponents` entry.
|
|
@@ -284,498 +302,498 @@ export interface K3BomEntry {
|
|
|
284
302
|
* @remarks TODO(WIP) — This interface will grow as more configurator data is
|
|
285
303
|
* exposed to plugins.
|
|
286
304
|
*/
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
305
|
+
interface CustomLayoutComponentProps {
|
|
306
|
+
/** The slot name this component was mounted under. */
|
|
307
|
+
name: string;
|
|
308
|
+
/**
|
|
309
|
+
* Live Bill-of-Materials rows derived from the current selection.
|
|
310
|
+
* Each entry represents one article line or surcharge line.
|
|
311
|
+
*/
|
|
312
|
+
bom: K3BomEntry[];
|
|
313
|
+
/**
|
|
314
|
+
* Aggregated total price for the current configuration in the app's currency unit.
|
|
315
|
+
* TODO(WIP): Currency/formatting helpers are not yet part of the public API.
|
|
316
|
+
*/
|
|
317
|
+
totalPrice: number;
|
|
318
|
+
/** Any additional props forwarded by the layout. */
|
|
319
|
+
[key: string]: unknown;
|
|
320
|
+
}
|
|
321
|
+
interface K3ViewerExtensions {
|
|
322
|
+
/** Wraps the root Three.js / R3F canvas element. */
|
|
323
|
+
canvas?: HOCWithDescription;
|
|
324
|
+
/**
|
|
325
|
+
* Named React components injected into the configurator layout by key.
|
|
326
|
+
* Consumed by `getDynamicComponents` to render plugin-provided UI inside layout slots.
|
|
327
|
+
* Use a plain component (no HOC wrapping needed).
|
|
328
|
+
*
|
|
329
|
+
* Components receive {@link CustomLayoutComponentProps} with BOM and total price data.
|
|
330
|
+
*/
|
|
331
|
+
customLayoutComponents?: Record<string, React.ComponentType<CustomLayoutComponentProps>>;
|
|
332
|
+
/** Dynamic 3D model definitions contributed by this plugin. Equivalent to the top-level `dynamicModels`. */
|
|
333
|
+
models?: DynamicModel[];
|
|
334
|
+
/** Override the label / hotspot overlay components rendered on the 3D canvas. */
|
|
335
|
+
labels?: {
|
|
336
|
+
/** Wraps the label action display overlay on desktop. Alias for `ui.layout.labelActionDisplay`. */
|
|
337
|
+
display?: HOCWithDescription;
|
|
338
|
+
/** Wraps the label action display overlay on mobile. Alias for `ui.layout.mobileLabelActionDisplay`. */
|
|
339
|
+
mobile?: HOCWithDescription;
|
|
340
|
+
};
|
|
323
341
|
}
|
|
324
342
|
/** [x, y, z] coordinate tuple used on camera objects. */
|
|
325
|
-
|
|
343
|
+
type K3Coordinates = [number, number, number];
|
|
326
344
|
/**
|
|
327
345
|
* Restricts a camera to a specific configurator context.
|
|
328
346
|
* `"group"` / `"variable"` — camera activates only when that item is in view; `id` is the entity's database ID.
|
|
329
347
|
* `"general"` — camera is always available regardless of the active group or variable.
|
|
330
348
|
*/
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
349
|
+
type K3CameraScope = {
|
|
350
|
+
type: "group" | "variable";
|
|
351
|
+
id: number;
|
|
334
352
|
} | {
|
|
335
|
-
|
|
336
|
-
|
|
353
|
+
type: "general";
|
|
354
|
+
id?: null;
|
|
337
355
|
};
|
|
338
356
|
interface K3BaseCamera {
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
357
|
+
/** Unique database ID of the camera record. */
|
|
358
|
+
id: string;
|
|
359
|
+
/** Human-readable camera name as set in the scene editor. */
|
|
360
|
+
name: string;
|
|
361
|
+
/** World-space XYZ position of the camera. */
|
|
362
|
+
position: K3Coordinates;
|
|
363
|
+
/** World-space XYZ point the camera is aimed at. */
|
|
364
|
+
lookAt: K3Coordinates;
|
|
365
|
+
/** Euler rotation [x, y, z] in radians. */
|
|
366
|
+
rotation: K3Coordinates;
|
|
367
|
+
/** Optional override for the screenshot render resolution in pixels. */
|
|
368
|
+
resolution?: {
|
|
369
|
+
width: number;
|
|
370
|
+
height: number;
|
|
371
|
+
};
|
|
372
|
+
/** Transition easing threshold used by the camera animation driver. */
|
|
373
|
+
threshold?: number;
|
|
374
|
+
/**
|
|
375
|
+
* How the camera's look-at target is computed.
|
|
376
|
+
* `"dynamic"` — recalculated from the current scene bounding box (default).
|
|
377
|
+
* `"static"` — uses the stored `lookAt` value unchanged.
|
|
378
|
+
*/
|
|
379
|
+
focusType?: "dynamic" | "static";
|
|
380
|
+
/** Restricts this camera to a specific group or variable context, or `"general"` for all contexts. */
|
|
381
|
+
scope?: K3CameraScope;
|
|
382
|
+
/** Orthographic zoom factor or perspective field-of-view multiplier. */
|
|
383
|
+
zoom?: number;
|
|
384
|
+
[key: string]: unknown;
|
|
367
385
|
}
|
|
368
386
|
/** A perspective camera configured in the K3 scene editor. */
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
387
|
+
interface K3PerspectiveCamera extends K3BaseCamera {
|
|
388
|
+
type: "PerspectiveCamera";
|
|
389
|
+
/** Intrinsic perspective parameters: field-of-view in degrees, aspect ratio, near/far clip planes. */
|
|
390
|
+
baseSettings?: {
|
|
391
|
+
fov: number;
|
|
392
|
+
aspect: number;
|
|
393
|
+
near: number;
|
|
394
|
+
far: number;
|
|
395
|
+
};
|
|
378
396
|
}
|
|
379
397
|
/** An orthographic camera configured in the K3 scene editor. */
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
398
|
+
interface K3OrthographicCamera extends K3BaseCamera {
|
|
399
|
+
type: "OrthographicCamera";
|
|
400
|
+
/** Intrinsic orthographic parameters: frustum left/right/top/bottom extents and near/far clip planes. */
|
|
401
|
+
baseSettings?: {
|
|
402
|
+
left: number;
|
|
403
|
+
right: number;
|
|
404
|
+
top: number;
|
|
405
|
+
bottom: number;
|
|
406
|
+
near: number;
|
|
407
|
+
far: number;
|
|
408
|
+
};
|
|
391
409
|
}
|
|
392
410
|
/** A scene camera — perspective or orthographic. Passed to screenshot / camera-list callbacks. */
|
|
393
|
-
|
|
411
|
+
type K3Camera = K3PerspectiveCamera | K3OrthographicCamera;
|
|
394
412
|
/** Pixel dimensions used for screenshot rendering. */
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
413
|
+
interface K3ScreenshotDimensions {
|
|
414
|
+
width: number;
|
|
415
|
+
height: number;
|
|
398
416
|
}
|
|
399
417
|
/** AR platform identifier. */
|
|
400
|
-
|
|
418
|
+
type K3ARPlatform = "iOS" | "AndroidOS";
|
|
401
419
|
/**
|
|
402
420
|
* Minimal structural representation of a Three.js scene graph node.
|
|
403
421
|
* Cast to `import("three").Object3D` for full Three.js access.
|
|
404
422
|
*/
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
423
|
+
interface K3Scene {
|
|
424
|
+
/** Three.js object type string, e.g. `"Scene"`, `"Mesh"`, `"Group"`. */
|
|
425
|
+
type: string;
|
|
426
|
+
/** Direct child nodes of this scene graph node. */
|
|
427
|
+
children: readonly K3Scene[];
|
|
428
|
+
/** Arbitrary metadata attached by K3 or the GLTF loader (e.g. material names, model IDs). */
|
|
429
|
+
userData: Record<string, unknown>;
|
|
430
|
+
traverse(callback: (object: K3Scene) => void): void;
|
|
431
|
+
getObjectByName(name: string): K3Scene | undefined;
|
|
414
432
|
}
|
|
415
433
|
/** Context passed to `core.onExportAR`. */
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
434
|
+
interface K3ARExportContext {
|
|
435
|
+
/** Platform the AR export is targeting. */
|
|
436
|
+
platform: K3ARPlatform;
|
|
437
|
+
/**
|
|
438
|
+
* Live Three.js scene graph.
|
|
439
|
+
* Cast to `import("three").Object3D` for full Three.js access.
|
|
440
|
+
*/
|
|
441
|
+
scene: K3Scene;
|
|
424
442
|
}
|
|
425
443
|
/** An uploaded file in a save operation (e.g. a screenshot per camera). */
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
444
|
+
interface K3UploadFile {
|
|
445
|
+
/** Camera name or custom key identifying this file. */
|
|
446
|
+
key: string;
|
|
447
|
+
/** The file data. */
|
|
448
|
+
file: Blob;
|
|
449
|
+
/** Optional explicit file name. */
|
|
450
|
+
fileName?: string;
|
|
433
451
|
}
|
|
434
452
|
/** Result returned to `core.onOpenPdf` after a save/order action. */
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
453
|
+
interface K3SaveResult {
|
|
454
|
+
/** Generated configuration code. */
|
|
455
|
+
code?: string;
|
|
456
|
+
/** Pricing verification info. */
|
|
457
|
+
price?: {
|
|
458
|
+
okay: boolean;
|
|
459
|
+
priceSent?: number;
|
|
460
|
+
priceCalculated?: number;
|
|
461
|
+
};
|
|
462
|
+
/** `true` if the save action encountered a server-side error. */
|
|
463
|
+
error?: boolean;
|
|
464
|
+
/** Optional human-readable error or status message from the server. */
|
|
465
|
+
message?: string;
|
|
466
|
+
/** URL to a shop or cart page the user can be redirected to after saving. */
|
|
467
|
+
shopLink?: string;
|
|
468
|
+
/** URL to the generated PDF. */
|
|
469
|
+
pdf?: string;
|
|
470
|
+
/** Suggested file name for the generated PDF download. */
|
|
471
|
+
pdfName?: string;
|
|
472
|
+
[key: string]: unknown;
|
|
455
473
|
}
|
|
456
474
|
/**
|
|
457
475
|
* Payload dispatched when a configuration is saved (e.g. "order", "cart", "pdf").
|
|
458
476
|
* Passed to `config.onSaveEvent`.
|
|
459
477
|
*/
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
[key: string]: unknown;
|
|
472
|
-
};
|
|
478
|
+
interface K3ConfigurationSavedEvent {
|
|
479
|
+
type: "K3ConfigurationSaved";
|
|
480
|
+
/** Save action key, e.g. "cart", "pdf", "email". */
|
|
481
|
+
actionKey: string;
|
|
482
|
+
/** Generated configuration code. */
|
|
483
|
+
code: string;
|
|
484
|
+
/** Optional customer data if collected during the save flow. */
|
|
485
|
+
customer?: {
|
|
486
|
+
email?: string;
|
|
487
|
+
firstName?: string;
|
|
488
|
+
lastName?: string;
|
|
473
489
|
[key: string]: unknown;
|
|
490
|
+
};
|
|
491
|
+
[key: string]: unknown;
|
|
474
492
|
}
|
|
475
493
|
/** A persisted configuration object. Passed to `config.onUpdate` and `config.onSave`. */
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
[key: string]: unknown;
|
|
496
|
-
};
|
|
497
|
-
/** Screenshot files, keyed by camera name then file name. */
|
|
498
|
-
files: Record<string, Record<string, string>>;
|
|
494
|
+
interface K3Configuration {
|
|
495
|
+
/** Database ID of the saved configuration record. */
|
|
496
|
+
id: number | string;
|
|
497
|
+
/** ID of the K3 app this configuration belongs to. */
|
|
498
|
+
appId: number;
|
|
499
|
+
/** Human-readable configuration code generated by the backend (e.g. "ABC-123"). */
|
|
500
|
+
code: string;
|
|
501
|
+
/** Calculated total price, or `null` if pricing is not configured. */
|
|
502
|
+
price: number | null;
|
|
503
|
+
/** ISO language code. */
|
|
504
|
+
lang: string;
|
|
505
|
+
/** Serialised selection state and BOM. */
|
|
506
|
+
json: {
|
|
507
|
+
/** Array of variable selection states at save time. */
|
|
508
|
+
variables: unknown[];
|
|
509
|
+
/** Bill-of-materials rows derived from the current selection. */
|
|
510
|
+
bom: unknown[];
|
|
511
|
+
/** Aggregated summary data (e.g. totals, labels). */
|
|
512
|
+
summary: unknown;
|
|
499
513
|
[key: string]: unknown;
|
|
514
|
+
};
|
|
515
|
+
/** Screenshot files, keyed by camera name then file name. */
|
|
516
|
+
files: Record<string, Record<string, string>>;
|
|
517
|
+
[key: string]: unknown;
|
|
500
518
|
}
|
|
501
519
|
/** A configuration not yet persisted (no `id` or `code`). */
|
|
502
|
-
|
|
520
|
+
type K3NewConfiguration = Omit<K3Configuration, "id" | "code">;
|
|
503
521
|
/** An individual variable selection state. */
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
[key: string]: unknown;
|
|
519
|
-
};
|
|
522
|
+
interface K3Selection {
|
|
523
|
+
/** Unique selection ID. */
|
|
524
|
+
id: string;
|
|
525
|
+
/** ID of the variable this selection belongs to. */
|
|
526
|
+
variableId: number;
|
|
527
|
+
/** ID of the chosen value, or `null` / `undefined` when no value is selected. */
|
|
528
|
+
valueId?: number | string | null;
|
|
529
|
+
data?: {
|
|
530
|
+
/** Number variable input value. */
|
|
531
|
+
inputValue?: number;
|
|
532
|
+
/** Text variable input value. */
|
|
533
|
+
inputText?: string;
|
|
534
|
+
/** Image variable URL. */
|
|
535
|
+
url?: string;
|
|
520
536
|
[key: string]: unknown;
|
|
537
|
+
};
|
|
538
|
+
[key: string]: unknown;
|
|
521
539
|
}
|
|
522
540
|
/** Full application snapshot passed to `core.preprocessFullApp` before the store initialises. */
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
[key: string]: unknown;
|
|
555
|
-
}>;
|
|
556
|
-
models: Array<{
|
|
557
|
-
id: number;
|
|
558
|
-
[key: string]: unknown;
|
|
559
|
-
}>;
|
|
560
|
-
images: Array<{
|
|
561
|
-
id: number;
|
|
562
|
-
[key: string]: unknown;
|
|
563
|
-
}>;
|
|
564
|
-
rules: Array<{
|
|
565
|
-
id: number;
|
|
566
|
-
[key: string]: unknown;
|
|
567
|
-
}>;
|
|
568
|
-
ruleItems: Array<{
|
|
569
|
-
id: number;
|
|
570
|
-
[key: string]: unknown;
|
|
571
|
-
}>;
|
|
541
|
+
interface K3FullApp {
|
|
542
|
+
app: {
|
|
543
|
+
id: number;
|
|
544
|
+
[key: string]: unknown;
|
|
545
|
+
};
|
|
546
|
+
client: {
|
|
547
|
+
id: number;
|
|
548
|
+
[key: string]: unknown;
|
|
549
|
+
};
|
|
550
|
+
groups: Array<{
|
|
551
|
+
id: number;
|
|
552
|
+
[key: string]: unknown;
|
|
553
|
+
}>;
|
|
554
|
+
variables: Array<{
|
|
555
|
+
id: number;
|
|
556
|
+
[key: string]: unknown;
|
|
557
|
+
}>;
|
|
558
|
+
values: Array<{
|
|
559
|
+
id: number | string;
|
|
560
|
+
[key: string]: unknown;
|
|
561
|
+
}>;
|
|
562
|
+
articles: Array<{
|
|
563
|
+
id: number;
|
|
564
|
+
[key: string]: unknown;
|
|
565
|
+
}>;
|
|
566
|
+
prices: Array<{
|
|
567
|
+
id: number;
|
|
568
|
+
[key: string]: unknown;
|
|
569
|
+
}>;
|
|
570
|
+
materials: Array<{
|
|
571
|
+
id: number;
|
|
572
572
|
[key: string]: unknown;
|
|
573
|
+
}>;
|
|
574
|
+
models: Array<{
|
|
575
|
+
id: number;
|
|
576
|
+
[key: string]: unknown;
|
|
577
|
+
}>;
|
|
578
|
+
images: Array<{
|
|
579
|
+
id: number;
|
|
580
|
+
[key: string]: unknown;
|
|
581
|
+
}>;
|
|
582
|
+
rules: Array<{
|
|
583
|
+
id: number;
|
|
584
|
+
[key: string]: unknown;
|
|
585
|
+
}>;
|
|
586
|
+
ruleItems: Array<{
|
|
587
|
+
id: number;
|
|
588
|
+
[key: string]: unknown;
|
|
589
|
+
}>;
|
|
590
|
+
[key: string]: unknown;
|
|
573
591
|
}
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
592
|
+
interface K3LogicExtensions {
|
|
593
|
+
/** Hooks into the configuration data lifecycle (create, update, save). */
|
|
594
|
+
config?: {
|
|
595
|
+
/**
|
|
596
|
+
* Called every time the active configuration object is updated in the store (e.g. on every selection change).
|
|
597
|
+
* Return a modified copy to alter prices, codes, or any other configuration field.
|
|
598
|
+
*/
|
|
599
|
+
onUpdate?: CallbackWithDescription<(config: K3Configuration) => K3Configuration>;
|
|
600
|
+
/**
|
|
601
|
+
* Called just before a configuration is persisted (order, cart, email, …).
|
|
602
|
+
* Return a modified copy to inject extra fields or override values before saving.
|
|
603
|
+
*/
|
|
604
|
+
onSave?: CallbackWithDescription<(config: K3Configuration | K3NewConfiguration) => K3Configuration | K3NewConfiguration>;
|
|
605
|
+
/**
|
|
606
|
+
* Called with the list of screenshot files that will be uploaded alongside the save.
|
|
607
|
+
* Return a modified array to add, remove, or rename files.
|
|
608
|
+
*/
|
|
609
|
+
onSaveFiles?: CallbackWithDescription<(files: K3UploadFile[]) => K3UploadFile[]>;
|
|
610
|
+
/**
|
|
611
|
+
* Called after a successful save action with the dispatched event payload.
|
|
612
|
+
* Return a modified payload to add custom fields consumed by downstream integrations.
|
|
613
|
+
*/
|
|
614
|
+
onSaveEvent?: CallbackWithDescription<(payload: K3ConfigurationSavedEvent) => K3ConfigurationSavedEvent>;
|
|
615
|
+
};
|
|
616
|
+
/** Hooks into the camera and screenshot pipeline. */
|
|
617
|
+
camera?: {
|
|
618
|
+
/**
|
|
619
|
+
* Called with the list of cameras used for automated screenshot capture.
|
|
620
|
+
* Return a modified array to add, remove, or reorder screenshot cameras.
|
|
621
|
+
*/
|
|
622
|
+
onSetScreenshotCameras?: CallbackWithDescription<(cameras: K3Camera[]) => K3Camera[]>;
|
|
623
|
+
/**
|
|
624
|
+
* Called with the full list of scene cameras available in the viewer.
|
|
625
|
+
* Return a modified array to filter or reorder cameras shown in the UI.
|
|
626
|
+
*/
|
|
627
|
+
onSetCameraList?: CallbackWithDescription<(cameras: K3Camera[]) => K3Camera[]>;
|
|
628
|
+
/**
|
|
629
|
+
* Called to determine the pixel dimensions used when rendering screenshots.
|
|
630
|
+
* Return modified dimensions to override the default canvas size.
|
|
631
|
+
*/
|
|
632
|
+
getScreenshotDimensions?: CallbackWithDescription<(dim: K3ScreenshotDimensions) => K3ScreenshotDimensions>;
|
|
633
|
+
};
|
|
634
|
+
/** Core app lifecycle hooks. */
|
|
635
|
+
core?: {
|
|
636
|
+
/**
|
|
637
|
+
* Called once with the full application data object before the K3 store is initialised.
|
|
638
|
+
* Return a modified copy to patch groups, variables, values, rules, or any other app data.
|
|
639
|
+
*/
|
|
640
|
+
preprocessFullApp?: CallbackWithDescription<(app: K3FullApp) => K3FullApp>;
|
|
641
|
+
/**
|
|
642
|
+
* Called after a PDF is generated and the save result is available.
|
|
643
|
+
* Use this to open, download, or post-process the PDF URL from `result.pdf`.
|
|
644
|
+
*/
|
|
645
|
+
onOpenPdf?: CallbackWithDescription<(result: K3SaveResult) => void>;
|
|
646
|
+
/**
|
|
647
|
+
* Called when the user triggers an AR export.
|
|
648
|
+
* Receives the target platform and live Three.js scene; must return a `Blob` of the AR file.
|
|
649
|
+
*/
|
|
650
|
+
onExportAR?: CallbackWithDescription<(ctx: K3ARExportContext) => Promise<Blob>>;
|
|
651
|
+
};
|
|
634
652
|
}
|
|
635
653
|
/**
|
|
636
654
|
* Declares a named slot where child models can be placed inside a parent dynamic model.
|
|
637
655
|
* Attach an array of these to `DynamicModel.slotDefinitions`.
|
|
638
656
|
*/
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
657
|
+
interface SlotDefinition {
|
|
658
|
+
/** Unique identifier (UUID) — primary key used in rule columns to reference this slot. */
|
|
659
|
+
id: string;
|
|
660
|
+
/** Human-readable name shown in the admin slot picker. */
|
|
661
|
+
name: string;
|
|
662
|
+
/** Optional fallback model ID rendered when no rule assigns a model to this slot. */
|
|
663
|
+
defaultModelId?: string | number;
|
|
646
664
|
}
|
|
647
665
|
/**
|
|
648
666
|
* A resolved model instance placed into a slot at runtime.
|
|
649
667
|
* Received via `DynamicModelComponentProps.slots[slotId]`.
|
|
650
668
|
*/
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
669
|
+
interface SlotModelInstance {
|
|
670
|
+
/** The model data object for this slot instance. */
|
|
671
|
+
model: {
|
|
672
|
+
id: string | number;
|
|
673
|
+
[key: string]: unknown;
|
|
674
|
+
};
|
|
675
|
+
/** URL of the model's 3D file, or `undefined` if this is a dynamic model with a component. */
|
|
676
|
+
fileURL: string | undefined;
|
|
677
|
+
/** The React component used to render this model if it is a dynamic model otherwise `undefined`. */
|
|
678
|
+
component: React.ComponentType<any> | undefined;
|
|
679
|
+
/** Evaluated props passed to the model component. */
|
|
680
|
+
props: Record<string, unknown>;
|
|
681
|
+
/** The rule-engine action that placed this model into the scene. */
|
|
682
|
+
modelAction: {
|
|
683
|
+
/** Unique ID of the model action record. */
|
|
684
|
+
id: string;
|
|
685
|
+
/** ID of the model referenced by this action. */
|
|
686
|
+
modelId: string | number;
|
|
687
|
+
/** Props overrides defined on the action. */
|
|
688
|
+
props?: Record<string, unknown>;
|
|
689
|
+
/** ID of the slot this action targets. */
|
|
690
|
+
slotId?: string;
|
|
691
|
+
[key: string]: unknown;
|
|
692
|
+
};
|
|
693
|
+
/** The slot definition this instance was placed into. */
|
|
694
|
+
slotDefinition: SlotDefinition;
|
|
695
|
+
/** Recursively nested slot instances when the slotted model itself has slots. */
|
|
696
|
+
slots?: Record<string, SlotModelInstance[]>;
|
|
679
697
|
}
|
|
680
698
|
/**
|
|
681
699
|
* Props automatically injected into every `DynamicModel.component` at runtime.
|
|
682
700
|
* Extend this with your custom prop types: `DynamicModelComponentProps & { myProp: string }`.
|
|
683
701
|
*/
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
}
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
}
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
702
|
+
interface DynamicModelComponentProps {
|
|
703
|
+
/**
|
|
704
|
+
* Resolved child model instances keyed by slot ID.
|
|
705
|
+
* Only present when the model has `slotDefinitions` and at least one slot is filled.
|
|
706
|
+
*/
|
|
707
|
+
slots?: Record<string, SlotModelInstance[]>;
|
|
708
|
+
[key: string]: unknown;
|
|
709
|
+
}
|
|
710
|
+
interface DynamicModel {
|
|
711
|
+
/** Unique type key used to reference this model from rule items, e.g. `"acme.my-model"`. */
|
|
712
|
+
type: string;
|
|
713
|
+
/** Human-readable display name shown in the admin model picker. */
|
|
714
|
+
label: string;
|
|
715
|
+
/** Describe what this dynamic model does. Shown in the plugin extensions dialog. */
|
|
716
|
+
description: string | LocalizedString;
|
|
717
|
+
/** Optional URL to a preview screenshot shown in the admin model picker. */
|
|
718
|
+
screenshot?: string;
|
|
719
|
+
/** List of Three.js material name patterns this model applies to in the scene. */
|
|
720
|
+
materials: string[];
|
|
721
|
+
/** When `true`, this model is excluded from AR exports (e.g. because it uses unsupported shaders). */
|
|
722
|
+
disabledForAR: boolean;
|
|
723
|
+
/** The React component rendered inside the Three.js canvas for this model. */
|
|
724
|
+
component: React.ComponentType<any>;
|
|
725
|
+
/**
|
|
726
|
+
* Schema for the admin props-editor dialog.
|
|
727
|
+
* Each key maps to a `ModelProp` descriptor that controls which editor widget is rendered.
|
|
728
|
+
*/
|
|
729
|
+
propsDialog: Record<string, ModelProp>;
|
|
730
|
+
/**
|
|
731
|
+
* Default prop values used when a new model action is created.
|
|
732
|
+
* Each key matches a `propsDialog` key; values may be plain data or `{ expression: string }`.
|
|
733
|
+
* Include `slotDefinitions` here to declare named slots for child models.
|
|
734
|
+
*/
|
|
735
|
+
defaultProps: {
|
|
736
|
+
slotDefinitions?: SlotDefinition[];
|
|
737
|
+
[key: string]: string | number | boolean | ModelPropDefault | undefined | SlotDefinition[];
|
|
738
|
+
};
|
|
739
|
+
/** Optional tag used to group or filter models in the admin UI. */
|
|
740
|
+
tag?: string;
|
|
741
|
+
}
|
|
742
|
+
interface ModelProp {
|
|
743
|
+
/**
|
|
744
|
+
* Editor widget type for this prop in the admin dialog.
|
|
745
|
+
* `"basic"` — plain text/number input.
|
|
746
|
+
* `"model"` — K3 model selector.
|
|
747
|
+
* `"variable"` — K3 variable selector.
|
|
748
|
+
* `"expression"` — expression / formula editor.
|
|
749
|
+
*/
|
|
750
|
+
type?: "basic" | "model" | "variable" | "expression";
|
|
751
|
+
/** Human-readable label shown next to the editor widget in the admin dialog. */
|
|
752
|
+
label?: string;
|
|
753
|
+
/** For type="variable": restrict which variable types are selectable. */
|
|
754
|
+
allowedTypes?: VariableTypes[];
|
|
755
|
+
/** For type="model": allow selecting multiple models. */
|
|
756
|
+
multiple?: boolean;
|
|
739
757
|
}
|
|
740
758
|
/** All variable type string literals. */
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
759
|
+
declare const VariableType: {
|
|
760
|
+
readonly List: "list";
|
|
761
|
+
readonly Color: "color";
|
|
762
|
+
readonly Number: "number";
|
|
763
|
+
readonly Text: "text";
|
|
764
|
+
readonly MultiSelect: "multiSelect";
|
|
765
|
+
readonly Boolean: "boolean";
|
|
766
|
+
readonly Image: "image";
|
|
767
|
+
readonly Upload: "upload";
|
|
768
|
+
readonly Components: "components";
|
|
769
|
+
readonly Information: "information";
|
|
752
770
|
};
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
771
|
+
type VariableTypes = (typeof VariableType)[keyof typeof VariableType];
|
|
772
|
+
interface ModelPropDefault {
|
|
773
|
+
/** An expression string evaluated at runtime instead of a static value (e.g. `"group.width * 2"`). */
|
|
774
|
+
expression?: string;
|
|
757
775
|
}
|
|
758
776
|
/** K3 Value object (list / color / boolean selection). */
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
777
|
+
interface Value {
|
|
778
|
+
/** Unique database ID of the value. */
|
|
779
|
+
id: number | string;
|
|
780
|
+
/** Optional stable string key for the value, usable as an alternative identifier. */
|
|
781
|
+
key?: string | null;
|
|
782
|
+
/** The underlying data value: a hex color string, boolean flag, or generic string payload. */
|
|
783
|
+
value?: string | boolean | null;
|
|
784
|
+
/** Human-readable display label shown in the configurator UI. */
|
|
785
|
+
label: string;
|
|
768
786
|
}
|
|
769
787
|
/**
|
|
770
788
|
* Context passed to plugin dynamic model components at runtime.
|
|
771
789
|
*/
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
790
|
+
interface PluginModelContext {
|
|
791
|
+
/** Only set during screenshot rendering. */
|
|
792
|
+
screenshotCameraName?: string;
|
|
793
|
+
/** The unique ID of the model action this instance is rendered for. */
|
|
794
|
+
modelActionId?: string;
|
|
777
795
|
}
|
|
778
796
|
/** @deprecated Use K3PluginDescriptor */
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
797
|
+
type K3Plugin = Pick<K3PluginDescriptor, "dynamicModels">;
|
|
798
|
+
//#endregion
|
|
799
|
+
export { CallbackWithDescription, CustomLayoutComponentProps, DynamicModel, DynamicModelComponentProps, HOC, HOCWithDescription, K3ARExportContext, K3ARPlatform, K3BomEntry, K3Camera, K3CameraScope, K3Configuration, K3ConfigurationSavedEvent, K3Coordinates, K3DialogExtensions, K3FullApp, K3InputExtensions, K3LayoutExtensions, K3LogicExtensions, K3NewConfiguration, K3OrderDialogExtensions, K3OrthographicCamera, K3PerspectiveCamera, K3Plugin, K3PluginDescriptor, K3SaveResult, K3Scene, K3ScreenshotDimensions, K3Selection, K3UIExtensions, K3UploadFile, K3VariableComponentProps, K3ViewerExtensions, K3WarningExtensions, LocalizedString, ModelProp, ModelPropDefault, PluginModelContext, SlotDefinition, SlotModelInstance, Value, VariableType, VariableTypes, VariableVisualisation, getSettings, init, useK3PluginSettings };
|