@openpen/module-api 1.3.0 → 1.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.
@@ -17,6 +17,16 @@
17
17
  fill: var(--openpen-color-popover-frame);
18
18
  }
19
19
 
20
+ /* A popover that holds an AppPopoverPanel takes the host popup-panel frame:
21
+ border-hi frame and the small shadow. Other popovers keep the default frame. */
22
+ .openpen-popover-content:has(.openpen-popover-panel) {
23
+ border-color: var(--openpen-color-border-hi);
24
+ box-shadow: var(--openpen-shadow-sm);
25
+ }
26
+ .openpen-popover-content:has(.openpen-popover-panel) .openpen-popover-arrow {
27
+ fill: var(--openpen-color-border-hi);
28
+ }
29
+
20
30
  /* ── Open / close animations ────────────────────────────────────────────────
21
31
  Reka UI's Presence keeps the element in the DOM until the running CSS
22
32
  animation ends, so animations targeting [data-state="closed"] DO play
@@ -51,8 +61,88 @@ to { opacity: 0; transform: scale(0.92);
51
61
  }
52
62
  }
53
63
 
64
+ .openpen-popover-panel[data-v-ffa56c48] {
65
+ /*
66
+ * Three shared columns for every row in the panel (rows use `subgrid`):
67
+ * label (as wide as the widest label), control (takes the rest), value
68
+ * (optional; zero width when no row has one). The 10px between columns is
69
+ * put on the label and value cells instead of a column gap so an unused
70
+ * value column leaves no empty space at the right edge.
71
+ */
72
+ display: grid;
73
+ grid-template-columns: auto minmax(140px, 1fr) auto;
74
+ align-items: center;
75
+ row-gap: 10px;
76
+ column-gap: 0;
77
+ }
78
+ .openpen-popover-title[data-v-ffa56c48] {
79
+ grid-column: 1 / -1;
80
+ font-size: 11px;
81
+ font-weight: 600;
82
+ letter-spacing: 0.08em;
83
+ text-transform: uppercase;
84
+ color: var(--openpen-color-text-muted);
85
+ margin-bottom: 6px;
86
+ }
87
+
88
+ .openpen-popover-row[data-v-6d95e79e] {
89
+ /* Join the panel's label / control / value columns so every row lines up. */
90
+ display: grid;
91
+ grid-template-columns: subgrid;
92
+ grid-column: 1 / -1;
93
+ align-items: center;
94
+ }
95
+
96
+ /* A row without a label (buttons, a segmented control) spans all columns. */
97
+ .openpen-popover-row--bare[data-v-6d95e79e] {
98
+ display: flex;
99
+ gap: 10px;
100
+ }
101
+
102
+ /*
103
+ * Third child = optional value text: right-aligned, equal digit width, never
104
+ * narrower than 5ch so the control does not move while a number gains a digit.
105
+ * (Slider values belong in the AppSlider bubble, not here.)
106
+ */
107
+ .openpen-popover-row[data-v-6d95e79e] > *:nth-child(3) {
108
+ justify-self: end;
109
+ min-width: 5ch;
110
+ margin-left: 10px;
111
+ text-align: right;
112
+ font-variant-numeric: tabular-nums;
113
+ }
114
+ .openpen-popover-row-label[data-v-6d95e79e] {
115
+ margin-right: 10px;
116
+ font-size: 13px;
117
+ color: var(--openpen-color-text-dim);
118
+ white-space: nowrap;
119
+ }
120
+
121
+ /* A segmented control placed in a row takes the remaining width. */
122
+ .openpen-popover-row[data-v-6d95e79e] .app-seg {
123
+ flex: 1;
124
+ }
125
+
126
+ /* ── Value bubble (shown while dragging) ───────────────────────────────────── */
127
+ .app-slider-bubble[data-v-49f1dd0d] {
128
+ position: absolute;
129
+ left: 50%;
130
+ bottom: calc(100% + 6px);
131
+ transform: translateX(-50%);
132
+ padding: 2px 6px;
133
+ border-radius: var(--openpen-radius-sm);
134
+ background: var(--openpen-color-tooltip-bg);
135
+ color: var(--openpen-color-tooltip-text);
136
+ border: 1px solid var(--openpen-color-tooltip-border);
137
+ font-size: 11px;
138
+ font-variant-numeric: tabular-nums;
139
+ white-space: nowrap;
140
+ pointer-events: none;
141
+ z-index: 1;
142
+ }
143
+
54
144
  /* ── Root container ────────────────────────────────────────────────────────── */
