@perses-dev/components 0.55.0-beta.14 → 0.55.0-beta.15

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.
Files changed (57) hide show
  1. package/dist/DragAndDrop/DragAndDropList.d.ts +10 -2
  2. package/dist/DragAndDrop/DragAndDropList.d.ts.map +1 -1
  3. package/dist/DragAndDrop/DragAndDropList.js +6 -4
  4. package/dist/DragAndDrop/DragAndDropList.js.map +1 -1
  5. package/dist/EChart/EChart.d.ts +1 -1
  6. package/dist/EChart/EChart.d.ts.map +1 -1
  7. package/dist/EChart/EChart.js +12 -25
  8. package/dist/EChart/EChart.js.map +1 -1
  9. package/dist/Legend/TableLegend.js.map +1 -1
  10. package/dist/LinksEditor/LinkEditorForm.d.ts +1 -0
  11. package/dist/LinksEditor/LinkEditorForm.d.ts.map +1 -1
  12. package/dist/LinksEditor/LinkEditorForm.js +1 -0
  13. package/dist/LinksEditor/LinkEditorForm.js.map +1 -1
  14. package/dist/SettingsAutocomplete/SettingsAutocomplete.d.ts.map +1 -1
  15. package/dist/SettingsAutocomplete/SettingsAutocomplete.js +6 -3
  16. package/dist/SettingsAutocomplete/SettingsAutocomplete.js.map +1 -1
  17. package/dist/Table/Table.d.ts.map +1 -1
  18. package/dist/Table/Table.js +3 -0
  19. package/dist/Table/Table.js.map +1 -1
  20. package/dist/Table/TableToolbar.d.ts.map +1 -1
  21. package/dist/Table/TableToolbar.js +1 -0
  22. package/dist/Table/TableToolbar.js.map +1 -1
  23. package/dist/Table/VirtualizedTable.d.ts +1 -1
  24. package/dist/Table/VirtualizedTable.d.ts.map +1 -1
  25. package/dist/Table/VirtualizedTable.js +10 -19
  26. package/dist/Table/VirtualizedTable.js.map +1 -1
  27. package/dist/Table/model/table-model.d.ts +6 -2
  28. package/dist/Table/model/table-model.d.ts.map +1 -1
  29. package/dist/Table/model/table-model.js.map +1 -1
  30. package/dist/ThresholdsEditor/ThresholdsEditor.js +1 -3
  31. package/dist/ThresholdsEditor/ThresholdsEditor.js.map +1 -1
  32. package/dist/TimeRangeSelector/DateTimeRangePicker.js +1 -1
  33. package/dist/TimeRangeSelector/DateTimeRangePicker.js.map +1 -1
  34. package/dist/TimeRangeSelector/TimeRangeSelector.js +4 -4
  35. package/dist/TimeRangeSelector/TimeRangeSelector.js.map +1 -1
  36. package/dist/TimeSeriesTooltip/TimeChartTooltip.d.ts.map +1 -1
  37. package/dist/TimeSeriesTooltip/TimeChartTooltip.js +27 -16
  38. package/dist/TimeSeriesTooltip/TimeChartTooltip.js.map +1 -1
  39. package/dist/controls/TextField.d.ts.map +1 -1
  40. package/dist/controls/TextField.js +15 -10
  41. package/dist/controls/TextField.js.map +1 -1
  42. package/dist/utils/component-ids.d.ts +1 -6
  43. package/dist/utils/component-ids.d.ts.map +1 -1
  44. package/dist/utils/component-ids.js +5 -12
  45. package/dist/utils/component-ids.js.map +1 -1
  46. package/dist/utils/index.d.ts +0 -1
  47. package/dist/utils/index.d.ts.map +1 -1
  48. package/dist/utils/index.js +0 -1
  49. package/dist/utils/index.js.map +1 -1
  50. package/dist/utils/text.d.ts.map +1 -1
  51. package/dist/utils/text.js +14 -18
  52. package/dist/utils/text.js.map +1 -1
  53. package/package.json +2 -2
  54. package/dist/utils/memo.d.ts +0 -13
  55. package/dist/utils/memo.d.ts.map +0 -1
  56. package/dist/utils/memo.js +0 -50
  57. package/dist/utils/memo.js.map +0 -1
@@ -15,7 +15,7 @@ import { Box, MenuItem, Popover, Select, IconButton, TextField, Stack } from "@m
15
15
  import { isRelativeTimeRange, toAbsoluteTimeRange } from "@perses-dev/spec";
16
16
  import Calendar from "mdi-material-ui/Calendar";
17
17
  import EarthIcon from "mdi-material-ui/Earth";
18
- import { useMemo, useRef, useState } from "react";
18
+ import { useMemo, useState } from "react";
19
19
  import { useTimeZone } from "../context/index.js";
20
20
  import { getTimeZoneOptions } from "../model/timeZoneOption.js";
21
21
  import { SettingsAutocomplete } from "../SettingsAutocomplete/index.js";
@@ -30,7 +30,7 @@ import { buildCustomTimeOption, formatTimeRange } from "./utils.js";
30
30
  */ export function TimeRangeSelector({ value, timeOptions, onChange, height, showCustomTimeRange = true, timeZone: timeZoneProp, timeZoneOptions, onTimeZoneChange }) {
31
31
  const { timeZone: ctxTimeZone } = useTimeZone();
32
32
  const timeZone = timeZoneProp ?? ctxTimeZone;
33
- const anchorEl = useRef();
33
+ const [anchorEl, setAnchorEl] = useState(null);
34
34
  const [showCustomDateSelector, setShowCustomDateSelector] = useState(false);
35
35
  const convertedTimeRange = useMemo(()=>{
36
36
  return isRelativeTimeRange(value) ? toAbsoluteTimeRange(value) : value;
@@ -98,7 +98,7 @@ import { buildCustomTimeOption, formatTimeRange } from "./utils.js";
98
98
  })
99
99
  }),
100
100
  /*#__PURE__*/ _jsx(Popover, {
101
- anchorEl: anchorEl.current,
101
+ anchorEl: anchorEl,
102
102
  anchorOrigin: {
103
103
  vertical: 'bottom',
104
104
  horizontal: 'center'
@@ -120,7 +120,7 @@ import { buildCustomTimeOption, formatTimeRange } from "./utils.js";
120
120
  })
121
121
  }),
