sanity-plugin-iconify 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +206 -0
- package/dist/index.esm.js +456 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.js +467 -0
- package/dist/index.js.map +1 -0
- package/package.json +1 -1
- package/src/iconify-input.tsx +50 -30
- package/src/iconify-preview.tsx +34 -8
- package/src/lib/query-client.tsx +11 -0
- package/src/lib/use-pretty-icon-name.ts +12 -3
package/src/iconify-input.tsx
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import { Flex, Stack, Text } from '@sanity/ui';
|
|
2
|
-
import {
|
|
3
|
-
import { useCallback } from 'react';
|
|
1
|
+
import { Flex, RootTheme, Stack, Text, ThemeProvider, studioTheme, useTheme } from '@sanity/ui';
|
|
2
|
+
import { useCallback, useMemo } from 'react';
|
|
4
3
|
import { ObjectInputProps, set, unset } from 'sanity';
|
|
5
4
|
import { IconifyCombobox } from './combobox';
|
|
5
|
+
import { QueryClientProvider } from './lib/query-client';
|
|
6
6
|
import { IconOptions, IconifyPluginConfig } from './lib/types';
|
|
7
7
|
import { usePrettyIconName } from './lib/use-pretty-icon-name';
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
// -------------- //
|
|
10
|
+
// ICONIFY INPUT //
|
|
11
|
+
// -------------- //
|
|
10
12
|
|
|
11
13
|
interface IconifyInputProps extends ObjectInputProps {
|
|
12
14
|
config: IconifyPluginConfig;
|
|
@@ -15,8 +17,7 @@ interface IconifyInputProps extends ObjectInputProps {
|
|
|
15
17
|
export function IconifyInput(props: IconifyInputProps) {
|
|
16
18
|
const { config, value, onChange: pushChange, schemaType } = props;
|
|
17
19
|
|
|
18
|
-
const selectedIcon = value?.name ?? null;
|
|
19
|
-
const prettyName = usePrettyIconName(selectedIcon);
|
|
20
|
+
const selectedIcon: string | null = value?.name ?? null;
|
|
20
21
|
|
|
21
22
|
const options: IconOptions = schemaType.options;
|
|
22
23
|
const collections =
|
|
@@ -25,6 +26,12 @@ export function IconifyInput(props: IconifyInputProps) {
|
|
|
25
26
|
null;
|
|
26
27
|
const showName = options?.showName ?? config?.showName ?? false;
|
|
27
28
|
|
|
29
|
+
const parentTheme = useTheme();
|
|
30
|
+
const theme: RootTheme = useMemo(
|
|
31
|
+
() => (parentTheme ? { ...parentTheme.sanity, color: studioTheme.color } : studioTheme),
|
|
32
|
+
[parentTheme],
|
|
33
|
+
);
|
|
34
|
+
|
|
28
35
|
const handleSelect = useCallback(
|
|
29
36
|
(icon: string) => {
|
|
30
37
|
pushChange(icon === '' ? unset() : set(icon, ['name']));
|
|
@@ -33,32 +40,45 @@ export function IconifyInput(props: IconifyInputProps) {
|
|
|
33
40
|
);
|
|
34
41
|
|
|
35
42
|
return (
|
|
36
|
-
<QueryClientProvider
|
|
37
|
-
<
|
|
38
|
-
<
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
+
<QueryClientProvider>
|
|
44
|
+
<ThemeProvider theme={theme}>
|
|
45
|
+
<Stack space={2}>
|
|
46
|
+
<IconifyCombobox
|
|
47
|
+
selectedIcon={selectedIcon}
|
|
48
|
+
onSelect={handleSelect}
|
|
49
|
+
collections={collections}
|
|
50
|
+
/>
|
|
43
51
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
52
|
+
{showName && selectedIcon ? <IconifyNameDisplay name={selectedIcon} /> : null}
|
|
53
|
+
</Stack>
|
|
54
|
+
</ThemeProvider>
|
|
55
|
+
</QueryClientProvider>
|
|
56
|
+
);
|
|
57
|
+
}
|
|
49
58
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
59
|
+
interface IconifyNameDisplayProps {
|
|
60
|
+
name?: string | null;
|
|
61
|
+
}
|
|
53
62
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
+
function IconifyNameDisplay(props: IconifyNameDisplayProps) {
|
|
64
|
+
const { name } = props;
|
|
65
|
+
const prettyName = usePrettyIconName({ name });
|
|
66
|
+
|
|
67
|
+
return (
|
|
68
|
+
<Flex gap={1}>
|
|
69
|
+
<Text size={1} muted>
|
|
70
|
+
Selected:
|
|
71
|
+
</Text>
|
|
72
|
+
|
|
73
|
+
<Text size={1} weight="semibold">
|
|
74
|
+
{prettyName?.name ?? name}
|
|
75
|
+
</Text>
|
|
76
|
+
|
|
77
|
+
{prettyName?.collection && (
|
|
78
|
+
<Text size={1} muted style={{ fontStyle: 'italic' }}>
|
|
79
|
+
by {prettyName?.collection}
|
|
80
|
+
</Text>
|
|
81
|
+
)}
|
|
82
|
+
</Flex>
|
|
63
83
|
);
|
|
64
84
|
}
|
package/src/iconify-preview.tsx
CHANGED
|
@@ -1,20 +1,46 @@
|
|
|
1
1
|
import { Icon } from '@iconify/react';
|
|
2
2
|
import { PreviewProps } from 'sanity';
|
|
3
3
|
import { usePrettyIconName } from './lib/use-pretty-icon-name';
|
|
4
|
+
import { IconifyIconName, stringToIcon } from '@iconify/utils';
|
|
5
|
+
import { QueryClientProvider } from './lib/query-client';
|
|
6
|
+
|
|
7
|
+
// --------------- //
|
|
8
|
+
// ICONIFY PREVIEW //
|
|
9
|
+
// --------------- //
|
|
4
10
|
|
|
5
11
|
export function IconifyPreview(props: PreviewProps) {
|
|
6
12
|
const { title } = props;
|
|
7
|
-
const
|
|
13
|
+
const iconName = typeof props.title === 'string' ? stringToIcon(props.title) : null;
|
|
8
14
|
|
|
9
15
|
// We check this double to avoid the TS error
|
|
10
|
-
if (typeof title === 'string' &&
|
|
11
|
-
return
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
});
|
|
16
|
+
if (typeof title === 'string' && iconName) {
|
|
17
|
+
return (
|
|
18
|
+
<QueryClientProvider>
|
|
19
|
+
<IconifyPreviewInner {...props} iconName={title} iconMeta={iconName} />
|
|
20
|
+
</QueryClientProvider>
|
|
21
|
+
);
|
|
17
22
|
}
|
|
18
23
|
|
|
19
24
|
return props.renderDefault(props);
|
|
20
25
|
}
|
|
26
|
+
|
|
27
|
+
// --------------------- //
|
|
28
|
+
// ICONIFY PREVIEW INNER //
|
|
29
|
+
// --------------------- //
|
|
30
|
+
|
|
31
|
+
interface IconifyPreviewInnerProps extends PreviewProps {
|
|
32
|
+
iconName: string;
|
|
33
|
+
iconMeta: IconifyIconName;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function IconifyPreviewInner(props: IconifyPreviewInnerProps) {
|
|
37
|
+
const { iconMeta, iconName, ...previewProps } = props;
|
|
38
|
+
const prettyName = usePrettyIconName({ iconMeta });
|
|
39
|
+
|
|
40
|
+
return props.renderDefault({
|
|
41
|
+
...previewProps,
|
|
42
|
+
media: <Icon icon={iconName} />,
|
|
43
|
+
title: prettyName?.name ?? iconName,
|
|
44
|
+
subtitle: prettyName?.collection,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import {
|
|
2
|
+
QueryClient,
|
|
3
|
+
QueryClientProvider as ReactQueryClientProvider,
|
|
4
|
+
} from '@tanstack/react-query';
|
|
5
|
+
import { ReactNode } from 'react';
|
|
6
|
+
|
|
7
|
+
export const queryClient = new QueryClient();
|
|
8
|
+
|
|
9
|
+
export function QueryClientProvider(props: { children: ReactNode }) {
|
|
10
|
+
return <ReactQueryClientProvider client={queryClient}>{props.children}</ReactQueryClientProvider>;
|
|
11
|
+
}
|
|
@@ -1,10 +1,19 @@
|
|
|
1
|
-
import { stringToIcon } from '@iconify/utils';
|
|
1
|
+
import { IconifyIconName, stringToIcon } from '@iconify/utils';
|
|
2
2
|
import { sentenceCase } from 'change-case';
|
|
3
3
|
import { useMemo } from 'react';
|
|
4
4
|
import { useIconSetInfo } from './api';
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
interface UsePrettyIconNameProps {
|
|
7
|
+
name?: string | null;
|
|
8
|
+
iconMeta?: IconifyIconName | null;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function usePrettyIconName(props: UsePrettyIconNameProps) {
|
|
12
|
+
const { name } = props;
|
|
13
|
+
const iconMeta = useMemo(
|
|
14
|
+
() => props.iconMeta ?? (name ? stringToIcon(name) : null),
|
|
15
|
+
[name, props.iconMeta],
|
|
16
|
+
);
|
|
8
17
|
const iconSetInfo = useIconSetInfo({ prefix: iconMeta?.prefix ?? null });
|
|
9
18
|
|
|
10
19
|
return useMemo(
|