k3-plugin-api 1.4.5 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -13,7 +13,7 @@
13
13
 
14
14
  ## What is this package?
15
15
 
16
- `k3-plugin-api` contains the **TypeScript types** required to build K3 plugins — packages that extend the K3 configurator runtime with custom UI components, 3D models, pricing logic, and lifecycle hooks. The package ships zero runtime code; every export is a type, interface, or const enum.
16
+ `k3-plugin-api` provides the **TypeScript types and runtime hooks** required to build K3 plugins — packages that extend the K3 configurator runtime with custom UI components, 3D models, pricing logic, and lifecycle hooks. It ships a thin runtime layer (reactive hooks like `useBOM()`, `useApp()`, etc.) that K3 injects at load time, plus all the type definitions for the plugin descriptor API.
17
17
 
18
18
  ---
19
19
 
@@ -41,14 +41,20 @@ const plugin: K3PluginDescriptor = {
41
41
  ui: {
42
42
  layout: {
43
43
  // wrap the default header with your own component
44
- header: (Default) => (props) => <MyCustomHeader fallback={Default} {...props} />,
44
+ header: {
45
+ hoc: (Default) => (props) => <MyCustomHeader fallback={Default} {...props} />,
46
+ description: "Custom branded header",
47
+ },
45
48
  },
46
49
  },
47
50
 
48
51
  logic: {
49
52
  config: {
50
53
  // attach a custom order code to the configuration before it is persisted
51
- onSave: (config) => ({ ...config, code: `TEST-${config.code}` }),
54
+ onSave: {
55
+ fn: (config) => ({ ...config, code: `TEST-${config.code}` }),
56
+ description: "Prepend TEST- to configuration code",
57
+ },
52
58
  },
53
59
  },
54
60
  };
@@ -64,35 +70,62 @@ K3 plugins can extend three layers of the configurator.
64
70
 
65
71
  ### Runtime Hooks
66
72
 
67
- Plugins can access K3 configurator state at runtime using React hooks. These hooks are automatically injected when the plugin is loaded.
73
+ Plugins can access K3 configurator state at runtime using React hooks. These are automatically injected when the plugin is loaded via `init()`.
68
74
 
69
75
  ```ts
70
- import { useSettings, useBOM, usePrice } from "k3-plugin-api";
76
+ import {
77
+ useK3PluginSettings,
78
+ useConfigurationVariables,
79
+ useConfigurationVariable,
80
+ useBOM,
81
+ useTotalPrice,
82
+ useFormattedTotalPrice,
83
+ useApp,
84
+ getSettings,
85
+ } from "k3-plugin-api";
71
86
 
72
87
  const MyComponent = () => {
73
- // Access plugin-specific settings
74
- const settings = useSettings("acme.my-plugin");
75
-
76
- // Access current Bill-of-Materials
88
+ // Reactive plugin settings
89
+ const settings = useK3PluginSettings("acme.my-plugin") as { apiKey?: string };
90
+
91
+ // All configuration variables as a key-value map
92
+ const variables = useConfigurationVariables();
93
+
94
+ // Single variable by key
95
+ const color = useConfigurationVariable("color");
96
+
97
+ // Bill-of-Materials
77
98
  const bom = useBOM();
78
-
79
- // Access current total price
80
- const price = usePrice();
81
-
99
+
100
+ // Price (raw number or formatted string)
101
+ const price = useTotalPrice();
102
+ const formattedPrice = useFormattedTotalPrice();
103
+
104
+ // App metadata (product, subscription, etc.)
105
+ const app = useApp();
106
+
82
107
  return (
83
108
  <div>
84
109
  <p>API Key: {settings.apiKey}</p>
85
110
  <p>Total items: {bom.length}</p>
86
- <p>Price: {price}</p>
111
+ <p>Price: {formattedPrice}</p>
87
112
  </div>
88
113
  );
89
114
  };
90
115
  ```
91
116
 
