astro-tractstack 2.0.0-rc.65 → 2.0.0-rc.66
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/package.json
CHANGED
|
@@ -27,7 +27,7 @@ const SettingsPanel = ({ config, availableCodeHooks }: SettingsPanelProps) => {
|
|
|
27
27
|
|
|
28
28
|
return (
|
|
29
29
|
<div
|
|
30
|
-
className="bg-mydarkgrey flex h-full max-w-sm flex-col rounded-xl bg-opacity-20 p-0.5 backdrop-blur-sm"
|
|
30
|
+
className="bg-mydarkgrey min-w-xs flex h-full max-w-sm flex-col rounded-xl bg-opacity-20 p-0.5 backdrop-blur-sm"
|
|
31
31
|
style={
|
|
32
32
|
{
|
|
33
33
|
animation: window.matchMedia(
|
|
@@ -38,10 +38,7 @@ interface WidgetStyles {
|
|
|
38
38
|
bgColor: string;
|
|
39
39
|
bgOpacity: number;
|
|
40
40
|
}
|
|
41
|
-
type StoredDisclosureItem = Omit<
|
|
42
|
-
DisclosureItem,
|
|
43
|
-
'id' | 'isDisabled' | 'isCustom'
|
|
44
|
-
>;
|
|
41
|
+
type StoredDisclosureItem = Omit<DisclosureItem, 'id' | 'isDisabled'>;
|
|
45
42
|
interface InteractiveDisclosureWidgetProps {
|
|
46
43
|
node: FlatNode;
|
|
47
44
|
onUpdate: (params: string[]) => void;
|
|
@@ -91,6 +88,7 @@ const IconSelector = ({
|
|
|
91
88
|
<Combobox.Input
|
|
92
89
|
className="w-full rounded-md border-gray-300 py-1.5 pl-3 pr-10 shadow-sm"
|
|
93
90
|
placeholder="Search icons..."
|
|
91
|
+
autoFocus
|
|
94
92
|
/>
|
|
95
93
|
<Combobox.Trigger className="absolute inset-y-0 right-0 flex items-center pr-2">
|
|
96
94
|
<i className={`bi bi-${value} mr-2 text-lg`}></i>
|
|
@@ -141,6 +139,13 @@ const DisclosureItemEditor = ({
|
|
|
141
139
|
isFirst: boolean;
|
|
142
140
|
isLast: boolean;
|
|
143
141
|
}) => {
|
|
142
|
+
const [isEditingIcon, setIsEditingIcon] = useState(false);
|
|
143
|
+
|
|
144
|
+
const handleIconChange = (newIcon: string) => {
|
|
145
|
+
onUpdate({ icon: newIcon });
|
|
146
|
+
setIsEditingIcon(false);
|
|
147
|
+
};
|
|
148
|
+
|
|
144
149
|
return (
|
|
145
150
|
<div
|
|
146
151
|
className={`space-y-4 rounded-lg border bg-white p-4 shadow-sm transition-opacity ${
|
|
@@ -169,9 +174,11 @@ const DisclosureItemEditor = ({
|
|
|
169
174
|
</div>
|
|
170
175
|
<h4 className="font-bold text-gray-800">
|
|
171
176
|
{item.title}{' '}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
177
|
+
{!item.isCustom && (
|
|
178
|
+
<span className="text-xs font-normal text-gray-500">
|
|
179
|
+
(Key: {item.beliefValue})
|
|
180
|
+
</span>
|
|
181
|
+
)}
|
|
175
182
|
</h4>
|
|
176
183
|
</div>
|
|
177
184
|
<button
|
|
@@ -189,13 +196,6 @@ const DisclosureItemEditor = ({
|
|
|
189
196
|
</button>
|
|
190
197
|
</div>
|
|
191
198
|
<fieldset disabled={item.isDisabled} className="space-y-4">
|
|
192
|
-
{item.isCustom && (
|
|
193
|
-
<SingleParam
|
|
194
|
-
label="Key / Value"
|
|
195
|
-
value={item.beliefValue}
|
|
196
|
-
onChange={(value) => onUpdate({ beliefValue: value })}
|
|
197
|
-
/>
|
|
198
|
-
)}
|
|
199
199
|
<SingleParam
|
|
200
200
|
label="Display Title"
|
|
201
201
|
value={item.title}
|
|
@@ -206,10 +206,29 @@ const DisclosureItemEditor = ({
|
|
|
206
206
|
value={item.description || ''}
|
|
207
207
|
onChange={(value) => onUpdate({ description: value })}
|
|
208
208
|
/>
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
209
|
+
|
|
210
|
+
{isEditingIcon ? (
|
|
211
|
+
<IconSelector value={item.icon} onChange={handleIconChange} />
|
|
212
|
+
) : (
|
|
213
|
+
<div>
|
|
214
|
+
<label className="block text-xs font-bold text-gray-600">
|
|
215
|
+
Icon
|
|
216
|
+
</label>
|
|
217
|
+
<div className="mt-1 flex items-center justify-between rounded-md border border-gray-300 bg-white px-3 py-1.5 shadow-sm">
|
|
218
|
+
<div className="flex items-center gap-2">
|
|
219
|
+
<i className={`bi bi-${item.icon} text-lg`}></i>
|
|
220
|
+
<span className="text-sm">{item.icon}</span>
|
|
221
|
+
</div>
|
|
222
|
+
<button
|
|
223
|
+
type="button"
|
|
224
|
+
onClick={() => setIsEditingIcon(true)}
|
|
225
|
+
className="text-sm font-bold text-cyan-600 hover:text-cyan-800"
|
|
226
|
+
>
|
|
227
|
+
Change
|
|
228
|
+
</button>
|
|
229
|
+
</div>
|
|
230
|
+
</div>
|
|
231
|
+
)}
|
|
213
232
|
|
|
214
233
|
{item.isCustom ? (
|
|
215
234
|
<div className="relative rounded-md border p-3">
|
|
@@ -243,8 +262,8 @@ export default function InteractiveDisclosureWidget({
|
|
|
243
262
|
const [selectedBeliefTag, setSelectedBeliefTag] = useState<string>('');
|
|
244
263
|
const [disclosures, setDisclosures] = useState<DisclosureItem[]>([]);
|
|
245
264
|
const [widgetStyles, setWidgetStyles] = useState<WidgetStyles>({
|
|
246
|
-
textColor: '',
|
|
247
|
-
bgColor: '',
|
|
265
|
+
textColor: '#000000',
|
|
266
|
+
bgColor: '#ffffff',
|
|
248
267
|
bgOpacity: 100,
|
|
249
268
|
});
|
|
250
269
|
const [isModalOpen, setIsModalOpen] = useState(false);
|
|
@@ -268,7 +287,11 @@ export default function InteractiveDisclosureWidget({
|
|
|
268
287
|
try {
|
|
269
288
|
const parsed = JSON.parse(payloadJson);
|
|
270
289
|
setWidgetStyles(
|
|
271
|
-
parsed.styles || {
|
|
290
|
+
parsed.styles || {
|
|
291
|
+
textColor: '#000000',
|
|
292
|
+
bgColor: '#ffffff',
|
|
293
|
+
bgOpacity: 100,
|
|
294
|
+
}
|
|
272
295
|
);
|
|
273
296
|
const loadedDisclosures =
|
|
274
297
|
(parsed.disclosures as StoredDisclosureItem[]) || [];
|
|
@@ -290,6 +313,7 @@ export default function InteractiveDisclosureWidget({
|
|
|
290
313
|
const isFromScale = scaleKeys.some(
|
|
291
314
|
(sk) => sk.slug === loadedItem.beliefValue
|
|
292
315
|
);
|
|
316
|
+
|
|
293
317
|
return {
|
|
294
318
|
...loadedItem,
|
|
295
319
|
id: generateId(),
|
|
@@ -308,7 +332,7 @@ export default function InteractiveDisclosureWidget({
|
|
|
308
332
|
beliefValue: slug,
|
|
309
333
|
title: name,
|
|
310
334
|
description: '',
|
|
311
|
-
icon: '
|
|
335
|
+
icon: 'chat-heart-fill',
|
|
312
336
|
actionLisp: `(${actionCommand} ${beliefTag} ${quoteIfNecessary(actionCommand, slug)})`,
|
|
313
337
|
isCustom: false,
|
|
314
338
|
isDisabled: true,
|
|
@@ -321,7 +345,11 @@ export default function InteractiveDisclosureWidget({
|
|
|
321
345
|
}
|
|
322
346
|
} else {
|
|
323
347
|
setDisclosures([]);
|
|
324
|
-
setWidgetStyles({
|
|
348
|
+
setWidgetStyles({
|
|
349
|
+
textColor: '#000000',
|
|
350
|
+
bgColor: '#ffffff',
|
|
351
|
+
bgOpacity: 100,
|
|
352
|
+
});
|
|
325
353
|
}
|
|
326
354
|
setIsDataLoaded(true);
|
|
327
355
|
}, [node, beliefs]);
|
|
@@ -352,13 +380,18 @@ export default function InteractiveDisclosureWidget({
|
|
|
352
380
|
const handleUpdate = () => {
|
|
353
381
|
const disclosuresToStore: StoredDisclosureItem[] = disclosures
|
|
354
382
|
.filter((d) => !d.isDisabled)
|
|
355
|
-
.map(({ id,
|
|
383
|
+
.map(({ id, isDisabled, ...rest }) => rest);
|
|
356
384
|
const payload = { styles: widgetStyles, disclosures: disclosuresToStore };
|
|
357
385
|
onUpdate([selectedBeliefTag, JSON.stringify(payload)]);
|
|
358
386
|
};
|
|
359
387
|
|
|
360
388
|
const handleBeliefChange = (tag: string) => {
|
|
361
389
|
setSelectedBeliefTag(tag);
|
|
390
|
+
setWidgetStyles({
|
|
391
|
+
textColor: '#000000',
|
|
392
|
+
bgColor: '#ffffff',
|
|
393
|
+
bgOpacity: 100,
|
|
394
|
+
});
|
|
362
395
|
const belief = beliefs.find((b) => b.slug === tag);
|
|
363
396
|
let newDisclosures: DisclosureItem[] = [];
|
|
364
397
|
if (belief) {
|
|
@@ -375,7 +408,7 @@ export default function InteractiveDisclosureWidget({
|
|
|
375
408
|
beliefValue: slug,
|
|
376
409
|
title: name,
|
|
377
410
|
description: '',
|
|
378
|
-
icon: '
|
|
411
|
+
icon: 'chat-heart-fill',
|
|
379
412
|
actionLisp: `(${actionCommand} ${tag} ${quoteIfNecessary(actionCommand, slug)})`,
|
|
380
413
|
isCustom: false,
|
|
381
414
|
isDisabled: false,
|
|
@@ -399,10 +432,12 @@ export default function InteractiveDisclosureWidget({
|
|
|
399
432
|
const addCustomDisclosure = () => {
|
|
400
433
|
const newItem: DisclosureItem = {
|
|
401
434
|
id: generateId(),
|
|
402
|
-
beliefValue: `custom
|
|
435
|
+
beliefValue: `custom-${Date.now()}-${Math.random()
|
|
436
|
+
.toString(36)
|
|
437
|
+
.substring(2, 6)}`,
|
|
403
438
|
title: 'New Custom Item',
|
|
404
439
|
description: '',
|
|
405
|
-
icon: '
|
|
440
|
+
icon: 'chat-heart-fill',
|
|
406
441
|
actionLisp: '',
|
|
407
442
|
isCustom: true,
|
|
408
443
|
isDisabled: false,
|
|
@@ -418,12 +453,20 @@ export default function InteractiveDisclosureWidget({
|
|
|
418
453
|
const updateWidgetStyles = (updates: Partial<WidgetStyles>) =>
|
|
419
454
|
setWidgetStyles((prev) => ({ ...prev, ...updates }));
|
|
420
455
|
|
|
421
|
-
const toggleDisclosure = (id: string) =>
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
456
|
+
const toggleDisclosure = (id: string) => {
|
|
457
|
+
const itemToToggle = disclosures.find((d) => d.id === id);
|
|
458
|
+
if (!itemToToggle) return;
|
|
459
|
+
|
|
460
|
+
if (itemToToggle.isCustom) {
|
|
461
|
+
setDisclosures(disclosures.filter((d) => d.id !== id));
|
|
462
|
+
} else {
|
|
463
|
+
setDisclosures(
|
|
464
|
+
disclosures.map((d) =>
|
|
465
|
+
d.id === id ? { ...d, isDisabled: !d.isDisabled } : d
|
|
466
|
+
)
|
|
467
|
+
);
|
|
468
|
+
}
|
|
469
|
+
};
|
|
427
470
|
|
|
428
471
|
const handleColorChange = (
|
|
429
472
|
key: 'textColor' | 'bgColor',
|
|
@@ -171,7 +171,7 @@ for (const [key, value] of Astro.url.searchParams) {
|
|
|
171
171
|
<main id="mainContent" class="relative flex-1 overflow-x-auto">
|
|
172
172
|
<div class="bg-myblue/20 bg-mylightgrey h-full p-1.5">
|
|
173
173
|
<div
|
|
174
|
-
class="h-fit min-h-screen pb-
|
|
174
|
+
class="h-fit min-h-screen pb-96"
|
|
175
175
|
style={{
|
|
176
176
|
backgroundImage:
|
|
177
177
|
'repeating-linear-gradient(135deg, transparent, transparent 10px, rgba(0,0,0,0.05) 10px, rgba(0,0,0,0.05) 20px)',
|
|
@@ -159,16 +159,10 @@ for (const [key, value] of Astro.url.searchParams) {
|
|
|
159
159
|
<StoryKeepToolMode isContext={true} client:only="react" />
|
|
160
160
|
|
|
161
161
|
<!-- Main Content Area -->
|
|
162
|
-
<main
|
|
163
|
-
id="mainContent"
|
|
164
|
-
class="relative flex-1 overflow-x-auto"
|
|
165
|
-
style={{
|
|
166
|
-
paddingBottom: 'var(--bottom-right-controls-bottom-offset, 16px)',
|
|
167
|
-
}}
|
|
168
|
-
>
|
|
162
|
+
<main id="mainContent" class="relative flex-1 overflow-x-auto">
|
|
169
163
|
<div class="bg-myblue/20 bg-mylightgrey h-full p-1.5">
|
|
170
164
|
<div
|
|
171
|
-
class="h-fit min-h-screen"
|
|
165
|
+
class="h-fit min-h-screen pb-96"
|
|
172
166
|
style={{
|
|
173
167
|
backgroundImage:
|
|
174
168
|
'repeating-linear-gradient(135deg, transparent, transparent 10px, rgba(0,0,0,0.05) 10px, rgba(0,0,0,0.05) 20px)',
|