diff --git a/packages/insert-menu/package.json b/packages/insert-menu/package.json index e344572b5..741cf4d80 100644 --- a/packages/insert-menu/package.json +++ b/packages/insert-menu/package.json @@ -40,12 +40,14 @@ "browserslist": "extends @sanity/browserslist-config", "dependencies": { "@sanity/icons": "^3.2.0", - "@sanity/ui": "^2.3.3" + "@sanity/ui": "^2.3.3", + "lodash.startcase": "^4.4.0" }, "devDependencies": { "@sanity/pkg-utils": "^6.9.3", "@sanity/types": "^3.45.0", "@sanity/ui-workshop": "^2.0.15", + "@types/lodash.startcase": "^4.4.9", "@typescript-eslint/eslint-plugin": "^7.13.0", "@typescript-eslint/parser": "^7.13.0", "eslint": "^8.57.0", diff --git a/packages/insert-menu/src/InsertMenu.tsx b/packages/insert-menu/src/InsertMenu.tsx index aa5ba8782..83cb8596b 100644 --- a/packages/insert-menu/src/InsertMenu.tsx +++ b/packages/insert-menu/src/InsertMenu.tsx @@ -15,6 +15,7 @@ import { TextInput, Tooltip, } from '@sanity/ui' +import startCase from 'lodash.startcase' import {type ChangeEvent, createElement, type CSSProperties, useReducer, useState} from 'react' import {isValidElementType} from 'react-is' @@ -73,7 +74,9 @@ export type InsertMenuProps = InsertMenuOptions & { export function InsertMenu(props: InsertMenuProps): React.JSX.Element { const showIcons = props.showIcons === undefined ? true : props.showIcons const showFilter = - props.filter === 'on' ? true : props.filter === 'off' ? false : props.schemaTypes.length > 5 + props.filter === undefined || props.filter === 'auto' + ? props.schemaTypes.length > 5 + : props.filter const [state, send] = useReducer(fullInsertMenuReducer, { query: '', groups: props.groups @@ -149,7 +152,7 @@ export function InsertMenu(props: InsertMenuProps): React.JSX.Element { id={`${group.name}-tab`} aria-controls={`${group.name}-panel`} key={group.name} - label={group.title ?? group.name} + label={group.title ?? startCase(group.name)} selected={group.selected} onClick={() => { send({type: 'select group', name: group.name}) @@ -178,7 +181,7 @@ export function InsertMenu(props: InsertMenuProps): React.JSX.Element { onClick={() => { props.onSelect(schemaType) }} - previewImageUrl={selectedView.previewImageUrl(schemaType.name)} + previewImageUrl={selectedView.previewImageUrl?.(schemaType.name)} schemaType={schemaType} /> ))} @@ -192,7 +195,7 @@ export function InsertMenu(props: InsertMenuProps): React.JSX.Element { onClick={() => { props.onSelect(schemaType) }} - text={schemaType.title ?? schemaType.name} + text={schemaType.title ?? startCase(schemaType.name)} /> ))} @@ -248,7 +251,9 @@ type GridMenuItemProps = { schemaType: SchemaType icon: MenuItemProps['icon'] previewImageUrl: ReturnType< - Extract[number], {name: 'grid'}>['previewImageUrl'] + NonNullable< + Extract[number], {name: 'grid'}>['previewImageUrl'] + > > } diff --git a/packages/insert-menu/src/InsertMenuOptions.ts b/packages/insert-menu/src/InsertMenuOptions.ts index 3d9ac24a6..9d1f4f4bd 100644 --- a/packages/insert-menu/src/InsertMenuOptions.ts +++ b/packages/insert-menu/src/InsertMenuOptions.ts @@ -5,12 +5,13 @@ export interface InsertMenuOptions { * `filter: 'auto'` automatically turns on filtering if there are more than 5 * schema types added to the menu. */ - filter?: 'auto' | 'on' | 'off' + filter?: 'auto' | boolean groups?: Array<{name: string; title?: string; of?: Array}> /** defaultValue `true` */ showIcons?: boolean /** @defaultValue `[{name: 'list'}]` */ views?: Array< - {name: 'list'} | {name: 'grid'; previewImageUrl: (schemaTypeName: string) => string | undefined} + | {name: 'list'} + | {name: 'grid'; previewImageUrl?: (schemaTypeName: string) => string | undefined} > } diff --git a/packages/insert-menu/src/__workshop__/full.tsx b/packages/insert-menu/src/__workshop__/full.tsx index cc5e8a7e7..937729380 100644 --- a/packages/insert-menu/src/__workshop__/full.tsx +++ b/packages/insert-menu/src/__workshop__/full.tsx @@ -64,7 +64,6 @@ const schemaTypes: ObjectSchemaType[] = [ { jsonType: 'object', name: 'videos', - title: 'Videos', icon: DocumentVideoIcon, fields: [], __experimental_search: [], @@ -86,7 +85,12 @@ const views: InsertMenuProps['views'] = [ export default function FullStory() { const iconsEnabled = useSelect('showIcons', {true: true, false: false}, true) - const filter = useSelect('filter', {undefined: 'undefined', auto: 'auto', on: 'on', off: 'off'}) + const filter = useSelect('filter', { + undefined: 'undefined', + auto: 'auto', + true: true, + false: false, + }) const groupsEnabled = useSelect('groups', {true: true, false: false}, true) const viewsEnabled = useSelect('views', {true: true, false: false}, true) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 24a1b3888..32145715d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1022,6 +1022,9 @@ importers: '@sanity/ui': specifier: ^2.3.3 version: 2.4.0(react-dom@18.3.1)(react-is@18.3.1)(react@18.3.1)(styled-components@6.1.11) + lodash.startcase: + specifier: ^4.4.0 + version: 4.4.0 devDependencies: '@sanity/pkg-utils': specifier: ^6.9.3 @@ -1032,6 +1035,9 @@ importers: '@sanity/ui-workshop': specifier: ^2.0.15 version: 2.0.15(@sanity/icons@3.2.0)(@sanity/ui@2.4.0)(react-dom@18.3.1)(react@18.3.1)(styled-components@6.1.11) + '@types/lodash.startcase': + specifier: ^4.4.9 + version: 4.4.9 '@typescript-eslint/eslint-plugin': specifier: ^7.13.0 version: 7.13.1(@typescript-eslint/parser@7.13.1)(eslint@8.57.0)(typescript@5.4.5) @@ -8028,6 +8034,12 @@ packages: '@types/lodash': 4.17.0 dev: false + /@types/lodash.startcase@4.4.9: + resolution: {integrity: sha512-C0M4DlN1pnn2vEEhLHkTHxiRZ+3GlTegpoAEHHGXnuJkSOXyJMHGiSc+SLRzBlFZWHsBkixe6FqvEAEU04g14g==} + dependencies: + '@types/lodash': 4.17.0 + dev: true + /@types/lodash@4.17.0: resolution: {integrity: sha512-t7dhREVv6dbNj0q17X12j7yDG4bD/DHYX7o5/DbDxobP0HnGPgpRz2Ej77aL7TZT3DSw13fqUTj8J4mMnqa7WA==} @@ -8224,7 +8236,6 @@ packages: typescript: 5.4.5 transitivePeerDependencies: - supports-color - dev: true /@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.5): resolution: {integrity: sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==} @@ -8273,7 +8284,6 @@ packages: dependencies: '@typescript-eslint/types': 5.62.0 '@typescript-eslint/visitor-keys': 5.62.0 - dev: true /@typescript-eslint/scope-manager@6.21.0: resolution: {integrity: sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==} @@ -8333,7 +8343,6 @@ packages: /@typescript-eslint/types@5.62.0: resolution: {integrity: sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dev: true /@typescript-eslint/types@6.21.0: resolution: {integrity: sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==} @@ -8363,7 +8372,6 @@ packages: typescript: 5.4.5 transitivePeerDependencies: - supports-color - dev: true /@typescript-eslint/typescript-estree@6.21.0(typescript@5.4.5): resolution: {integrity: sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==} @@ -8450,7 +8458,6 @@ packages: dependencies: '@typescript-eslint/types': 5.62.0 eslint-visitor-keys: 3.4.3 - dev: true /@typescript-eslint/visitor-keys@6.21.0: resolution: {integrity: sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==} @@ -12389,7 +12396,6 @@ packages: resolve: 1.22.8 transitivePeerDependencies: - supports-color - dev: true /eslint-import-resolver-node@0.3.9: resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} @@ -12421,7 +12427,6 @@ packages: - eslint-import-resolver-node - eslint-import-resolver-webpack - supports-color - dev: true /eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0): resolution: {integrity: sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==} @@ -12473,7 +12478,6 @@ packages: eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.7)(eslint-plugin-import@2.29.1)(eslint@8.57.0) transitivePeerDependencies: - supports-color - dev: true /eslint-module-utils@2.8.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): resolution: {integrity: sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==} @@ -12503,7 +12507,6 @@ packages: eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.7)(eslint-plugin-import@2.29.1)(eslint@8.57.0) transitivePeerDependencies: - supports-color - dev: true /eslint-module-utils@2.8.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): resolution: {integrity: sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==} @@ -12607,7 +12610,6 @@ packages: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - dev: true /eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==} @@ -12628,7 +12630,7 @@ packages: doctrine: 2.1.0 eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + eslint-module-utils: 2.8.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) hasown: 2.0.2 is-core-module: 2.13.1 is-glob: 4.0.3 @@ -15833,6 +15835,10 @@ packages: /lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + /lodash.startcase@4.4.0: + resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} + dev: false + /lodash.truncate@4.4.2: resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==} dev: true @@ -22859,7 +22865,6 @@ packages: /tslib@1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} - dev: true /tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} @@ -22880,7 +22885,6 @@ packages: dependencies: tslib: 1.14.1 typescript: 5.4.5 - dev: true /tuf-js@1.1.7: resolution: {integrity: sha512-i3P9Kgw3ytjELUfpuKVDNBJvk4u5bXL6gskv572mcevPbSKCV3zt3djhmlEQ65yERjIbOSncy7U4cQJaB1CBCg==}