Skip to content

feat(AssetInput): add AssetInput component#2726

Open
fulopdaniel wants to merge 8 commits into
mainfrom
feat/asset-input-component
Open

feat(AssetInput): add AssetInput component#2726
fulopdaniel wants to merge 8 commits into
mainfrom
feat/asset-input-component

Conversation

@fulopdaniel
Copy link
Copy Markdown
Contributor

This PR contributes a rewritten version of the legacy AssetInput to the components package.

Example usages:

Placeholder

<AssetInput.Placeholder>
    <AssetInput.UploadInput onFileChange={fn()} />
    <AssetInput.BrowseInput onBrowse={fn()} />
</AssetInput.Placeholder>
image

Preview

<AssetInput.Root orientation="horizontal" isOpen={false} onPress={fn()}>
    <AssetInput.Preview>
        <AssetInput.PreviewImage src="https://picsum.photos/100/150" />
    </AssetInput.Preview>
    <AssetInput.Title>foo1</AssetInput.Title>
    <AssetInput.Metadata>
        <Flex align="center" gap={0.5}>
            <IconArrowCircleUp size="16" />
            Uploaded
        </Flex>
    </AssetInput.Metadata>
    <AssetInput.Metadata>JPG</AssetInput.Metadata>
    <AssetInput.Metadata>2000 bytes</AssetInput.Metadata>
</AssetInput.Root>
image

See storybook for more examples.

@fulopdaniel fulopdaniel requested a review from noahwaldner May 13, 2026 12:49
@fulopdaniel fulopdaniel requested a review from a team as a code owner May 13, 2026 12:49
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 13, 2026

🦋 Changeset detected

Latest commit: 79ac3bf

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@frontify/fondue-components Patch
@frontify/fondue Patch
@frontify/fondue-rte Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@netlify
Copy link
Copy Markdown

netlify Bot commented May 13, 2026

Deploy Preview for fondue-components ready!

Name Link
🔨 Latest commit 79ac3bf
🔍 Latest deploy log https://app.netlify.com/projects/fondue-components/deploys/6a0c4ee93fd5e20008498ef9
😎 Deploy Preview https://deploy-preview-2726.components.fondue-components.frontify.com
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Copy link
Copy Markdown
Contributor

@noahwaldner noahwaldner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your contribution!

The component works and looks correct 💪🏻

I added comments regarding optimization. Many things could be done with css to avoid the expensive parsing of children.

I did not yet review the scss file as it will change a lot once more layout logic is moved there.

Comment thread packages/components/src/components/AssetInput/AssetInputPlaceholder.tsx Outdated
Comment thread packages/components/src/components/AssetInput/AssetInputPlaceholder.tsx Outdated
Comment thread packages/components/src/components/AssetInput/AssetInputBrowseInput.tsx Outdated
Comment thread packages/components/src/components/AssetInput/AssetInputUploadInput.tsx Outdated
};

export const AssetInputPreview = ({ children }: AssetInputPreviewProps) => {
const previewParts = useMemo(() => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not necessary, we can use types to ensure only the correct children are passed

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I adjusted all implementations to avoid the Children.forEach and rely on typing the children prop like this:

type AssetInputPreviewPart = ReactElement<
    AssetInputPreviewImageProps | AssetInputPreviewIconProps | AssetInputPreviewLoadingProps
>;

type AssetInputPreviewProps = {
    children: AssetInputPreviewPart | AssetInputPreviewPart[];
};

However, this does not seem to be working for me, type validation does not kick in. E.g. I can do this without any errors:

    <AssetInputPreview>
        <div>Invalid part</div>
        <AssetInputPreviewImage src="https://picsum.photos/101/150" />
    </AssetInputPreview>

What am I missing?

Comment thread packages/components/src/components/AssetInput/AssetInputPreview.tsx Outdated
});
if (previewParts.length > 1 && previewParts.length < 4) {
const emptyParts = Array.from({ length: 4 - previewParts.length }, (_, i) => (
<div className={styles.previewSlot} key={`empty-part-${i}`} />
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not necessary, can be done by setting a bg on the preview container

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The preview container background is white, and each item inside has this grayish background. There are thin white lines separating the items, that's why I opted for this "empty parts" approach.

Image

Comment thread packages/components/src/components/AssetInput/AssetInputPreview.tsx Outdated
Comment thread packages/components/src/components/AssetInput/AssetInputPreview.tsx
@fulopdaniel fulopdaniel requested a review from noahwaldner May 20, 2026 07:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants