@usefillo/react 0.3.2 → 0.4.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/styles.css CHANGED
@@ -24,6 +24,7 @@
24
24
  --fillo-font: inherit;
25
25
  --fillo-control-bg: #ffffff;
26
26
 
27
+ color-scheme: light;
27
28
  font-family: var(--fillo-font);
28
29
  color: var(--fillo-text);
29
30
  background: var(--fillo-bg);
@@ -33,8 +34,38 @@
33
34
  max-width: 100%;
34
35
  }
35
36
 
37
+ .fillo-form[data-fillo-color-scheme="light"] {
38
+ color-scheme: light;
39
+ }
40
+
41
+ .fillo-form[data-fillo-color-scheme="dark"] {
42
+ --fillo-primary: #fafafa;
43
+ --fillo-primary-contrast: #18181b;
44
+ --fillo-text: #f4f4f5;
45
+ --fillo-muted: #a1a1aa;
46
+ --fillo-border: #3f3f46;
47
+ --fillo-error: #f87171;
48
+ --fillo-control-bg: #18181b;
49
+
50
+ color-scheme: dark;
51
+ }
52
+
53
+ @media (prefers-color-scheme: dark) {
54
+ .fillo-form:not([data-fillo-color-scheme="light"]):not([data-fillo-has-color-theme]) {
55
+ --fillo-primary: #fafafa;
56
+ --fillo-primary-contrast: #18181b;
57
+ --fillo-text: #f4f4f5;
58
+ --fillo-muted: #a1a1aa;
59
+ --fillo-border: #3f3f46;
60
+ --fillo-error: #f87171;
61
+ --fillo-control-bg: #18181b;
62
+
63
+ color-scheme: dark;
64
+ }
65
+ }
66
+
36
67
  .fillo-header { display: flex; flex-direction: column; gap: 0.5rem; }
37
- .fillo-title { font-size: 1.6rem; font-weight: 650; letter-spacing: -0.02em; margin: 0; }
68
+ .fillo-title { font-size: 1.6rem; font-weight: 650; letter-spacing: 0; margin: 0; }
38
69
  .fillo-form-description { color: var(--fillo-muted); margin: 0; line-height: 1.55; }
39
70
  .fillo-page-title { font-size: 1.2rem; font-weight: 600; margin: 0; }
40
71
 
@@ -48,6 +79,7 @@
48
79
  .fillo-optional { color: var(--fillo-muted); font-weight: 400; font-size: 0.85em; }
49
80
  .fillo-description { color: var(--fillo-muted); font-size: 0.85rem; margin: 0; line-height: 1.5; }
50
81
  .fillo-error { color: var(--fillo-error); font-size: 0.85rem; margin: 0; }
82
+ .fillo-submit-error { color: var(--fillo-error); font-size: 0.85rem; font-weight: 500; margin: 0; }
51
83
 
52
84
  /* ---------- Inputs ---------- */
53
85
  .fillo-input {
@@ -57,23 +89,93 @@
57
89
  background: var(--fillo-control-bg);
58
90
  border: 1px solid var(--fillo-border);
59
91
  border-radius: var(--fillo-radius);
92
+ min-height: 2.5rem;
60
93
  padding: 0.6rem 0.8rem;
61
94
  transition: border-color 120ms ease, box-shadow 120ms ease;
62
95
  width: 100%;
63
96
  box-sizing: border-box;
64
97
  }
65
- .fillo-input:focus {
98
+ .fillo-input:focus-visible {
66
99
  outline: none;
67
100
  border-color: var(--fillo-primary);
68
101
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--fillo-primary) 15%, transparent);
69
102
  }
70
103
  .fillo-field--error .fillo-input { border-color: var(--fillo-error); }
71
104
  .fillo-textarea { resize: vertical; min-height: 6rem; }
