@magicfeedback/native 2.1.7-alpha.9 → 2.1.12

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.
Files changed (31) hide show
  1. package/README.md +315 -467
  2. package/dist/magicfeedback-sdk.browser.js +1 -1
  3. package/dist/magicfeedback-sdk.node.js +1 -1
  4. package/dist/styles/magicfeedback-default.css +193 -80
  5. package/dist/types/src/models/pageGraphs.d.ts +52 -0
  6. package/dist/types/src/models/types.d.ts +92 -3
  7. package/dist/types/src/render/helpers.d.ts +3 -0
  8. package/dist/types/src/render/ratingHelpers.d.ts +3 -0
  9. package/dist/types/src/render/registry.d.ts +3 -0
  10. package/dist/types/src/render/renderBoolean.d.ts +2 -0
  11. package/dist/types/src/render/renderChoice.d.ts +2 -0
  12. package/dist/types/src/render/renderConsent.d.ts +2 -0
  13. package/dist/types/src/render/renderDate.d.ts +2 -0
  14. package/dist/types/src/render/renderEmail.d.ts +2 -0
  15. package/dist/types/src/render/renderInfoPage.d.ts +2 -0
  16. package/dist/types/src/render/renderLongText.d.ts +2 -0
  17. package/dist/types/src/render/renderMatrix.d.ts +2 -0
  18. package/dist/types/src/render/renderMultipleChoiceImage.d.ts +2 -0
  19. package/dist/types/src/render/renderNumber.d.ts +2 -0
  20. package/dist/types/src/render/renderPassword.d.ts +2 -0
  21. package/dist/types/src/render/renderPointSystem.d.ts +2 -0
  22. package/dist/types/src/render/renderPriorityList.d.ts +2 -0
  23. package/dist/types/src/render/renderRatingEmoji.d.ts +2 -0
  24. package/dist/types/src/render/renderRatingNumber.d.ts +2 -0
  25. package/dist/types/src/render/renderRatingStar.d.ts +2 -0
  26. package/dist/types/src/render/renderSelect.d.ts +2 -0
  27. package/dist/types/src/render/renderText.d.ts +2 -0
  28. package/dist/types/src/render/renderUploadFile.d.ts +2 -0
  29. package/dist/types/src/render/renderUploadImage.d.ts +2 -0
  30. package/dist/types/src/render/types.d.ts +20 -0
  31. package/package.json +1 -1
package/README.md CHANGED
@@ -1,552 +1,400 @@
1
- # MagicFeedbackAI SDK
1
+ # MagicFeedback SDK
2
2
 
