feat: add Unsplash search hook and API proxy routes

- Implemented `useUnsplashSearch` hook for searching Unsplash photos with debounce.
- Created Unsplash API client functions for searching photos and triggering downloads.
- Added proxy routes for Unsplash API to handle search requests and background image uploads.
- Introduced accessibility utilities for WCAG compliance checks and motion preference management.
- Developed theme sharing module for encoding and decoding theme configurations as base64url strings.
This commit is contained in:
catlog22
2026-02-08 20:01:28 +08:00
parent 87daccdc48
commit 166211dcd4
52 changed files with 5798 additions and 142 deletions

View File

@@ -116,6 +116,7 @@ export const CheckboxComponentSchema = z.object({
checked: BooleanContentSchema.optional(),
onChange: ActionSchema,
label: TextContentSchema.optional(),
description: TextContentSchema.optional(),
}),
});
@@ -202,6 +203,8 @@ export const ComponentSchema: z.ZodType<any> = z.union([
export const SurfaceComponentSchema = z.object({
id: z.string(),
component: ComponentSchema,
/** Page index for multi-page surfaces (0-based) */
page: z.number().int().min(0).optional(),
});
/** Display mode for A2UI surfaces */

View File

@@ -51,17 +51,28 @@ export const A2UICheckbox: ComponentRenderer = ({ component, state, onAction, re
? resolveTextContent(checkboxConfig.label, resolveBinding)
: '';
// Resolve description text
const descriptionText = checkboxConfig.description
? resolveTextContent(checkboxConfig.description, resolveBinding)
: '';
return (
<div className="flex items-center space-x-2">
<div className="flex items-start space-x-2">
<Checkbox
className="mt-0.5"
checked={checked}
onCheckedChange={handleChange}
/>
{labelText && (
<Label className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">
{labelText}
</Label>
)}
<div className="grid gap-0.5">
{labelText && (
<Label className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">
{labelText}
</Label>
)}
{descriptionText && (
<p className="text-xs text-muted-foreground">{descriptionText}</p>
)}
</div>
</div>
);
};