Title describes the issue pretty well. When using a DateField in an Admin Block UI extension the picker is rendered outside the scrollable body of the website, and as such is unusable. See attached screenshot.
Hey @MrPunkin - I’m not able to replicate the issue on my end here after doing a bit of testing. Here’s the code I’m working with if it’s helpful:
import {
reactExtension,
useApi,
AdminBlock,
BlockStack,
Text,
DatePicker,
} from '@shopify/ui-extensions-react/admin';
import {useState} from 'react';
(./shopify.extension.toml)
const TARGET = 'admin.product-details.block.render';
export default reactExtension(TARGET, () => <App />);
function App() {
const {i18n, data} = useApi(TARGET);
console.log({data});
const [selectedDate, setSelectedDate] = useState(new Date());
return (
<AdminBlock heading="My Block Extension">
<BlockStack>
<Text fontWeight="bold">{i18n.translate('welcome', {target: TARGET})}</Text>
<Text>Placeholder text 1</Text>
<Text>Placeholder text 2</Text>
<Text>Placeholder text 3</Text>
<Text>Placeholder text 4</Text>
<Text>Placeholder text 5</Text>
<DatePicker selected={selectedDate} onChange={setSelectedDate} />
</BlockStack>
</AdminBlock>
);
}
If you’re able to share your extension code, I can try to see if I’m able to replicate the behaviour you’re seeing on your end there (I am just using text placeholders, but I see you’re using some actual components). If you’d like to share that via DM, that’s alright too, just let me know in this thread and I can set the DM up so we can continue digging into this.
Sure, I just simplified my code to be safe to share and just render the component without dynamic calls for data and whatnot. It still renders just the same, with the same issues. I did notice however that this is in Safari, but in Chrome it seems to extend the scrollable body of the page beyond the “Save” button to accommodate the DatePicker that will render when clicking on the DateField. See attached screenshots.
import { useEffect, useState } from "react";
import {
AdminBlock,
Form,
BlockStack,
InlineStack,
Section,
DateField,
Checkbox,
ProgressIndicator,
Box,
Badge,
Heading,
Pressable,
reactExtension,
useApi,
} from "@shopify/ui-extensions-react/admin";
export default reactExtension("admin.product-details.block.render", () => <App />);
function App() {
const { i18n } = useApi();
const [loading, setLoading] = useState(false);
const [product, setProduct] = useState({
unfulfilled: { count: 0, query: '' },
fulfilled: { count: 0, query: '' },
});
const [availableAt, setAvailableAt] = useState(new Date());
const [backorder, setBackorder] = useState(false);
return loading ? (
<InlineStack blockAlignment='center' inlineAlignment='center'>
<ProgressIndicator size="small-300" />
</InlineStack>
) : (
<AdminBlock>
<Form>
<BlockStack gap="base">
<InlineStack gap="large">
<Section heading={i18n.translate('headings.unfulfilled_orders')}>
<Pressable href={`shopify:admin/orders?query=${product.unfulfilled.query}`}>
<Heading size="1">{ product.unfulfilled.count.toLocaleString() }</Heading>
</Pressable>
</Section>
<Section heading={i18n.translate('headings.fulfilled_orders')}>
<Pressable href={`shopify:admin/orders?query=${product.fulfilled.query}`}>
<Heading size="1">{ product.fulfilled.count.toLocaleString() }</Heading>
</Pressable>
</Section>
</InlineStack>
<DateField
label={i18n.translate('labels.available_at')}
defaultValue={availableAt}
value={availableAt}
selected={[availableAt]}
onChange={setAvailableAt}
/>
<InlineStack gap="large" blockAlignment="end">
<Box inlineSize="auto">
<Checkbox
label={i18n.translate('labels.backorder')}
defaultValue={backorder}
checked={backorder}
onChange={setBackorder}
/>
</Box>
<Box inlineSize="auto" />
<Badge tone="warning" icon="ClockMajor">{i18n.translate('status_names.backorder')}</Badge>
</InlineStack>
</BlockStack>
</Form>
</AdminBlock>
);
}
Safari
Chrome
@Alan_G Tagging just in case
Thanks @MrPunkin, really appreciate you sending that my way - I’m able to replicate the behaviour on my end now I think:
I tried reconfiguring some of the code to see if we could wrap the DatePicker in another context to get it position correctly, but I think you may be right that there is something up on our end. Can’t confirm that at the moment, but I’ll do some more digging into this and loop back with you when I have some next steps.