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.
@@ -1,12 +1,14 @@
1
- import { Flex, Stack, Text } from '@sanity/ui';
2
- import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
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
- const queryClient = new QueryClient();
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 client={queryClient}>
37
- <Stack space={2}>
38
- <IconifyCombobox
39
- selectedIcon={selectedIcon}
40
- onSelect={handleSelect}
41
- collections={collections}
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
- {showName && selectedIcon ? (
45
- <Flex gap={1}>
46
- <Text size={1} muted>
47
- Selected:
48
- </Text>
52
+ {showName && selectedIcon ? <IconifyNameDisplay name={selectedIcon} /> : null}
53
+ </Stack>
54
+ </ThemeProvider>
55
+ </QueryClientProvider>
56
+ );
57
+ }
49
58
 
50
- <Text size={1} weight="semibold">
51
- {prettyName?.name ?? selectedIcon}
52
- </Text>
59
+ interface IconifyNameDisplayProps {
60
+ name?: string | null;
61
+ }
53
62
 
54
- {prettyName?.collection && (
55
- <Text size={1} muted style={{ fontStyle: 'italic' }}>
56
- by {prettyName?.collection}
57
- </Text>
58
- )}
59
- </Flex>
60
- ) : null}
61
- </Stack>
62
- </QueryClientProvider>
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
  }
@@ -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 prettyName = usePrettyIconName(typeof title === 'string' ? title : null);
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' && prettyName) {
11
- return props.renderDefault({
12
- ...props,
13
- media: <Icon icon={title} />,
14
- title: prettyName.name,
15
- subtitle: prettyName.collection,
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
- export function usePrettyIconName(name?: string | null) {
7
- const iconMeta = useMemo(() => (name ? stringToIcon(name) : null), [name]);
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(