({
defaultValue,
fallbackValue,
cookieKey,
queryStringKey,
onValue,
preferenceName,
options,
ariaLabel,
}: Props)
| 21 | ariaLabel: string |
| 22 | } |
| 23 | export const InArticlePicker = ({ |
| 24 | defaultValue, |
| 25 | fallbackValue, |
| 26 | cookieKey, |
| 27 | queryStringKey, |
| 28 | onValue, |
| 29 | preferenceName, |
| 30 | options, |
| 31 | ariaLabel, |
| 32 | }: Props) => { |
| 33 | const router = useRouter() |
| 34 | const { query, locale } = router |
| 35 | const [currentValue, setCurrentValue] = useState('') |
| 36 | |
| 37 | // Run on mount for client-side only features |
| 38 | useEffect(() => { |
| 39 | const raw = query[queryStringKey] |
| 40 | let value = '' |
| 41 | if (raw) { |
| 42 | if (Array.isArray(raw)) value = raw[0] |
| 43 | else value = raw |
| 44 | } |
| 45 | // Only pick it up from the possible query string if its value |
| 46 | // is a valid option. |
| 47 | const possibleValues = options.map((option) => option.value) |
| 48 | if (!value || !possibleValues.includes(value)) { |
| 49 | const cookieValue = Cookies.get(cookieKey) |
| 50 | if (defaultValue) { |
| 51 | value = defaultValue |
| 52 | } else if (cookieValue && possibleValues.includes(cookieValue)) { |
| 53 | value = cookieValue |
| 54 | } else { |
| 55 | value = fallbackValue |
| 56 | } |
| 57 | } |
| 58 | setCurrentValue(value) |
| 59 | }, [query, fallbackValue, defaultValue, options]) |
| 60 | |
| 61 | const [asPathRoot, asPathQuery = ''] = router.asPath.split('#')[0].split('?') |
| 62 | |
| 63 | useEffect(() => { |
| 64 | // This will make the hook run this callback on mount and on change. |
| 65 | // That's important because even though the user hasn't interacted |
| 66 | // and made an overriding choice, we still want to run this callback |
| 67 | // because the page might need to be corrected based on *a* choice |
| 68 | // independent of whether it's a change. |
| 69 | if (currentValue) { |
| 70 | onValue(currentValue) |
| 71 | } |
| 72 | }, [ |
| 73 | currentValue, |
| 74 | // This is important because we can't otherwise rely on the firing |
| 75 | // of this effect on initial mount. It also needs to fire when the |
| 76 | // URL (i.e. route) changes. |
| 77 | // Don't use `router.asPath` because that contains the query string |
| 78 | // which we handle in the other useEffect above. |
| 79 | asPathRoot, |
| 80 | ]) |
nothing calls this directly
no test coverage detected