72
- .fillo-select { cursor: pointer; }
105
+
106
+ /* Phone field: country picker + national input */
107
+ .fillo-phone { position: relative; display: flex; align-items: stretch; gap: 0.4rem; }
108
+ .fillo-phone-country { position: relative; flex: 0 0 auto; }
109
+ .fillo-phone-flag {
110
+ display: inline-flex; align-items: center; gap: 0.35rem;
111
+ height: 100%; min-height: 2.5rem; padding: 0 0.6rem;
112
+ font: inherit; color: var(--fillo-text);
113
+ background: var(--fillo-control-bg);
114
+ border: 1px solid var(--fillo-border); border-radius: var(--fillo-radius);
115
+ cursor: pointer; white-space: nowrap;
116
+ transition: border-color 120ms ease, box-shadow 120ms ease;
117
+ }
118
+ .fillo-phone-flag:focus-visible {
119
+ outline: none; border-color: var(--fillo-primary);
120
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--fillo-primary) 15%, transparent);
121
+ }
122
+ .fillo-phone-flag-emoji { font-size: 1.15em; line-height: 1; }
123
+ .fillo-phone-dial { font-variant-numeric: tabular-nums; color: var(--fillo-muted); }
124
+ .fillo-phone-caret { font-size: 0.65em; color: var(--fillo-muted); }
125
+ .fillo-phone-input { flex: 1 1 auto; min-width: 0; }
126
+ .fillo-field--error .fillo-phone-flag { border-color: var(--fillo-error); }
127
+ .fillo-phone-popover {
128
+ position: absolute; z-index: 30; top: calc(100% + 0.3rem); left: 0;
129
+ width: 18rem; max-width: 84vw; padding: 0.4rem;
130
+ display: flex; flex-direction: column; gap: 0.35rem;
131
+ background: var(--fillo-control-bg);
132
+ border: 1px solid var(--fillo-border); border-radius: var(--fillo-radius);
133
+ box-shadow: 0 12px 32px -14px rgba(0, 0, 0, 0.35);
134
+ }
135
+ .fillo-phone-search {
136
+ appearance: none; font: inherit; width: 100%; box-sizing: border-box;
137
+ color: var(--fillo-text); background: var(--fillo-bg);
138
+ border: 1px solid var(--fillo-border);
139
+ border-radius: calc(var(--fillo-radius) - 3px); padding: 0.45rem 0.6rem;
140
+ }
141
+ .fillo-phone-search:focus-visible { outline: none; border-color: var(--fillo-primary); }
142
+ .fillo-phone-list { list-style: none; margin: 0; padding: 0; max-height: 14rem; overflow-y: auto; }
143
+ .fillo-phone-option {
144
+ display: flex; align-items: center; gap: 0.5rem;
145
+ padding: 0.45rem 0.5rem; border-radius: calc(var(--fillo-radius) - 3px);
146
+ cursor: pointer; color: var(--fillo-text);
147
+ }
148
+ .fillo-phone-option--active { background: color-mix(in srgb, var(--fillo-primary) 10%, transparent); }
149
+ .fillo-phone-option-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
150
+ .fillo-phone-option-dial { color: var(--fillo-muted); font-variant-numeric: tabular-nums; }
151
+ .fillo-phone-empty { padding: 0.6rem 0.5rem; color: var(--fillo-muted); }
152
+ .fillo-select-wrap {
153
+ position: relative;
154
+ display: block;
155
+ }
156
+ .fillo-select {
157
+ cursor: pointer;
158
+ padding-right: 2.45rem;
159
+ }
160
+ .fillo-select-icon {
161
+ pointer-events: none;
162
+ position: absolute;
163
+ top: 50%;
164
+ right: 0.9rem;
165
+ width: 0.62rem;
166
+ height: 0.62rem;
167
+ border-right: 1.5px solid currentColor;
168
+ border-bottom: 1.5px solid currentColor;
169
+ color: var(--fillo-muted);
170
+ transform: translateY(-65%) rotate(45deg);
171
+ transition: color 120ms ease;
172
+ }
173
+ .fillo-select-wrap:focus-within .fillo-select-icon { color: var(--fillo-primary); }
73
174
 
