feat: Nova UI component library + Studio dropdown/picker polish

- Add Nova UI library: Button, TextInput, Textarea, FormField, Select,
  NovaSelect, Checkbox, Radio/RadioGroup, Toggle, DatePicker,
  DateRangePicker, Modal + barrel index.js
- Replace all native <select> in Studio with NovaSelect (StudioFilters,
  StudioToolbar, BulkActionsBar) including frosted-glass portal and
  category group headers
- Replace native checkboxes in StudioGridCard, StudioTable, UploadSidebar,
  UploadWizard, Upload/Index with custom Checkbox component
- Add nova-scrollbar CSS utility (thin 4px, semi-transparent)
- Fix portal position drift: use viewport-relative coords (no scrollY offset)
  for NovaSelect, DatePicker and DateRangePicker
- Close portals on external scroll instead of remeasuring
- Improve hover highlight visibility in NovaSelect (bg-white/[0.13])
- Move search icon to right side in NovaSelect dropdown
- Reduce Studio layout top spacing (py-6 -> pt-4 pb-8)
- Add StudioCheckbox and SquareCheckbox backward-compat shims
- Add sync.sh rsync deploy script
This commit is contained in:
2026-03-01 10:41:43 +01:00
parent e3ca845a6d
commit a875203482
26 changed files with 2087 additions and 132 deletions

View File

@@ -1,5 +1,6 @@
import React from 'react'
import TagInput from '../tags/TagInput'
import Checkbox from '../../Components/ui/Checkbox'
export default function UploadSidebar({
title = 'Artwork details',
@@ -75,20 +76,17 @@ export default function UploadSidebar({
</section>
<section className="rounded-xl border border-white/10 bg-white/[0.03] p-4">
<label className="flex items-start gap-3 text-sm text-white/90">
<input
id="upload-sidebar-rights"
type="checkbox"
checked={Boolean(metadata.rightsAccepted)}
onChange={(event) => onToggleRights?.(event.target.checked)}
className="mt-0.5 h-5 w-5 rounded-md border border-white/30 bg-slate-900/70 text-emerald-400 accent-emerald-500 focus:ring-2 focus:ring-emerald-400/40"
/>
<span>
I confirm I own the rights to this content. <span className="text-red-300">*</span>
<span className="mt-1 block text-xs text-white/60">Required before publishing.</span>
{errors.rights && <span className="mt-1 block text-xs text-red-200">{errors.rights}</span>}
</span>
</label>
<Checkbox
id="upload-sidebar-rights"
checked={Boolean(metadata.rightsAccepted)}
onChange={(event) => onToggleRights?.(event.target.checked)}
variant="emerald"
size={20}
label="I confirm I own the rights to this content."
hint="Required before publishing."
error={errors.rights}
required
/>
</section>
</div>
</aside>