You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/src/uix/eidos/components/image-picker
dev dc62a0268b
feat(eidos): canonize theming scales + tokenize magic numbers
4 months ago
..
README.md feat(uix): cropper, image-picker, image-adjustments + reusable zoom-pan layer 4 months ago
image-picker.css feat(eidos): canonize theming scales + tokenize magic numbers 4 months ago
image-picker.svelte feat(uix): cropper, image-picker, image-adjustments + reusable zoom-pan layer 4 months ago
index.ts feat(uix): cropper, image-picker, image-adjustments + reusable zoom-pan layer 4 months ago
types.ts feat(uix): cropper, image-picker, image-adjustments + reusable zoom-pan layer 4 months ago

README.md

ImagePicker (eidos)

The styled, configured image picker — a pure composition of three already-built framework components: FileUpload (drop + click) → Image (preview, fit modes) + a rotate/remove toolbar + ImageAdjustments (filters). The consumer uses the configured root; the empty/ready states + the toolbar are rendered internally.

<script>
  import ImagePicker from '$uix/eidos/components/image-picker';
  let file = $state(null);
</script>

<ImagePicker bind:file onChange={(v) => save(v)} />

Baseline

No Air baseline. ImagePicker is a new component (2026-06-10); there is no air/ predecessor to recover. It was designed fresh against the references below, not ported.

Comparativa

Audited against the visual reference (Untitled UI) + the headless / file references:

Capability Untitled UI Chakra Ark UI Radix MUI → UIX
Image picker primitive ✅ image-pickers ❌ ❌ ❌ ❌ ✅
File-upload base ✅ ✅ FileUpload ✅ FileUpload ❌ ❌ (base-ui open issue) ✅ reuse file-upload
Preview + fill modes ✅ fill/fit/crop/tile ❌ ❌ ❌ ❌ ✅ reuse image (cover/contain/fill)
90° rotation ✅ ❌ ❌ ❌ ❌ ✅
Filter / effect sliders ✅ ❌ ❌ ❌ ❌ ✅ reuse ImageAdjustments
Crop ❌ (separate) ❌ ✅ image-cropper ❌ ❌ hand-off (next component)
Sound / haptic on actions ❌ ❌ ❌ ❌ ❌ ✅ sema

No mainstream component library ships an image picker as a primitive — it's app code over a file input. UIX composes three resolved components and emits a cropper-ready value.

What it composes

State Renders
empty <FileUpload> (drop + click), accept="image/*", single file
ready <Image> preview + a floating rotate/remove toolbar + <ImageAdjustments>

Props

ProviderProps (soma) + composition knobs:

Prop Type Default Notes
file / fit / rotation / adjustments — — bindable — see soma README
onChange (v: ImagePickerValue) => void — cropper-ready value
disabled boolean false → both FileUpload + controls
accept string 'image/*' → FileUpload
maxSize number — → FileUpload
size 'sm' | 'md' | 'lg' 'sm' embedded ImageAdjustments scale
showAdjustments boolean true render the filters panel

Decisiones

  • Composition over reimplementation. ImagePicker renders <FileUpload> / <Image> / <ImageAdjustments> — it never re-declares a dropzone, an image surface or a slider. The morfo declares only the picker's OWN orchestration.
  • rotate is a handle verb. Spatial manipulation (with drag / resize / scroll), even though a discrete button triggers it — that's its canonical family. select / remove are commit.
  • Object-URL lives in soma. Created on file change and revoked via the effect cleanup (previous URL on replace, last on unmount). createObjectURL is used directly, matching the file-upload / words precedent (it is not an ActiveDom concern).
  • data-fit is reflected on the picker even though <Image> owns the visual object-fit. It is a picker-level state reflection (parallel to data-rotation / data-state) so tooling and consumer CSS can read the picker's fit from its own DOM. Chosen over removing it (which would hide the state) and over a contrived CSS rule.
  • Rotation rotates a .canvas wrapper, not the toolbar. The toolbar is a sibling of the canvas inside the Preview, so it stays upright while the image rotates.

Recipe tokens

Public, themeable — --image-picker-* (the composed components bring their own):

Token Default
gap space-3 (preview → adjustments)
preview-radius / preview-bg / preview-border / preview-aspect rounded box, 4/3
toolbar-gap / toolbar-inset floating top-right
button-* icon-button chrome (rotate / remove)

eidos-lint image-picker → invalid 0 (15 morfo-backed selectors). CSS is imported from the wrapper (code-split chunk) — intentionally NOT in eidos/index.css.

Gaps

Gap Disposition Notes
Crop (region selection) descartar here Belongs to the separate Ark-style image-cropper; ImagePicker hands it url/file.
Rotation letterbox at 90°/270° diferir The preview box doesn't swap dimensions, so a non-square image letterboxes. Revisit when the cropper lands.
highlights / shadows tone curves diferir Need canvas / SVG feComponentTransfer; tracked in ImageAdjustments.
Multiple images / gallery descartar Single image by design (multiple={false}); use file-upload directly for multi.
WAI-ARIA APG pattern diferir No single APG pattern covers a file-picker composite; the dropzone is a button, the root a labelled group.

Powered by TurnKey Linux.