92
- Available hooks:
93
- - `useSettings(pluginId: string)` — Access settings for a specific plugin
94
- - `useBOM()` — Get current Bill-of-Materials entries
95
- - `usePrice()` Get current total price (MOV-adjusted or overall)
117
+ Available hooks & functions:
118
+
119
+ | Export | Description |
120
+ | ------------------------------- | ----------------------------------------------------------------------------- |
121
+ | `getSettings(pluginId)` | Non-reactive snapshot of plugin settings |
122
+ | `useK3PluginSettings(pluginId)` | Reactive hook — re-renders on settings change |
123
+ | `useConfigurationVariables()` | All configuration variables as `Record<string, K3ConfigurationVariableEntry>` |
124
+ | `useConfigurationVariable(key)` | Single variable value by its stable key |
125
+ | `useBOM()` | Current Bill-of-Materials (`K3BomEntry[]`) |
126
+ | `useTotalPrice()` | Raw total price as `number` |
127
+ | `useFormattedTotalPrice()` | Locale-formatted price string (e.g. `"1.299,00 €"`) |
128
+ | `useApp()` | App metadata (`K3AppInfo \| null`) — product, subscription, feature flags |
96
129
 
97
130
  ### `settings` — Plugin Settings Component
98
131
 
@@ -120,6 +153,7 @@ const plugin: K3PluginDescriptor = {
120
153
  ```
121
154
 
122
155
  The `settings` component receives:
156
+
123
157
  - `settings: unknown` — The current settings object (initially `{}`)
124
158
  - `onSave: (settings: unknown) => void` — Callback to persist updated settings
125
159
 
@@ -187,18 +221,24 @@ const plugin: K3PluginDescriptor = {
187
221
 
188
222
  ## Key Types
189
223
 
190
- | Type | Description |
191
- | --------------------------- | --------------------------------------------------------------- |
192
- | `K3PluginDescriptor` | Root descriptor object exported by a plugin |
193
- | `K3Hooks` | Runtime hooks interface (useSettings, useBOM, usePrice) |
194
- | `HOC<P>` | Higher-Order Component: `(Default: FC<P>) => FC<P>` |
195
- | `VariableVisualisation` | Descriptor for a custom input visualisation |
196
- | `K3VariableComponentProps` | Props injected into a custom variable renderer |
197
- | `DynamicModel` | 3D model type definition for the viewer |
198
- | `K3Configuration` | A persisted configuration with code, price, and selection JSON |
199
- | `K3ConfigurationSavedEvent` | Event payload dispatched on completed save |
200
- | `K3BomEntry` | Single Bill-of-Materials entry |
201
- | `VariableType` | Const enum of all variable types |
224
+ | Type | Description |
225
+ | ------------------------------ | -------------------------------------------------------------- |
226
+ | `K3PluginDescriptor` | Root descriptor object exported by a plugin |
227
+ | `HOC<P>` | Higher-Order Component: `(Default: FC<P>) => FC<P>` |
228
+ | `HOCWithDescription` | HOC + admin description (used in layout/dialog slots) |
229
+ | `CallbackWithDescription<T>` | Logic callback + admin description |
230
+ | `VariableVisualisation` | Descriptor for a custom input visualisation |
231
+ | `K3VariableComponentProps` | Props injected into a custom variable renderer |
232
+ | `DynamicModel` | 3D model type definition for the viewer |
233
+ | `K3Configuration` | A persisted configuration with code, price, and selection JSON |
234
+ | `K3ConfigurationSavedEvent` | Event payload dispatched on completed save |
235
+ | `K3BomEntry` | Single Bill-of-Materials entry |
236
+ | `K3ConfigurationVariables` | Full variables map keyed by variable key |
237
+ | `K3ConfigurationVariableEntry` | Single variable value (number, string, or simplified value) |
238
+ | `K3SimplifiedValue` | Resolved value option (id, key, label, value, thumbnail) |
239
+ | `K3AppInfo` | App metadata (product, subscription, feature flags) |
240
+ | `K3FullApp` | Full app snapshot passed to `preprocessFullApp` |
241
+ | `VariableType` | Const enum of all variable types |
202
242
 
203
243
  ---
204
244
 
package/dist/index.cjs ADDED
@@ -0,0 +1,175 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region index.ts
3
+ /**
4
+ * Internal getter function injected by K3 at runtime.
5
+ */
6
+ let _getSettings = null;
7
+ /**
8
+ * Internal reactive hook injected by K3 at runtime.
9
+ */
10
+ let _usePluginSettings = null;
11
+ /** @internal */
12
+ let _useSelections = null;
13
+ /** @internal */
14
+ let _useSelectionByVariableKey = null;
15
+ /** @internal */
16
+ let _useBOM = null;
17
+ /** @internal */
18
+ let _useTotalPrice = null;
19
+ /** @internal */
20
+ let _useFormattedTotalPrice = null;
21
+ /** @internal */
22
+ let _useApp = null;
23
+ /**
24
+ * Get plugin-specific settings from the K3 store.
25
+ * Returns a snapshot of the current settings - not reactive.
26
+ * Use this in plugin components that need access to settings configured in the admin.
27
+ *
28
+ * @param pluginId - The unique plugin ID (e.g. "acme.my-plugin")
29
+ * @returns The settings object for this plugin, or `{}` if none are configured
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * const settings = getSettings("acme.my-plugin") as { apiKey?: string };
34
+ * if (settings.apiKey) {
35
+ * // Use API key
36
+ * }
37
+ * ```
38
+ */
39
+ function getSettings(pluginId) {
40
+ if (!_getSettings) throw new Error("k3-plugin-api not initialized. Make sure K3 calls init() before using getSettings().");
41
+ return _getSettings(pluginId);
42
+ }
43
+ /**
44
+ * Get plugin-specific settings from the K3 store as a reactive hook.
45
+ * Re-renders the component whenever the settings change.
46
+ * Use this in plugin React components.
47
+ *
48
+ * @param pluginId - The unique plugin ID (e.g. "acme.my-plugin")
49
+ * @returns The settings object for this plugin, or `{}` if none are configured
50
+ *
51
+ * @example
52
+ * ```typescript
53
+ * const settings = useK3PluginSettings("acme.my-plugin") as { apiKey?: string };
54
+ * ```
55
+ */
56
+ function useK3PluginSettings(pluginId) {
57
+ if (!_usePluginSettings) throw new Error("k3-plugin-api not initialized. Make sure K3 calls init() before using useK3PluginSettings().");
58
+ return _usePluginSettings(pluginId);
59
+ }
60
+ /**
61
+ * Reactive hook – returns all current configuration variables as a key-value map.
62
+ * Keys are the variable's stable `key` string. Values are resolved (labels, not raw IDs).
63
+ * Re-renders whenever any selection changes.
64
+ *
65
+ * @example
66
+ * ```typescript
67
+ * const variables = useConfigurationVariables();
68
+ * const color = variables["color"] as K3SimplifiedValue;
69
+ * ```
70
+ */
71
+ function useConfigurationVariables() {
72
+ if (!_useSelections) throw new Error("k3-plugin-api not initialized. Make sure K3 calls init() before using useConfigurationVariables().");
73
+ return _useSelections();
74
+ }
75
+ /**
76
+ * Reactive hook – returns the resolved value for a specific variable by its key,
77
+ * or `undefined` if the variable has no active selection.
78
+ *
79
+ * @param variableKey - The stable key of the variable (as defined in the admin)
80
+ *
81
+ * @example
82
+ * ```typescript
83
+ * const width = useConfigurationVariable("width") as number;
84
+ * const material = useConfigurationVariable("material") as K3SimplifiedValue;
85
+ * ```
86
+ */
87
+ function useConfigurationVariable(variableKey) {
88
+ if (!_useSelectionByVariableKey) throw new Error("k3-plugin-api not initialized. Make sure K3 calls init() before using useConfigurationVariable().");
89
+ return _useSelectionByVariableKey(variableKey);
90
+ }
91
+ /**
92
+ * Reactive hook – returns the current Bill of Materials (Stückliste).
93
+ * Re-renders whenever the BOM changes (i.e. on any selection change).
94
+ *
95
+ * @example
96
+ * ```typescript
97
+ * const bom = useBOM() as K3BomEntry[];
98
+ * const total = bom.reduce((sum, e) => sum + e.price.price * e.qty, 0);
99
+ * ```
100
+ */
101
+ function useBOM() {
102
+ if (!_useBOM) throw new Error("k3-plugin-api not initialized. Make sure K3 calls init() before using useBOM().");
103
+ return _useBOM();
104
+ }
105
+ /**
106
+ * Reactive hook – returns the current total price as a raw number.
107
+ * Re-renders whenever the price changes.
108
+ */
109
+ function useTotalPrice() {
110
+ if (!_useTotalPrice) throw new Error("k3-plugin-api not initialized. Make sure K3 calls init() before using useTotalPrice().");
111
+ return _useTotalPrice();
112
+ }
113
+ /**
114
+ * Reactive hook – returns the current total price formatted as a locale string
115
+ * (e.g. `"1.299,00 €"`), ready for display.
116
+ * Re-renders whenever the price changes.
117
+ */
118
+ function useFormattedTotalPrice() {
119
+ if (!_useFormattedTotalPrice) throw new Error("k3-plugin-api not initialized. Make sure K3 calls init() before using useFormattedTotalPrice().");
120
+ return _useFormattedTotalPrice();
121
+ }
122
+ /**
123
+ * Reactive hook – returns the current K3 app metadata, including the booked
124
+ * product identifier. Returns `null` while the app has not yet loaded.
125
+ *
126
+ * @example
127
+ * ```typescript
128
+ * const app = useApp() as K3AppInfo | null;
129
+ * if (app?.product === "k3-pro") {
130
+ * // enable pro-only features
131
+ * }
132
+ * ```
133
+ */
134
+ function useApp() {
135
+ if (!_useApp) throw new Error("k3-plugin-api not initialized. Make sure K3 calls init() before using useApp().");
136
+ return _useApp();
137
+ }
138
+ /**
139
+ * Called by K3 when the plugin is loaded to inject runtime API functions.
140
+ * @internal This function is called by K3 automatically - plugins should not call it directly.
141
+ */
142
+ function init(api) {
143
+ _getSettings = api.getSettings;
144
+ _usePluginSettings = api.usePluginSettings;
145
+ _useSelections = api.useConfigurationVariables;
146
+ _useSelectionByVariableKey = api.useConfigurationVariable;
147
+ _useBOM = api.useBOM;
148
+ _useTotalPrice = api.useTotalPrice;
149
+ _useFormattedTotalPrice = api.useFormattedTotalPrice;
150
+ _useApp = api.useApp;
151
+ }
152
+ /** All variable type string literals. */
153
+ const VariableType = {
154
+ List: "list",
155
+ Color: "color",
156
+ Number: "number",
157
+ Text: "text",
158
+ MultiSelect: "multiSelect",
159
+ Boolean: "boolean",
160
+ Image: "image",
161
+ Upload: "upload",
162
+ Components: "components",
163
+ Information: "information"
164
+ };
165
+ //#endregion
166
+ exports.VariableType = VariableType;
167
+ exports.getSettings = getSettings;
168
+ exports.init = init;
169
+ exports.useApp = useApp;
170
+ exports.useBOM = useBOM;
171
+ exports.useConfigurationVariable = useConfigurationVariable;
172
+ exports.useConfigurationVariables = useConfigurationVariables;
173
+ exports.useFormattedTotalPrice = useFormattedTotalPrice;
174
+ exports.useK3PluginSettings = useK3PluginSettings;
175
+ exports.useTotalPrice = useTotalPrice;