k3-plugin-api 1.4.3 → 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} +176 -240
- package/dist/index.d.ts +688 -680
- 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,292 +1,300 @@
|
|
|
1
|
-
import
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
//#region index.d.ts
|
|
4
|
+
|
|
2
5
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
6
|
+
* Get plugin-specific settings from the K3 store.
|
|
7
|
+
* Returns a snapshot of the current settings - not reactive.
|
|
8
|
+
* Use this in plugin components that need access to settings configured in the admin.
|
|
9
|
+
*
|
|
10
|
+
* @param pluginId - The unique plugin ID (e.g. "acme.my-plugin")
|
|
11
|
+
* @returns The settings object for this plugin, or `{}` if none are configured
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* const settings = getSettings("acme.my-plugin") as { apiKey?: string };
|
|
16
|
+
* if (settings.apiKey) {
|
|
17
|
+
* // Use API key
|
|
18
|
+
* }
|
|
19
|
+
* ```
|
|
5
20
|
*/
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* React hook to access plugin-specific settings.
|
|
9
|
-
* @param pluginId - The unique plugin ID (e.g. "acme.my-plugin")
|
|
10
|
-
* @returns The settings object for this plugin, or `{}` if none are configured
|
|
11
|
-
*/
|
|
12
|
-
useSettings: (pluginId: string) => unknown;
|
|
13
|
-
/**
|
|
14
|
-
* React hook to access the current Bill-of-Materials.
|
|
15
|
-
* @returns Array of BOM entries derived from the current selection
|
|
16
|
-
*/
|
|
17
|
-
useBOM: () => K3BomEntry[];
|
|
18
|
-
/**
|
|
19
|
-
* React hook to access the current total price.
|
|
20
|
-
* @returns The effective total price (MOV-adjusted or overall price)
|
|
21
|
-
*/
|
|
22
|
-
usePrice: () => number;
|
|
23
|
-
}
|
|
21
|
+
declare function getSettings(pluginId: string): unknown;
|
|
24
22
|
/**
|
|
25
|
-
*
|
|
26
|
-
*
|
|
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
|
+
* ```
|
|
27
34
|
*/
|
|
28
|
-
|
|
29
|
-
export declare const useBOM: K3Hooks["useBOM"];
|
|
30
|
-
export declare const usePrice: K3Hooks["usePrice"];
|
|
35
|
+
declare function useK3PluginSettings(pluginId: string): unknown;
|
|
31
36
|
/**
|
|
32
|
-
* Called by K3 when the plugin is loaded to inject runtime
|
|
37
|
+
* Called by K3 when the plugin is loaded to inject runtime API functions.
|
|
33
38
|
* @internal This function is called by K3 automatically - plugins should not call it directly.
|
|
34
39
|
*/
|
|
35
|
-
|
|
40
|
+
declare function init(api: {
|
|
41
|
+
getSettings: (pluginId: string) => unknown;
|
|
42
|
+
usePluginSettings: (pluginId: string) => unknown;
|
|
43
|
+
}): void;
|
|
36
44
|
/** A Higher-Order Component: takes the default component, returns a new one. */
|
|
37
|
-
|
|
45
|
+
type HOC<P = Record<string, unknown>> = (comp: React.FC<P>) => React.FC<P>;
|
|
38
46
|
/** Four editor languages supported by K3. */
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
47
|
+
type LocalizedString = {
|
|
48
|
+
de?: string;
|
|
49
|
+
en?: string;
|
|
50
|
+
nl?: string;
|
|
51
|
+
fr?: string;
|
|
44
52
|
};
|
|
45
53
|
/** An HOC slot with a required description for the admin UI. */
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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;
|
|
50
58
|
}
|
|
51
59
|
/** A logic callback with a required description for the admin UI. */
|
|
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
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
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;
|
|
132
140
|
}
|
|
133
141
|
/**
|
|
134
142
|
* Props passed to a plugin variable component (VariableVisualisation.component) at runtime.
|
|
135
143
|
* Use these to render a fully custom variable input UI.
|
|
136
144
|
*/
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
[key: string]: unknown;
|
|
154
|
-
};
|
|
155
|
-
[key: string]: unknown;
|
|
156
|
-
};
|
|
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;
|
|
157
161
|
[key: string]: unknown;
|
|
162
|
+
};
|
|
163
|
+
[key: string]: unknown;
|
|
158
164
|
};
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
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;
|
|
168
174
|
};
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
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;
|
|
189
197
|
}
|
|
190
198
|
/**
|
|
191
199
|
* A plugin-registered variable renderer (VariableVisualisation).
|
|
192
200
|
* Displayed as a selectable option in the admin visualisation chooser.
|
|
193
201
|
* The component owns its full UI — label, input, chrome.
|
|
194
202
|
*/
|
|
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
|
-
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
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;
|
|
264
272
|
}
|
|
265
273
|
/**
|
|
266
274
|
* A single Bill-of-Materials entry exposed to plugin components.
|
|
267
275
|
* Mirrors the internal BOMEntry shape using only primitive/simple types.
|
|
268
276
|
*/
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
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;
|
|
290
298
|
}
|
|
291
299
|
/**
|
|
292
300
|
* Props automatically injected into every `customLayoutComponents` entry.
|
|
@@ -294,498 +302,498 @@ export interface K3BomEntry {
|
|
|
294
302
|
* @remarks TODO(WIP) — This interface will grow as more configurator data is
|
|
295
303
|
* exposed to plugins.
|
|
296
304
|
*/
|
|
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
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
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
|
+
};
|
|
333
341
|
}
|
|
334
342
|
/** [x, y, z] coordinate tuple used on camera objects. */
|
|
335
|
-
|
|
343
|
+
type K3Coordinates = [number, number, number];
|
|
336
344
|
/**
|
|
337
345
|
* Restricts a camera to a specific configurator context.
|
|
338
346
|
* `"group"` / `"variable"` — camera activates only when that item is in view; `id` is the entity's database ID.
|
|
339
347
|
* `"general"` — camera is always available regardless of the active group or variable.
|
|
340
348
|
*/
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
349
|
+
type K3CameraScope = {
|
|
350
|
+
type: "group" | "variable";
|
|
351
|
+
id: number;
|
|
344
352
|
} | {
|
|
345
|
-
|
|
346
|
-
|
|
353
|
+
type: "general";
|
|
354
|
+
id?: null;
|
|
347
355
|
};
|
|
348
356
|
interface K3BaseCamera {
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
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;
|
|
377
385
|
}
|
|
378
386
|
/** A perspective camera configured in the K3 scene editor. */
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
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
|
+
};
|
|
388
396
|
}
|
|
389
397
|
/** An orthographic camera configured in the K3 scene editor. */
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
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
|
+
};
|
|
401
409
|
}
|
|
402
410
|
/** A scene camera — perspective or orthographic. Passed to screenshot / camera-list callbacks. */
|
|
403
|
-
|
|
411
|
+
type K3Camera = K3PerspectiveCamera | K3OrthographicCamera;
|
|
404
412
|
/** Pixel dimensions used for screenshot rendering. */
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
413
|
+
interface K3ScreenshotDimensions {
|
|
414
|
+
width: number;
|
|
415
|
+
height: number;
|
|
408
416
|
}
|
|
409
417
|
/** AR platform identifier. */
|
|
410
|
-
|
|
418
|
+
type K3ARPlatform = "iOS" | "AndroidOS";
|
|
411
419
|
/**
|
|
412
420
|
* Minimal structural representation of a Three.js scene graph node.
|
|
413
421
|
* Cast to `import("three").Object3D` for full Three.js access.
|
|
414
422
|
*/
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
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;
|
|
424
432
|
}
|
|
425
433
|
/** Context passed to `core.onExportAR`. */
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
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;
|
|
434
442
|
}
|
|
435
443
|
/** An uploaded file in a save operation (e.g. a screenshot per camera). */
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
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;
|
|
443
451
|
}
|
|
444
452
|
/** Result returned to `core.onOpenPdf` after a save/order action. */
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
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;
|
|
465
473
|
}
|
|
466
474
|
/**
|
|
467
475
|
* Payload dispatched when a configuration is saved (e.g. "order", "cart", "pdf").
|
|
468
476
|
* Passed to `config.onSaveEvent`.
|
|
469
477
|
*/
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
[key: string]: unknown;
|
|
482
|
-
};
|
|
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;
|
|
483
489
|
[key: string]: unknown;
|
|
490
|
+
};
|
|
491
|
+
[key: string]: unknown;
|
|
484
492
|
}
|
|
485
493
|
/** A persisted configuration object. Passed to `config.onUpdate` and `config.onSave`. */
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
[key: string]: unknown;
|
|
506
|
-
};
|
|
507
|
-
/** Screenshot files, keyed by camera name then file name. */
|
|
508
|
-
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;
|
|
509
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;
|
|
510
518
|
}
|
|
511
519
|
/** A configuration not yet persisted (no `id` or `code`). */
|
|
512
|
-
|
|
520
|
+
type K3NewConfiguration = Omit<K3Configuration, "id" | "code">;
|
|
513
521
|
/** An individual variable selection state. */
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
[key: string]: unknown;
|
|
529
|
-
};
|
|
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;
|
|
530
536
|
[key: string]: unknown;
|
|
537
|
+
};
|
|
538
|
+
[key: string]: unknown;
|
|
531
539
|
}
|
|
532
540
|
/** Full application snapshot passed to `core.preprocessFullApp` before the store initialises. */
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
[key: string]: unknown;
|
|
573
|
-
}>;
|
|
574
|
-
rules: Array<{
|
|
575
|
-
id: number;
|
|
576
|
-
[key: string]: unknown;
|
|
577
|
-
}>;
|
|
578
|
-
ruleItems: Array<{
|
|
579
|
-
id: number;
|
|
580
|
-
[key: string]: unknown;
|
|
581
|
-
}>;
|
|
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
|
+
[key: string]: unknown;
|
|
573
|
+
}>;
|
|
574
|
+
models: Array<{
|
|
575
|
+
id: number;
|
|
576
|
+
[key: string]: unknown;
|
|
577
|
+
}>;
|
|
578
|
+
images: Array<{
|
|
579
|
+
id: number;
|
|
582
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;
|
|
583
591
|
}
|
|
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
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
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
|
+
};
|
|
644
652
|
}
|
|
645
653
|
/**
|
|
646
654
|
* Declares a named slot where child models can be placed inside a parent dynamic model.
|
|
647
655
|
* Attach an array of these to `DynamicModel.slotDefinitions`.
|
|
648
656
|
*/
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
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;
|
|
656
664
|
}
|
|
657
665
|
/**
|
|
658
666
|
* A resolved model instance placed into a slot at runtime.
|
|
659
667
|
* Received via `DynamicModelComponentProps.slots[slotId]`.
|
|
660
668
|
*/
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
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[]>;
|
|
689
697
|
}
|
|
690
698
|
/**
|
|
691
699
|
* Props automatically injected into every `DynamicModel.component` at runtime.
|
|
692
700
|
* Extend this with your custom prop types: `DynamicModelComponentProps & { myProp: string }`.
|
|
693
701
|
*/
|
|
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
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
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;
|
|
749
757
|
}
|
|
750
758
|
/** All variable type string literals. */
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
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";
|
|
762
770
|
};
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
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;
|
|
767
775
|
}
|
|
768
776
|
/** K3 Value object (list / color / boolean selection). */
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
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;
|
|
778
786
|
}
|
|
779
787
|
/**
|
|
780
788
|
* Context passed to plugin dynamic model components at runtime.
|
|
781
789
|
*/
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
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;
|
|
787
795
|
}
|
|
788
796
|
/** @deprecated Use K3PluginDescriptor */
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
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 };
|