UNPKG

@grafana/ui

Version:
138 lines (135 loc) 4.11 kB
import { jsx } from 'react/jsx-runtime'; import { isString, toLower, isEmpty } from 'lodash'; import { useCallback, useMemo } from 'react'; import { getTimeZoneGroups, getTimeZoneInfo, InternalTimeZones } from '@grafana/data'; import { t } from '@grafana/i18n'; import { Select } from '../Select/Select.mjs'; import { TimeZoneGroup } from './TimeZonePicker/TimeZoneGroup.mjs'; import { formatUtcOffset } from './TimeZonePicker/TimeZoneOffset.mjs'; import { CompactTimeZoneOption, WideTimeZoneOption } from './TimeZonePicker/TimeZoneOption.mjs'; const TimeZonePicker = (props) => { const { onChange, width, autoFocus = false, onBlur, value, includeInternal = false, disabled = false, inputId, menuShouldPortal = true, openMenuOnFocus = true } = props; const groupedTimeZones = useTimeZones(includeInternal); const selected = useSelectedTimeZone(groupedTimeZones, value); const filterBySearchIndex = useFilterBySearchIndex(); const TimeZoneOption = width && width <= 45 ? CompactTimeZoneOption : WideTimeZoneOption; const onChangeTz = useCallback( (selectable) => { if (!selectable || !isString(selectable.value)) { return onChange(value); } onChange(selectable.value); }, [onChange, value] ); return /* @__PURE__ */ jsx( Select, { inputId, value: selected, placeholder: t("time-picker.zone.select-search-input", "Type to search (country, city, abbreviation)"), autoFocus, menuShouldPortal, openMenuOnFocus, width, filterOption: filterBySearchIndex, options: groupedTimeZones, onChange: onChangeTz, onBlur, components: { Option: TimeZoneOption, Group: TimeZoneGroup }, disabled, "aria-label": t("time-picker.zone.select-aria-label", "Time zone picker") } ); }; const useTimeZones = (includeInternal) => { const now = Date.now(); const timeZoneGroups = useMemo(() => { return getTimeZoneGroups(includeInternal).map((group) => { const options = group.zones.reduce((options2, zone) => { const info = getTimeZoneInfo(zone, now); if (!info) { return options2; } const name = info.name.replace(/_/g, " "); options2.push({ label: name, value: info.zone, searchIndex: getSearchIndex(name, info, now) }); return options2; }, []); return { label: group.name, options }; }); }, [includeInternal, now]); return timeZoneGroups; }; const useSelectedTimeZone = (groups, timeZone) => { return useMemo(() => { if (timeZone === void 0) { return void 0; } const tz = toLower(timeZone); const group = groups.find((group2) => { if (!group2.label) { return isInternal(tz); } return tz.startsWith(toLower(group2.label)); }); return group == null ? void 0 : group.options.find((option) => { if (isEmpty(tz)) { return option.value === InternalTimeZones.default; } return toLower(option.value) === tz; }); }, [groups, timeZone]); }; const isInternal = (timeZone) => { switch (timeZone) { case InternalTimeZones.default: case InternalTimeZones.localBrowserTime: case InternalTimeZones.utc: return true; default: return false; } }; const useFilterBySearchIndex = () => { return useCallback((option, searchQuery) => { if (!searchQuery || !option.data || !option.data.searchIndex) { return true; } return option.data.searchIndex.indexOf(toLower(searchQuery)) > -1; }, []); }; const getSearchIndex = (label, info, timestamp) => { const parts = [ toLower(info.zone), toLower(info.abbreviation), toLower(formatUtcOffset(timestamp, info.zone)) ]; if (label !== info.zone) { parts.push(toLower(label)); } for (const country of info.countries) { parts.push(toLower(country.name)); parts.push(toLower(country.code)); } return parts.join("|"); }; export { TimeZonePicker }; //# sourceMappingURL=TimeZonePicker.mjs.map