74
175
  /* ---------- Choices ---------- */
75
176
  .fillo-options { display: flex; flex-direction: column; gap: 0.5rem; }
76
177
  .fillo-option {
178
+ position: relative;
77
179
  display: flex;
78
180
  align-items: center;
79
181
  gap: 0.6rem;
@@ -85,25 +187,129 @@
85
187
  transition: border-color 120ms ease, background 120ms ease;
86
188
  }
87
189
  .fillo-option:hover { border-color: color-mix(in srgb, var(--fillo-primary) 45%, var(--fillo-border)); }
190
+ .fillo-option:focus-within {
191
+ border-color: var(--fillo-primary);
192
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--fillo-primary) 14%, transparent);
193
+ }
88
194
  .fillo-option--selected {
89
195
  border-color: var(--fillo-primary);
90
196
  background: color-mix(in srgb, var(--fillo-primary) 6%, var(--fillo-control-bg));
91
197
  }
92
- .fillo-option-input { accent-color: var(--fillo-primary); margin: 0; }
198
+ .fillo-option-input {
199
+ accent-color: var(--fillo-primary);
200
+ flex: 0 0 auto;
201
+ width: 1rem;
202
+ height: 1rem;
203
+ margin: 0;
204
+ }
205
+ .fillo-option-input:focus-visible { outline: none; }
206
+ .fillo-option--has-icon .fillo-option-input {
207
+ position: absolute;
208
+ width: 1px;
209
+ height: 1px;
210
+ overflow: hidden;
211
+ opacity: 0;
212
+ pointer-events: none;
213
+ }
214
+ .fillo-option-icon {
215
+ width: 1.05rem;
216
+ height: 1.05rem;
217
+ flex: 0 0 auto;
218
+ color: var(--fillo-muted);
219
+ transition: color 120ms ease;
220
+ }
221
+ .fillo-option--selected .fillo-option-icon { color: var(--fillo-primary); }
93
222
  .fillo-option-label { font-size: 0.95rem; }
94
223
 
