tangled
alpha
login
or
join now
e.xyehr.cn
/
standard.site
forked from
standard.site/standard.site
0
fork
atom
Standard.site landing page built in Next.js
0
fork
atom
overview
issues
pulls
pipelines
Inline code styling
brookie.blog
2 months ago
b180817a
ac9e7b71
verified
This commit was signed with the committer's
known signature
.
brookie.blog
SSH Key Fingerprint:
SHA256:mpAy8tRb8/3HN/v8kJeSgvRPQnKQq5zVHkq1TxQaVls=
+107
-75
1 changed file
expand all
collapse all
unified
split
app
components
ExpandableField.tsx
+107
-75
app/components/ExpandableField.tsx
···
85
85
return entries.map(([name, prop]) => {
86
86
const constraints: string[] = []
87
87
88
88
-
if (prop.maxLength) constraints.push(`maxLength: ${ prop.maxLength }`)
89
89
-
if (prop.maxGraphemes) constraints.push(`maxGraphemes: ${ prop.maxGraphemes }`)
88
88
+
if (prop.maxLength) constraints.push(`maxLength: ${prop.maxLength}`)
89
89
+
if (prop.maxGraphemes) constraints.push(`maxGraphemes: ${prop.maxGraphemes}`)
90
90
if (prop.maxSize) {
91
91
const bytes = prop.maxSize
92
92
-
const formatted = bytes >= 1_000_000 ? `${ bytes / 1_000_000 }MB` : bytes >= 1_000 ? `${ bytes / 1_000 }KB` : `${ bytes }B`
93
93
-
constraints.push(`maxSize: ${ formatted }`)
92
92
+
const formatted = bytes >= 1_000_000 ? `${bytes / 1_000_000}MB` : bytes >= 1_000 ? `${bytes / 1_000}KB` : `${bytes}B`
93
93
+
constraints.push(`maxSize: ${formatted}`)
94
94
}
95
95
-
if (prop.accept) constraints.push(`accept: [${ prop.accept.join(', ') }]`)
95
95
+
if (prop.accept) constraints.push(`accept: [${prop.accept.join(', ')}]`)
96
96
97
97
if (prop.items) {
98
98
-
if (prop.items.maxLength) constraints.push(`items.maxLength: ${ prop.items.maxLength }`)
99
99
-
if (prop.items.maxGraphemes) constraints.push(`items.maxGraphemes: ${ prop.items.maxGraphemes }`)
98
98
+
if (prop.items.maxLength) constraints.push(`items.maxLength: ${prop.items.maxLength}`)
99
99
+
if (prop.items.maxGraphemes) constraints.push(`items.maxGraphemes: ${prop.items.maxGraphemes}`)
100
100
}
101
101
102
102
let type = prop.type
103
103
-
if (prop.format) type = `${ prop.type }:${ prop.format }`
103
103
+
if (prop.format) type = `${prop.type}:${prop.format}`
104
104
if (prop.ref) type = prop.ref
105
105
if (prop.type === 'array' && prop.items) {
106
106
-
type = `array<${ prop.items.type }>`
106
106
+
type = `array<${prop.items.type}>`
107
107
}
108
108
109
109
const refs = (prop as { refs?: string[] }).refs
···
142
142
let type = def.type
143
143
144
144
if (def.type === 'array' && def.items) {
145
145
-
type = `array<${ def.items.type }>`
146
146
-
if (def.items.maxLength) constraints.push(`items.maxLength: ${ def.items.maxLength }`)
147
147
-
if (def.items.maxGraphemes) constraints.push(`items.maxGraphemes: ${ def.items.maxGraphemes }`)
145
145
+
type = `array<${def.items.type}>`
146
146
+
if (def.items.maxLength) constraints.push(`items.maxLength: ${def.items.maxLength}`)
147
147
+
if (def.items.maxGraphemes) constraints.push(`items.maxGraphemes: ${def.items.maxGraphemes}`)
148
148
}
149
149
150
150
if ((def as ExtendedLexiconDef).minimum !== undefined) {
151
151
-
constraints.push(`minimum: ${ (def as ExtendedLexiconDef).minimum }`)
151
151
+
constraints.push(`minimum: ${(def as ExtendedLexiconDef).minimum}`)
152
152
}
153
153
if ((def as ExtendedLexiconDef).maximum !== undefined) {
154
154
-
constraints.push(`maximum: ${ (def as ExtendedLexiconDef).maximum }`)
154
154
+
constraints.push(`maximum: ${(def as ExtendedLexiconDef).maximum}`)
155
155
}
156
156
157
157
return {
···
162
162
}
163
163
}
164
164
165
165
+
// Helper to parse description with inline code (backticks)
166
166
+
function parseInlineCode(text: string): React.ReactNode {
167
167
+
const parts: React.ReactNode[] = []
168
168
+
let lastIndex = 0
169
169
+
const regex = /`([^`]+)`/g
170
170
+
let match
171
171
+
172
172
+
while ((match = regex.exec(text)) !== null) {
173
173
+
// Add text before the match
174
174
+
if (match.index > lastIndex) {
175
175
+
parts.push(text.slice(lastIndex, match.index))
176
176
+
}
177
177
+
// Add the code part with styling
178
178
+
parts.push(
179
179
+
<code
180
180
+
key={match.index}
181
181
+
className="rounded bg-base-200 px-1 mx-0.5 font-mono text-sm text-base-content italic"
182
182
+
>
183
183
+
{match[1]}
184
184
+
</code>
185
185
+
)
186
186
+
lastIndex = match.index + match[0].length
187
187
+
}
188
188
+
189
189
+
// Add remaining text
190
190
+
if (lastIndex < text.length) {
191
191
+
parts.push(text.slice(lastIndex))
192
192
+
}
193
193
+
194
194
+
return parts.length > 0 ? parts : text
195
195
+
}
196
196
+
165
197
function TypeBadge({ name, type, required }: { name: string; type: string; required?: boolean }) {
166
198
return (
167
199
<div className="flex flex-wrap items-center gap-2">
168
200
<span className="font-mono font-semibold text-base leading-snug tracking-tight text-base-content">
169
169
-
{ name }
201
201
+
{name}
170
202
</span>
171
203
<span className="rounded border border-sky-200 bg-sky-100 text-sky-800 dark:border-sky-900 dark:bg-sky-950 dark:text-sky-100 px-1 py-0.5 font-mono font-medium text-sm leading-none tracking-tight">
172
172
-
{ type }
204
204
+
{type}
173
205
</span>
174
174
-
{ required && (
206
206
+
{required && (
175
207
<span className="rounded border border-red-200 bg-red-100 text-red-800 dark:border-red-900 dark:bg-red-950 dark:text-red-100 px-1 py-0.5 font-mono font-medium text-sm leading-none tracking-tight">
176
208
required
177
209
</span>
178
178
-
) }
210
210
+
)}
179
211
</div>
180
212
)
181
213
}
···
183
215
function RefBadge({ ref }: { ref: string }) {
184
216
return (
185
217
<span className="rounded border border-emerald-200 bg-emerald-100 text-emerald-800 dark:border-emerald-900 dark:bg-emerald-950 dark:text-emerald-100 px-1 py-0.5 font-mono font-medium text-sm leading-none tracking-tight">
186
186
-
{ ref }
187
187
-
</span>
218
218
+
{ref}
219
219
+
</span>
188
220
)
189
221
}
190
222
···
200
232
return (
201
233
<div className="flex flex-col gap-1 p-4">
202
234
<div className="flex flex-wrap items-center gap-2">
203
203
-
<span className="rounded border border-sky-200 bg-sky-100 text-sky-800 dark:border-sky-900 dark:bg-sky-950 dark:text-sky-100 px-1 py-0.5 font-mono font-medium text-sm leading-none tracking-tight">
204
204
-
{ summary.type }
205
205
-
</span>
235
235
+
<span className="rounded border border-sky-200 bg-sky-100 text-sky-800 dark:border-sky-900 dark:bg-sky-950 dark:text-sky-100 px-1 py-0.5 font-mono font-medium text-sm leading-none tracking-tight">
236
236
+
{summary.type}
237
237
+
</span>
206
238
</div>
207
239
208
208
-
{/* Union refs as badges */ }
209
209
-
{ summary.refs && summary.refs.length > 0 && (
240
240
+
{/* Union refs as badges */}
241
241
+
{summary.refs && summary.refs.length > 0 && (
210
242
<div className="flex flex-wrap gap-2">
211
211
-
{ summary.refs.map((ref) => (
212
212
-
<RefBadge key={ ref } ref={ ref } />
213
213
-
)) }
243
243
+
{summary.refs.map((ref) => (
244
244
+
<RefBadge key={ref} ref={ref} />
245
245
+
))}
214
246
</div>
215
215
-
) }
247
247
+
)}
216
248
217
217
-
{ summary.constraints.length > 0 && (
249
249
+
{summary.constraints.length > 0 && (
218
250
<div className="flex flex-wrap gap-4 font-mono text-sm leading-none tracking-tight text-muted">
219
219
-
{ summary.constraints.map((constraint) => (
220
220
-
<span key={ constraint }>{ constraint }</span>
221
221
-
)) }
251
251
+
{summary.constraints.map((constraint) => (
252
252
+
<span key={constraint}>{constraint}</span>
253
253
+
))}
222
254
</div>
223
223
-
) }
255
255
+
)}
224
256
225
225
-
{ summary.description && (
257
257
+
{summary.description && (
226
258
<p className="text-sm italic leading-snug tracking-tight text-muted">
227
227
-
{ summary.description }
259
259
+
{parseInlineCode(summary.description)}
228
260
</p>
229
229
-
) }
261
261
+
)}
230
262
</div>
231
263
)
232
264
}
···
253
285
const isExpandable = !!field.ref && !NON_EXPANDABLE_REFS.includes(field.ref)
254
286
255
287
const toggleExpand = () => {
256
256
-
setExpanded( !expanded)
288
288
+
setExpanded(!expanded)
257
289
}
258
290
259
291
const resolvedDef = field.ref ? resolveRef(field.ref, schema) : null
···
268
300
269
301
return (
270
302
<div className="flex flex-col gap-1 border-b border-border p-4 last:border-b-0">
271
271
-
<TypeBadge name={ field.name } type={ field.type } required={ field.required } />
303
303
+
<TypeBadge name={field.name} type={field.type} required={field.required} />
272
304
273
273
-
{/* Union refs as badges */ }
274
274
-
{ field.refs && field.refs.length > 0 && (
305
305
+
{/* Union refs as badges */}
306
306
+
{field.refs && field.refs.length > 0 && (
275
307
<div className="flex flex-wrap gap-2">
276
276
-
{ field.refs.map((ref) => (
277
277
-
<RefBadge key={ ref } ref={ ref } />
278
278
-
)) }
308
308
+
{field.refs.map((ref) => (
309
309
+
<RefBadge key={ref} ref={ref} />
310
310
+
))}
279
311
</div>
280
280
-
) }
312
312
+
)}
281
313
282
282
-
{ field.constraints.length > 0 && (
314
314
+
{field.constraints.length > 0 && (
283
315
<div className="flex flex-wrap gap-4 font-mono text-sm leading-none tracking-tight text-muted">
284
284
-
{ field.constraints.map((constraint) => (
285
285
-
<span key={ constraint }>{ constraint }</span>
286
286
-
)) }
316
316
+
{field.constraints.map((constraint) => (
317
317
+
<span key={constraint}>{constraint}</span>
318
318
+
))}
287
319
</div>
288
288
-
) }
320
320
+
)}
289
321
290
290
-
{ field.description && (
322
322
+
{field.description && (
291
323
<p className="text-sm italic leading-snug tracking-tight text-muted">
292
292
-
{ field.description }
324
324
+
{parseInlineCode(field.description)}
293
325
</p>
294
294
-
) }
326
326
+
)}
295
327
296
296
-
{ isExpandable && (
328
328
+
{isExpandable && (
297
329
<div className="pt-2">
298
330
<div className="flex flex-col rounded-xl border border-border bg-base-200 overflow-hidden">
299
299
-
{/* Header button */ }
331
331
+
{/* Header button */}
300
332
<button
301
301
-
onClick={ toggleExpand }
302
302
-
className={ `flex items-center gap-2 px-4 py-2.5 hover:bg-base-300 transition-colors hover:cursor-pointer ${ expanded ? 'border-b border-border' : '' }` }
333
333
+
onClick={toggleExpand}
334
334
+
className={`flex items-center gap-2 px-4 py-2.5 hover:bg-base-300 transition-colors hover:cursor-pointer ${expanded ? 'border-b border-border' : ''}`}
303
335
>
304
336
<FileIcon className="size-4 text-base-content" />
305
337
<span className="font-medium text-base leading-snug tracking-tight text-base-content">
306
306
-
{ refDisplayName }
338
338
+
{refDisplayName}
307
339
</span>
308
340
<motion.div
309
341
className="ml-auto"
310
310
-
initial={ false }
342
342
+
initial={false}
311
343
animate={{ opacity: 1 }}
312
344
>
313
313
-
{ expanded ? (
345
345
+
{expanded ? (
314
346
<EyeOffIcon className="size-4 text-muted" />
315
347
) : (
316
348
<EyeIcon className="size-4 text-muted" />
317
317
-
) }
349
349
+
)}
318
350
</motion.div>
319
351
</button>
320
352
321
321
-
{/* Expandable content */ }
322
322
-
<AnimatePresence initial={ false }>
323
323
-
{ expanded && (
353
353
+
{/* Expandable content */}
354
354
+
<AnimatePresence initial={false}>
355
355
+
{expanded && (
324
356
<motion.div
325
357
initial={{ height: 0, opacity: 0 }}
326
358
animate={{ height: 'auto', opacity: 1 }}
···
330
362
>
331
363
<div className="p-1">
332
364
<div className="flex flex-col rounded-xl border border-border bg-card overflow-hidden">
333
333
-
{ hasNestedFields ? (
365
365
+
{hasNestedFields ? (
334
366
nestedFields.map((nestedField) => (
335
367
<ExpandableField
336
336
-
key={ nestedField.name }
337
337
-
field={ nestedField }
338
338
-
schema={ schema }
368
368
+
key={nestedField.name}
369
369
+
field={nestedField}
370
370
+
schema={schema}
339
371
/>
340
372
))
341
373
) : resolvedDef ? (
342
342
-
<DefSummaryDisplay def={ resolvedDef as ExtendedLexiconDef } />
343
343
-
) : null }
374
374
+
<DefSummaryDisplay def={resolvedDef as ExtendedLexiconDef} />
375
375
+
) : null}
344
376
</div>
345
377
</div>
346
378
</motion.div>
347
347
-
) }
379
379
+
)}
348
380
</AnimatePresence>
349
381
</div>
350
382
</div>
351
351
-
) }
383
383
+
)}
352
384
</div>
353
385
)
354
386
}
···
368
400
return (
369
401
<div className="p-1">
370
402
<div className="flex flex-col rounded-xl border border-border bg-card overflow-hidden">
371
371
-
{ fields.map((field) => (
372
372
-
<ExpandableField key={ field.name } field={ field } schema={ schema } />
373
373
-
)) }
403
403
+
{fields.map((field) => (
404
404
+
<ExpandableField key={field.name} field={field} schema={schema} />
405
405
+
))}
374
406
</div>
375
407
</div>
376
408
)