fdbck-react 0.2.0 → 0.2.2

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
@@ -1,6 +1,9 @@
1
1
  # fdbck-react
2
2
 
3
- Official React SDK for [fdbck](https://fdbck.sh) — embed feedback questions natively in your React app with Shadow DOM CSS isolation.
3
+ [![npm version](https://img.shields.io/npm/v/fdbck-react.svg)](https://www.npmjs.com/package/fdbck-react)
4
+ [![license](https://img.shields.io/npm/l/fdbck-react.svg)](https://www.npmjs.com/package/fdbck-react)
5
+
6
+ Official React SDK for [fdbck](https://fdbck.sh) - embed feedback questions natively in your React app with Shadow DOM CSS isolation.
4
7
 
5
8
  ## Install
6
9
 
@@ -8,13 +11,21 @@ Official React SDK for [fdbck](https://fdbck.sh) — embed feedback questions na
8
11
  npm install fdbck-react
9
12
  ```
10
13
 
14
+ ```bash
15
+ yarn add fdbck-react
16
+ ```
17
+
18
+ ```bash
19
+ pnpm add fdbck-react
20
+ ```
21
+
11
22
  Requires React 18+.
12
23
 
13
24
  ## Quick start
14
25
 
15
26
  ### 1. Direct token (simplest)
16
27
 
17
- Generate a response token on your backend (via the Node.js or Python SDK), then pass it to the widget:
28
+ Generate a response token on your backend (via the REST API, node.js or python SDK), then pass it to the widget:
18
29
 
19
30
  ```tsx
20
31
  import { FdbckWidget } from 'fdbck-react';
@@ -32,7 +43,7 @@ function App() {
32
43
 
33
44
  ### 2. Imperative API (provider pattern)
34
45
 
35
- For showing feedback modals/popovers imperatively:
46
+ For showing feedback modals / popovers imperatively:
36
47
 
37
48
  ```tsx
38
49
  import { FdbckProvider, useFdbck } from 'fdbck-react';
@@ -140,6 +151,13 @@ The widget uses `useEffect` for all DOM operations (Shadow DOM, fetch). It rende
140
151
 
141
152
  ~7KB gzipped (including all CSS).
142
153
 
154
+ ## Links
155
+
156
+ - [npm](https://www.npmjs.com/package/fdbck-react)
157
+ - [Documentation](https://docs.fdbck.sh/sdks/react)
158
+ - [GitHub](https://github.com/fdbck-sh/fdbck-react)
159
+ - [fdbck](https://fdbck.sh)
160
+
143
161
  ## License
144
162
 
145
163
  MIT
package/dist/index.js CHANGED
@@ -223,22 +223,47 @@ var import_react3 = require("react");
223
223
  var import_react_dom = require("react-dom");
224
224
 
225
225
  // src/styles/base.css
226
- var base_default = {};
226
+ var base_default = "/* fdbck widget \u2014 base styles */\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n}\n\n:host {\n display: block;\n font-family: var(--fdbck-font-family);\n font-size: var(--fdbck-font-size);\n line-height: 1.5;\n color: var(--fdbck-text-primary);\n -webkit-font-smoothing: antialiased;\n}\n\n.fdbck-card {\n width: var(--fdbck-width);\n max-width: var(--fdbck-max-width);\n background: var(--fdbck-card-bg);\n border: 1px solid var(--fdbck-border);\n border-radius: var(--fdbck-border-radius);\n padding: 1.5rem;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n\n.fdbck-welcome {\n font-size: var(--fdbck-font-size);\n color: var(--fdbck-text-secondary);\n margin-bottom: 1rem;\n white-space: pre-line;\n}\n\n.fdbck-question {\n font-size: 1.125rem;\n font-weight: 600;\n color: var(--fdbck-text-primary);\n margin-bottom: 1.5rem;\n}\n\n.fdbck-error-text {\n color: #ef4444;\n font-size: var(--fdbck-font-size);\n margin-bottom: 1rem;\n}\n\n.fdbck-center {\n display: flex;\n align-items: center;\n justify-content: center;\n text-align: center;\n flex-direction: column;\n}\n\n.fdbck-loading {\n min-height: 200px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.fdbck-spinner {\n width: 1.5rem;\n height: 1.5rem;\n border: 2px solid transparent;\n border-top-color: var(--fdbck-accent);\n border-right-color: var(--fdbck-accent);\n border-radius: 50%;\n animation: fdbck-spin 0.6s linear infinite;\n}\n\n@keyframes fdbck-spin {\n to { transform: rotate(360deg); }\n}\n\n.fdbck-error-state {\n padding: 2rem 0;\n text-align: center;\n}\n\n.fdbck-error-state h2 {\n font-size: 1.125rem;\n font-weight: 600;\n color: var(--fdbck-text-primary);\n margin-bottom: 0.25rem;\n}\n\n.fdbck-error-state p {\n color: var(--fdbck-text-secondary);\n}\n\n.fdbck-retry-btn {\n margin-top: 1rem;\n padding: 0.5rem 1rem;\n border: 1px solid var(--fdbck-border);\n border-radius: 0.5rem;\n background: transparent;\n color: var(--fdbck-text-primary);\n font-size: var(--fdbck-font-size);\n cursor: pointer;\n transition: border-color 0.15s;\n}\n\n.fdbck-retry-btn:hover {\n border-color: var(--fdbck-accent);\n}\n";
227
227
 
228
228
  // src/styles/question-types.css
229
- var question_types_default = {};
229
+ var question_types_default = '/* fdbck widget \u2014 question type styles */\n\n/* Shared option button */\n.fdbck-option-btn {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n width: 100%;\n padding: 0.75rem 1rem;\n border: 1px solid var(--fdbck-border);\n border-radius: 0.5rem;\n background: transparent;\n color: var(--fdbck-text-primary);\n font-size: var(--fdbck-font-size);\n text-align: left;\n cursor: pointer;\n transition: border-color 0.15s;\n}\n\n.fdbck-option-btn:hover:not(:disabled) {\n border-color: var(--fdbck-accent);\n}\n\n.fdbck-option-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.fdbck-option-btn[data-selected="true"] {\n border-color: var(--fdbck-accent);\n}\n\n/* Yes/No grid */\n.fdbck-yesno-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 0.75rem;\n}\n\n.fdbck-yesno-grid .fdbck-option-btn {\n justify-content: center;\n font-weight: 500;\n}\n\n/* Single/Multiple choice list */\n.fdbck-choice-list {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n/* Radio dot indicator */\n.fdbck-radio {\n width: 1rem;\n height: 1rem;\n border: 2px solid var(--fdbck-indicator-border);\n border-radius: 50%;\n flex-shrink: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: border-color 0.15s;\n}\n\n.fdbck-radio[data-selected="true"] {\n border-color: var(--fdbck-accent);\n}\n\n.fdbck-radio-dot {\n width: 0.5rem;\n height: 0.5rem;\n border-radius: 50%;\n background: var(--fdbck-accent);\n}\n\n/* Checkbox indicator */\n.fdbck-checkbox {\n width: 1rem;\n height: 1rem;\n border: 2px solid var(--fdbck-indicator-border);\n border-radius: 0.25rem;\n flex-shrink: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: border-color 0.15s, background-color 0.15s;\n}\n\n.fdbck-checkbox[data-selected="true"] {\n border-color: var(--fdbck-accent);\n background-color: var(--fdbck-accent);\n}\n\n.fdbck-checkbox svg {\n width: 0.75rem;\n height: 0.75rem;\n color: #fff;\n}\n\n/* Submit button (multiple choice) */\n.fdbck-submit-btn {\n margin-top: 0.5rem;\n padding: 0.625rem 1rem;\n border: none;\n border-radius: 0.5rem;\n background: var(--fdbck-accent);\n color: #fff;\n font-size: var(--fdbck-font-size);\n font-weight: 500;\n cursor: pointer;\n transition: opacity 0.15s;\n}\n\n.fdbck-submit-btn:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n\n/* Rating grid */\n.fdbck-rating-grid {\n display: grid;\n gap: 0.375rem;\n}\n\n.fdbck-rating-btn {\n aspect-ratio: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n border: 1px solid var(--fdbck-border);\n border-radius: 0.5rem;\n background: transparent;\n color: var(--fdbck-text-primary);\n font-size: var(--fdbck-font-size);\n font-weight: 500;\n cursor: pointer;\n transition: border-color 0.15s, background-color 0.15s, color 0.15s;\n}\n\n.fdbck-rating-btn:hover:not(:disabled) {\n border-color: var(--fdbck-accent);\n}\n\n.fdbck-rating-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.fdbck-rating-btn[data-selected="true"] {\n background-color: var(--fdbck-accent);\n border-color: var(--fdbck-accent);\n color: #fff;\n}\n\n.fdbck-rating-labels {\n display: flex;\n justify-content: space-between;\n margin-top: 0.5rem;\n font-size: 0.75rem;\n color: var(--fdbck-text-muted);\n}\n';
230
230
 
231
231
  // src/styles/confirmation.css
232
- var confirmation_default = {};
232
+ var confirmation_default = "/* fdbck widget \u2014 confirmation state */\n.fdbck-confirmation {\n padding: 2rem 0;\n text-align: center;\n}\n\n.fdbck-check-circle {\n width: 3rem;\n height: 3rem;\n border-radius: 50%;\n background: var(--fdbck-accent-alpha);\n display: flex;\n align-items: center;\n justify-content: center;\n margin: 0 auto 1rem;\n animation: fdbck-scale-in 0.3s ease-out;\n}\n\n.fdbck-check-circle svg {\n width: 1.5rem;\n height: 1.5rem;\n color: var(--fdbck-accent);\n}\n\n.fdbck-confirmation h2 {\n font-size: 1.125rem;\n font-weight: 600;\n color: var(--fdbck-text-primary);\n margin-bottom: 0.25rem;\n}\n\n.fdbck-confirmation p {\n color: var(--fdbck-text-secondary);\n white-space: pre-line;\n}\n\n@keyframes fdbck-scale-in {\n from { transform: scale(0.5); opacity: 0; }\n to { transform: scale(1); opacity: 1; }\n}\n";
233
233
 
234
234
  // src/styles/branding.css
235
- var branding_default = {};
235
+ var branding_default = `/* fdbck widget \u2014 "Powered by fdbck" footer */
236
+ .fdbck-branding {
237
+ display: flex;
238
+ justify-content: center;
239
+ margin-top: 1rem;
240
+ padding-top: 0.75rem;
241
+ border-top: 1px solid var(--fdbck-border);
242
+ }
243
+
244
+ .fdbck-branding a {
245
+ font-size: 0.75rem;
246
+ color: var(--fdbck-text-muted);
247
+ text-decoration: none;
248
+ transition: color 0.15s;
249
+ }
250
+
251
+ .fdbck-branding a:hover {
252
+ color: var(--fdbck-text-secondary);
253
+ }
254
+
255
+ .fdbck-branding-name {
256
+ font-family: 'JetBrains Mono', monospace;
257
+ font-weight: 500;
258
+ color: var(--fdbck-accent);
259
+ }
260
+ `;
236
261
 
237
262
  // src/styles/modal.css
238
- var modal_default = {};
263
+ var modal_default = "/* fdbck widget \u2014 modal mode */\n.fdbck-modal-backdrop {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 1rem;\n z-index: 2147483647;\n animation: fdbck-fade-in 0.2s ease-out;\n}\n\n.fdbck-modal-content {\n position: relative;\n animation: fdbck-scale-up 0.2s ease-out;\n}\n\n.fdbck-close-btn {\n position: absolute;\n top: -0.5rem;\n right: -0.5rem;\n width: 1.75rem;\n height: 1.75rem;\n border: 1px solid var(--fdbck-border);\n border-radius: 50%;\n background: var(--fdbck-card-bg);\n color: var(--fdbck-text-secondary);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1rem;\n line-height: 1;\n transition: border-color 0.15s;\n z-index: 1;\n}\n\n.fdbck-close-btn:hover {\n border-color: var(--fdbck-accent);\n}\n\n@keyframes fdbck-fade-in {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n@keyframes fdbck-scale-up {\n from { transform: scale(0.95); opacity: 0; }\n to { transform: scale(1); opacity: 1; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .fdbck-modal-backdrop,\n .fdbck-modal-content {\n animation: none;\n }\n}\n";
239
264
 
240
265
  // src/styles/popover.css
241
- var popover_default = {};
266
+ var popover_default = "/* fdbck widget \u2014 popover mode */\n.fdbck-popover {\n position: fixed;\n bottom: 1.5rem;\n right: 1.5rem;\n z-index: 2147483647;\n animation: fdbck-slide-up 0.25s ease-out;\n}\n\n.fdbck-popover .fdbck-close-btn {\n position: absolute;\n top: -0.5rem;\n right: -0.5rem;\n}\n\n/* Mobile: bottom sheet */\n@media (max-width: 640px) {\n .fdbck-popover {\n bottom: 0;\n right: 0;\n left: 0;\n padding: 0;\n animation: fdbck-sheet-up 0.25s ease-out;\n }\n\n .fdbck-popover .fdbck-card {\n max-width: 100%;\n width: 100%;\n border-radius: var(--fdbck-border-radius) var(--fdbck-border-radius) 0 0;\n border-bottom: none;\n }\n\n .fdbck-popover .fdbck-close-btn {\n top: 0.75rem;\n right: 0.75rem;\n }\n}\n\n@keyframes fdbck-slide-up {\n from { transform: translateY(1rem); opacity: 0; }\n to { transform: translateY(0); opacity: 1; }\n}\n\n@keyframes fdbck-sheet-up {\n from { transform: translateY(100%); }\n to { transform: translateY(0); }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .fdbck-popover {\n animation: none;\n }\n}\n";
242
267
 
243
268
  // src/styles/index.ts
244
269
  var WIDGET_CSS = [
package/dist/index.mjs CHANGED
@@ -196,22 +196,47 @@ import { useRef, useEffect as useEffect2, useState } from "react";
196
196
  import { createPortal } from "react-dom";
197
197
 
198
198
  // src/styles/base.css
199
- var base_default = {};
199
+ var base_default = "/* fdbck widget \u2014 base styles */\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n}\n\n:host {\n display: block;\n font-family: var(--fdbck-font-family);\n font-size: var(--fdbck-font-size);\n line-height: 1.5;\n color: var(--fdbck-text-primary);\n -webkit-font-smoothing: antialiased;\n}\n\n.fdbck-card {\n width: var(--fdbck-width);\n max-width: var(--fdbck-max-width);\n background: var(--fdbck-card-bg);\n border: 1px solid var(--fdbck-border);\n border-radius: var(--fdbck-border-radius);\n padding: 1.5rem;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n\n.fdbck-welcome {\n font-size: var(--fdbck-font-size);\n color: var(--fdbck-text-secondary);\n margin-bottom: 1rem;\n white-space: pre-line;\n}\n\n.fdbck-question {\n font-size: 1.125rem;\n font-weight: 600;\n color: var(--fdbck-text-primary);\n margin-bottom: 1.5rem;\n}\n\n.fdbck-error-text {\n color: #ef4444;\n font-size: var(--fdbck-font-size);\n margin-bottom: 1rem;\n}\n\n.fdbck-center {\n display: flex;\n align-items: center;\n justify-content: center;\n text-align: center;\n flex-direction: column;\n}\n\n.fdbck-loading {\n min-height: 200px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.fdbck-spinner {\n width: 1.5rem;\n height: 1.5rem;\n border: 2px solid transparent;\n border-top-color: var(--fdbck-accent);\n border-right-color: var(--fdbck-accent);\n border-radius: 50%;\n animation: fdbck-spin 0.6s linear infinite;\n}\n\n@keyframes fdbck-spin {\n to { transform: rotate(360deg); }\n}\n\n.fdbck-error-state {\n padding: 2rem 0;\n text-align: center;\n}\n\n.fdbck-error-state h2 {\n font-size: 1.125rem;\n font-weight: 600;\n color: var(--fdbck-text-primary);\n margin-bottom: 0.25rem;\n}\n\n.fdbck-error-state p {\n color: var(--fdbck-text-secondary);\n}\n\n.fdbck-retry-btn {\n margin-top: 1rem;\n padding: 0.5rem 1rem;\n border: 1px solid var(--fdbck-border);\n border-radius: 0.5rem;\n background: transparent;\n color: var(--fdbck-text-primary);\n font-size: var(--fdbck-font-size);\n cursor: pointer;\n transition: border-color 0.15s;\n}\n\n.fdbck-retry-btn:hover {\n border-color: var(--fdbck-accent);\n}\n";
200
200
 
201
201
  // src/styles/question-types.css
202
- var question_types_default = {};
202
+ var question_types_default = '/* fdbck widget \u2014 question type styles */\n\n/* Shared option button */\n.fdbck-option-btn {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n width: 100%;\n padding: 0.75rem 1rem;\n border: 1px solid var(--fdbck-border);\n border-radius: 0.5rem;\n background: transparent;\n color: var(--fdbck-text-primary);\n font-size: var(--fdbck-font-size);\n text-align: left;\n cursor: pointer;\n transition: border-color 0.15s;\n}\n\n.fdbck-option-btn:hover:not(:disabled) {\n border-color: var(--fdbck-accent);\n}\n\n.fdbck-option-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.fdbck-option-btn[data-selected="true"] {\n border-color: var(--fdbck-accent);\n}\n\n/* Yes/No grid */\n.fdbck-yesno-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 0.75rem;\n}\n\n.fdbck-yesno-grid .fdbck-option-btn {\n justify-content: center;\n font-weight: 500;\n}\n\n/* Single/Multiple choice list */\n.fdbck-choice-list {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n/* Radio dot indicator */\n.fdbck-radio {\n width: 1rem;\n height: 1rem;\n border: 2px solid var(--fdbck-indicator-border);\n border-radius: 50%;\n flex-shrink: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: border-color 0.15s;\n}\n\n.fdbck-radio[data-selected="true"] {\n border-color: var(--fdbck-accent);\n}\n\n.fdbck-radio-dot {\n width: 0.5rem;\n height: 0.5rem;\n border-radius: 50%;\n background: var(--fdbck-accent);\n}\n\n/* Checkbox indicator */\n.fdbck-checkbox {\n width: 1rem;\n height: 1rem;\n border: 2px solid var(--fdbck-indicator-border);\n border-radius: 0.25rem;\n flex-shrink: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: border-color 0.15s, background-color 0.15s;\n}\n\n.fdbck-checkbox[data-selected="true"] {\n border-color: var(--fdbck-accent);\n background-color: var(--fdbck-accent);\n}\n\n.fdbck-checkbox svg {\n width: 0.75rem;\n height: 0.75rem;\n color: #fff;\n}\n\n/* Submit button (multiple choice) */\n.fdbck-submit-btn {\n margin-top: 0.5rem;\n padding: 0.625rem 1rem;\n border: none;\n border-radius: 0.5rem;\n background: var(--fdbck-accent);\n color: #fff;\n font-size: var(--fdbck-font-size);\n font-weight: 500;\n cursor: pointer;\n transition: opacity 0.15s;\n}\n\n.fdbck-submit-btn:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n\n/* Rating grid */\n.fdbck-rating-grid {\n display: grid;\n gap: 0.375rem;\n}\n\n.fdbck-rating-btn {\n aspect-ratio: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n border: 1px solid var(--fdbck-border);\n border-radius: 0.5rem;\n background: transparent;\n color: var(--fdbck-text-primary);\n font-size: var(--fdbck-font-size);\n font-weight: 500;\n cursor: pointer;\n transition: border-color 0.15s, background-color 0.15s, color 0.15s;\n}\n\n.fdbck-rating-btn:hover:not(:disabled) {\n border-color: var(--fdbck-accent);\n}\n\n.fdbck-rating-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.fdbck-rating-btn[data-selected="true"] {\n background-color: var(--fdbck-accent);\n border-color: var(--fdbck-accent);\n color: #fff;\n}\n\n.fdbck-rating-labels {\n display: flex;\n justify-content: space-between;\n margin-top: 0.5rem;\n font-size: 0.75rem;\n color: var(--fdbck-text-muted);\n}\n';
203
203
 
204
204
  // src/styles/confirmation.css
205
- var confirmation_default = {};
205
+ var confirmation_default = "/* fdbck widget \u2014 confirmation state */\n.fdbck-confirmation {\n padding: 2rem 0;\n text-align: center;\n}\n\n.fdbck-check-circle {\n width: 3rem;\n height: 3rem;\n border-radius: 50%;\n background: var(--fdbck-accent-alpha);\n display: flex;\n align-items: center;\n justify-content: center;\n margin: 0 auto 1rem;\n animation: fdbck-scale-in 0.3s ease-out;\n}\n\n.fdbck-check-circle svg {\n width: 1.5rem;\n height: 1.5rem;\n color: var(--fdbck-accent);\n}\n\n.fdbck-confirmation h2 {\n font-size: 1.125rem;\n font-weight: 600;\n color: var(--fdbck-text-primary);\n margin-bottom: 0.25rem;\n}\n\n.fdbck-confirmation p {\n color: var(--fdbck-text-secondary);\n white-space: pre-line;\n}\n\n@keyframes fdbck-scale-in {\n from { transform: scale(0.5); opacity: 0; }\n to { transform: scale(1); opacity: 1; }\n}\n";
206
206
 
207
207
  // src/styles/branding.css
208
- var branding_default = {};
208
+ var branding_default = `/* fdbck widget \u2014 "Powered by fdbck" footer */
209
+ .fdbck-branding {
210
+ display: flex;
211
+ justify-content: center;
212
+ margin-top: 1rem;
213
+ padding-top: 0.75rem;
214
+ border-top: 1px solid var(--fdbck-border);
215
+ }
216
+
217
+ .fdbck-branding a {
218
+ font-size: 0.75rem;
219
+ color: var(--fdbck-text-muted);
220
+ text-decoration: none;
221
+ transition: color 0.15s;
222
+ }
223
+
224
+ .fdbck-branding a:hover {
225
+ color: var(--fdbck-text-secondary);
226
+ }
227
+
228
+ .fdbck-branding-name {
229
+ font-family: 'JetBrains Mono', monospace;
230
+ font-weight: 500;
231
+ color: var(--fdbck-accent);
232
+ }
233
+ `;
209
234
 
210
235
  // src/styles/modal.css
211
- var modal_default = {};
236
+ var modal_default = "/* fdbck widget \u2014 modal mode */\n.fdbck-modal-backdrop {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 1rem;\n z-index: 2147483647;\n animation: fdbck-fade-in 0.2s ease-out;\n}\n\n.fdbck-modal-content {\n position: relative;\n animation: fdbck-scale-up 0.2s ease-out;\n}\n\n.fdbck-close-btn {\n position: absolute;\n top: -0.5rem;\n right: -0.5rem;\n width: 1.75rem;\n height: 1.75rem;\n border: 1px solid var(--fdbck-border);\n border-radius: 50%;\n background: var(--fdbck-card-bg);\n color: var(--fdbck-text-secondary);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1rem;\n line-height: 1;\n transition: border-color 0.15s;\n z-index: 1;\n}\n\n.fdbck-close-btn:hover {\n border-color: var(--fdbck-accent);\n}\n\n@keyframes fdbck-fade-in {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n@keyframes fdbck-scale-up {\n from { transform: scale(0.95); opacity: 0; }\n to { transform: scale(1); opacity: 1; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .fdbck-modal-backdrop,\n .fdbck-modal-content {\n animation: none;\n }\n}\n";
212
237
 
213
238
  // src/styles/popover.css
214
- var popover_default = {};
239
+ var popover_default = "/* fdbck widget \u2014 popover mode */\n.fdbck-popover {\n position: fixed;\n bottom: 1.5rem;\n right: 1.5rem;\n z-index: 2147483647;\n animation: fdbck-slide-up 0.25s ease-out;\n}\n\n.fdbck-popover .fdbck-close-btn {\n position: absolute;\n top: -0.5rem;\n right: -0.5rem;\n}\n\n/* Mobile: bottom sheet */\n@media (max-width: 640px) {\n .fdbck-popover {\n bottom: 0;\n right: 0;\n left: 0;\n padding: 0;\n animation: fdbck-sheet-up 0.25s ease-out;\n }\n\n .fdbck-popover .fdbck-card {\n max-width: 100%;\n width: 100%;\n border-radius: var(--fdbck-border-radius) var(--fdbck-border-radius) 0 0;\n border-bottom: none;\n }\n\n .fdbck-popover .fdbck-close-btn {\n top: 0.75rem;\n right: 0.75rem;\n }\n}\n\n@keyframes fdbck-slide-up {\n from { transform: translateY(1rem); opacity: 0; }\n to { transform: translateY(0); opacity: 1; }\n}\n\n@keyframes fdbck-sheet-up {\n from { transform: translateY(100%); }\n to { transform: translateY(0); }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .fdbck-popover {\n animation: none;\n }\n}\n";
215
240
 
216
241
  // src/styles/index.ts
217
242
  var WIDGET_CSS = [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fdbck-react",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Official React SDK for fdbck — embed feedback questions natively in your React app",
5
5
  "license": "MIT",
6
6
  "author": "fdbck",
package/dist/index.css DELETED
@@ -1,418 +0,0 @@
1
- /* src/styles/base.css */
2
- *,
3
- *::before,
4
- *::after {
5
- box-sizing: border-box;
6
- margin: 0;
7
- padding: 0;
8
- }
9
- :host {
10
- display: block;
11
- font-family: var(--fdbck-font-family);
12
- font-size: var(--fdbck-font-size);
13
- line-height: 1.5;
14
- color: var(--fdbck-text-primary);
15
- -webkit-font-smoothing: antialiased;
16
- }
17
- .fdbck-card {
18
- width: var(--fdbck-width);
19
- max-width: var(--fdbck-max-width);
20
- background: var(--fdbck-card-bg);
21
- border: 1px solid var(--fdbck-border);
22
- border-radius: var(--fdbck-border-radius);
23
- padding: 1.5rem;
24
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
25
- }
26
- .fdbck-welcome {
27
- font-size: var(--fdbck-font-size);
28
- color: var(--fdbck-text-secondary);
29
- margin-bottom: 1rem;
30
- white-space: pre-line;
31
- }
32
- .fdbck-question {
33
- font-size: 1.125rem;
34
- font-weight: 600;
35
- color: var(--fdbck-text-primary);
36
- margin-bottom: 1.5rem;
37
- }
38
- .fdbck-error-text {
39
- color: #ef4444;
40
- font-size: var(--fdbck-font-size);
41
- margin-bottom: 1rem;
42
- }
43
- .fdbck-center {
44
- display: flex;
45
- align-items: center;
46
- justify-content: center;
47
- text-align: center;
48
- flex-direction: column;
49
- }
50
- .fdbck-loading {
51
- min-height: 200px;
52
- display: flex;
53
- align-items: center;
54
- justify-content: center;
55
- }
56
- .fdbck-spinner {
57
- width: 1.5rem;
58
- height: 1.5rem;
59
- border: 2px solid transparent;
60
- border-top-color: var(--fdbck-accent);
61
- border-right-color: var(--fdbck-accent);
62
- border-radius: 50%;
63
- animation: fdbck-spin 0.6s linear infinite;
64
- }
65
- @keyframes fdbck-spin {
66
- to {
67
- transform: rotate(360deg);
68
- }
69
- }
70
- .fdbck-error-state {
71
- padding: 2rem 0;
72
- text-align: center;
73
- }
74
- .fdbck-error-state h2 {
75
- font-size: 1.125rem;
76
- font-weight: 600;
77
- color: var(--fdbck-text-primary);
78
- margin-bottom: 0.25rem;
79
- }
80
- .fdbck-error-state p {
81
- color: var(--fdbck-text-secondary);
82
- }
83
- .fdbck-retry-btn {
84
- margin-top: 1rem;
85
- padding: 0.5rem 1rem;
86
- border: 1px solid var(--fdbck-border);
87
- border-radius: 0.5rem;
88
- background: transparent;
89
- color: var(--fdbck-text-primary);
90
- font-size: var(--fdbck-font-size);
91
- cursor: pointer;
92
- transition: border-color 0.15s;
93
- }
94
- .fdbck-retry-btn:hover {
95
- border-color: var(--fdbck-accent);
96
- }
97
-
98
- /* src/styles/question-types.css */
99
- .fdbck-option-btn {
100
- display: flex;
101
- align-items: center;
102
- gap: 0.75rem;
103
- width: 100%;
104
- padding: 0.75rem 1rem;
105
- border: 1px solid var(--fdbck-border);
106
- border-radius: 0.5rem;
107
- background: transparent;
108
- color: var(--fdbck-text-primary);
109
- font-size: var(--fdbck-font-size);
110
- text-align: left;
111
- cursor: pointer;
112
- transition: border-color 0.15s;
113
- }
114
- .fdbck-option-btn:hover:not(:disabled) {
115
- border-color: var(--fdbck-accent);
116
- }
117
- .fdbck-option-btn:disabled {
118
- opacity: 0.5;
119
- cursor: not-allowed;
120
- }
121
- .fdbck-option-btn[data-selected=true] {
122
- border-color: var(--fdbck-accent);
123
- }
124
- .fdbck-yesno-grid {
125
- display: grid;
126
- grid-template-columns: 1fr 1fr;
127
- gap: 0.75rem;
128
- }
129
- .fdbck-yesno-grid .fdbck-option-btn {
130
- justify-content: center;
131
- font-weight: 500;
132
- }
133
- .fdbck-choice-list {
134
- display: flex;
135
- flex-direction: column;
136
- gap: 0.5rem;
137
- }
138
- .fdbck-radio {
139
- width: 1rem;
140
- height: 1rem;
141
- border: 2px solid var(--fdbck-indicator-border);
142
- border-radius: 50%;
143
- flex-shrink: 0;
144
- display: flex;
145
- align-items: center;
146
- justify-content: center;
147
- transition: border-color 0.15s;
148
- }
149
- .fdbck-radio[data-selected=true] {
150
- border-color: var(--fdbck-accent);
151
- }
152
- .fdbck-radio-dot {
153
- width: 0.5rem;
154
- height: 0.5rem;
155
- border-radius: 50%;
156
- background: var(--fdbck-accent);
157
- }
158
- .fdbck-checkbox {
159
- width: 1rem;
160
- height: 1rem;
161
- border: 2px solid var(--fdbck-indicator-border);
162
- border-radius: 0.25rem;
163
- flex-shrink: 0;
164
- display: flex;
165
- align-items: center;
166
- justify-content: center;
167
- transition: border-color 0.15s, background-color 0.15s;
168
- }
169
- .fdbck-checkbox[data-selected=true] {
170
- border-color: var(--fdbck-accent);
171
- background-color: var(--fdbck-accent);
172
- }
173
- .fdbck-checkbox svg {
174
- width: 0.75rem;
175
- height: 0.75rem;
176
- color: #fff;
177
- }
178
- .fdbck-submit-btn {
179
- margin-top: 0.5rem;
180
- padding: 0.625rem 1rem;
181
- border: none;
182
- border-radius: 0.5rem;
183
- background: var(--fdbck-accent);
184
- color: #fff;
185
- font-size: var(--fdbck-font-size);
186
- font-weight: 500;
187
- cursor: pointer;
188
- transition: opacity 0.15s;
189
- }
190
- .fdbck-submit-btn:disabled {
191
- opacity: 0.4;
192
- cursor: not-allowed;
193
- }
194
- .fdbck-rating-grid {
195
- display: grid;
196
- gap: 0.375rem;
197
- }
198
- .fdbck-rating-btn {
199
- aspect-ratio: 1;
200
- display: flex;
201
- align-items: center;
202
- justify-content: center;
203
- padding: 0;
204
- border: 1px solid var(--fdbck-border);
205
- border-radius: 0.5rem;
206
- background: transparent;
207
- color: var(--fdbck-text-primary);
208
- font-size: var(--fdbck-font-size);
209
- font-weight: 500;
210
- cursor: pointer;
211
- transition:
212
- border-color 0.15s,
213
- background-color 0.15s,
214
- color 0.15s;
215
- }
216
- .fdbck-rating-btn:hover:not(:disabled) {
217
- border-color: var(--fdbck-accent);
218
- }
219
- .fdbck-rating-btn:disabled {
220
- opacity: 0.5;
221
- cursor: not-allowed;
222
- }
223
- .fdbck-rating-btn[data-selected=true] {
224
- background-color: var(--fdbck-accent);
225
- border-color: var(--fdbck-accent);
226
- color: #fff;
227
- }
228
- .fdbck-rating-labels {
229
- display: flex;
230
- justify-content: space-between;
231
- margin-top: 0.5rem;
232
- font-size: 0.75rem;
233
- color: var(--fdbck-text-muted);
234
- }
235
-
236
- /* src/styles/confirmation.css */
237
- .fdbck-confirmation {
238
- padding: 2rem 0;
239
- text-align: center;
240
- }
241
- .fdbck-check-circle {
242
- width: 3rem;
243
- height: 3rem;
244
- border-radius: 50%;
245
- background: var(--fdbck-accent-alpha);
246
- display: flex;
247
- align-items: center;
248
- justify-content: center;
249
- margin: 0 auto 1rem;
250
- animation: fdbck-scale-in 0.3s ease-out;
251
- }
252
- .fdbck-check-circle svg {
253
- width: 1.5rem;
254
- height: 1.5rem;
255
- color: var(--fdbck-accent);
256
- }
257
- .fdbck-confirmation h2 {
258
- font-size: 1.125rem;
259
- font-weight: 600;
260
- color: var(--fdbck-text-primary);
261
- margin-bottom: 0.25rem;
262
- }
263
- .fdbck-confirmation p {
264
- color: var(--fdbck-text-secondary);
265
- white-space: pre-line;
266
- }
267
- @keyframes fdbck-scale-in {
268
- from {
269
- transform: scale(0.5);
270
- opacity: 0;
271
- }
272
- to {
273
- transform: scale(1);
274
- opacity: 1;
275
- }
276
- }
277
-
278
- /* src/styles/branding.css */
279
- .fdbck-branding {
280
- display: flex;
281
- justify-content: center;
282
- margin-top: 1rem;
283
- padding-top: 0.75rem;
284
- border-top: 1px solid var(--fdbck-border);
285
- }
286
- .fdbck-branding a {
287
- font-size: 0.75rem;
288
- color: var(--fdbck-text-muted);
289
- text-decoration: none;
290
- transition: color 0.15s;
291
- }
292
- .fdbck-branding a:hover {
293
- color: var(--fdbck-text-secondary);
294
- }
295
- .fdbck-branding-name {
296
- font-family: "JetBrains Mono", monospace;
297
- font-weight: 500;
298
- color: var(--fdbck-accent);
299
- }
300
-
301
- /* src/styles/modal.css */
302
- .fdbck-modal-backdrop {
303
- position: fixed;
304
- inset: 0;
305
- background: rgba(0, 0, 0, 0.5);
306
- display: flex;
307
- align-items: center;
308
- justify-content: center;
309
- padding: 1rem;
310
- z-index: 2147483647;
311
- animation: fdbck-fade-in 0.2s ease-out;
312
- }
313
- .fdbck-modal-content {
314
- position: relative;
315
- animation: fdbck-scale-up 0.2s ease-out;
316
- }
317
- .fdbck-close-btn {
318
- position: absolute;
319
- top: -0.5rem;
320
- right: -0.5rem;
321
- width: 1.75rem;
322
- height: 1.75rem;
323
- border: 1px solid var(--fdbck-border);
324
- border-radius: 50%;
325
- background: var(--fdbck-card-bg);
326
- color: var(--fdbck-text-secondary);
327
- cursor: pointer;
328
- display: flex;
329
- align-items: center;
330
- justify-content: center;
331
- font-size: 1rem;
332
- line-height: 1;
333
- transition: border-color 0.15s;
334
- z-index: 1;
335
- }
336
- .fdbck-close-btn:hover {
337
- border-color: var(--fdbck-accent);
338
- }
339
- @keyframes fdbck-fade-in {
340
- from {
341
- opacity: 0;
342
- }
343
- to {
344
- opacity: 1;
345
- }
346
- }
347
- @keyframes fdbck-scale-up {
348
- from {
349
- transform: scale(0.95);
350
- opacity: 0;
351
- }
352
- to {
353
- transform: scale(1);
354
- opacity: 1;
355
- }
356
- }
357
- @media (prefers-reduced-motion: reduce) {
358
- .fdbck-modal-backdrop,
359
- .fdbck-modal-content {
360
- animation: none;
361
- }
362
- }
363
-
364
- /* src/styles/popover.css */
365
- .fdbck-popover {
366
- position: fixed;
367
- bottom: 1.5rem;
368
- right: 1.5rem;
369
- z-index: 2147483647;
370
- animation: fdbck-slide-up 0.25s ease-out;
371
- }
372
- .fdbck-popover .fdbck-close-btn {
373
- position: absolute;
374
- top: -0.5rem;
375
- right: -0.5rem;
376
- }
377
- @media (max-width: 640px) {
378
- .fdbck-popover {
379
- bottom: 0;
380
- right: 0;
381
- left: 0;
382
- padding: 0;
383
- animation: fdbck-sheet-up 0.25s ease-out;
384
- }
385
- .fdbck-popover .fdbck-card {
386
- max-width: 100%;
387
- width: 100%;
388
- border-radius: var(--fdbck-border-radius) var(--fdbck-border-radius) 0 0;
389
- border-bottom: none;
390
- }
391
- .fdbck-popover .fdbck-close-btn {
392
- top: 0.75rem;
393
- right: 0.75rem;
394
- }
395
- }
396
- @keyframes fdbck-slide-up {
397
- from {
398
- transform: translateY(1rem);
399
- opacity: 0;
400
- }
401
- to {
402
- transform: translateY(0);
403
- opacity: 1;
404
- }
405
- }
406
- @keyframes fdbck-sheet-up {
407
- from {
408
- transform: translateY(100%);
409
- }
410
- to {
411
- transform: translateY(0);
412
- }
413
- }
414
- @media (prefers-reduced-motion: reduce) {
415
- .fdbck-popover {
416
- animation: none;
417
- }
418
- }