95
- /* "Other" free-text input — inline inside the option row, block under dropdowns. */
96
- .fillo-other-input {
97
- flex: 1;
224
+ .fillo-option-main {
225
+ display: flex;
226
+ align-items: center;
227
+ gap: 0.6rem;
98
228
  min-width: 0;
99
- margin-left: 0.2rem;
100
- padding: 0.3rem 0.6rem;
101
- font-size: 0.9rem;
102
229
  }
103
- .fillo-other-input--block {
104
- flex: none;
230
+ .fillo-option--with-other {
231
+ align-items: stretch;
232
+ flex-direction: column;
233
+ gap: 0.55rem;
234
+ }
235
+ .fillo-option--with-other .fillo-option-label {
236
+ font-weight: 550;
237
+ }
238
+
239
+ /* ---------- Toggle checkbox ---------- */
240
+ .fillo-toggle {
241
+ position: relative;
242
+ display: flex;
243
+ align-items: center;
244
+ justify-content: space-between;
245
+ gap: 1rem;
246
+ border: 1px solid var(--fillo-border);
247
+ border-radius: var(--fillo-radius);
248
+ background: var(--fillo-control-bg);
249
+ padding: 0.65rem 0.8rem;
250
+ cursor: pointer;
251
+ transition: border-color 120ms ease, background 120ms ease, box-shadow 120ms ease;
252
+ }
253
+ .fillo-toggle:hover { border-color: color-mix(in srgb, var(--fillo-primary) 45%, var(--fillo-border)); }
254
+ .fillo-toggle-copy { min-width: 0; }
255
+ .fillo-toggle-input {
256
+ position: absolute;
257
+ width: 1px;
258
+ height: 1px;
259
+ overflow: hidden;
260
+ clip: rect(0 0 0 0);
261
+ clip-path: inset(50%);
262
+ white-space: nowrap;
263
+ }
264
+ .fillo-toggle-track {
265
+ position: relative;
266
+ display: inline-flex;
267
+ width: 2.35rem;
268
+ height: 1.35rem;
269
+ flex: 0 0 auto;
270
+ align-items: center;
271
+ border-radius: 999px;
272
+ background: color-mix(in srgb, var(--fillo-muted) 18%, var(--fillo-control-bg));
273
+ box-shadow: inset 0 0 0 1px var(--fillo-border);
274
+ transition: background 160ms ease, box-shadow 160ms ease;
275
+ }
276
+ .fillo-toggle-thumb {
277
+ width: 1rem;
278
+ height: 1rem;
279
+ margin-left: 0.18rem;
280
+ border-radius: 999px;
281
+ background: var(--fillo-control-bg);
282
+ box-shadow: 0 1px 2px color-mix(in srgb, var(--fillo-text) 18%, transparent);
283
+ transition: transform 160ms ease, background 160ms ease;
284
+ }
285
+ .fillo-toggle-input:checked + .fillo-toggle-track {
286
+ background: var(--fillo-primary);
287
+ box-shadow: inset 0 0 0 1px var(--fillo-primary);
288
+ }
289
+ .fillo-toggle-input:checked + .fillo-toggle-track .fillo-toggle-thumb {
290
+ transform: translateX(1rem);
291
+ background: var(--fillo-primary-contrast);
292
+ }
293
+ .fillo-toggle-input:focus-visible + .fillo-toggle-track {
294
+ box-shadow:
295
+ inset 0 0 0 1px var(--fillo-primary),
296
+ 0 0 0 3px color-mix(in srgb, var(--fillo-primary) 15%, transparent);
297
+ }
298
+ .fillo-toggle:has(.fillo-toggle-input:checked) {
299
+ border-color: var(--fillo-primary);
300
+ background: color-mix(in srgb, var(--fillo-primary) 5%, var(--fillo-control-bg));
301
+ }
302
+
303
+ /* "Other" free-text input — nested inside choice rows, block under dropdowns. */
304
+ .fillo-other-input {
105
305
  width: 100%;
306
+ min-width: 0;
106
307
  margin-left: 0;
308
+ padding: 0.5rem 0.7rem;
309
+ font-size: 0.92rem;
310
+ background: color-mix(in srgb, var(--fillo-primary) 3%, var(--fillo-control-bg));
311
+ }
312
+ .fillo-other-input--block {
107
313
  margin-top: 0.45rem;
108
314
  padding: 0.55rem 0.8rem;
109
315
  }
@@ -355,7 +561,7 @@
355
561
  color: var(--fillo-primary);
356
562
  font-size: 1.4rem; font-weight: 700;
357
563
  }
358
- .fillo-success-title { margin: 0; font-size: 1.35rem; letter-spacing: -0.01em; }
564
+ .fillo-success-title { margin: 0; font-size: 1.35rem; letter-spacing: 0; }
359
565
  .fillo-success-message { margin: 0; color: var(--fillo-muted); }
360
566
 
361
567
  /* Honeypot — off-screen, never display:none (bots check that) */
@@ -389,7 +595,7 @@
389
595
  text-align: center;
390
596
  font-size: 0.75rem;
391
597
  font-weight: 500;
392
- letter-spacing: 0.01em;
598
+ letter-spacing: 0;
393
599
  color: var(--fillo-muted);
394
600
  text-decoration: none;
395
601
  opacity: 0.75;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usefillo/react",
3
- "version": "0.3.2",
3
+ "version": "0.4.0",
4
4
  "description": "Headless React components for embedding Fillo forms natively in your product.",
5
5
  "license": "MIT",
6
6
  "keywords": [
@@ -32,7 +32,7 @@
32
32
  "access": "public"
33
33
  },
34
34
  "dependencies": {
35
- "@usefillo/core": "^0.3.2"
35
+ "@usefillo/core": "^0.4.0"
36
36
  },
37
37
  "peerDependencies": {
38
38
  "react": "^18.0.0 || ^19.0.0",