55
- .app-slider-root[data-v-ae09a023] {
145
+ .app-slider-root[data-v-49f1dd0d] {
56
146
  position: relative;
57
147
  display: flex;
58
148
  align-items: center;
@@ -61,47 +151,47 @@ to { opacity: 0; transform: scale(0.92);
61
151
  flex-shrink: 0;
62
152
  cursor: pointer;
63
153
  }
64
- .app-slider-root[data-orientation='horizontal'][data-v-ae09a023] {
154
+ .app-slider-root[data-orientation='horizontal'][data-v-49f1dd0d] {
65
155
  height: var(--track-height, 4px);
66
156
  }
67
- .app-slider-root[data-orientation='vertical'][data-v-ae09a023] {
157
+ .app-slider-root[data-orientation='vertical'][data-v-49f1dd0d] {
68
158
  flex-direction: column;
69
159
  width: var(--track-height, 4px);
70
160
  }
71
161
 
72
162
  /* ── Track ─────────────────────────────────────────────────────────────────── */
73
- .app-slider-track[data-v-ae09a023] {
163
+ .app-slider-track[data-v-49f1dd0d] {
74
164
  position: relative;
75
165
  flex-grow: 1;
76
166
  border-radius: var(--track-radius, 2px);
77
167
  background: var(--openpen-color-border-hi);
78
168
  }
79
- .app-slider-root[data-orientation='horizontal'] .app-slider-track[data-v-ae09a023] {
169
+ .app-slider-root[data-orientation='horizontal'] .app-slider-track[data-v-49f1dd0d] {
80
170
  height: var(--track-height, 4px);
81
171
  }
82
- .app-slider-root[data-orientation='vertical'] .app-slider-track[data-v-ae09a023] {
172
+ .app-slider-root[data-orientation='vertical'] .app-slider-track[data-v-49f1dd0d] {
83
173
  width: var(--track-height, 4px);
84
174
  }
85
175
 
86
176
  /* ── Range (filled portion) ─────────────────────────────────────────────────── */
87
- .app-slider-range[data-v-ae09a023] {
177
+ .app-slider-range[data-v-49f1dd0d] {
88
178
  position: absolute;
89
179
  border-radius: var(--track-radius, 2px);
90
180
  background: var(--openpen-color-accent);
91
181
  }
92
- .app-slider-root[data-orientation='horizontal'] .app-slider-range[data-v-ae09a023] {
182
+ .app-slider-root[data-orientation='horizontal'] .app-slider-range[data-v-49f1dd0d] {
93
183
  height: 100%;
94
184
  top: 0;
95
185
  left: 0;
96
186
  }
97
- .app-slider-root[data-orientation='vertical'] .app-slider-range[data-v-ae09a023] {
187
+ .app-slider-root[data-orientation='vertical'] .app-slider-range[data-v-49f1dd0d] {
98
188
  width: 100%;
99
189
  bottom: 0;
100
190
  left: 0;
101
191
  }
102
192
 
103
193
  /* ── Thumb ─────────────────────────────────────────────────────────────────── */
104
- .app-slider-thumb[data-v-ae09a023] {
194
+ .app-slider-thumb[data-v-49f1dd0d] {
105
195
  display: block;
106
196
  width: var(--thumb-w, 14px);
107
197
  height: var(--thumb-h, 14px);
@@ -112,15 +202,15 @@ to { opacity: 0; transform: scale(0.92);
112
202
  outline: none;
113
203
  transition: transform var(--openpen-duration-fast) var(--openpen-easing-standard);
114
204
  }
115
- .app-slider-thumb[data-v-ae09a023]:hover {
205
+ .app-slider-thumb[data-v-49f1dd0d]:hover {
116
206
  transform: scale(1.2);
117
207
  }
118
- .app-slider-thumb[data-v-ae09a023]:focus-visible {
208
+ .app-slider-thumb[data-v-49f1dd0d]:focus-visible {
119
209
  box-shadow: 0 0 0 3px var(--openpen-color-accent-glow);
120
210
  }
121
211
 
122
212
  /* Root — the toggle track */
123
- .app-toggle[data-v-d23dd615] {
213
+ .app-toggle[data-v-a8ed9b2b] {
124
214
  width: 40px;
125
215
  height: 24px;
126
216
  border-radius: 12px;
@@ -137,12 +227,12 @@ to { opacity: 0; transform: scale(0.92);
137
227
  display: inline-flex;
138
228
  align-items: center;
139
229
  }
140
- .app-toggle.on[data-v-d23dd615] {
230
+ .app-toggle.on[data-v-a8ed9b2b] {
141
231
  background: var(--openpen-color-accent);
142
232
  }
143
233
 
144
234
  /* Thumb — the white circular knob */
145
- .app-toggle-thumb[data-v-d23dd615] {
235
+ .app-toggle-thumb[data-v-a8ed9b2b] {
146
236
  position: absolute;
147
237
  top: 3px;
148
238
  left: 3px;
@@ -155,56 +245,208 @@ to { opacity: 0; transform: scale(0.92);
155
245
  display: block;
156
246
  pointer-events: none;
157
247
  }
158
- .app-toggle.on .app-toggle-thumb[data-v-d23dd615],
159
- .app-toggle[data-state='checked'] .app-toggle-thumb[data-v-d23dd615] {
248
+ .app-toggle.on .app-toggle-thumb[data-v-a8ed9b2b],
249
+ .app-toggle[data-state='checked'] .app-toggle-thumb[data-v-a8ed9b2b] {
160
250
  left: 19px;
161
251
  }
162
252
 
163
- .app-seg[data-v-eaacab1f] {
253
+ .openpen-tooltip-content {
254
+ background: var(--openpen-color-tooltip-bg);
255
+ border: 1px solid var(--openpen-color-border-hi);
256
+ border-radius: var(--openpen-radius-sm);
257
+ padding: 5px 9px;
258
+ color: var(--openpen-color-tooltip-text);
259
+ font-size: 12px;
260
+ line-height: 1.4;
261
+ /* Prevent text wrap for short tooltip labels */
262
+ white-space: nowrap;
263
+ box-shadow: var(--openpen-shadow-sm);
264
+ z-index: 200;
265
+ pointer-events: none;
266
+ }
267
+ .openpen-tooltip-arrow {
268
+ fill: var(--openpen-color-tooltip-bg);
269
+ }
270
+
271
+ /* ── Open / close animations ────────────────────────────────────────────────
272
+ Reka UI Presence keeps the element in the DOM until the CSS animation ends,
273
+ so data-state="delayed-open" / "instant-open" / "closed" all animate. */
274
+ .openpen-tooltip-content[data-state='delayed-open'],
275
+ .openpen-tooltip-content[data-state='instant-open'] {
276
+ animation: openpen-tooltip-in var(--openpen-duration-fast) var(--openpen-easing-standard);
277
+ }
278
+ .openpen-tooltip-content[data-state='closed'] {
279
+ animation: openpen-tooltip-out var(--openpen-duration-fast) ease forwards;
280
+ }
281
+ @keyframes openpen-tooltip-in {
282
+ from { opacity: 0; transform: scale(0.95);
283
+ }
284
+ to { opacity: 1; transform: scale(1);
285
+ }
286
+ }
287
+ @keyframes openpen-tooltip-out {
288
+ from { opacity: 1; transform: scale(1);
289
+ }
290
+ to { opacity: 0; transform: scale(0.95);
291
+ }
292
+ }
293
+
294
+ .app-seg[data-v-a90b77a6] {
164
295
  display: flex;
165
- gap: var(--openpen-space-xs);
296
+ gap: 0;
297
+ padding: 2px;
298
+ border-radius: var(--openpen-radius-sm);
299
+ background: var(--openpen-color-input-bg);
300
+ border: 1px solid var(--openpen-color-border);
166
301
  }
167
- .app-seg-btn[data-v-eaacab1f] {
302
+
303
+ /* One focus frame around the whole group (2px, 2px away). */
304
+ .app-seg[data-v-a90b77a6]:focus-within {
305
+ /* !important: Reka's roving-focus group writes an inline `outline: none` on this element. */
306
+ outline: 2px solid var(--openpen-color-accent) !important;
307
+ outline-offset: 2px;
308
+ }
309
+ .app-seg-btn[data-v-a90b77a6] {
168
310
  flex: 1;
169
311
  display: flex;
170
312
  align-items: center;
171
313
  justify-content: center;
172
314
  gap: 6px;
173
- padding: 6px var(--openpen-space-lg);
174
- border: 1.5px solid var(--openpen-color-border-hi);
175
- border-radius: var(--openpen-radius-sm);
176
- background: var(--openpen-color-input-bg);
315
+ padding: 5px var(--openpen-space-md);
316
+ border: 1px solid transparent;
317
+ border-radius: calc(var(--openpen-radius-sm) - 2px);
318
+ background: transparent;
177
319
  color: var(--openpen-color-text-dim);
178
320
  font-size: 12px;
179
321
  font-weight: 600;
180
322
  cursor: pointer;
181
323
  white-space: nowrap;
324
+ outline: none;
182
325
  transition:
183
326
  background var(--openpen-duration-fast) var(--openpen-easing-standard),
184
327
  color var(--openpen-duration-fast) var(--openpen-easing-standard),
185
- border-color var(--openpen-duration-fast) var(--openpen-easing-standard);
328
+ box-shadow var(--openpen-duration-fast) var(--openpen-easing-standard);
329
+ }
330
+ .app-seg-btn--icon[data-v-a90b77a6] {
331
+ padding: 5px var(--openpen-space-sm);
186
332
  }
187
- .app-seg-icon[data-v-eaacab1f] {
333
+ .app-seg-icon[data-v-a90b77a6] {
188
334
  display: inline-flex;
189
335
  align-items: center;
190
336
  justify-content: center;
191
337
  line-height: 0;
192
338
  }
193
- .app-seg-btn[data-v-eaacab1f]:hover {
339
+
340
+ /* Hover: a step on top of the track that is still visible (track is input-bg). */
341
+ .app-seg-btn[data-v-a90b77a6]:hover {
194
342
  color: var(--openpen-color-text-primary);
195
343
  background: var(--openpen-color-control-hover);
196
344
  }
197
- .app-seg-btn.active[data-v-eaacab1f] {
198
- background: var(--openpen-color-accent-bg);
345
+
346
+ /* Selected: raised segment — surface fill + thin border + soft shadow. */
347
+ .app-seg-btn.active[data-v-a90b77a6] {
348
+ background: var(--openpen-color-surface-popup);
199
349
  color: var(--openpen-color-accent);
200
- border-color: color-mix(in srgb, var(--openpen-color-accent) 40%, transparent);
350
+ border-color: var(--openpen-color-border-hi);
351
+ box-shadow: var(--openpen-shadow-sm);
201
352
  }
202
- .app-seg--disabled[data-v-eaacab1f] {
353
+ .app-seg--disabled[data-v-a90b77a6] {
203
354
  opacity: 0.45;
204
355
  pointer-events: none;
205
356
  cursor: not-allowed;
206
357
  }
207
358
 
359
+ .app-swatch-picker[data-v-c62ade43] {
360
+ display: flex;
361
+ flex-wrap: wrap;
362
+ align-items: center;
363
+ gap: var(--openpen-space-sm);
364
+ --app-swatch-size: 24px;
365
+ }
366
+ .app-swatch-picker--spacing-small[data-v-c62ade43] { gap: 6px;
367
+ }
368
+ .app-swatch-picker--small[data-v-c62ade43] { --app-swatch-size: 22px;
369
+ }
370
+ .app-swatch-picker--medium[data-v-c62ade43] { --app-swatch-size: 24px;
371
+ }
372
+ .app-swatch-picker--large[data-v-c62ade43] { --app-swatch-size: 28px;
373
+ }
374
+ .app-swatch[data-v-c62ade43] {
375
+ width: var(--app-swatch-size);
376
+ height: var(--app-swatch-size);
377
+ padding: 0;
378
+ border: 0;
379
+ border-radius: 50%;
380
+ cursor: pointer;
381
+ flex-shrink: 0;
382
+ /* Hairline so near-white / near-surface swatches keep an edge. */
383
+ box-shadow: inset 0 0 0 1px var(--openpen-color-border-hi);
384
+ outline: none;
385
+ transition: transform var(--openpen-duration-fast) var(--openpen-easing-standard);
386
+ }
387
+ .app-swatch-picker--rounded .app-swatch[data-v-c62ade43] { border-radius: var(--openpen-radius-sm);
388
+ }
389
+ .app-swatch-picker--square .app-swatch[data-v-c62ade43] { border-radius: 2px;
390
+ }
391
+ .app-swatch[data-v-c62ade43]:hover { transform: scale(1.1);
392
+ }
393
+
394
+ /* Selected: outer ring (primary text colour) + inner band (focus-band colour). */
395
+ .app-swatch.selected[data-v-c62ade43] {
396
+ box-shadow:
397
+ inset 0 0 0 2px var(--openpen-color-text-primary),
398
+ inset 0 0 0 4px var(--openpen-color-surface-popup);
399
+ }
400
+
401
+ /* Keyboard focus: separate outline outside the swatch. */
402
+ .app-swatch[data-v-c62ade43]:focus-visible {
403
+ outline: 2px solid var(--openpen-color-accent);
404
+ outline-offset: 2px;
405
+ }
406
+ .app-swatch-picker[data-disabled][data-v-c62ade43] {
407
+ opacity: 0.45;
408
+ pointer-events: none;
409
+ }
410
+
411
+ .app-toggle-btn[data-v-1d1a1150] {
412
+ display: inline-flex;
413
+ align-items: center;
414
+ justify-content: center;
415
+ min-width: 32px;
416
+ height: 32px;
417
+ padding: 0 var(--openpen-space-sm);
418
+ border: 1px solid var(--openpen-color-border-hi);
419
+ border-radius: var(--openpen-radius-sm);
420
+ background: var(--openpen-color-input-bg);
421
+ color: var(--openpen-color-text-dim);
422
+ font-size: 14px;
423
+ font-weight: 600;
424
+ line-height: 1;
425
+ cursor: pointer;
426
+ flex-shrink: 0;
427
+ transition:
428
+ background var(--openpen-duration-fast) var(--openpen-easing-standard),
429
+ color var(--openpen-duration-fast) var(--openpen-easing-standard),
430
+ border-color var(--openpen-duration-fast) var(--openpen-easing-standard);
431
+ }
432
+ .app-toggle-btn[data-v-1d1a1150]:hover {
433
+ background: var(--openpen-color-control-hover);
434
+ color: var(--openpen-color-text-primary);
435
+ }
436
+ .app-toggle-btn.pressed[data-v-1d1a1150] {
437
+ background: var(--openpen-color-accent-bg);
438
+ border-color: var(--openpen-color-text-dim);
439
+ color: var(--openpen-color-text-primary);
440
+ }
441
+ .app-toggle-btn[data-v-1d1a1150]:focus-visible {
442
+ outline: 2px solid var(--openpen-color-accent);
443
+ outline-offset: 2px;
444
+ }
445
+ .app-toggle-btn[data-v-1d1a1150]:disabled {
446
+ opacity: 0.45;
447
+ cursor: not-allowed;
448
+ }
449
+
208
450
  /* ── Overlay (transparent click absorber, NOT a dim backdrop) ─────────────────
209
451
  OpenPen's overlay window is transparent + frameless. A traditional dim/blur
210
452
  backdrop renders as a small dark patch only over the visible chrome — visually
@@ -460,47 +702,6 @@ to { opacity: 0; transform: scale(0.95);
460
702
  }
461
703
  }
462
704
 
463
- .openpen-tooltip-content {
464
- background: var(--openpen-color-tooltip-bg);
465
- border: 1px solid var(--openpen-color-border-hi);
466
- border-radius: var(--openpen-radius-sm);
467
- padding: 5px 9px;
468
- color: var(--openpen-color-tooltip-text);
469
- font-size: 12px;
470
- line-height: 1.4;
471
- /* Prevent text wrap for short tooltip labels */
472
- white-space: nowrap;
473
- box-shadow: var(--openpen-shadow-sm);
474
- z-index: 200;
475
- pointer-events: none;
476
- }
477
- .openpen-tooltip-arrow {
478
- fill: var(--openpen-color-tooltip-bg);
479
- }
480
-
481
- /* ── Open / close animations ────────────────────────────────────────────────
482
- Reka UI Presence keeps the element in the DOM until the CSS animation ends,
483
- so data-state="delayed-open" / "instant-open" / "closed" all animate. */
484
- .openpen-tooltip-content[data-state='delayed-open'],
485
- .openpen-tooltip-content[data-state='instant-open'] {
486
- animation: openpen-tooltip-in var(--openpen-duration-fast) var(--openpen-easing-standard);
487
- }
488
- .openpen-tooltip-content[data-state='closed'] {
489
- animation: openpen-tooltip-out var(--openpen-duration-fast) ease forwards;
490
- }
491
- @keyframes openpen-tooltip-in {
492
- from { opacity: 0; transform: scale(0.95);
493
- }
494
- to { opacity: 1; transform: scale(1);
495
- }
496
- }
497
- @keyframes openpen-tooltip-out {
498
- from { opacity: 1; transform: scale(1);
499
- }
500
- to { opacity: 0; transform: scale(0.95);
501
- }
502
- }
503
-
504
705
  /* ── Tab root ───────────────────────────────────────────────────────────────── */
505
706
  .openpen-tabs[data-v-5bab1555] {
506
707
  display: flex;
@@ -560,7 +761,7 @@ to { opacity: 0; transform: scale(0.95);
560
761
  border-radius: var(--openpen-radius-sm);
561
762
  }
562
763
 
563
- .app-banner[data-v-c68deb55] {
764
+ .app-banner[data-v-4f309880] {
564
765
  display: flex;
565
766
  align-items: flex-start;
566
767
  gap: 10px;
@@ -570,24 +771,24 @@ to { opacity: 0; transform: scale(0.95);
570
771
  font-size: 13px;
571
772
  line-height: 1.55;
572
773
  }
573
- .app-banner-inline[data-v-c68deb55] {
774
+ .app-banner-inline[data-v-4f309880] {
574
775
  padding: 7px 12px;
575
776
  align-items: center;
576
777
  font-size: 12px;
577
778
  }
578
- .app-banner-icon[data-v-c68deb55] {
779
+ .app-banner-icon[data-v-4f309880] {
579
780
  flex-shrink: 0;
580
781
  display: flex;
581
782
  align-items: center;
582
783
  margin-top: 1px;
583
784
  }
584
- .app-banner-inline .app-banner-icon[data-v-c68deb55] { margin-top: 0;
785
+ .app-banner-inline .app-banner-icon[data-v-4f309880] { margin-top: 0;
585
786
  }
586
- .app-banner-body[data-v-c68deb55] {
787
+ .app-banner-body[data-v-4f309880] {
587
788
  flex: 1;
588
789
  min-width: 0;
589
790
  }
590
- .app-banner-actions[data-v-c68deb55] {
791
+ .app-banner-actions[data-v-4f309880] {
591
792
  display: flex;
592
793
  align-items: center;
593
794
  gap: 6px;
@@ -596,36 +797,36 @@ to { opacity: 0; transform: scale(0.95);
596
797
  }
597
798
 
598
799
  /* Variants */
599
- .app-banner-info[data-v-c68deb55] {
800
+ .app-banner-info[data-v-4f309880] {
600
801
  background: var(--openpen-color-state-info-bg);
601
802
  border-color: var(--openpen-color-state-info-border);
602
803
  color: var(--openpen-color-state-info-text);
603
804
  }
604
- .app-banner-info .app-banner-icon[data-v-c68deb55] {
805
+ .app-banner-info .app-banner-icon[data-v-4f309880] {
605
806
  color: var(--openpen-color-state-info-icon);
606
807
  }
607
- .app-banner-warning[data-v-c68deb55] {
808
+ .app-banner-warning[data-v-4f309880] {
608
809
  background: var(--openpen-color-state-warning-bg);
609
810
  border-color: var(--openpen-color-state-warning-border);
610
811
  color: var(--openpen-color-state-warning-text);
611
812
  }
612
- .app-banner-warning .app-banner-icon[data-v-c68deb55] {
813
+ .app-banner-warning .app-banner-icon[data-v-4f309880] {
613
814
  color: var(--openpen-color-state-warning-icon);
614
815
  }
615
- .app-banner-success[data-v-c68deb55] {
816
+ .app-banner-success[data-v-4f309880] {
616
817
  background: var(--openpen-color-state-success-bg);
617
818
  border-color: var(--openpen-color-state-success-border);
618
819
  color: var(--openpen-color-state-success-text);
619
820
  }
620
- .app-banner-success .app-banner-icon[data-v-c68deb55] {
821
+ .app-banner-success .app-banner-icon[data-v-4f309880] {
621
822
  color: var(--openpen-color-state-success-icon);
622
823
  }
623
- .app-banner-error[data-v-c68deb55] {
824
+ .app-banner-error[data-v-4f309880] {
624
825
  background: var(--openpen-color-state-error-bg);
625
826
  border-color: var(--openpen-color-state-error-border);
626
827
  color: var(--openpen-color-state-error-text);
627
828
  }
628
- .app-banner-error .app-banner-icon[data-v-c68deb55] {
829
+ .app-banner-error .app-banner-icon[data-v-4f309880] {
629
830
  color: var(--openpen-color-state-error-icon);
630
831
  }
631
832
 
@@ -5,7 +5,7 @@
5
5
  * who need full control over markup and styling but still want Reka UI's
6
6
  * a11y / focus / keyboard navigation behaviour.
7
7
  *
8
- * Usage (escape hatch from high-level wrappers):
8
+ * Usage (when the high-level wrappers are not enough):
9
9
  * import { PopoverRoot, PopoverTrigger, ... } from '@openpen/module-api/uikit'
10
10
  * // or directly:
11
11
  * import { ... } from '@openpen/module-api/uikit/primitives' (if re-exported)
@@ -24,7 +24,8 @@
24
24
  * Dialog → AppDialog
25
25
  * Slider → AppSlider
26
26
  * Switch → AppToggle
27
- * RadioGroup → AppSegmented
27
+ * RadioGroup → AppSegmented, AppSwatchPicker
28
+ * Toggle → AppToggleButton
28
29
  * Select → AppSelect
29
30
  * Tooltip → AppTooltip
30
31
  * Tabs → AppTabs
@@ -33,6 +34,7 @@ export { PopoverRoot, PopoverTrigger, PopoverPortal, PopoverContent, PopoverArro
33
34
  export { DialogRoot, DialogTrigger, DialogPortal, DialogContent, DialogOverlay, DialogClose, DialogTitle, DialogDescription, } from 'reka-ui';
34
35
  export { SliderRoot, SliderTrack, SliderRange, SliderThumb, } from 'reka-ui';
35
36
  export { SwitchRoot, SwitchThumb, } from 'reka-ui';
37
+ export { Toggle } from 'reka-ui';
36
38
  export { RadioGroupRoot, RadioGroupItem, RadioGroupIndicator, } from 'reka-ui';
37
39
  export { SelectRoot, SelectTrigger, SelectPortal, SelectContent, SelectViewport, SelectItem, SelectItemText, SelectItemIndicator, SelectLabel, SelectGroup, SelectSeparator, SelectScrollUpButton, SelectScrollDownButton, SelectArrow, SelectValue, SelectIcon, } from 'reka-ui';
38
40
  export { TooltipProvider, TooltipRoot, TooltipTrigger, TooltipPortal, TooltipContent, TooltipArrow, } from 'reka-ui';
@@ -17,20 +17,21 @@
17
17
  /* ── Color (semantic; theme module may override actual values) ─────────── */
18
18
 
19
19
  /* Accent — primary brand / interactive highlight color */
20
- /* Source: src/style.css --accent: #818CF8 */
21
- --openpen-color-accent: #818cf8;
20
+ /* Follows the host's --accent (set from the user's accent setting); the
21
+ * indigo value is the fallback for environments without host variables. */
22
+ --openpen-color-accent: var(--accent, #818cf8);
22
23
 
23
24
  /* Accent hover — slightly deeper accent for :hover state */
24
25
  /* Source: src/style.css --accent-glow used as reference; approximated from #6366f1 */
25
26
  --openpen-color-accent-hover: #6366f1;
26
27
 
27
28
  /* Accent background — subtle tinted background for active items */
28
- /* Source: src/style.css --accent-bg: rgba(129, 140, 248, 0.18) */
29
- --openpen-color-accent-bg: rgba(129, 140, 248, 0.18);
29
+ /* Follows the host's --accent-bg; indigo fallback as above. */
30
+ --openpen-color-accent-bg: var(--accent-bg, rgba(129, 140, 248, 0.18));
30
31
 
31
32
  /* Accent glow — used for box-shadow rings on active elements */
32
- /* Source: src/style.css --accent-glow: rgba(129, 140, 248, 0.35) */
33
- --openpen-color-accent-glow: rgba(129, 140, 248, 0.35);
33
+ /* Follows the host's --accent-glow; indigo fallback as above. */
34
+ --openpen-color-accent-glow: var(--accent-glow, rgba(129, 140, 248, 0.35));
34
35
 
35
36
  /* Surface (dark) — main background for floating panels, bars */
36
37
  /* Source: src/style.css --surface: rgba(18, 26, 48, 0.88) */
@@ -13,9 +13,8 @@ import type { ModuleSetupContext } from './types/module';
13
13
  * @example
14
14
  * ```ts
15
15
  * // MySettingsPanel.vue
16
- * import { useModuleContext } from '@openpen/module-api'
16
+ * import { useModuleContext, z } from '@openpen/module-api'
17
17
  * import { onMounted, onUnmounted, ref } from 'vue'
18
- * import { z } from 'zod'
19
18
  *
20
19
  * const MySchema = z.object({ color: z.string().default('#fff') })
21
20
  * type MySettings = z.infer<typeof MySchema>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openpen/module-api",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "OpenPen Module API — public contract for built-in modules and third-party plugins",
5
5
  "author": "navishachiku <navishachiku@gmail.com>",
6
6
  "homepage": "https://github.com/openpen-platform/openpen#readme",
@@ -63,11 +63,11 @@
63
63
  "sdk"
64
64
  ],
65
65
  "dependencies": {
66
- "dompurify": "^3.4.8",
67
- "reka-ui": "~2.9.9"
66
+ "dompurify": "^3.4.17",
67
+ "reka-ui": "~2.11.0"
68
68
  },
69
69
  "peerDependencies": {
70
70
  "vue": "^3.5.0",
71
- "zod": "^3.23.0"
71
+ "zod": "^4.0.0"
72
72
  }
73
73
  }