{"version":3,"sources":["jsdelivr-header.js","/npm/@sanity/language-filter@4.1.0/src/filterField.ts","/npm/@sanity/language-filter@4.1.0/src/useSelectedLanguageIds.ts","/npm/@sanity/language-filter@4.1.0/src/LanguageFilterStudioContext.tsx","/npm/@sanity/language-filter@4.1.0/src/usePaneLanguages.ts","/npm/@sanity/language-filter@4.1.0/src/LanguageFilterMenuButton.tsx","/npm/@sanity/language-filter@4.1.0/src/LanguageFilterObjectInput.tsx","/npm/@sanity/language-filter@4.1.0/src/plugin.tsx"],"names":[],"mappings":"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","file":"/npm/@sanity/language-filter@4.1.0/lib/index.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/@sanity/language-filter@4.1.0/lib/index.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","import type {SchemaType} from 'sanity'\n\nimport type {FilterFieldFunction, LanguageFilterConfig, LanguageFilterSchema} from './types'\n\nexport const defaultFilterField: FilterFieldFunction = (\n  enclosingType,\n  field,\n  selectedLanguageIds,\n) => !enclosingType.name.startsWith('locale') || selectedLanguageIds.includes(field.name)\n\nexport function isLanguageFilterEnabled(\n  schemaType: SchemaType | undefined,\n  options: LanguageFilterConfig,\n): boolean {\n  const schemaFilter =\n    isDocument(schemaType) && (schemaType as LanguageFilterSchema)?.options?.languageFilter\n  const defaultEnabled = !options.documentTypes\n\n  return !!(\n    (defaultEnabled && schemaFilter !== false) ||\n    (!defaultEnabled && schemaFilter) ||\n    (schemaType && options.documentTypes?.includes(schemaType.name))\n  )\n}\n\nfunction isDocument(schemaType?: SchemaType) {\n  return schemaType?.jsonType === 'object' && getRootType(schemaType).name === 'document'\n}\n\nfunction getRootType(schema: SchemaType): SchemaType {\n  if (schema.type) {\n    return getRootType(schema.type)\n  }\n  return schema\n}\n","import {useState} from 'react'\n\nimport type {Language, LanguageFilterConfig} from './types'\nconst storageKey = '@sanity/plugin/language-filter/selected-languages'\n\nexport function getPersistedLanguageIds(options: LanguageFilterConfig): string[] {\n  const selectableLangs = getSelectableLanguages(options).map((l) => l.id)\n\n  let selected: string[] = selectableLangs\n  try {\n    const persistedValue = window.localStorage.getItem(storageKey)\n    if (persistedValue) {\n      selected = JSON.parse(persistedValue)\n    }\n  } catch (err) {} // eslint-disable-line no-empty\n\n  // constrain persisted/selected languages to the ones currently supported\n  selected = intersection(selected, selectableLangs)\n  return selected\n}\n\nexport function persistLanguageIds(languageIds: string[]): void {\n  window.localStorage.setItem(storageKey, JSON.stringify(languageIds))\n}\n\nfunction intersection(array1: string[], array2: string[]) {\n  return array1.filter((value) => array2.includes(value))\n}\n\nexport function getSelectableLanguages({\n  supportedLanguages,\n  defaultLanguages,\n}: LanguageFilterConfig): Language[] {\n  return Array.isArray(supportedLanguages)\n    ? supportedLanguages.filter((lang) => !defaultLanguages?.includes(lang.id))\n    : []\n}\n\nexport function useSelectedLanguageIds(\n  options: LanguageFilterConfig,\n): [string[], (ids: string[]) => void] {\n  return useState(() => [...(options.defaultLanguages ?? []), ...getPersistedLanguageIds(options)])\n}\n","import {createContext, useContext, useEffect, useMemo, useState} from 'react'\nimport {type LayoutProps, useClient} from 'sanity'\n\nimport {defaultFilterField} from './filterField'\nimport type {\n  Language,\n  LanguageCallback,\n  LanguageFilterConfig,\n  LanguageFilterConfigProcessed,\n} from './types'\nimport {useSelectedLanguageIds} from './useSelectedLanguageIds'\n\nexport interface LanguageFilterStudioContextProps {\n  // eslint-disable-next-line react/require-default-props\n  options: Required<LanguageFilterConfig>\n}\n\nexport interface LanguageFilterStudioContextProcessed {\n  options: Required<LanguageFilterConfigProcessed>\n}\n\nexport interface LanguageFilterStudioContextValue extends LanguageFilterStudioContextProcessed {\n  selectedLanguageIds: string[]\n  setSelectedLanguageIds: (ids: string[]) => void\n}\n\nexport const defaultContextValue: LanguageFilterStudioContextValue = {\n  options: {\n    apiVersion: '2022-11-27',\n    supportedLanguages: [],\n    defaultLanguages: [],\n    documentTypes: [],\n    filterField: defaultFilterField,\n  },\n  selectedLanguageIds: [],\n  setSelectedLanguageIds: () => console.error('LanguageFilterStudioContext not initialized'),\n}\n\nconst LanguageFilterStudioContext =\n  createContext<LanguageFilterStudioContextValue>(defaultContextValue)\n\n/**\n * This is a separate Provider from the Context that wraps the document pane\n * but it used to listen to changes to the selected language IDs inside it\n * and provide them to a Studio-wide context\n */\nexport function LanguageFilterStudioProvider(\n  props: LayoutProps & LanguageFilterStudioContextProps,\n) {\n  const client = useClient({apiVersion: '2023-01-01'})\n  const [languages, setLanguages] = useState<Language[]>(\n    Array.isArray(props.options.supportedLanguages) ? props.options.supportedLanguages : [],\n  )\n  useEffect(() => {\n    let asyncLanguages: Language[] = []\n\n    async function getLanguages(supportedLanguagesCallback: LanguageCallback) {\n      asyncLanguages = await supportedLanguagesCallback(client, {})\n      setLanguages(asyncLanguages)\n    }\n\n    if (!Array.isArray(props.options.supportedLanguages)) {\n      getLanguages(props.options.supportedLanguages)\n    }\n  }, [client, props.options.supportedLanguages])\n\n  const options = useMemo<Required<LanguageFilterConfigProcessed>>(() => {\n    return {\n      ...defaultContextValue.options,\n      ...props.options,\n      supportedLanguages: languages,\n    }\n  }, [props.options, languages])\n\n  const [selectedLanguageIds, setSelectedLanguageIds] = useSelectedLanguageIds(options)\n\n  return (\n    <LanguageFilterStudioContext.Provider\n      value={{options, selectedLanguageIds, setSelectedLanguageIds}}\n    >\n      {props.renderDefault(props)}\n    </LanguageFilterStudioContext.Provider>\n  )\n}\n\n/**\n * Retrieves plugin options and the currently selected\n * language IDs from anywhere in the Studio\n */\nexport function useLanguageFilterStudioContext() {\n  return useContext(LanguageFilterStudioContext)\n}\n","import {useCallback, useMemo} from 'react'\n\nimport {useLanguageFilterStudioContext} from './LanguageFilterStudioContext'\nimport {getSelectableLanguages, persistLanguageIds} from './useSelectedLanguageIds'\n\nconst unique = (arr: string[]) => Array.from(new Set(arr))\n\nexport function usePaneLanguages(): {\n  activeLanguages: string[]\n  allSelected: boolean\n  selectAll: () => void\n  selectNone: () => void\n  toggleLanguage: (languageId: string) => void\n} {\n  const {selectedLanguageIds, setSelectedLanguageIds, options} = useLanguageFilterStudioContext()\n  const {defaultLanguages = []} = options\n\n  const selectableLanguages = useMemo(() => getSelectableLanguages(options), [options])\n\n  const updateSelectedIds = useCallback(\n    (ids: string[]) => {\n      setSelectedLanguageIds(unique([...defaultLanguages, ...ids]))\n      persistLanguageIds(unique([...defaultLanguages, ...ids]))\n    },\n    [defaultLanguages, setSelectedLanguageIds],\n  )\n\n  const selectAll = useCallback(\n    () => updateSelectedIds(selectableLanguages.map((l) => l.id)),\n    [updateSelectedIds, selectableLanguages],\n  )\n\n  const selectNone = useCallback(() => {\n    updateSelectedIds(defaultLanguages)\n  }, [defaultLanguages, updateSelectedIds])\n\n  const toggleLanguage = useCallback(\n    (languageId: string) => {\n      let lang = selectedLanguageIds\n\n      if (lang.includes(languageId)) {\n        lang = lang.filter((l) => l !== languageId)\n      } else {\n        lang = unique([...lang, languageId])\n      }\n\n      updateSelectedIds(lang)\n    },\n    [updateSelectedIds, selectedLanguageIds],\n  )\n\n  const activeLanguages = useMemo(\n    () => unique([...(defaultLanguages ?? []), ...selectedLanguageIds]),\n    [defaultLanguages, selectedLanguageIds],\n  )\n\n  return {\n    activeLanguages,\n    allSelected:\n      selectedLanguageIds.length === selectableLanguages.length + defaultLanguages.length,\n    selectAll,\n    selectNone,\n    toggleLanguage,\n  }\n}\n","import {\n  CheckmarkCircleIcon,\n  CircleIcon,\n  EyeClosedIcon,\n  EyeOpenIcon,\n  TranslateIcon,\n} from '@sanity/icons'\nimport {\n  Badge,\n  Box,\n  Button,\n  Card,\n  Flex,\n  Popover,\n  Stack,\n  Text,\n  TextInput,\n  useClickOutside,\n} from '@sanity/ui'\nimport {type FormEvent, type MouseEventHandler, useCallback, useState} from 'react'\nimport {TextWithTone} from 'sanity'\nimport {styled} from 'styled-components'\n\nimport {useLanguageFilterStudioContext} from './LanguageFilterStudioContext'\nimport {usePaneLanguages} from './usePaneLanguages'\n\nconst StyledBox = styled(Box)`\n  max-height: calc(100vh - 200px);\n`\n\nexport function LanguageFilterMenuButton() {\n  const {options} = useLanguageFilterStudioContext()\n\n  const defaultLanguages = options.supportedLanguages.filter((l) =>\n    options.defaultLanguages?.includes(l.id),\n  )\n\n  const languageOptions = options.supportedLanguages.filter(\n    (l) => !options.defaultLanguages?.includes(l.id),\n  )\n  const [open, setOpen] = useState(false)\n  const {activeLanguages, allSelected, selectAll, selectNone, toggleLanguage} = usePaneLanguages()\n  const [button, setButton] = useState<HTMLElement | null>(null)\n  const [popover, setPopover] = useState<HTMLElement | null>(null)\n\n  const handleToggleAll: MouseEventHandler<HTMLButtonElement> = useCallback(\n    (event) => {\n      const checked = event.currentTarget.value === 'ALL'\n\n      if (checked) {\n        selectAll()\n      } else {\n        selectNone()\n      }\n    },\n    [selectAll, selectNone],\n  )\n\n  const handleClick = useCallback(() => setOpen((o) => !o), [])\n\n  const handleClickOutside = useCallback(() => setOpen(false), [])\n\n  useClickOutside(handleClickOutside, [button, popover])\n\n  const langCount = options.supportedLanguages.length\n\n  // Search filter query\n  const [query, setQuery] = useState('')\n  const handleQuery = useCallback((event: FormEvent<HTMLInputElement>) => {\n    if (event.currentTarget.value) {\n      setQuery(event.currentTarget.value)\n    } else {\n      setQuery('')\n    }\n  }, [])\n\n  const showSearch = langCount > 4\n\n  const content = (\n    <StyledBox overflow=\"auto\">\n      <Stack padding={1} space={1}>\n        {defaultLanguages.length > 0 && (\n          <>\n            {defaultLanguages.map((l) => (\n              <LanguageFilterOption key={l.id} id={l.id} title={l.title} selected />\n            ))}\n            <Card borderTop />\n          </>\n        )}\n\n        <Button\n          mode=\"bleed\"\n          onClick={handleToggleAll}\n          justify=\"flex-start\"\n          value={allSelected ? 'NONE' : 'ALL'}\n          disabled={!!query}\n        >\n          <Flex gap={3} align=\"center\">\n            <Text size={2}>\n              {allSelected ? (\n                <TextWithTone tone=\"primary\">\n                  <EyeClosedIcon />\n                </TextWithTone>\n              ) : (\n                <EyeOpenIcon />\n              )}\n            </Text>\n            <Box flex={1}>\n              <Text>{allSelected ? 'Hide all' : 'Show all'}</Text>\n            </Box>\n          </Flex>\n        </Button>\n\n        {showSearch ? (\n          <TextInput onChange={handleQuery} value={query} placeholder=\"Filter languages\" />\n        ) : (\n          <Card borderTop />\n        )}\n\n        {languageOptions\n          .filter((language) => {\n            if (query) {\n              return language.title.toLowerCase().includes(query.toLowerCase())\n            }\n            return true\n          })\n          .map((lang) => (\n            <LanguageFilterOption\n              id={lang.id}\n              key={lang.id}\n              onToggle={toggleLanguage}\n              selected={activeLanguages.includes(lang.id)}\n              title={lang.title}\n            />\n          ))}\n      </Stack>\n    </StyledBox>\n  )\n\n  const buttonText =\n    activeLanguages.length === langCount\n      ? 'Showing all'\n      : `Showing ${activeLanguages.length} / ${langCount}`\n  return (\n    <Popover animate content={content} open={open} portal ref={setPopover}>\n      <Button\n        text={buttonText}\n        icon={TranslateIcon}\n        mode=\"bleed\"\n        onClick={handleClick}\n        ref={setButton}\n        selected={open}\n      />\n    </Popover>\n  )\n}\n\nfunction LanguageFilterOption(props: {\n  id: string\n  selected: boolean\n  title: string\n  // eslint-disable-next-line react/require-default-props\n  onToggle?: (id: string) => void\n}) {\n  const {id, onToggle, selected, title} = props\n\n  const handleChange = useCallback(() => {\n    if (onToggle) {\n      onToggle(id)\n    }\n  }, [id, onToggle])\n\n  const disabled = !onToggle\n\n  return (\n    <Button mode=\"bleed\" onClick={handleChange} justify=\"flex-start\" disabled={disabled}>\n      <Flex gap={3} align=\"center\">\n        <Text size={2}>\n          {selected ? (\n            <TextWithTone tone={disabled ? 'default' : 'positive'}>\n              <CheckmarkCircleIcon />\n            </TextWithTone>\n          ) : (\n            <CircleIcon />\n          )}\n        </Text>\n        <Box flex={1}>\n          <Text>{title}</Text>\n        </Box>\n        <Badge>{id}</Badge>\n      </Flex>\n    </Button>\n  )\n}\n","import {useMemo} from 'react'\nimport {type ObjectInputProps, type ObjectMember, useFormValue, useSchema} from 'sanity'\n\nimport {isLanguageFilterEnabled} from './filterField'\nimport {useLanguageFilterStudioContext} from './LanguageFilterStudioContext'\n\n// First check that this Object is in a schema type for which language-filter is enabled\nexport function FilteredObjectWrapper(props: ObjectInputProps) {\n  const {options} = useLanguageFilterStudioContext()\n\n  const documentType = useFormValue(['_type']) as string\n  const schema = useSchema()\n  const languageFilterEnabled = isLanguageFilterEnabled(schema.get(documentType), options)\n  return languageFilterEnabled ? <FilteredObjectInput {...props} /> : props.renderDefault(props)\n}\n\n// Modify the object members based on selected languages in the filter\nexport function FilteredObjectInput(props: ObjectInputProps) {\n  const {members: membersProp, schemaType, renderDefault, ...restProps} = props\n  const {selectedLanguageIds, options} = useLanguageFilterStudioContext()\n  const {filterField} = options\n  const parentValue = props.value\n\n  const members: ObjectMember[] = useMemo(() => {\n    return membersProp\n      .filter((member) => {\n        return (\n          (member.kind === 'field' &&\n            filterField(schemaType, member, selectedLanguageIds, parentValue)) ||\n          member.kind === 'fieldSet' ||\n          member.kind === 'error'\n        )\n      })\n      .map((member) => {\n        if (member.kind === 'fieldSet') {\n          return {\n            ...member,\n            fieldSet: {\n              ...member.fieldSet,\n              members: member.fieldSet.members.filter((fieldsetMember) => {\n                return (\n                  fieldsetMember.kind === 'field' &&\n                  filterField(schemaType, fieldsetMember, selectedLanguageIds, parentValue)\n                )\n              }),\n            },\n          }\n        }\n        return member\n      })\n  }, [schemaType, membersProp, filterField, selectedLanguageIds, parentValue])\n\n  return renderDefault({...restProps, members, schemaType, renderDefault})\n}\n","import {\n  definePlugin,\n  type DocumentLanguageFilterComponent,\n  isObjectSchemaType,\n  type ObjectInputProps,\n} from 'sanity'\n\nimport {isLanguageFilterEnabled} from './filterField'\nimport {LanguageFilterMenuButton} from './LanguageFilterMenuButton'\nimport {FilteredObjectWrapper} from './LanguageFilterObjectInput'\nimport {defaultContextValue, LanguageFilterStudioProvider} from './LanguageFilterStudioContext'\nimport type {LanguageFilterConfig} from './types'\n\n/**\n * ## Usage in sanity.config.ts (or .js)\n *\n * ```\n * import {defineConfig} from 'sanity'\n * import {languageFilter} from '@sanity/language-filter'\n *\n * export const defineConfig({\n *     /...\n *     plugins: [\n *         languageFilter({\n *             supportedLanguages: [\n *               {id: 'nb', title: 'Norwegian (Bokmål)'},\n *               {id: 'nn', title: 'Norwegian (Nynorsk)'},\n *               {id: 'en', title: 'English'},\n *               {id: 'es', title: 'Spanish'},\n *               {id: 'arb', title: 'Arabic'},\n *               {id: 'pt', title: 'Portuguese'},\n *               //...\n *             ],\n *             // Select Norwegian (Bokmål) by default\n *             defaultLanguages: ['nb'],\n *             // Only show language filter for document type `page` (schemaType.name)\n *             // Can also enable via document-options: options.languageFilter: true\n *             documentTypes: ['page'],\n *             // default filter function shown\n *             filterField: (enclosingType, field, selectedLanguageIds) =>\n *               !enclosingType.name.startsWith('locale') || selectedLanguageIds.includes(field.name),\n *        })\n *    ]\n * })\n * ```\n */\nexport const languageFilter = definePlugin<LanguageFilterConfig>((options) => {\n  const RenderLanguageFilter: DocumentLanguageFilterComponent = () => {\n    return <LanguageFilterMenuButton />\n  }\n\n  const pluginOptions = {\n    ...defaultContextValue.options,\n    ...options,\n  }\n\n  return {\n    name: '@sanity/language-filter',\n    studio: {\n      components: {\n        layout: (props) => LanguageFilterStudioProvider({...props, options: pluginOptions}),\n      },\n    },\n\n    document: {\n      unstable_languageFilter: (prev, {schemaType, schema}) => {\n        if (isLanguageFilterEnabled(schema.get(schemaType), options)) {\n          return [...prev, RenderLanguageFilter]\n        }\n        return prev\n      },\n    },\n\n    form: {\n      components: {\n        input: (props) => {\n          if (props.id !== 'root' && isObjectSchemaType(props.schemaType)) {\n            return FilteredObjectWrapper(props as ObjectInputProps)\n          }\n\n          return props.renderDefault(props)\n        },\n      },\n    },\n  }\n})\n"]}