122
122
  /*#__PURE__*/ _jsx(Box, {
123
- ref: anchorEl,
123
+ ref: setAnchorEl,
124
124
  children: /*#__PURE__*/ _jsxs(Select, {
125
125
  open: open,
126
126
  value: formatTimeRange(value, timeZone),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/TimeRangeSelector/TimeRangeSelector.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Box, MenuItem, Popover, Select, IconButton, TextField, Stack } from '@mui/material';\nimport type { TimeRangeValue, AbsoluteTimeRange } from '@perses-dev/spec';\nimport { isRelativeTimeRange, toAbsoluteTimeRange } from '@perses-dev/spec';\nimport Calendar from 'mdi-material-ui/Calendar';\nimport EarthIcon from 'mdi-material-ui/Earth';\nimport type { ReactElement } from 'react';\nimport { useMemo, useRef, useState } from 'react';\n\nimport { useTimeZone } from '../context';\nimport type { TimeOption } from '../model';\nimport type { TimeZoneOption } from '../model/timeZoneOption';\nimport { getTimeZoneOptions } from '../model/timeZoneOption';\nimport { SettingsAutocomplete } from '../SettingsAutocomplete';\nimport { getGMTOffset } from '../utils/format';\nimport { DateTimeRangePicker } from './DateTimeRangePicker';\nimport { buildCustomTimeOption, formatTimeRange } from './utils';\n\ninterface TimeRangeSelectorProps {\n /**\n * The current value of the time range.\n */\n value: TimeRangeValue;\n /**\n * The list of time options to display in the dropdown.\n * The component will automatically add the last two options as a zoom out x2 and a custom absolute time range.\n */\n timeOptions: TimeOption[];\n /**\n * The callback to call when the time range changes.\n */\n onChange: (value: TimeRangeValue) => void;\n /**\n * Custom line height for the select component.\n */\n height?: string;\n /**\n * Whether to show the custom time range option.\n * Defaults to true.\n */\n showCustomTimeRange?: boolean;\n /** Optional explicit timezone and change handler to enable changing tz from the selector */\n timeZone?: string;\n timeZoneOptions?: TimeZoneOption[];\n onTimeZoneChange?: (timeZone: TimeZoneOption) => void;\n}\n\n/**\n * Date & time selection component to customize what data renders on dashboard.\n * This includes relative shortcuts and the ability to pick absolute start and end times.\n * @param props\n * @constructor\n */\nexport function TimeRangeSelector({\n value,\n timeOptions,\n onChange,\n height,\n showCustomTimeRange = true,\n timeZone: timeZoneProp,\n timeZoneOptions,\n onTimeZoneChange,\n}: TimeRangeSelectorProps): ReactElement {\n const { timeZone: ctxTimeZone } = useTimeZone();\n const timeZone = timeZoneProp ?? ctxTimeZone;\n\n const anchorEl = useRef();\n const [showCustomDateSelector, setShowCustomDateSelector] = useState(false);\n\n const convertedTimeRange = useMemo(() => {\n return isRelativeTimeRange(value) ? toAbsoluteTimeRange(value) : value;\n }, [value]);\n\n const lastOption = useMemo(\n () => buildCustomTimeOption(isRelativeTimeRange(value) ? undefined : value, timeZone),\n [value, timeZone],\n );\n\n const [open, setOpen] = useState(false);\n const tzOptions = timeZoneOptions ?? getTimeZoneOptions();\n const [tzAnchorEl, setTzAnchorEl] = useState<HTMLElement | null>(null);\n const tzOpen = Boolean(tzAnchorEl);\n const tzLabel = tzOptions.find((o) => o.value === timeZone)?.display ?? timeZone;\n const tzOffset = getGMTOffset(timeZone);\n const localOffset = getGMTOffset('local');\n const tzAutocompleteOptions = tzOptions.map((o) => ({ id: o.value, label: o.display }));\n const tzAutocompleteValue = tzAutocompleteOptions.find((option) => option.id === timeZone);\n\n return (\n <>\n <Popover\n anchorEl={tzAnchorEl}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}\n transformOrigin={{ vertical: 'top', horizontal: 'right' }}\n open={tzOpen}\n onClose={() => setTzAnchorEl(null)}\n sx={(theme) => ({ padding: theme.spacing(1) })}\n >\n <Box\n sx={{ p: 1, minWidth: 260 }}\n onClick={(e) => {\n e.stopPropagation();\n }}\n >\n <SettingsAutocomplete\n options={tzAutocompleteOptions}\n value={tzAutocompleteValue}\n onChange={(_e, option) => {\n if (option) {\n const selected = tzOptions.find((o) => o.value === option.id);\n if (selected) onTimeZoneChange?.(selected);\n }\n setTzAnchorEl(null);\n }}\n disableClearable\n renderInput={(params) => <TextField {...params} placeholder=\"Search timezones\" size=\"small\" />}\n />\n </Box>\n </Popover>\n <Popover\n anchorEl={anchorEl.current}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}\n open={showCustomDateSelector}\n onClose={() => setShowCustomDateSelector(false)}\n sx={(theme) => ({ padding: theme.spacing(2) })}\n >\n <DateTimeRangePicker\n initialTimeRange={convertedTimeRange}\n onChange={(value: AbsoluteTimeRange) => {\n onChange(value);\n setShowCustomDateSelector(false);\n setOpen(false);\n }}\n onCancel={() => setShowCustomDateSelector(false)}\n timeZone={timeZone}\n />\n </Popover>\n <Box ref={anchorEl}>\n <Select\n open={open}\n value={formatTimeRange(value, timeZone)}\n onClick={() => setOpen(!open)}\n IconComponent={Calendar}\n renderValue={() => (\n <Stack direction=\"row\" alignItems=\"center\" spacing={1}>\n <span>\n {timeOptions.find((opt) => formatTimeRange(opt.value, timeZone) === formatTimeRange(value, timeZone))\n ?.display ?? formatTimeRange(value, timeZone)}\n </span>\n {tzOffset !== localOffset && (\n <Box sx={{ typography: 'caption', color: 'text.secondary' }}>· {tzOffset}</Box>\n )}\n </Stack>\n )}\n inputProps={{ 'aria-label': `Select time range. Currently set to ${value}` }}\n sx={{\n '.MuiSelect-icon': { marginTop: '1px', transform: 'none' },\n '.MuiSelect-select.MuiSelect-outlined.MuiInputBase-input': { paddingRight: '36px' },\n '.MuiSelect-select': height ? { lineHeight: height, paddingY: 0 } : {},\n }}\n >\n <MenuItem\n disableRipple\n onClick={(e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n }}\n sx={{ cursor: 'default', '&:hover': { backgroundColor: 'transparent' }, py: 0.5, px: 1 }}\n >\n <Box sx={{ display: 'flex', alignItems: 'center', width: '100%', justifyContent: 'space-between' }}>\n <Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-start' }}>\n <Box sx={{ typography: 'subtitle1' }}>Time Range</Box>\n <Box sx={{ color: 'text.secondary', typography: 'caption', mt: 0.25 }}>Timezone: {tzLabel}</Box>\n </Box>\n <Box sx={{ display: 'flex', alignItems: 'center', pr: 1, ml: 1.5 }}>\n <IconButton\n size=\"small\"\n aria-label=\"Select timezone\"\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n setTzAnchorEl(e.currentTarget);\n }}\n >\n <EarthIcon fontSize=\"small\" />\n </IconButton>\n </Box>\n </Box>\n </MenuItem>\n {timeOptions.map((item, idx) => (\n <MenuItem\n key={idx}\n value={formatTimeRange(item.value, timeZone)}\n onClick={() => {\n onChange(item.value);\n }}\n >\n {item.display}\n </MenuItem>\n ))}\n {showCustomTimeRange && (\n <MenuItem\n value={formatTimeRange(lastOption.value, timeZone)}\n onClick={() => setShowCustomDateSelector(true)}\n >\n {lastOption.display}\n </MenuItem>\n )}\n </Select>\n </Box>\n </>\n );\n}\n"],"names":["Box","MenuItem","Popover","Select","IconButton","TextField","Stack","isRelativeTimeRange","toAbsoluteTimeRange","Calendar","EarthIcon","useMemo","useRef","useState","useTimeZone","getTimeZoneOptions","SettingsAutocomplete","getGMTOffset","DateTimeRangePicker","buildCustomTimeOption","formatTimeRange","TimeRangeSelector","value","timeOptions","onChange","height","showCustomTimeRange","timeZone","timeZoneProp","timeZoneOptions","onTimeZoneChange","ctxTimeZone","anchorEl","showCustomDateSelector","setShowCustomDateSelector","convertedTimeRange","lastOption","undefined","open","setOpen","tzOptions","tzAnchorEl","setTzAnchorEl","tzOpen","Boolean","tzLabel","find","o","display","tzOffset","localOffset","tzAutocompleteOptions","map","id","label","tzAutocompleteValue","option","anchorOrigin","vertical","horizontal","transformOrigin","onClose","sx","theme","padding","spacing","p","minWidth","onClick","e","stopPropagation","options","_e","selected","disableClearable","renderInput","params","placeholder","size","current","initialTimeRange","onCancel","ref","IconComponent","renderValue","direction","alignItems","span","opt","typography","color","inputProps","marginTop","transform","paddingRight","lineHeight","paddingY","disableRipple","preventDefault","cursor","backgroundColor","py","px","width","justifyContent","flexDirection","mt","pr","ml","aria-label","currentTarget","fontSize","item","idx"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/TimeRangeSelector/TimeRangeSelector.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Box, MenuItem, Popover, Select, IconButton, TextField, Stack } from '@mui/material';\nimport type { TimeRangeValue, AbsoluteTimeRange } from '@perses-dev/spec';\nimport { isRelativeTimeRange, toAbsoluteTimeRange } from '@perses-dev/spec';\nimport Calendar from 'mdi-material-ui/Calendar';\nimport EarthIcon from 'mdi-material-ui/Earth';\nimport type { ReactElement } from 'react';\nimport { useMemo, useState } from 'react';\n\nimport { useTimeZone } from '../context';\nimport type { TimeOption } from '../model';\nimport type { TimeZoneOption } from '../model/timeZoneOption';\nimport { getTimeZoneOptions } from '../model/timeZoneOption';\nimport { SettingsAutocomplete } from '../SettingsAutocomplete';\nimport { getGMTOffset } from '../utils/format';\nimport { DateTimeRangePicker } from './DateTimeRangePicker';\nimport { buildCustomTimeOption, formatTimeRange } from './utils';\n\ninterface TimeRangeSelectorProps {\n /**\n * The current value of the time range.\n */\n value: TimeRangeValue;\n /**\n * The list of time options to display in the dropdown.\n * The component will automatically add the last two options as a zoom out x2 and a custom absolute time range.\n */\n timeOptions: TimeOption[];\n /**\n * The callback to call when the time range changes.\n */\n onChange: (value: TimeRangeValue) => void;\n /**\n * Custom line height for the select component.\n */\n height?: string;\n /**\n * Whether to show the custom time range option.\n * Defaults to true.\n */\n showCustomTimeRange?: boolean;\n /** Optional explicit timezone and change handler to enable changing tz from the selector */\n timeZone?: string;\n timeZoneOptions?: TimeZoneOption[];\n onTimeZoneChange?: (timeZone: TimeZoneOption) => void;\n}\n\n/**\n * Date & time selection component to customize what data renders on dashboard.\n * This includes relative shortcuts and the ability to pick absolute start and end times.\n * @param props\n * @constructor\n */\nexport function TimeRangeSelector({\n value,\n timeOptions,\n onChange,\n height,\n showCustomTimeRange = true,\n timeZone: timeZoneProp,\n timeZoneOptions,\n onTimeZoneChange,\n}: TimeRangeSelectorProps): ReactElement {\n const { timeZone: ctxTimeZone } = useTimeZone();\n const timeZone = timeZoneProp ?? ctxTimeZone;\n\n const [anchorEl, setAnchorEl] = useState<HTMLDivElement | null>(null);\n const [showCustomDateSelector, setShowCustomDateSelector] = useState(false);\n\n const convertedTimeRange = useMemo(() => {\n return isRelativeTimeRange(value) ? toAbsoluteTimeRange(value) : value;\n }, [value]);\n\n const lastOption = useMemo(\n () => buildCustomTimeOption(isRelativeTimeRange(value) ? undefined : value, timeZone),\n [value, timeZone],\n );\n\n const [open, setOpen] = useState(false);\n const tzOptions = timeZoneOptions ?? getTimeZoneOptions();\n const [tzAnchorEl, setTzAnchorEl] = useState<HTMLElement | null>(null);\n const tzOpen = Boolean(tzAnchorEl);\n const tzLabel = tzOptions.find((o) => o.value === timeZone)?.display ?? timeZone;\n const tzOffset = getGMTOffset(timeZone);\n const localOffset = getGMTOffset('local');\n const tzAutocompleteOptions = tzOptions.map((o) => ({ id: o.value, label: o.display }));\n const tzAutocompleteValue = tzAutocompleteOptions.find((option) => option.id === timeZone);\n\n return (\n <>\n <Popover\n anchorEl={tzAnchorEl}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}\n transformOrigin={{ vertical: 'top', horizontal: 'right' }}\n open={tzOpen}\n onClose={() => setTzAnchorEl(null)}\n sx={(theme) => ({ padding: theme.spacing(1) })}\n >\n <Box\n sx={{ p: 1, minWidth: 260 }}\n onClick={(e) => {\n e.stopPropagation();\n }}\n >\n <SettingsAutocomplete\n options={tzAutocompleteOptions}\n value={tzAutocompleteValue}\n onChange={(_e, option) => {\n if (option) {\n const selected = tzOptions.find((o) => o.value === option.id);\n if (selected) onTimeZoneChange?.(selected);\n }\n setTzAnchorEl(null);\n }}\n disableClearable\n renderInput={(params) => <TextField {...params} placeholder=\"Search timezones\" size=\"small\" />}\n />\n </Box>\n </Popover>\n <Popover\n anchorEl={anchorEl}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}\n open={showCustomDateSelector}\n onClose={() => setShowCustomDateSelector(false)}\n sx={(theme) => ({ padding: theme.spacing(2) })}\n >\n <DateTimeRangePicker\n initialTimeRange={convertedTimeRange}\n onChange={(value: AbsoluteTimeRange) => {\n onChange(value);\n setShowCustomDateSelector(false);\n setOpen(false);\n }}\n onCancel={() => setShowCustomDateSelector(false)}\n timeZone={timeZone}\n />\n </Popover>\n <Box ref={setAnchorEl}>\n <Select\n open={open}\n value={formatTimeRange(value, timeZone)}\n onClick={() => setOpen(!open)}\n IconComponent={Calendar}\n renderValue={() => (\n <Stack direction=\"row\" alignItems=\"center\" spacing={1}>\n <span>\n {timeOptions.find((opt) => formatTimeRange(opt.value, timeZone) === formatTimeRange(value, timeZone))\n ?.display ?? formatTimeRange(value, timeZone)}\n </span>\n {tzOffset !== localOffset && (\n <Box sx={{ typography: 'caption', color: 'text.secondary' }}>· {tzOffset}</Box>\n )}\n </Stack>\n )}\n inputProps={{ 'aria-label': `Select time range. Currently set to ${value}` }}\n sx={{\n '.MuiSelect-icon': { marginTop: '1px', transform: 'none' },\n '.MuiSelect-select.MuiSelect-outlined.MuiInputBase-input': { paddingRight: '36px' },\n '.MuiSelect-select': height ? { lineHeight: height, paddingY: 0 } : {},\n }}\n >\n <MenuItem\n disableRipple\n onClick={(e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n }}\n sx={{ cursor: 'default', '&:hover': { backgroundColor: 'transparent' }, py: 0.5, px: 1 }}\n >\n <Box sx={{ display: 'flex', alignItems: 'center', width: '100%', justifyContent: 'space-between' }}>\n <Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-start' }}>\n <Box sx={{ typography: 'subtitle1' }}>Time Range</Box>\n <Box sx={{ color: 'text.secondary', typography: 'caption', mt: 0.25 }}>Timezone: {tzLabel}</Box>\n </Box>\n <Box sx={{ display: 'flex', alignItems: 'center', pr: 1, ml: 1.5 }}>\n <IconButton\n size=\"small\"\n aria-label=\"Select timezone\"\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n setTzAnchorEl(e.currentTarget);\n }}\n >\n <EarthIcon fontSize=\"small\" />\n </IconButton>\n </Box>\n </Box>\n </MenuItem>\n {timeOptions.map((item, idx) => (\n <MenuItem\n key={idx}\n value={formatTimeRange(item.value, timeZone)}\n onClick={() => {\n onChange(item.value);\n }}\n >\n {item.display}\n </MenuItem>\n ))}\n {showCustomTimeRange && (\n <MenuItem\n value={formatTimeRange(lastOption.value, timeZone)}\n onClick={() => setShowCustomDateSelector(true)}\n >\n {lastOption.display}\n </MenuItem>\n )}\n </Select>\n </Box>\n </>\n );\n}\n"],"names":["Box","MenuItem","Popover","Select","IconButton","TextField","Stack","isRelativeTimeRange","toAbsoluteTimeRange","Calendar","EarthIcon","useMemo","useState","useTimeZone","getTimeZoneOptions","SettingsAutocomplete","getGMTOffset","DateTimeRangePicker","buildCustomTimeOption","formatTimeRange","TimeRangeSelector","value","timeOptions","onChange","height","showCustomTimeRange","timeZone","timeZoneProp","timeZoneOptions","onTimeZoneChange","ctxTimeZone","anchorEl","setAnchorEl","showCustomDateSelector","setShowCustomDateSelector","convertedTimeRange","lastOption","undefined","open","setOpen","tzOptions","tzAnchorEl","setTzAnchorEl","tzOpen","Boolean","tzLabel","find","o","display","tzOffset","localOffset","tzAutocompleteOptions","map","id","label","tzAutocompleteValue","option","anchorOrigin","vertical","horizontal","transformOrigin","onClose","sx","theme","padding","spacing","p","minWidth","onClick","e","stopPropagation","options","_e","selected","disableClearable","renderInput","params","placeholder","size","initialTimeRange","onCancel","ref","IconComponent","renderValue","direction","alignItems","span","opt","typography","color","inputProps","marginTop","transform","paddingRight","lineHeight","paddingY","disableRipple","preventDefault","cursor","backgroundColor","py","px","width","justifyContent","flexDirection","mt","pr","ml","aria-label","currentTarget","fontSize","item","idx"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"TimeChartTooltip.d.ts","sourceRoot":"","sources":["../../src/TimeSeriesTooltip/TimeChartTooltip.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAI9C,OAAO,KAAK,EAAE,aAAa,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAEtE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAMzD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,gBAAgB,CAAC,eAAe,GAAG,SAAS,CAAC,CAAC;IACxD,IAAI,EAAE,UAAU,EAAE,CAAC;IACnB,aAAa,EAAE,sBAAsB,CAAC;IACtC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,SAAS,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACpC;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB;;OAEG;IACH,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC7C,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,eAAO,MAAM,gBAAgB,qKAW1B,qBAAqB,oDAsFtB,CAAC"}
1
+ {"version":3,"file":"TimeChartTooltip.d.ts","sourceRoot":"","sources":["../../src/TimeSeriesTooltip/TimeChartTooltip.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAI9C,OAAO,KAAK,EAAE,aAAa,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAGtE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAMzD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,gBAAgB,CAAC,eAAe,GAAG,SAAS,CAAC,CAAC;IACxD,IAAI,EAAE,UAAU,EAAE,CAAC;IACnB,aAAa,EAAE,sBAAsB,CAAC;IACtC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,SAAS,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACpC;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB;;OAEG;IACH,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC7C,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,eAAO,MAAM,gBAAgB,qKAW1B,qBAAqB,oDA0FtB,CAAC"}
@@ -21,7 +21,7 @@ import { TooltipHeader } from "./TooltipHeader.js";
21
21
  import { assembleTransform, getTooltipStyles } from "./utils.js";
22
22
  export const TimeChartTooltip = /*#__PURE__*/ memo(function TimeChartTooltip({ containerId, chartRef, data, seriesMapping, enablePinning = true, wrapLabels, format, seriesFormatMap, onUnpinClick, pinnedPos }) {
23
23
  const [showAllSeries, setShowAllSeries] = useState(false);
24
- const transform = useRef();
24
+ const [nearbySeries, setNearbySeries] = useState([]);
25
25
  const tooltipElementRef = useRef(null);
26
26
  const mousePos = useMousePosition();
27
27
  const { height, width, ref: tooltipRef } = useResizeObserver();
@@ -34,6 +34,29 @@ export const TimeChartTooltip = /*#__PURE__*/ memo(function TimeChartTooltip({ c
34
34
  tooltipRef
35
35
  ]);
36
36
  const containerElement = containerId ? document.querySelector(containerId) : undefined;
37
+ // Chart reads and highlight actions synchronize with ECharts after commit.
38
+ useLayoutEffect(()=>{
39
+ const chart = chartRef.current;
40
+ setNearbySeries(getNearbySeriesData({
41
+ mousePos,
42
+ data,
43
+ seriesMapping,
44
+ pinnedPos,
45
+ chart,
46
+ format,
47
+ seriesFormatMap,
48
+ showAllSeries
49
+ }));
50
+ }, [
51
+ chartRef,
52
+ mousePos,
53
+ data,
54
+ seriesMapping,
55
+ pinnedPos,
56
+ format,
57
+ seriesFormatMap,
58
+ showAllSeries
59
+ ]);
37
60
  // Synchronously reposition after every render to prevent one-frame viewport overflow.
38
61
  useLayoutEffect(()=>{
39
62
  if (mousePos === null) return;
@@ -42,27 +65,15 @@ export const TimeChartTooltip = /*#__PURE__*/ memo(function TimeChartTooltip({ c
42
65
  const rect = node.getBoundingClientRect();
43
66
  if (rect.height === 0 || rect.width === 0) return;
44
67
  const nextTransform = assembleTransform(mousePos, pinnedPos, rect.height, rect.width, containerElement);
45
- if (nextTransform && nextTransform !== transform.current) {
46
- transform.current = nextTransform;
68
+ if (nextTransform && nextTransform !== node.style.transform) {
47
69
  node.style.transform = nextTransform;
48
70
  }
49
71
  });
50
72
  if (mousePos === null || mousePos.target === null || data === null) return null;
51
73
  if (pinnedPos === null && mousePos.target.tagName !== 'CANVAS') return null;
52
- const chart = chartRef.current;
53
74
  // Cap height to container so the tooltip is not cut off.
54
75
  const maxHeight = containerElement ? containerElement.getBoundingClientRect().height : undefined;
55
- transform.current = assembleTransform(mousePos, pinnedPos, height ?? 0, width ?? 0, containerElement);
56
- const nearbySeries = getNearbySeriesData({
57
- mousePos,
58
- data,
59
- seriesMapping,
60
- pinnedPos,
61
- chart,
62
- format,
63
- seriesFormatMap,
64
- showAllSeries
65
- });
76
+ const transform = assembleTransform(mousePos, pinnedPos, height ?? 0, width ?? 0, containerElement);
66
77
  if (nearbySeries.length === 0) {
67
78
  return null;
68
79
  }
@@ -73,7 +84,7 @@ export const TimeChartTooltip = /*#__PURE__*/ memo(function TimeChartTooltip({ c
73
84
  ref: setTooltipRef,
74
85
  sx: (theme)=>getTooltipStyles(theme, pinnedPos, maxHeight),
75
86
  style: {
76
- transform: transform.current
87
+ transform
77
88
  },
78
89
  children: /*#__PURE__*/ _jsxs(Stack, {
79
90
  spacing: 0.5,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/TimeSeriesTooltip/TimeChartTooltip.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Box, Portal, Stack } from '@mui/material';\nimport type { TimeSeries } from '@perses-dev/spec';\nimport type { ECharts as EChartsInstance } from 'echarts/core';\nimport type { MutableRefObject } from 'react';\nimport { memo, useCallback, useLayoutEffect, useRef, useState } from 'react';\nimport useResizeObserver from 'use-resize-observer';\n\nimport type { FormatOptions, TimeChartSeriesMapping } from '../model';\nimport { getNearbySeriesData } from './nearby-series';\nimport type { CursorCoordinates } from './tooltip-model';\nimport { useMousePosition } from './tooltip-model';\nimport { TooltipContent } from './TooltipContent';\nimport { TooltipHeader } from './TooltipHeader';\nimport { assembleTransform, getTooltipStyles } from './utils';\n\nexport interface TimeChartTooltipProps {\n chartRef: MutableRefObject<EChartsInstance | undefined>;\n data: TimeSeries[];\n seriesMapping: TimeChartSeriesMapping;\n enablePinning?: boolean;\n pinnedPos: CursorCoordinates | null;\n /**\n * The id of the container that will have the chart tooltip appended to it.\n * By default, the chart tooltip is attached to document.body.\n */\n containerId?: string;\n onUnpinClick?: () => void;\n format?: FormatOptions;\n /**\n * Map of series ID to format options for per-series formatting (used with multiple Y axes)\n */\n seriesFormatMap?: Map<string, FormatOptions>;\n wrapLabels?: boolean;\n}\n\nexport const TimeChartTooltip = memo(function TimeChartTooltip({\n containerId,\n chartRef,\n data,\n seriesMapping,\n enablePinning = true,\n wrapLabels,\n format,\n seriesFormatMap,\n onUnpinClick,\n pinnedPos,\n}: TimeChartTooltipProps) {\n const [showAllSeries, setShowAllSeries] = useState(false);\n const transform = useRef<string | undefined>();\n const tooltipElementRef = useRef<HTMLDivElement | null>(null);\n\n const mousePos = useMousePosition();\n const { height, width, ref: tooltipRef } = useResizeObserver();\n\n const isTooltipPinned = pinnedPos !== null && enablePinning;\n\n // Stable callback — prevents the ResizeObserver from disconnecting/reconnecting on every render.\n const setTooltipRef = useCallback(\n (node: HTMLDivElement | null): void => {\n tooltipElementRef.current = node;\n tooltipRef(node);\n },\n [tooltipRef],\n );\n\n const containerElement = containerId ? document.querySelector(containerId) : undefined;\n\n // Synchronously reposition after every render to prevent one-frame viewport overflow.\n useLayoutEffect(() => {\n if (mousePos === null) return;\n const node = tooltipElementRef.current;\n if (!node) return;\n const rect = node.getBoundingClientRect();\n if (rect.height === 0 || rect.width === 0) return;\n const nextTransform = assembleTransform(mousePos, pinnedPos, rect.height, rect.width, containerElement);\n if (nextTransform && nextTransform !== transform.current) {\n transform.current = nextTransform;\n node.style.transform = nextTransform;\n }\n });\n\n if (mousePos === null || mousePos.target === null || data === null) return null;\n\n if (pinnedPos === null && (mousePos.target as HTMLElement).tagName !== 'CANVAS') return null;\n\n const chart = chartRef.current;\n\n // Cap height to container so the tooltip is not cut off.\n const maxHeight = containerElement ? containerElement.getBoundingClientRect().height : undefined;\n\n transform.current = assembleTransform(mousePos, pinnedPos, height ?? 0, width ?? 0, containerElement);\n\n const nearbySeries = getNearbySeriesData({\n mousePos,\n data,\n seriesMapping,\n pinnedPos,\n chart,\n format,\n seriesFormatMap,\n showAllSeries,\n });\n if (nearbySeries.length === 0) {\n return null;\n }\n\n const totalSeries = data.length;\n\n return (\n <Portal container={containerElement}>\n <Box\n ref={setTooltipRef}\n sx={(theme) => getTooltipStyles(theme, pinnedPos, maxHeight)}\n style={{\n transform: transform.current,\n }}\n >\n <Stack spacing={0.5}>\n <TooltipHeader\n nearbySeries={nearbySeries}\n totalSeries={totalSeries}\n enablePinning={enablePinning}\n isTooltipPinned={isTooltipPinned}\n showAllSeries={showAllSeries}\n onShowAllClick={(checked) => setShowAllSeries(checked)}\n onUnpinClick={onUnpinClick}\n />\n <TooltipContent series={nearbySeries} wrapLabels={wrapLabels} />\n </Stack>\n </Box>\n </Portal>\n );\n});\n"],"names":["Box","Portal","Stack","memo","useCallback","useLayoutEffect","useRef","useState","useResizeObserver","getNearbySeriesData","useMousePosition","TooltipContent","TooltipHeader","assembleTransform","getTooltipStyles","TimeChartTooltip","containerId","chartRef","data","seriesMapping","enablePinning","wrapLabels","format","seriesFormatMap","onUnpinClick","pinnedPos","showAllSeries","setShowAllSeries","transform","tooltipElementRef","mousePos","height","width","ref","tooltipRef","isTooltipPinned","setTooltipRef","node","current","containerElement","document","querySelector","undefined","rect","getBoundingClientRect","nextTransform","style","target","tagName","chart","maxHeight","nearbySeries","length","totalSeries","container","sx","theme","spacing","onShowAllClick","checked","series"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/TimeSeriesTooltip/TimeChartTooltip.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Box, Portal, Stack } from '@mui/material';\nimport type { TimeSeries } from '@perses-dev/spec';\nimport type { ECharts as EChartsInstance } from 'echarts/core';\nimport type { MutableRefObject } from 'react';\nimport { memo, useCallback, useLayoutEffect, useRef, useState } from 'react';\nimport useResizeObserver from 'use-resize-observer';\n\nimport type { FormatOptions, TimeChartSeriesMapping } from '../model';\nimport type { NearbySeriesArray } from './nearby-series';\nimport { getNearbySeriesData } from './nearby-series';\nimport type { CursorCoordinates } from './tooltip-model';\nimport { useMousePosition } from './tooltip-model';\nimport { TooltipContent } from './TooltipContent';\nimport { TooltipHeader } from './TooltipHeader';\nimport { assembleTransform, getTooltipStyles } from './utils';\n\nexport interface TimeChartTooltipProps {\n chartRef: MutableRefObject<EChartsInstance | undefined>;\n data: TimeSeries[];\n seriesMapping: TimeChartSeriesMapping;\n enablePinning?: boolean;\n pinnedPos: CursorCoordinates | null;\n /**\n * The id of the container that will have the chart tooltip appended to it.\n * By default, the chart tooltip is attached to document.body.\n */\n containerId?: string;\n onUnpinClick?: () => void;\n format?: FormatOptions;\n /**\n * Map of series ID to format options for per-series formatting (used with multiple Y axes)\n */\n seriesFormatMap?: Map<string, FormatOptions>;\n wrapLabels?: boolean;\n}\n\nexport const TimeChartTooltip = memo(function TimeChartTooltip({\n containerId,\n chartRef,\n data,\n seriesMapping,\n enablePinning = true,\n wrapLabels,\n format,\n seriesFormatMap,\n onUnpinClick,\n pinnedPos,\n}: TimeChartTooltipProps) {\n const [showAllSeries, setShowAllSeries] = useState(false);\n const [nearbySeries, setNearbySeries] = useState<NearbySeriesArray>([]);\n const tooltipElementRef = useRef<HTMLDivElement | null>(null);\n\n const mousePos = useMousePosition();\n const { height, width, ref: tooltipRef } = useResizeObserver();\n\n const isTooltipPinned = pinnedPos !== null && enablePinning;\n\n // Stable callback — prevents the ResizeObserver from disconnecting/reconnecting on every render.\n const setTooltipRef = useCallback(\n (node: HTMLDivElement | null): void => {\n tooltipElementRef.current = node;\n tooltipRef(node);\n },\n [tooltipRef],\n );\n\n const containerElement = containerId ? document.querySelector(containerId) : undefined;\n\n // Chart reads and highlight actions synchronize with ECharts after commit.\n useLayoutEffect(() => {\n const chart = chartRef.current;\n setNearbySeries(\n getNearbySeriesData({\n mousePos,\n data,\n seriesMapping,\n pinnedPos,\n chart,\n format,\n seriesFormatMap,\n showAllSeries,\n }),\n );\n }, [chartRef, mousePos, data, seriesMapping, pinnedPos, format, seriesFormatMap, showAllSeries]);\n\n // Synchronously reposition after every render to prevent one-frame viewport overflow.\n useLayoutEffect(() => {\n if (mousePos === null) return;\n const node = tooltipElementRef.current;\n if (!node) return;\n const rect = node.getBoundingClientRect();\n if (rect.height === 0 || rect.width === 0) return;\n const nextTransform = assembleTransform(mousePos, pinnedPos, rect.height, rect.width, containerElement);\n if (nextTransform && nextTransform !== node.style.transform) {\n node.style.transform = nextTransform;\n }\n });\n\n if (mousePos === null || mousePos.target === null || data === null) return null;\n\n if (pinnedPos === null && (mousePos.target as HTMLElement).tagName !== 'CANVAS') return null;\n\n // Cap height to container so the tooltip is not cut off.\n const maxHeight = containerElement ? containerElement.getBoundingClientRect().height : undefined;\n\n const transform = assembleTransform(mousePos, pinnedPos, height ?? 0, width ?? 0, containerElement);\n\n if (nearbySeries.length === 0) {\n return null;\n }\n\n const totalSeries = data.length;\n\n return (\n <Portal container={containerElement}>\n <Box\n ref={setTooltipRef}\n sx={(theme) => getTooltipStyles(theme, pinnedPos, maxHeight)}\n style={{\n transform,\n }}\n >\n <Stack spacing={0.5}>\n <TooltipHeader\n nearbySeries={nearbySeries}\n totalSeries={totalSeries}\n enablePinning={enablePinning}\n isTooltipPinned={isTooltipPinned}\n showAllSeries={showAllSeries}\n onShowAllClick={(checked) => setShowAllSeries(checked)}\n onUnpinClick={onUnpinClick}\n />\n <TooltipContent series={nearbySeries} wrapLabels={wrapLabels} />\n </Stack>\n </Box>\n </Portal>\n );\n});\n"],"names":["Box","Portal","Stack","memo","useCallback","useLayoutEffect","useRef","useState","useResizeObserver","getNearbySeriesData","useMousePosition","TooltipContent","TooltipHeader","assembleTransform","getTooltipStyles","TimeChartTooltip","containerId","chartRef","data","seriesMapping","enablePinning","wrapLabels","format","seriesFormatMap","onUnpinClick","pinnedPos","showAllSeries","setShowAllSeries","nearbySeries","setNearbySeries","tooltipElementRef","mousePos","height","width","ref","tooltipRef","isTooltipPinned","setTooltipRef","node","current","containerElement","document","querySelector","undefined","chart","rect","getBoundingClientRect","nextTransform","style","transform","target","tagName","maxHeight","length","totalSeries","container","sx","theme","spacing","onShowAllClick","checked","series"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"TextField.d.ts","sourceRoot":"","sources":["../../src/controls/TextField.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,cAAc,IAAI,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAMzE,KAAK,cAAc,GAAG,IAAI,CAAC,iBAAiB,EAAE,UAAU,CAAC,GAAG;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,CAAC;AAExH,eAAO,MAAM,SAAS,wHAqBpB,CAAC"}
1
+ {"version":3,"file":"TextField.d.ts","sourceRoot":"","sources":["../../src/controls/TextField.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,cAAc,IAAI,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAOzE,KAAK,cAAc,GAAG,IAAI,CAAC,iBAAiB,EAAE,UAAU,CAAC,GAAG;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,CAAC;AAExH,eAAO,MAAM,SAAS,wHAwBpB,CAAC"}
@@ -13,22 +13,27 @@
13
13
  import { jsx as _jsx } from "react/jsx-runtime";
14
14
  import { TextField as MuiTextField } from "@mui/material";
15
15
  import debounce from "lodash/debounce";
16
- import { forwardRef, useCallback, useMemo, useState } from "react";
16
+ import { forwardRef, useCallback, useLayoutEffect, useRef, useState } from "react";
17
17
  export const TextField = /*#__PURE__*/ forwardRef(function({ debounceMs = 250, value, onChange, ...props }, ref) {
18
18
  const [currentValue, setCurrentValue] = useState(value);
19
- function handleChange(event) {
20
- setCurrentValue(event.target.value);
21
- debounceFn(event.target.value);
22
- }
23
- const handleDebounceFn = useCallback((inputValue)=>{
24
- onChange?.(inputValue);
19
+ const onChangeRef = useRef(onChange);
20
+ useLayoutEffect(()=>{
21
+ onChangeRef.current = onChange;
25
22
  }, [
26
23
  onChange
27
24
  ]);
28
- const debounceFn = useMemo(()=>debounce(handleDebounceFn, debounceMs), [
29
- debounceMs,
30
- handleDebounceFn
25
+ const debounceRef = useRef(null);
26
+ useLayoutEffect(()=>{
27
+ const debounceFn = debounce((inputValue)=>onChangeRef.current?.(inputValue), debounceMs);
28
+ debounceRef.current = debounceFn;
29
+ return ()=>debounceFn.cancel();
30
+ }, [
31
+ debounceMs
31
32
  ]);
33
+ const handleChange = useCallback((event)=>{
34
+ setCurrentValue(event.target.value);
35
+ debounceRef.current?.(event.target.value);
36
+ }, []);
32
37
  return /*#__PURE__*/ _jsx(MuiTextField, {
33
38
  ref: ref,
34
39
  value: currentValue,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/controls/TextField.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport type { TextFieldProps as MuiTextFieldProps } from '@mui/material';\nimport { TextField as MuiTextField } from '@mui/material';\nimport debounce from 'lodash/debounce';\nimport type { ChangeEvent, ForwardedRef } from 'react';\nimport { forwardRef, useCallback, useMemo, useState } from 'react';\n\ntype TextFieldProps = Omit<MuiTextFieldProps, 'onChange'> & { debounceMs?: number; onChange?: (value: string) => void };\n\nexport const TextField = forwardRef(function (\n { debounceMs = 250, value, onChange, ...props }: TextFieldProps,\n ref: ForwardedRef<HTMLDivElement>,\n) {\n const [currentValue, setCurrentValue] = useState(value);\n\n function handleChange(event: ChangeEvent<HTMLInputElement>): void {\n setCurrentValue(event.target.value);\n debounceFn(event.target.value);\n }\n\n const handleDebounceFn = useCallback(\n (inputValue: string) => {\n onChange?.(inputValue);\n },\n [onChange],\n );\n\n const debounceFn = useMemo(() => debounce(handleDebounceFn, debounceMs), [debounceMs, handleDebounceFn]);\n\n return <MuiTextField ref={ref} value={currentValue} onChange={handleChange} {...props} />;\n});\nTextField.displayName = 'TextField';\n"],"names":["TextField","MuiTextField","debounce","forwardRef","useCallback","useMemo","useState","debounceMs","value","onChange","props","ref","currentValue","setCurrentValue","handleChange","event","target","debounceFn","handleDebounceFn","inputValue","displayName"],"mappings":"AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;;AAGjC,SAASA,aAAaC,YAAY,QAAQ,gBAAgB;AAC1D,OAAOC,cAAc,kBAAkB;AAEvC,SAASC,UAAU,EAAEC,WAAW,EAAEC,OAAO,EAAEC,QAAQ,QAAQ,QAAQ;AAInE,OAAO,MAAMN,0BAAYG,WAAW,SAClC,EAAEI,aAAa,GAAG,EAAEC,KAAK,EAAEC,QAAQ,EAAE,GAAGC,OAAuB,EAC/DC,GAAiC;IAEjC,MAAM,CAACC,cAAcC,gBAAgB,GAAGP,SAASE;IAEjD,SAASM,aAAaC,KAAoC;QACxDF,gBAAgBE,MAAMC,MAAM,CAACR,KAAK;QAClCS,WAAWF,MAAMC,MAAM,CAACR,KAAK;IAC/B;IAEA,MAAMU,mBAAmBd,YACvB,CAACe;QACCV,WAAWU;IACb,GACA;QAACV;KAAS;IAGZ,MAAMQ,aAAaZ,QAAQ,IAAMH,SAASgB,kBAAkBX,aAAa;QAACA;QAAYW;KAAiB;IAEvG,qBAAO,KAACjB;QAAaU,KAAKA;QAAKH,OAAOI;QAAcH,UAAUK;QAAe,GAAGJ,KAAK;;AACvF,GAAG;AACHV,UAAUoB,WAAW,GAAG"}
1
+ {"version":3,"sources":["../../src/controls/TextField.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport type { TextFieldProps as MuiTextFieldProps } from '@mui/material';\nimport { TextField as MuiTextField } from '@mui/material';\nimport type { DebouncedFunc } from 'lodash';\nimport debounce from 'lodash/debounce';\nimport type { ChangeEvent, ForwardedRef } from 'react';\nimport { forwardRef, useCallback, useLayoutEffect, useRef, useState } from 'react';\n\ntype TextFieldProps = Omit<MuiTextFieldProps, 'onChange'> & { debounceMs?: number; onChange?: (value: string) => void };\n\nexport const TextField = forwardRef(function (\n { debounceMs = 250, value, onChange, ...props }: TextFieldProps,\n ref: ForwardedRef<HTMLDivElement>,\n) {\n const [currentValue, setCurrentValue] = useState(value);\n\n const onChangeRef = useRef(onChange);\n useLayoutEffect(() => {\n onChangeRef.current = onChange;\n }, [onChange]);\n\n const debounceRef = useRef<DebouncedFunc<(inputValue: string) => void> | null>(null);\n useLayoutEffect(() => {\n const debounceFn = debounce((inputValue: string) => onChangeRef.current?.(inputValue), debounceMs);\n debounceRef.current = debounceFn;\n return (): void => debounceFn.cancel();\n }, [debounceMs]);\n\n const handleChange = useCallback((event: ChangeEvent<HTMLInputElement>): void => {\n setCurrentValue(event.target.value);\n debounceRef.current?.(event.target.value);\n }, []);\n\n return <MuiTextField ref={ref} value={currentValue} onChange={handleChange} {...props} />;\n});\nTextField.displayName = 'TextField';\n"],"names":["TextField","MuiTextField","debounce","forwardRef","useCallback","useLayoutEffect","useRef","useState","debounceMs","value","onChange","props","ref","currentValue","setCurrentValue","onChangeRef","current","debounceRef","debounceFn","inputValue","cancel","handleChange","event","target","displayName"],"mappings":"AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;;AAGjC,SAASA,aAAaC,YAAY,QAAQ,gBAAgB;AAE1D,OAAOC,cAAc,kBAAkB;AAEvC,SAASC,UAAU,EAAEC,WAAW,EAAEC,eAAe,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,QAAQ;AAInF,OAAO,MAAMP,0BAAYG,WAAW,SAClC,EAAEK,aAAa,GAAG,EAAEC,KAAK,EAAEC,QAAQ,EAAE,GAAGC,OAAuB,EAC/DC,GAAiC;IAEjC,MAAM,CAACC,cAAcC,gBAAgB,GAAGP,SAASE;IAEjD,MAAMM,cAAcT,OAAOI;IAC3BL,gBAAgB;QACdU,YAAYC,OAAO,GAAGN;IACxB,GAAG;QAACA;KAAS;IAEb,MAAMO,cAAcX,OAA2D;IAC/ED,gBAAgB;QACd,MAAMa,aAAahB,SAAS,CAACiB,aAAuBJ,YAAYC,OAAO,GAAGG,aAAaX;QACvFS,YAAYD,OAAO,GAAGE;QACtB,OAAO,IAAYA,WAAWE,MAAM;IACtC,GAAG;QAACZ;KAAW;IAEf,MAAMa,eAAejB,YAAY,CAACkB;QAChCR,gBAAgBQ,MAAMC,MAAM,CAACd,KAAK;QAClCQ,YAAYD,OAAO,GAAGM,MAAMC,MAAM,CAACd,KAAK;IAC1C,GAAG,EAAE;IAEL,qBAAO,KAACR;QAAaW,KAAKA;QAAKH,OAAOI;QAAcH,UAAUW;QAAe,GAAGV,KAAK;;AACvF,GAAG;AACHX,UAAUwB,WAAW,GAAG"}
@@ -1,8 +1,3 @@
1
- declare global {
2
- var useIdValue: number;
3
- }
4
- /**
5
- * Generates a unique (stable) ID for a component. Should be replaced with React.useId once we support only React 18.
6
- */
1
+ /** Generates a unique, stable React ID with the given prefix. */
7
2
  export declare function useId(prefix: string): string;
8
3
  //# sourceMappingURL=component-ids.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"component-ids.d.ts","sourceRoot":"","sources":["../../src/utils/component-ids.ts"],"names":[],"mappings":"AAeA,OAAO,CAAC,MAAM,CAAC;IAEb,IAAI,UAAU,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAU5C"}
1
+ {"version":3,"file":"component-ids.d.ts","sourceRoot":"","sources":["../../src/utils/component-ids.ts"],"names":[],"mappings":"AAeA,iEAAiE;AACjE,wBAAgB,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAI5C"}
@@ -10,18 +10,11 @@
10
10
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
11
  // See the License for the specific language governing permissions and
12
12
  // limitations under the License.
13
- import { useRef } from "react";
14
- /**
15
- * Generates a unique (stable) ID for a component. Should be replaced with React.useId once we support only React 18.
16
- */ export function useId(prefix) {
17
- if (globalThis.useIdValue === undefined) {
18
- globalThis.useIdValue = 0;
19
- }
20
- const id = useRef(undefined);
21
- if (id.current === undefined) {
22
- id.current = `${prefix}-${globalThis.useIdValue++}`;
23
- }
24
- return id.current;
13
+ import { useId as useReactId, useState } from "react";
14
+ /** Generates a unique, stable React ID with the given prefix. */ export function useId(prefix) {
15
+ const id = useReactId();
16
+ const [initialPrefix] = useState(prefix);
17
+ return `${initialPrefix}-${id}`;
25
18
  }
26
19
 
27
20
  //# sourceMappingURL=component-ids.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/component-ids.ts"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { useRef } from 'react';\n\ndeclare global {\n // eslint-disable-next-line no-var\n var useIdValue: number;\n}\n\n/**\n * Generates a unique (stable) ID for a component. Should be replaced with React.useId once we support only React 18.\n */\nexport function useId(prefix: string): string {\n if (globalThis.useIdValue === undefined) {\n globalThis.useIdValue = 0;\n }\n\n const id = useRef<string | undefined>(undefined);\n if (id.current === undefined) {\n id.current = `${prefix}-${globalThis.useIdValue++}`;\n }\n return id.current;\n}\n"],"names":["useRef","useId","prefix","globalThis","useIdValue","undefined","id","current"],"mappings":"AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,SAASA,MAAM,QAAQ,QAAQ;AAO/B;;CAEC,GACD,OAAO,SAASC,MAAMC,MAAc;IAClC,IAAIC,WAAWC,UAAU,KAAKC,WAAW;QACvCF,WAAWC,UAAU,GAAG;IAC1B;IAEA,MAAME,KAAKN,OAA2BK;IACtC,IAAIC,GAAGC,OAAO,KAAKF,WAAW;QAC5BC,GAAGC,OAAO,GAAG,GAAGL,OAAO,CAAC,EAAEC,WAAWC,UAAU,IAAI;IACrD;IACA,OAAOE,GAAGC,OAAO;AACnB"}
1
+ {"version":3,"sources":["../../src/utils/component-ids.ts"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { useId as useReactId, useState } from 'react';\n\n/** Generates a unique, stable React ID with the given prefix. */\nexport function useId(prefix: string): string {\n const id = useReactId();\n const [initialPrefix] = useState(prefix);\n return `${initialPrefix}-${id}`;\n}\n"],"names":["useId","useReactId","useState","prefix","id","initialPrefix"],"mappings":"AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,SAASA,SAASC,UAAU,EAAEC,QAAQ,QAAQ,QAAQ;AAEtD,+DAA+D,GAC/D,OAAO,SAASF,MAAMG,MAAc;IAClC,MAAMC,KAAKH;IACX,MAAM,CAACI,cAAc,GAAGH,SAASC;IACjC,OAAO,GAAGE,cAAc,CAAC,EAAED,IAAI;AACjC"}
@@ -5,7 +5,6 @@ export * from './combine-sx';
5
5
  export * from './component-ids';
6
6
  export * from './data-field-interpolation';
7
7
  export * from './format';
8
- export * from './memo';
9
8
  export * from './request-interpolation';
10
9
  export * from './selection-interpolation';
11
10
  export * from './theme-gen';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAaA,cAAc,QAAQ,CAAC;AACvB,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,aAAa,CAAC;AAC5B,cAAc,0BAA0B,CAAC;AACzC,cAAc,iBAAiB,CAAC;AAChC,cAAc,UAAU,CAAC;AACzB,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAaA,cAAc,QAAQ,CAAC;AACvB,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,UAAU,CAAC;AACzB,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,aAAa,CAAC;AAC5B,cAAc,0BAA0B,CAAC;AACzC,cAAc,iBAAiB,CAAC;AAChC,cAAc,UAAU,CAAC;AACzB,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC"}
@@ -17,7 +17,6 @@ export * from "./combine-sx.js";
17
17
  export * from "./component-ids.js";
18
18
  export * from "./data-field-interpolation.js";
19
19
  export * from "./format.js";
20
- export * from "./memo.js";
21
20
  export * from "./request-interpolation.js";
22
21
  export * from "./selection-interpolation.js";
23
22
  export * from "./theme-gen.js";
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/index.ts"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nexport * from './axis';\nexport * from './browser-storage';\nexport * from './chart-actions';\nexport * from './combine-sx';\nexport * from './component-ids';\nexport * from './data-field-interpolation';\nexport * from './format';\nexport * from './memo';\nexport * from './request-interpolation';\nexport * from './selection-interpolation';\nexport * from './theme-gen';\nexport * from './variable-interpolation';\nexport * from './value-mapping';\nexport * from './regexp';\nexport * from './transform-data';\nexport * from './time-series-data';\nexport * from './trace-data';\nexport * from './types';\nexport * from './text';\n"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,cAAc,YAAS;AACvB,cAAc,uBAAoB;AAClC,cAAc,qBAAkB;AAChC,cAAc,kBAAe;AAC7B,cAAc,qBAAkB;AAChC,cAAc,gCAA6B;AAC3C,cAAc,cAAW;AACzB,cAAc,YAAS;AACvB,cAAc,6BAA0B;AACxC,cAAc,+BAA4B;AAC1C,cAAc,iBAAc;AAC5B,cAAc,8BAA2B;AACzC,cAAc,qBAAkB;AAChC,cAAc,cAAW;AACzB,cAAc,sBAAmB;AACjC,cAAc,wBAAqB;AACnC,cAAc,kBAAe;AAC7B,cAAc,aAAU;AACxB,cAAc,YAAS"}
1
+ {"version":3,"sources":["../../src/utils/index.ts"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nexport * from './axis';\nexport * from './browser-storage';\nexport * from './chart-actions';\nexport * from './combine-sx';\nexport * from './component-ids';\nexport * from './data-field-interpolation';\nexport * from './format';\nexport * from './request-interpolation';\nexport * from './selection-interpolation';\nexport * from './theme-gen';\nexport * from './variable-interpolation';\nexport * from './value-mapping';\nexport * from './regexp';\nexport * from './transform-data';\nexport * from './time-series-data';\nexport * from './trace-data';\nexport * from './types';\nexport * from './text';\n"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,cAAc,YAAS;AACvB,cAAc,uBAAoB;AAClC,cAAc,qBAAkB;AAChC,cAAc,kBAAe;AAC7B,cAAc,qBAAkB;AAChC,cAAc,gCAA6B;AAC3C,cAAc,cAAW;AACzB,cAAc,6BAA0B;AACxC,cAAc,+BAA4B;AAC1C,cAAc,iBAAc;AAC5B,cAAc,8BAA2B;AACzC,cAAc,qBAAkB;AAChC,cAAc,cAAW;AACzB,cAAc,sBAAmB;AACjC,cAAc,wBAAqB;AACnC,cAAc,kBAAe;AAC7B,cAAc,aAAU;AACxB,cAAc,YAAS"}
@@ -1 +1 @@
1
- {"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../src/utils/text.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEnD,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,QAAQ,EAAE,QAAQ,EAAE,CAAC,GAAG,MAAM,CAY9E;AAED;;;GAGG;AACH,wBAAgB,8BAA8B,CAAC,CAAC,SAAS,QAAQ,EAAE,QAAQ,EAAE,CAAC,GAAG,MAAM,CAYtF"}
1
+ {"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../src/utils/text.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAenD,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,QAAQ,EAAE,QAAQ,EAAE,CAAC,GAAG,MAAM,CAE9E;AAED;;;GAGG;AACH,wBAAgB,8BAA8B,CAAC,CAAC,SAAS,QAAQ,EAAE,QAAQ,EAAE,CAAC,GAAG,MAAM,CAGtF"}
@@ -10,30 +10,26 @@
10
10
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
11
  // See the License for the specific language governing permissions and
12
12
  // limitations under the License.
13
+ function getDisplayName(spec) {
14
+ if (typeof spec !== 'object' || spec === null || !('display' in spec)) return undefined;
15
+ const { display } = spec;
16
+ if (typeof display !== 'object' || display === null || !('name' in display)) return undefined;
17
+ return typeof display.name === 'string' && display.name ? display.name : undefined;
18
+ }
19
+ function getSpecDisplayName(spec) {
20
+ // Variables wrap their display settings in a nested spec.
21
+ const nestedSpec = typeof spec === 'object' && spec !== null && 'spec' in spec ? spec.spec : undefined;
22
+ return getDisplayName(nestedSpec) ?? getDisplayName(spec);
23
+ }
13
24
  export function getResourceDisplayName(resource) {
14
- // Variables
15
- if (resource.spec?.spec?.display?.name) {
16
- return resource.spec.spec.display.name;
17
- }
18
- // Other resources with display
19
- if (resource.spec?.display?.name) {
20
- return resource.spec.display.name;
21
- }
22
- return resource.metadata.name;
25
+ return getSpecDisplayName(resource.spec) ?? resource.metadata.name;
23
26
  }
24
27
  /**
25
28
  * If the resource has a display name, return the resource display name with the resource name too
26
29
  * Else, only return the resource name
27
30
  */ export function getResourceExtendedDisplayName(resource) {
28
- // Variables
29
- if (resource.spec?.spec?.display?.name) {
30
- return `${resource.spec.spec.display.name} (ID: ${resource.metadata.name})`;
31
- }
32
- // Other resources with display
33
- if (resource.spec?.display?.name) {
34
- return `${resource.spec.display.name} (ID: ${resource.metadata.name})`;
35
- }
36
- return resource.metadata.name;
31
+ const displayName = getSpecDisplayName(resource.spec);
32
+ return displayName ? `${displayName} (ID: ${resource.metadata.name})` : resource.metadata.name;
37
33
  }
38
34
 
39
35
  //# sourceMappingURL=text.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/text.ts"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport type { Resource } from '@perses-dev/client';\n\nexport function getResourceDisplayName<T extends Resource>(resource: T): string {\n // Variables\n if (resource.spec?.spec?.display?.name) {\n return resource.spec.spec.display.name;\n }\n\n // Other resources with display\n if (resource.spec?.display?.name) {\n return resource.spec.display.name;\n }\n\n return resource.metadata.name;\n}\n\n/**\n * If the resource has a display name, return the resource display name with the resource name too\n * Else, only return the resource name\n */\nexport function getResourceExtendedDisplayName<T extends Resource>(resource: T): string {\n // Variables\n if (resource.spec?.spec?.display?.name) {\n return `${resource.spec.spec.display.name} (ID: ${resource.metadata.name})`;\n }\n\n // Other resources with display\n if (resource.spec?.display?.name) {\n return `${resource.spec.display.name} (ID: ${resource.metadata.name})`;\n }\n\n return resource.metadata.name;\n}\n"],"names":["getResourceDisplayName","resource","spec","display","name","metadata","getResourceExtendedDisplayName"],"mappings":"AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAIjC,OAAO,SAASA,uBAA2CC,QAAW;IACpE,YAAY;IACZ,IAAIA,SAASC,IAAI,EAAEA,MAAMC,SAASC,MAAM;QACtC,OAAOH,SAASC,IAAI,CAACA,IAAI,CAACC,OAAO,CAACC,IAAI;IACxC;IAEA,+BAA+B;IAC/B,IAAIH,SAASC,IAAI,EAAEC,SAASC,MAAM;QAChC,OAAOH,SAASC,IAAI,CAACC,OAAO,CAACC,IAAI;IACnC;IAEA,OAAOH,SAASI,QAAQ,CAACD,IAAI;AAC/B;AAEA;;;CAGC,GACD,OAAO,SAASE,+BAAmDL,QAAW;IAC5E,YAAY;IACZ,IAAIA,SAASC,IAAI,EAAEA,MAAMC,SAASC,MAAM;QACtC,OAAO,GAAGH,SAASC,IAAI,CAACA,IAAI,CAACC,OAAO,CAACC,IAAI,CAAC,MAAM,EAAEH,SAASI,QAAQ,CAACD,IAAI,CAAC,CAAC,CAAC;IAC7E;IAEA,+BAA+B;IAC/B,IAAIH,SAASC,IAAI,EAAEC,SAASC,MAAM;QAChC,OAAO,GAAGH,SAASC,IAAI,CAACC,OAAO,CAACC,IAAI,CAAC,MAAM,EAAEH,SAASI,QAAQ,CAACD,IAAI,CAAC,CAAC,CAAC;IACxE;IAEA,OAAOH,SAASI,QAAQ,CAACD,IAAI;AAC/B"}
1
+ {"version":3,"sources":["../../src/utils/text.ts"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport type { Resource } from '@perses-dev/client';\n\nfunction getDisplayName(spec: unknown): string | undefined {\n if (typeof spec !== 'object' || spec === null || !('display' in spec)) return undefined;\n const { display } = spec;\n if (typeof display !== 'object' || display === null || !('name' in display)) return undefined;\n return typeof display.name === 'string' && display.name ? display.name : undefined;\n}\n\nfunction getSpecDisplayName(spec: unknown): string | undefined {\n // Variables wrap their display settings in a nested spec.\n const nestedSpec = typeof spec === 'object' && spec !== null && 'spec' in spec ? spec.spec : undefined;\n return getDisplayName(nestedSpec) ?? getDisplayName(spec);\n}\n\nexport function getResourceDisplayName<T extends Resource>(resource: T): string {\n return getSpecDisplayName(resource.spec) ?? resource.metadata.name;\n}\n\n/**\n * If the resource has a display name, return the resource display name with the resource name too\n * Else, only return the resource name\n */\nexport function getResourceExtendedDisplayName<T extends Resource>(resource: T): string {\n const displayName = getSpecDisplayName(resource.spec);\n return displayName ? `${displayName} (ID: ${resource.metadata.name})` : resource.metadata.name;\n}\n"],"names":["getDisplayName","spec","undefined","display","name","getSpecDisplayName","nestedSpec","getResourceDisplayName","resource","metadata","getResourceExtendedDisplayName","displayName"],"mappings":"AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAIjC,SAASA,eAAeC,IAAa;IACnC,IAAI,OAAOA,SAAS,YAAYA,SAAS,QAAQ,CAAE,CAAA,aAAaA,IAAG,GAAI,OAAOC;IAC9E,MAAM,EAAEC,OAAO,EAAE,GAAGF;IACpB,IAAI,OAAOE,YAAY,YAAYA,YAAY,QAAQ,CAAE,CAAA,UAAUA,OAAM,GAAI,OAAOD;IACpF,OAAO,OAAOC,QAAQC,IAAI,KAAK,YAAYD,QAAQC,IAAI,GAAGD,QAAQC,IAAI,GAAGF;AAC3E;AAEA,SAASG,mBAAmBJ,IAAa;IACvC,0DAA0D;IAC1D,MAAMK,aAAa,OAAOL,SAAS,YAAYA,SAAS,QAAQ,UAAUA,OAAOA,KAAKA,IAAI,GAAGC;IAC7F,OAAOF,eAAeM,eAAeN,eAAeC;AACtD;AAEA,OAAO,SAASM,uBAA2CC,QAAW;IACpE,OAAOH,mBAAmBG,SAASP,IAAI,KAAKO,SAASC,QAAQ,CAACL,IAAI;AACpE;AAEA;;;CAGC,GACD,OAAO,SAASM,+BAAmDF,QAAW;IAC5E,MAAMG,cAAcN,mBAAmBG,SAASP,IAAI;IACpD,OAAOU,cAAc,GAAGA,YAAY,MAAM,EAAEH,SAASC,QAAQ,CAACL,IAAI,CAAC,CAAC,CAAC,GAAGI,SAASC,QAAQ,CAACL,IAAI;AAChG"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@perses-dev/components",
3
- "version": "0.55.0-beta.14",
3
+ "version": "0.55.0-beta.15",
4
4
  "description": "Common UI components used across Perses features",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://github.com/perses/perses/blob/main/README.md",
@@ -35,7 +35,7 @@
35
35
  "@fontsource/inter": "^5.0.0",
36
36
  "@mui/x-date-pickers": "^7.23.1",
37
37
  "@perses-dev/spec": "0.3.0-beta.10",
38
- "@perses-dev/client": "0.55.0-beta.14",
38
+ "@perses-dev/client": "0.55.0-beta.15",
39
39
  "numbro": "^2.3.6",
40
40
  "@tanstack/match-sorter-utils": "^8.19.4",
41
41
  "@tanstack/react-table": "^8.20.5",
@@ -1,13 +0,0 @@
1
- import type { DependencyList } from 'react';
2
- /**
3
- * Like React's useMemo, but guarantees the value will only be recalulated if
4
- * a dependency changes. Uses strict equality (===) for comparison. (React's
5
- * useMemo does not offer this guarantee, it's only a performance optimization).
6
- */
7
- export declare function useMemoized<T>(factory: () => T, deps: DependencyList): T;
8
- /**
9
- * Like React's useMemo, except it does a deep equality comparison with lodash's
10
- * isEqual on the dependency list.
11
- */
12
- export declare function useDeepMemo<T>(factory: () => T, deps: DependencyList): T;
13
- //# sourceMappingURL=memo.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"memo.d.ts","sourceRoot":"","sources":["../../src/utils/memo.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAQ5C;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,IAAI,EAAE,cAAc,GAAG,CAAC,CAgBxE;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,IAAI,EAAE,cAAc,GAAG,CAAC,CAMxE"}
@@ -1,50 +0,0 @@
1
- // Copyright The Perses Authors
2
- // Licensed under the Apache License, Version 2.0 (the "License");
3
- // you may not use this file except in compliance with the License.
4
- // You may obtain a copy of the License at
5
- //
6
- // http://www.apache.org/licenses/LICENSE-2.0
7
- //
8
- // Unless required by applicable law or agreed to in writing, software
9
- // distributed under the License is distributed on an "AS IS" BASIS,
10
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
- // See the License for the specific language governing permissions and
12
- // limitations under the License.
13
- import isEqual from "lodash/isEqual";
14
- import { useRef } from "react";
15
- /**
16
- * Like React's useMemo, but guarantees the value will only be recalulated if
17
- * a dependency changes. Uses strict equality (===) for comparison. (React's
18
- * useMemo does not offer this guarantee, it's only a performance optimization).
19
- */ export function useMemoized(factory, deps) {
20
- const ref = useRef();
21
- let areEqual = true;
22
- for(let i = 0; i < deps.length; i++){
23
- if (ref.current?.deps[i] !== deps[i]) {
24
- areEqual = false;
25
- break;
26
- }
27
- }
28
- if (ref.current === undefined || areEqual === false) {
29
- ref.current = {
30
- value: factory(),
31
- deps: deps
32
- };
33
- }
34
- return ref.current.value;
35
- }
36
- /**
37
- * Like React's useMemo, except it does a deep equality comparison with lodash's
38
- * isEqual on the dependency list.
39
- */ export function useDeepMemo(factory, deps) {
40
- const ref = useRef();
41
- if (ref.current === undefined || isEqual(deps, ref.current.deps) === false) {
42
- ref.current = {
43
- value: factory(),
44
- deps
45
- };
46
- }
47
- return ref.current.value;
48
- }
49
-
50
- //# sourceMappingURL=memo.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/utils/memo.ts"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport isEqual from 'lodash/isEqual';\nimport type { DependencyList } from 'react';\nimport { useRef } from 'react';\n\ntype MemoRef<T> = {\n value: T;\n deps: DependencyList;\n};\n\n/**\n * Like React's useMemo, but guarantees the value will only be recalulated if\n * a dependency changes. Uses strict equality (===) for comparison. (React's\n * useMemo does not offer this guarantee, it's only a performance optimization).\n */\nexport function useMemoized<T>(factory: () => T, deps: DependencyList): T {\n const ref = useRef<MemoRef<T>>();\n\n let areEqual = true;\n for (let i = 0; i < deps.length; i++) {\n if (ref.current?.deps[i] !== deps[i]) {\n areEqual = false;\n break;\n }\n }\n\n if (ref.current === undefined || areEqual === false) {\n ref.current = { value: factory(), deps: deps };\n }\n\n return ref.current.value;\n}\n\n/**\n * Like React's useMemo, except it does a deep equality comparison with lodash's\n * isEqual on the dependency list.\n */\nexport function useDeepMemo<T>(factory: () => T, deps: DependencyList): T {\n const ref = useRef<MemoRef<T>>();\n if (ref.current === undefined || isEqual(deps, ref.current.deps) === false) {\n ref.current = { value: factory(), deps };\n }\n return ref.current.value;\n}\n"],"names":["isEqual","useRef","useMemoized","factory","deps","ref","areEqual","i","length","current","undefined","value","useDeepMemo"],"mappings":"AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,OAAOA,aAAa,iBAAiB;AAErC,SAASC,MAAM,QAAQ,QAAQ;AAO/B;;;;CAIC,GACD,OAAO,SAASC,YAAeC,OAAgB,EAAEC,IAAoB;IACnE,MAAMC,MAAMJ;IAEZ,IAAIK,WAAW;IACf,IAAK,IAAIC,IAAI,GAAGA,IAAIH,KAAKI,MAAM,EAAED,IAAK;QACpC,IAAIF,IAAII,OAAO,EAAEL,IAAI,CAACG,EAAE,KAAKH,IAAI,CAACG,EAAE,EAAE;YACpCD,WAAW;YACX;QACF;IACF;IAEA,IAAID,IAAII,OAAO,KAAKC,aAAaJ,aAAa,OAAO;QACnDD,IAAII,OAAO,GAAG;YAAEE,OAAOR;YAAWC,MAAMA;QAAK;IAC/C;IAEA,OAAOC,IAAII,OAAO,CAACE,KAAK;AAC1B;AAEA;;;CAGC,GACD,OAAO,SAASC,YAAeT,OAAgB,EAAEC,IAAoB;IACnE,MAAMC,MAAMJ;IACZ,IAAII,IAAII,OAAO,KAAKC,aAAaV,QAAQI,MAAMC,IAAII,OAAO,CAACL,IAAI,MAAM,OAAO;QAC1EC,IAAII,OAAO,GAAG;YAAEE,OAAOR;YAAWC;QAAK;IACzC;IACA,OAAOC,IAAII,OAAO,CAACE,KAAK;AAC1B"}