3
- This JavaScript library empowers you to effortlessly integrate the power
4
- of [MagicFeedback.io](https://magicfeedback.io/) into your web applications. With minimal code, you can capture valuable
5
- user feedback and insights, driving continuous improvement and enhancing user experience.
3
+ Browser SDK for rendering MagicFeedback surveys/forms, resuming sessions, previewing question definitions, and sending feedback directly from your app.
6
4
 
7
- ## Table of Contents
5
+ ## What this SDK covers
8
6
 
9
- * [Install](#install)
10
- * [Init](#init)
11
- * [How to use](#how-to-use)
12
- * [Style](#style)
7
+ - Render a hosted MagicFeedback form with `appId` + `publicKey`
8
+ - Resume an existing survey flow with `sessionId`
9
+ - Submit feedback directly when you already own the UI
10
+ - Preview one or more question objects locally
11
+ - Use the bundled default theme or override CSS variables
12
+
13
+ ## Important before you start
14
+
15
+ - This is a browser-oriented SDK. It relies on `window`, `document`, `navigator`, and `localStorage`.
16
+ - Use it on the client side only. Server-side rendering and Node-only execution are not supported.
17
+ - Call `magicfeedback.init()` before `form()`, `session()`, or `send()`. `init()` sets the API base URL.
18
+ - `form.generate()` expects a DOM element id such as `"survey-root"`, not a CSS selector such as `"#survey-root"`.
13
19
 
14
20
  ## Install
15
21
 
16
- This library is available as a [package on NPM](https://www.npmjs.com/package/@magicfeedback/native). To install into a
17
- project using NPM with a front-end packager such as [Browserify](http://browserify.org/)
18
- or [Webpack](https://webpack.github.io/):
22
+ Install from [npm](https://www.npmjs.com/package/@magicfeedback/native):
19
23
 
20
24
  ```sh
21
- npm i @magicfeedback/native
25
+ npm install @magicfeedback/native
22
26
  ```
23
27
 
24
- You can then require the lib like a standard Node.js module:
25
-
26
- ```js
27
- var magicfeedback = require("@magicfeedback/native");
28
-
29
- // or
28
+ ## Quick start
30
29
 
31
- import magicfeedback from "@magicfeedback/native";
30
+ ### Plain HTML
32
31
 
32
+ ```html
33
+ <link
34
+ rel="stylesheet"
35
+ href="./node_modules/@magicfeedback/native/dist/styles/magicfeedback-default.css"
36
+ />
37
+
38
+ <div id="survey-root"></div>
39
+
40
+ <script src="./node_modules/@magicfeedback/native/dist/magicfeedback-sdk.browser.js"></script>
41
+ <script>
42
+ window.magicfeedback.init({
43
+ env: "prod",
44
+ debug: false
45
+ });
46
+
47
+ const form = window.magicfeedback.form("APP_ID", "PUBLIC_KEY");
48
+
49
+ form.generate("survey-root", {
50
+ addButton: true,
51
+ addSuccessScreen: true
52
+ });
53
+ </script>
33
54
  ```
34
55
 
35
- ## Init
56
+ ### Vite / Webpack / SPA
36
57
 
37
- This method is optional. You can start actived the debug mode to see on console the messages
58
+ ```ts
59
+ import magicfeedback from "@magicfeedback/native";
60
+ import "@magicfeedback/native/dist/styles/magicfeedback-default.css";
38
61
 
39
- ```js
40
62
  magicfeedback.init({
41
- debug: true | false, // Default false
42
- env: "prod" // Default
43
- })
63
+ env: "prod"
64
+ });
44
65
 
45
- ```
66
+ const form = magicfeedback.form("APP_ID", "PUBLIC_KEY");
46
67
 
47
- ## How to use
48
-
49
- This guide provides instructions for utilizing various features and functionalities of the application. Each section
50
- below highlights a specific use case and provides a code snippet to demonstrate its implementation.
51
-
52
- ### A. Generate feedback forms
53
-
54
- The feedback form generation functionality allows you to easily create and display feedback forms on your website. This
55
- section provides an overview of how to use this feature and the necessary code snippets.
56
-
57
- To generate a feedback form, you need to include the following HTML code snippet in your web page:
68
+ await form.generate("survey-root", {
69
+ addButton: true,
70
+ addSuccessScreen: true
71
+ });
72
+ ```
58
73
 
59
74
  ```html
60
-
61
- <div id="demo_form_div"></div>
75
+ <div id="survey-root"></div>
62
76
  ```
63
77
 
64
- This code snippet creates a placeholder element with the ID "demo_form_div" where the feedback form will be inserted.
65
-
66
- Next, you need to include the following JavaScript code snippet in your application:
78
+ ## Initialization
67
79
 
68
- ```js
69
- let form = window.magicfeedback.form(
70
- "$_APP_ID",
71
- "$_PUBLIC_KEY"
72
- );
73
- // or
74
- let form = window.magicfeedback.session(
75
- "$_SESSION_ID",
76
- );
80
+ `init()` should be called once before any networked usage.
77
81
 
78
- form.generate(
79
- "demo_form_div",
80
- {
81
- addButton: true | false, // Default false, option to add a button to send the form
82
- sendButtonText: string, // Default "Send", option to change the text of the send button
83
- backButtonText: string, // Default "Back", option to change the text of the back button
84
- nextButtonText: string, // Default "Next", option to change the text of the next button
85
- addSuccessScreen: boolean, // Default flase, option to add a success screen after send the form
86
- successMessage: string, // Default "Thank you for your feedback!", option to change the success message
87
- questionFormat: "standard" | "slim", // Default "standard", option to change the format of the questions.
88
- getMetaData: boolean, // Default true, option to get the metadata of the form
89
- beforeSubmitEvent: ({
90
- loading: boolean,
91
- progress: number,
92
- total: number
93
- }) => {
94
- }, //Function to execute before send the form
95
- afterSubmitEvent: ({
96
- loading: boolean,
97
- progress: number,
98
- total: number,
99
- response: string, // Response of the server if everything is ok
100
- error: string, // Error of the server if something is wrong
101
- }) => {
102
- }, //Function to execute after send the form with the response
103
- onLoadedEvent: ({
104
- loading: boolean,
105
- progress: number,
106
- total: number,
107
- formData: FormData
108
- }) => {
109
- }, //Function to execute after load the form
110
- onBackEvent: ({
111
- loading: boolean,
112
- progress: number,
113
- followup: boolean,
114
- error: string, // Error of the server if something is wrong
115
- }) => {
116
- } //Function to execute after back the form
117
- /*
118
- class FormData {
119
- id: string;
120
- name: string;
121
- description: string;
122
- type: string;
123
- identity: string;
124
- status: string;
125
- createdAt: Date;
126
- updatedAt: Date;
127
- externalId?: string | null;
128
- companyId: string;
129
- productId: string;
130
- userId: string;
131
- setting: Record<string, any>;
132
- conf: Record<string, any>;
133
- */
134
- }
135
- )
82
+ ```ts
83
+ magicfeedback.init({
84
+ env: "prod",
85
+ debug: false,
86
+ dryRun: false
87
+ });
136
88
  ```
137
89
 
138
- In this code snippet, you need to replace $_APP_ID with the actual ID of your feedback application. This ID is provided
139
- by the magicfeedback service.
140
-
141
- The **form.generate()** function generates the feedback form inside the specified container element ("demo_form_div" in
142
- this example). You can customize the form generation by including the optional parameters:
90
+ | Option | Type | Default | Description |
91
+ | --- | --- | --- | --- |
92
+ | `env` | `"prod" \| "dev"` | `"prod"` | Selects the production or development API host. |
93
+ | `debug` | `boolean` | `false` | Enables console logging. |
94
+ | `dryRun` | `boolean` | `false` | Loads and navigates forms without sending feedback or requesting follow-up questions. |
143
95
 
144
- * **addButton**: This setting determines whether to include a "Submit" button that enables users to submit the form
145
- themselves. By default, this value is set to false, indicating that the button will not be displayed.
146
- * **beforeSubmitEvent**: An optional function that you can define to execute some actions or validations before the form
147
- is submitted.
148
- * **afterSubmitEvent**: An optional function that you can define to execute actions after the form is submitted. This
149
- function receives the server response as a parameter.
150
- * **onLoadedEvent**: An optional function that you can define to execute actions after the form is loaded.
96
+ `dryRun` is the safest way to QA a survey before giving it to a client.
151
97
 
152
- In teh case that you don't want to use the buttons of the sdk to manage the send and back actions, you can use the
153
- following functions to manage the form.
98
+ ## Render a form
154
99
 
155
- ```js
156
- form.send() // Get the answers in the form to send and go to the next question or finish.
100
+ Create a form instance with an app id and public key:
157
101
 
158
- form.back() // Go to the previous question.
102
+ ```ts
103
+ const form = magicfeedback.form("APP_ID", "PUBLIC_KEY");
159
104
  ```
160
105
 
161
- If you would like to include additional information with your feedback, you can do so by adding it to the `metadata`
162
- , `metrics` o `profile` variables. These variables are optional and should be formatted as follows:
163
-
164
- ```js
165
- [
166
- {
167
- "key": "key_1",
168
- "value": "value_1"
106
+ Then render it into a container:
107
+
108
+ ```ts
109
+ await form.generate("survey-root", {
110
+ addButton: true,
111
+ sendButtonText: "Send",
112
+ backButtonText: "Back",
113
+ nextButtonText: "Next",
114
+ startButtonText: "Start",
115
+ addSuccessScreen: true,
116
+ successMessage: "Thank you for your feedback!",
117
+ questionFormat: "standard",
118
+ getMetaData: true,
119
+ customMetaData: [
120
+ { key: "customer-id", value: ["acme-42"] },
121
+ { key: "plan", value: ["enterprise"] }
122
+ ],
123
+ onLoadedEvent: ({ formData, progress, total, error }) => {
124
+ console.log("loaded", { formData, progress, total, error });
169
125
  },
170
- {
171
- "key": "key_2",
172
- "value": "value_2"
126
+ beforeSubmitEvent: ({ progress, total }) => {
127
+ console.log("before submit", { progress, total });
128
+ },
129
+ afterSubmitEvent: ({ response, progress, total, completed, followup, error }) => {
130
+ console.log("after submit", {
131
+ response,
132
+ progress,
133
+ total,
134
+ completed,
135
+ followup,
136
+ error
137
+ });
173
138
  },
174
- /* ... */
175
- ]
139
+ onBackEvent: ({ progress, followup, error }) => {
140
+ console.log("back", { progress, followup, error });
141
+ }
142
+ });
176
143
  ```
177
144
 
178
- Here is an example of how to submit feedback with additional information:
179
-
180
- ```js
181
- form.send(
182
- metadata, //{key:string, value:string[]}[] OPTIONAL
183
- metrics, //{key:string, value:string[]}[] OPTIONAL
184
- profile, //{key:string, value:string[]}[] OPTIONAL
185
- )
145
+ ### `generate()` options used by the current runtime
146
+
147
+ | Option | Default | Description |
148
+ | --- | --- | --- |
149
+ | `addButton` | `true` | Renders the built-in action buttons. |
150
+ | `sendButtonText` | `"Send"` | Label for the final submit button. |
151
+ | `backButtonText` | `"Back"` | Label for the back button. |
152
+ | `nextButtonText` | `"Next"` | Label for the next button in multi-step flows. |
153
+ | `startButtonText` | `"Go!"` | Label for the start button when the form has a backend start message. |
154
+ | `addSuccessScreen` | `true` | Shows the built-in success view when the flow finishes. |
155
+ | `successMessage` | `"Thank you for your feedback!"` | Custom success text. |
156
+ | `questionFormat` | `"standard"` | `"standard"` or `"slim"`. |
157
+ | `getMetaData` | `true` | Appends browser and page metadata automatically. |
158
+ | `customMetaData` | `[]` | Extra metadata merged into `feedback.metadata` when `getMetaData` is enabled. |
159
+ | `onLoadedEvent` | `undefined` | Called after the form or start screen is ready. |
160
+ | `beforeSubmitEvent` | `undefined` | Called before a page is submitted. |
161
+ | `afterSubmitEvent` | `undefined` | Called after a page submit, follow-up render, or final completion. |
162
+ | `onBackEvent` | `undefined` | Called after navigating back. |
163
+
164
+ When `getMetaData` is enabled, the SDK includes the current URL, origin, pathname, query string, user agent, browser language, platform, app metadata, screen size, and the session id when rendering from `session()`. Query params are also expanded into metadata entries as `query-<param>` with all values for that param.
165
+
166
+ ## Resume an existing session
167
+
168
+ If you already have a MagicFeedback session id, render it directly:
169
+
170
+ ```ts
171
+ magicfeedback.init({ env: "prod" });
172
+
173
+ const form = magicfeedback.session("SESSION_ID");
174
+ await form.generate("survey-root", {
175
+ addButton: true
176
+ });
186
177
  ```
187
178
 
188
- This function triggers the submission of the generated feedback form.
189
-
190
- ![](./public/A_form.png)
179
+ ## Manual navigation
191
180
 
192
- By following these steps and including the appropriate HTML and JavaScript code snippets, you can easily generate and
193
- display feedback forms on your website using the magicfeedback service.
181
+ If you want to control your own buttons, disable the built-in actions and call `send()` / `back()` yourself.
194
182
 
195
- ### B. Send feedback directly
183
+ ```ts
184
+ const form = magicfeedback.form("APP_ID", "PUBLIC_KEY");
196
185
 
197
- With this option you can send feedback directly without generate a form. This section provides an overview of how to use
198
- this feature and the necessary code snippets.
186
+ await form.generate("survey-root", {
187
+ addButton: false
188
+ });
199
189
 
200
- To send feedback directly, you need to include the following JavaScript code snippet in your application:
190
+ document.getElementById("next-btn")?.addEventListener("click", () => {
191
+ form.send(
192
+ [{ key: "source", value: ["pricing-page"] }],
193
+ [{ key: "account-score", value: ["92"] }],
194
+ [{ key: "customer-email", value: ["user@example.com"] }]
195
+ );
196
+ });
201
197
 
202
- ```js
203
- window.magicfeedback.send(
204
- "$_APP_ID",
205
- "$_PUBLIC_KEY",
206
- feedbackData,
207
- completed, // Default true
208
- "$_ID", // Optional
209
- "$_PRIVATE_KEY", // Optional
210
- )
198
+ document.getElementById("back-btn")?.addEventListener("click", () => {
199
+ form.back();
200
+ });
211
201
  ```
212
202
 
213
- In this code snippet, you need to replace $_APP_ID with the actual ID of your feedback application and the $_PUBLIC_KEY
214
- with the public key of your feedback application. This ID and key is provided by the magicfeedback service.
203
+ `form.send()` accepts arguments in this order:
215
204
 
216
- ###### FeedbackData
205
+ 1. `metadata`
206
+ 2. `metrics`
207
+ 3. `profile`
217
208
 
218
- Then, you can include the feedback data in an object with the following structure:
209
+ Each item should follow the same shape:
210
+
211
+ ```ts
212
+ { key: "some-key", value: ["some-value"] }
213
+ ```
219
214
 
220
- ```js
221
- {
222
- text: "string", /* Optional */
215
+ ## Send feedback directly
216
+
217
+ Use `magicfeedback.send()` when you do not want the SDK to render any UI.
218
+
219
+ ```ts
220
+ await magicfeedback.send(
221
+ "APP_ID",
222
+ "PUBLIC_KEY",
223
+ {
224
+ text: "",
223
225
  answers: [
224
- {
225
- key: 'string',
226
- value: ["string"]
227
- },
226
+ { key: "nps", value: ["9"] },
227
+ { key: "favorite-feature", value: ["Conditional logic"] }
228
228
  ],
229
229
  metadata: [
230
- {
231
- key: 'string',
232
- value: "string"
233
- },
230
+ { key: "source", value: ["pricing-page"] }
234
231
  ],
235
232
  metrics: [
236
- {
237
- key: 'string',
238
- value: "string"
239
- },
233
+ { key: "plan", value: ["pro"] }
240
234
  ],
241
235
  profile: [
242
- {
243
- key: 'string',
244
- value: "string"
245
- },
236
+ { key: "email", value: ["user@example.com"] }
246
237
  ]
247
- }
238
+ },
239
+ true
240
+ );
248
241
  ```
249
242
 
250
- * **key**: This setting determines the key of the feedback data.
251
- * **value**: This setting determines the value of the feedback data.
252
-
253
- Not all the fields are required. You can send only the fields that you need. But you need to send one of that minimal.
243
+ Signature:
254
244
 
255
- Finally, to send the feedback, you can use the magicfeedback.send() function.
256
-
257
- ## Style
258
-
259
- To use the default modern theme included in the bundle, import the CSS after loading the bundle:
260
-
261
- ```html
262
- <link rel="stylesheet" href="./node_modules/@magicfeedback/native/dist/styles/magicfeedback-default.css" />
245
+ ```ts
246
+ magicfeedback.send(
247
+ appId,
248
+ publicKey,
249
+ feedback,
250
+ completed = true,
251
+ id?,
252
+ privateKey?
253
+ );
263
254
  ```
264
255
 
265
- If you bundle with Webpack/Vite, you can also import directly into your entry:
256
+ ## Preview a question locally
257
+
258
+ `previewQuestion()` renders one question or an array of questions without changing the internal flow state.
259
+
260
+ ```ts
261
+ const previewForm = magicfeedback.form("demo", "demo");
262
+
263
+ previewForm.previewQuestion("preview-root", {
264
+ id: "q_text",
265
+ title: "What is your name?",
266
+ type: "TEXT",
267
+ questionType: { conf: [] },
268
+ ref: "name",
269
+ require: true,
270
+ external_id: "",
271
+ value: [],
272
+ defaultValue: "",
273
+ followup: false,
274
+ position: 1,
275
+ assets: {
276
+ placeholder: "Type your name",
277
+ subtitle: "Used only for preview"
278
+ },
279
+ refMetric: "",
280
+ integrationId: "demo",
281
+ integrationPageId: "demo"
282
+ }, {
283
+ format: "standard",
284
+ language: "en",
285
+ product: { customIcons: false },
286
+ clearContainer: true,
287
+ wrap: true
288
+ });
289
+ ```
266
290
 
267
- ```js
268
- import '@magicfeedback/native/dist/styles/magicfeedback-default.css';
291
+ This is useful for QA, local demos, and visual regression checks.
292
+
293
+ ## Supported rendered question types
294
+
295
+ The renderer currently supports these question types:
296
+
297
+ - `TEXT`
298
+ - `LONGTEXT`
299
+ - `NUMBER`
300
+ - `RADIO`
301
+ - `MULTIPLECHOICE`
302
+ - `SELECT`
303
+ - `DATE`
304
+ - `EMAIL`
305
+ - `PASSWORD`
306
+ - `BOOLEAN`
307
+ - `CONSENT`
308
+ - `RATING_STAR`
309
+ - `RATING_EMOJI`
310
+ - `RATING_NUMBER`
311
+ - `MULTIPLECHOISE_IMAGE`
312
+ - `MULTI_QUESTION_MATRIX`
313
+ - `POINT_SYSTEM`
314
+ - `PRIORITY_LIST`
315
+ - `INFO_PAGE`
316
+ - `UPLOAD_FILE`
317
+ - `UPLOAD_IMAGE`
318
+
319
+ For the output payload generated by `Form.answer()`, see [docs/answer-format.md](docs/answer-format.md). That document describes payload serialization, while the list above reflects the question types currently rendered by the browser UI.
320
+
321
+ Important payload notes:
322
+
323
+ - `EMAIL` answers are also copied into `feedback.profile` as `email`.
324
+ - `POINT_SYSTEM` answers are serialized as values such as `"Quality:60%"`.
325
+ - `MULTI_QUESTION_MATRIX` answers are grouped into a single JSON string entry.
326
+ - Required `MULTI_QUESTION_MATRIX` questions must have an answer in every row before the SDK allows submission.
327
+ - `INFO_PAGE`, `UPLOAD_FILE`, and `UPLOAD_IMAGE` render in the UI but do not currently create answer entries.
328
+
329
+ ## Styling
330
+
331
+ Import the bundled stylesheet:
332
+
333
+ ```ts
334
+ import "@magicfeedback/native/dist/styles/magicfeedback-default.css";
269
335
  ```
270
336
 
271
- You can override CSS variables defined in `:root` to customize colors without modifying the original file:
337
+ Or with plain HTML:
272
338
 
273
- ```css
274
- :root {
275
- /* Colors - Neutral Palette */
276
- --mf-primary: #2563eb;
277
- --mf-primary-hover: #1d4ed8;
278
- --mf-primary-light: #dbeafe;
279
-
280
- --mf-text-primary: #0f172a;
281
- --mf-text-secondary: #64748b;
282
- --mf-text-muted: #94a3b8;
283
-
284
- --mf-bg-primary: #ffffff;
285
- --mf-bg-secondary: #f8fafc;
286
- --mf-bg-hover: #f1f5f9;
287
-
288
- --mf-border: #e2e8f0;
289
- --mf-border-focus: #2563eb;
290
-
291
- --mf-success: #10b981;
292
- --mf-error: #ef4444;
293
- --mf-warning: #f59e0b;
294
-
295
- /* Spacing */
296
- --mf-space-xs: 0.25rem;
297
- --mf-space-sm: 0.5rem;
298
- --mf-space-md: 0.75rem;
299
- --mf-space-lg: 1rem;
300
- --mf-space-xl: 1.5rem;
301
-
302
- /* Border Radius */
303
- --mf-radius-sm: 0.375rem;
304
- --mf-radius-md: 0.5rem;
305
- --mf-radius-lg: 0.75rem;
306
- --mf-radius-full: 9999px;
307
-
308
- /* Shadows */
309
- --mf-shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
310
- --mf-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
311
- --mf-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
312
- --mf-shadow-focus: 0 0 0 3px rgba(37, 99, 235, 0.1);
313
-
314
- /* Typography */
315
- --mf-font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Helvetica", "Arial", sans-serif;
316
- --mf-font-size-sm: 0.875rem;
317
- --mf-font-size-base: 1rem;
318
- --mf-font-size-lg: 1.125rem;
319
- --mf-font-size-xl: 1.25rem;
320
- --mf-line-height: 1.6;
321
-
322
- /* Transitions */
323
- --mf-transition: all 0.2s ease;
324
- --mf-transition-fast: all 0.15s ease;
325
- }
339
+ ```html
340
+ <link
341
+ rel="stylesheet"
342
+ href="./node_modules/@magicfeedback/native/dist/styles/magicfeedback-default.css"
343
+ />
326
344
  ```
327
345
 
328
- The file includes subtle animations and variations for focus, selection, and loading states (skeleton). Adjust or extend the classes as needed.
346
+ You can override the main CSS variables without modifying the distributed file:
329
347
 
330
348
  ```css
331
- /* Overall container for the feedback form */
332
- .magicfeedback-container {
333
- /* ... add your container styles here ... */
334
- }
335
-
336
- /* Main form element */
337
- .magicfeedback-form {
338
- /* ... add your form styles here ... */
339
- }
340
-
341
- /* Section for questions */
342
- .magicfeedback-questions {
343
- /* ... add your questions section styles here ... */
344
- }
345
-
346
- /* Section for div */
347
- .magicfeedback-div {
348
- /* ... add your generic div styles here ... */
349
- }
350
-
351
- /* Generic styles for various input elements */
352
- .magicfeedback-label,
353
- .magicfeedback-input,
354
- .magicfeedback-contact,
355
- .magicfeedback-password,
356
- .magicfeedback-email,
357
- .magicfeedback-boolean,
358
- .magicfeedback-consent,
359
- .magicfeedback-date,
360
- .magicfeedback-select,
361
- .magicfeedback-radio,
362
- .magicfeedback-checkbox,
363
- .magicfeedback-rating,
364
- .magicfeedback-rating-container,
365
- .magicfeedback-rating-option,
366
- .magicfeedback-rating-option-label-container,
367
- .magicfeedback-number,
368
- .magicfeedback-longtext,
369
- .magicfeedback-text,
370
- .magicfeedback-priority-list{
371
- /* ... add your generic input styles here ... */
372
- }
373
-
374
- .magicfeedback-skip-container {
375
- /* ... add your skip container styles here ... */
376
- }
377
-
378
- .magicfeedback-skip{
379
- /* ... add your skip button styles here ... */
380
- }
381
-
382
- .magicfeedback-image {
383
- /* ... add your image styles here ... */
384
- }
385
-
386
- /* Specific styles for individual input types */
387
- .magicfeedback-radio-container,
388
- .magicfeedback-boolean-container,
389
- .magicfeedback-consent-container,
390
- .magicfeedback-checkbox-container,
391
- .magicfeedback-longtext-container,
392
- .magicfeedback-priority-list-container{
393
- /* ... add styles for radio/checkbox containers ... */
394
- }
395
-
396
- .magicfeedback-rating-placeholder {
397
- /* ... add your rating placeholder styles here ... */
398
- }
399
-
400
- .magicfeedback-rating-placeholder-min {
401
- /* ... add your rating placeholder min styles here ... */
402
- }
403
-
404
- .magicfeedback-rating-placeholder-max {
405
- /* ... add your rating placeholder max styles here ... */
406
- }
407
-
408
- .magicfeedback-rating-image1,
409
- .magicfeedback-rating-image2,
410
- .magicfeedback-rating-image3,
411
- .magicfeedback-rating-image4,
412
- .magicfeedback-rating-image5,
413
- .magicfeedback-rating-image6,
414
- .magicfeedback-rating-image7,
415
- .magicfeedback-rating-image8,
416
- .magicfeedback-rating-image9,
417
- .magicfeedback-rating-image10,
418
- .magicfeedback-rating-image-extra {
419
- /* ... add styles for rating images ... */
420
- }
421
-
422
- /* Section for number rating */
423
- .magicfeedback-rating-number-container {
424
- /* ... add your number rating container styles here ... */
425
- }
426
-
427
- .magicfeedback-rating-number-placeholder {
428
- /* ... add your number rating placeholder styles here ... */
429
- }
430
-
431
- .magicfeedback-rating-number-placeholder-min {
432
- /* ... add your number rating placeholder min styles here ... */
433
- }
434
-
435
- .magicfeedback-rating-number-placeholder-max {
436
- /* ... add your number rating placeholder max styles here ... */
437
- }
438
-
439
- .magicfeedback-rating-number-option {
440
- /* ... add your number rating option styles here ... */
441
- }
442
-
443
- .magicfeedback-rating-number-option-label-container {
444
- /* ... add your number rating option label container styles here ... */
445
- }
446
-
447
-
448
- /* Section for star rating */
449
- .magicfeedback-rating-star {
450
- /* ... add your star rating container styles here ... */
451
- }
452
-
453
- .magicfeedback-rating-star-container {
454
- /* ... add your star rating styles here ... */
455
- }
456
-
457
- .magicfeedback-rating-star-option {
458
- /* ... add your star rating option styles here ... */
459
- }
349
+ :root {
350
+ --mf-primary: #0f766e;
351
+ --mf-primary-hover: #115e59;
352
+ --mf-primary-light: #ccfbf1;
460
353
 
461
- .magicfeedback-rating-star-selected {
462
- /* ... add your star rating selected styles here ... */
463
- }
354
+ --mf-text-primary: #0f172a;
355
+ --mf-text-secondary: #475569;
464
356
 
465
- /* Section for multiple choice image */
466
- .magicfeedback-multiple-choice-image {
467
- /* ... add your multiple choice image container styles here ... */
468
- }
357
+ --mf-bg-primary: #ffffff;
358
+ --mf-bg-secondary: #f8fafc;
469
359
 
470
- .magicfeedback-multiple-choice-image-container {
471
- /* ... add your multiple choice image styles here ... */
472
- }
360
+ --mf-border: #cbd5e1;
361
+ --mf-border-focus: #0f766e;
473
362
 
474
- .magicfeedback-multiple-choice-image-option {
475
- /* ... add your multiple choice image option styles here ... */
363
+ --mf-radius-md: 0.5rem;
364
+ --mf-shadow-md: 0 10px 20px rgba(15, 23, 42, 0.08);
476
365
  }
366
+ ```
477
367
 
478
- .magicfeedback-image-option-label-container {
479
- /* ... add your multiple choice image option label container styles here ... */
480
- }
368
+ For deeper customization, inspect `dist/styles/magicfeedback-default.css` and override the generated classes from your own stylesheet.
481
369
 
482
- .magicfeedback-multiple-choice-image-label {
483
- /* ... add your multiple choice image label styles here ... */
484
- }
370
+ ## QA and staging
485
371
 
486
- .magicfeedback-multiple-choice-image-input {
487
- /* ... add your multiple choice image input styles here ... */
488
- }
489
-
490
- .magicfeedback-multiple-choice-image-image {
491
- /* ... add your multiple choice image image styles here ... */
492
- }
372
+ Recommended setup for client review:
493
373
 
494
- /* Section for priority-list */
495
- .magicfeedback-priority-list-container {
496
- /* ... add your priority list container styles here ... */
497
- }
498
- .magicfeedback-priority-list-list {
499
- /* ... add your priority list list styles here ... */
500
- }
501
- .magicfeedback-priority-list-item{
502
- /* ... add your priority list item styles here ... */
503
- }
504
- .magicfeedback-priority-list-item-label{
505
- /* ... add your priority list item label styles here ... */
506
- }
507
- .magicfeedback-priority-list-arrow-up,
508
- .magicfeedback-priority-list-arrow-down{
509
- /* ... add your priority list arrow up styles here ... */
510
-
511
- }
512
- /* Action buttons container */
513
- .magicfeedback-action-container {
514
- /* ... add your action button container styles here ... */
515
- }
516
-
517
- /* Submit button */
518
- .magicfeedback-submit {
519
- /* ... add your submit button styles here ... */
520
- }
521
-
522
- /* Back button */
523
- .magicfeedback-back {
524
- /* ... add your back button styles here ... */
525
- }
374
+ ```ts
375
+ magicfeedback.init({
376
+ env: "dev",
377
+ debug: true,
378
+ dryRun: true
379
+ });
380
+ ```
526
381
 
527
- /* Start message */
528
- .magicfeedback-start-message-container {
529
- /* ... add your start message container styles here ... */
530
- }
382
+ This combination lets you load the survey, navigate questions, and inspect callbacks without creating real feedback records.
531
383
 
532
- .magicfeedback-start-message {
533
- /* ... add your start message styles here ... */
534
- }
384
+ ## Examples in this repository
535
385
 
536
- .magicfeedback-start-message-button {
537
- /* ... add your start message button styles here ... */
538
- }
386
+ - `examples/frontend/browser.html` - minimal browser integration
387
+ - `examples/frontend/browser_static.html` - live form plus local previews for all supported question types
388
+ - `examples/frontend/form.html` - embed the SDK inside an existing page layout
389
+ - `examples/frontend/embedded_in_form.html` - combine static inputs with SDK-managed questions
390
+ - `docs/answer-format.md` - exact payload format produced by `Form.answer()`
539
391
 
540
- .magicfeedback-info-page {
541
- /* ... add your info page styles here ... */
542
- }
392
+ ## Troubleshooting
543
393
 
544
- .magicfeedback-info-message{
545
- /* ... add your info message styles here ... */
546
- }
394
+ If the form does not load:
547
395
 
548
- /* Success message (if applicable) */
549
- .magicfeedback-success {
550
- /* ... add your success message styles here ... */
551
- }
552
- ````
396
+ - Confirm that `magicfeedback.init()` has been called.
397
+ - Confirm that the container id passed to `generate()` exists in the DOM.
398
+ - Check that you are using the correct `APP_ID`, `PUBLIC_KEY`, or `SESSION_ID`.
399
+ - Turn on `debug: true` to inspect SDK logs.
400
+ - Use `dryRun: true` when validating the flow before production rollout.