-
Notifications
You must be signed in to change notification settings - Fork 18
Studio v.3 compatibility #28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Hi Fabien, I just opened up my editor for that purpose 5 min ago :) It will feature v3 compatibility and a complete rewrite in TS. The API will most likely not change however. |
What a coincidence! Sounds good, thanks! Any chance to include the async options (beta) functionality too? |
I'll definitely take a look at that as well! |
I would definitely appreciate v3 compatibility as well 🤞 |
any update please? |
Hey there, would be great to have an update on when this might be released 😀 |
Hey everyone! First of all, apologies for the lack of feedback on my part. Secondly, to update you on the progress - there is a branch with the current state of the progress: As for when I'll have the time to actually finish it and publish it... I'm sorry to say that I'm not sure. I would love to publish it asap, but there are personal circumstances in the way. I would really like to invite you all to contribute to this project since that would probably be the fastest way to move forward. The feature branch is mostly finished but it needs testing and some cleaning up. Unless such a hero shows up to assist on this project all I can say is that I'm aware that there are a lot of people waiting for this and I'll do my best to finish it as soon as possible after circumstances are better. I ask for your understanding and offer my apologies for the delays 🙇 |
@KimPaow Let us know how it goes 🙏🏻 |
Hi, is the v3 version supposedly working in the v3 branch? I've tried adding it into the project without success. :(
|
Has anyone been successful in getting this to work with v3? |
I've created a custom input component to use in the meantime. Code is below. ColorSelector.tsx import type { StringInputProps } from 'sanity';
import { set, unset } from 'sanity';
import { Stack, Flex, TextInput, Text, Avatar, Card, Grid } from '@sanity/ui';
import React, { useCallback } from 'react';
type ColorList = {
title: string;
value: string;
};
type SchemaTypeOption = { list: ColorList[] } | undefined;
const ColorSelector = ({
schemaType,
value = '',
onChange,
}: StringInputProps) => {
const schemeTypeOptions = schemaType.options as SchemaTypeOption;
const handleChange = useCallback(
(event: React.ChangeEvent<HTMLInputElement>) =>
onChange(
event.currentTarget.value ? set(event.currentTarget.value) : unset(),
),
[onChange],
);
const handleSelect = useCallback(
(hex: string) => onChange(hex ? set(hex) : unset()),
[onChange],
);
return (
<Stack space={3}>
<Grid columns={2} gap={1}>
<Avatar size={1} style={{ backgroundColor: value, width: '100%' }} />
<TextInput
fontSize={1}
padding={3}
placeholder='Enter hex (#ffffff) or select color below'
onChange={handleChange}
value={value}
/>
</Grid>
<Card borderTop paddingTop={3}>
<Flex direction={'row'} wrap={'wrap'}>
{schemeTypeOptions.list.map(({ title, value }) => {
return (
<ColorCircle
key={value}
colorName={title}
hex={value}
onClickHandler={handleSelect}
/>
);
})}
</Flex>
</Card>
</Stack>
);
};
export default ColorSelector;
type ColorCircle = {
colorName: string;
hex: string;
onClickHandler: (hex: string) => void;
};
const ColorCircle = ({ colorName, hex, onClickHandler }: ColorCircle) => {
return (
<Card paddingRight={2} paddingBottom={4}>
<Avatar
size={2}
style={{
backgroundColor: hex,
cursor: 'pointer',
}}
onClick={() => onClickHandler(hex)}
/>
<Text size={1} align={'center'} style={{ marginTop: '1em' }}>
{colorName}
</Text>
</Card>
);
}; your-schema.ts import { defineType } from 'sanity';
import ColorSelector from '../../../components/inputs/ColorSelector';
export default defineType({
name: 'color',
title: 'Color',
description: 'Choose a color for the background',
type: 'string',
components: { input: ColorSelector },
options: {
list: [
{ title: 'Orange', value: '#F27021' },
{ title: 'Grey', value: '#091C21' },
],
},
}); |
First of all, a huge thanks to @timbeglinger for the custom input component, I'm just starting to use Sanity v3 now and needed to migrate the color-list type, and it was awesome finding this component ready to use and adapt. I've taken the liberty of adding a bunch of features to it and want to return the favor and share the code back. Here's some of the features I added:
Feel free to suggest improvements, I can't promise I'll add them as I spent too much time on this already, but I might, and they're welcome anyway. And here's the code. ColorSelector.tsx import { Avatar, Card, Flex, Grid, Stack, Text, TextInput } from '@sanity/ui';
import React, { useCallback } from 'react';
import { set, StringInputProps, unset } from 'sanity';
export function colorHexValidator(value?: string) {
if (value && !value.match(/^#[a-fA-f0-9]{6}$/)) {
return 'Color must be a valid hex (e.g. #A4F23B)';
}
return true;
}
type ColorCircleProps = {
colorName: string;
hex: string;
active: boolean;
withColorName: boolean;
onClickHandler: (hex: string) => void;
};
const ColorCircle = ({
colorName,
hex,
active,
withColorName,
onClickHandler,
}: ColorCircleProps) => {
return (
<Card paddingRight={2} paddingBottom={4}>
<div
style={{
padding: '4px',
borderRadius: '50%',
backgroundColor: active ? hex : 'transparent',
border: active ? '1px solid var(--card-hairline-soft-color)' : '1px solid transparent',
cursor: 'pointer',
}}
onClick={() => onClickHandler(hex)}
>
<Avatar
size={1}
style={{
backgroundColor: hex,
border: '1px solid var(--card-hairline-soft-color)',
}}
/>
</div>
{withColorName && (
<Text size={1} align={'center'} style={{ marginTop: '.5em' }}>
{colorName}
</Text>
)}
</Card>
);
};
type ColorObject = {
title: string;
value: string;
};
type ColorSelectorProps = StringInputProps &
(
| {
list: ColorObject[];
withColorNames?: boolean;
withHexInput?: boolean;
}
| {
list?: never;
withColorNames?: never;
withHexInput: true;
}
);
const ColorSelector = ({
value = '',
onChange,
list,
withHexInput,
withColorNames,
}: ColorSelectorProps) => {
// Removes non-hex chars from the string, trims to 6 chars,
// adds a # at the beginning and upper cases it
const preprocessValue = (str: string) => {
const validHexChars = /[0-9a-fA-F]/g;
const hexChars = str.match(validHexChars)?.join('') || '';
const hasHashSymbol = hexChars.startsWith('#');
return (hasHashSymbol ? '' : '#') + hexChars.replace(/^#/, '').substring(0, 6).toUpperCase();
};
const handleChange = useCallback(
(event: React.ChangeEvent<HTMLInputElement>) =>
onChange(
event.currentTarget.value ? set(preprocessValue(event.currentTarget.value)) : unset(),
),
[onChange],
);
const handleSelect = useCallback(
(hex: string) => onChange(hex && hex !== value ? set(preprocessValue(hex)) : unset()),
[onChange, value],
);
return (
<Stack space={3}>
{withHexInput && (
<>
<Text size={1}>Enter hex</Text>
<Grid
columns={2}
gap={1}
style={{
gridTemplateColumns: 'auto 1fr',
}}
>
<Avatar
size={1}
style={{
backgroundColor: value,
border: '1px solid var(--card-hairline-soft-color)',
}}
/>
<TextInput
style={{ flexGrow: 1 }}
fontSize={1}
padding={3}
placeholder={'#FFFFFF'}
onChange={handleChange}
value={value}
/>
</Grid>
</>
)}
{list && (
<Card
borderTop={withHexInput}
paddingTop={withHexInput ? 3 : 0}
style={{
transform: 'translateX(-4px)',
}}
>
{withHexInput && (
<Text size={1} style={{ marginBottom: '.5em' }}>
or select color below
</Text>
)}
<Flex direction={'row'} wrap={'wrap'}>
{list.map(colorItem => {
return (
<ColorCircle
key={colorItem.value}
colorName={colorItem.title}
hex={colorItem.value}
active={colorItem.value === value}
withColorName={!!withColorNames}
onClickHandler={handleSelect}
/>
);
})}
</Flex>
</Card>
)}
</Stack>
);
};
export default ColorSelector; your-schema.tsx import ColorSelector, { colorHexValidator } from '../../src/components/ColorSelector';
...
defineField({
name: 'color',
title: 'Color',
type: 'string',
components: {
input: props => (
<ColorSelector
{...props}
withHexInput
withColorNames
list={[
{ title: 'Orange', value: '#F27021' },
{ title: 'Grey', value: '#DDDDDD' },
{ title: 'White', value: '#FFFFFF' },
{ title: 'Dark', value: '#101112' },
]}
/>
),
},
validation: Rule => Rule.custom(colorHexValidator).required(),
}) |
Any update on merging the v3 feature branch? |
Hey guys, since there is still people asking, you can use my forked version that I developed for one of my projects: |
Hi, thanks for this plugin!
Now that Studio v.3 has been released as developer preview, do you think you'll be releasing a compatible plugin for it?
The text was updated successfully, but these errors were encountered: