@backstage/ui 0.18.0 → 0.19.0-next.0
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.
- package/CHANGELOG.md +20 -0
- package/dist/analytics/getNodeText.esm.js.map +1 -1
- package/dist/analytics/useAnalytics.esm.js.map +1 -1
- package/dist/components/Accordion/Accordion.esm.js.map +1 -1
- package/dist/components/Accordion/Accordion.module.css.esm.js.map +1 -1
- package/dist/components/Accordion/definition.esm.js.map +1 -1
- package/dist/components/Alert/Alert.esm.js.map +1 -1
- package/dist/components/Alert/Alert.module.css.esm.js.map +1 -1
- package/dist/components/Alert/definition.esm.js.map +1 -1
- package/dist/components/Avatar/Avatar.esm.js.map +1 -1
- package/dist/components/Avatar/Avatar.module.css.esm.js.map +1 -1
- package/dist/components/Avatar/definition.esm.js.map +1 -1
- package/dist/components/Badge/Badge.esm.js.map +1 -1
- package/dist/components/Badge/Badge.module.css.esm.js.map +1 -1
- package/dist/components/Badge/definition.esm.js.map +1 -1
- package/dist/components/Box/Box.esm.js.map +1 -1
- package/dist/components/Box/Box.module.css.esm.js.map +1 -1
- package/dist/components/Box/definition.esm.js.map +1 -1
- package/dist/components/Button/Button.esm.js.map +1 -1
- package/dist/components/Button/Button.module.css.esm.js.map +1 -1
- package/dist/components/Button/definition.esm.js.map +1 -1
- package/dist/components/ButtonIcon/ButtonIcon.esm.js.map +1 -1
- package/dist/components/ButtonIcon/ButtonIcon.module.css.esm.js.map +1 -1
- package/dist/components/ButtonIcon/definition.esm.js.map +1 -1
- package/dist/components/ButtonLink/ButtonLink.esm.js.map +1 -1
- package/dist/components/ButtonLink/ButtonLink.module.css.esm.js.map +1 -1
- package/dist/components/ButtonLink/definition.esm.js.map +1 -1
- package/dist/components/Card/Card.esm.js.map +1 -1
- package/dist/components/Card/Card.module.css.esm.js.map +1 -1
- package/dist/components/Card/definition.esm.js.map +1 -1
- package/dist/components/Checkbox/Checkbox.esm.js.map +1 -1
- package/dist/components/Checkbox/Checkbox.module.css.esm.js.map +1 -1
- package/dist/components/Checkbox/definition.esm.js.map +1 -1
- package/dist/components/CheckboxGroup/CheckboxGroup.esm.js.map +1 -1
- package/dist/components/CheckboxGroup/CheckboxGroup.module.css.esm.js.map +1 -1
- package/dist/components/CheckboxGroup/definition.esm.js.map +1 -1
- package/dist/components/Combobox/Combobox.esm.js +72 -10
- package/dist/components/Combobox/Combobox.esm.js.map +1 -1
- package/dist/components/Combobox/Combobox.module.css.esm.js.map +1 -1
- package/dist/components/Combobox/ComboboxInput.esm.js.map +1 -1
- package/dist/components/Combobox/ComboboxItem.esm.js.map +1 -1
- package/dist/components/Combobox/ComboboxListBox.esm.js +11 -34
- package/dist/components/Combobox/ComboboxListBox.esm.js.map +1 -1
- package/dist/components/Combobox/definition.esm.js +1 -1
- package/dist/components/Combobox/definition.esm.js.map +1 -1
- package/dist/components/Combobox/useAsyncComboboxState.esm.js.map +1 -1
- package/dist/components/Container/Container.esm.js.map +1 -1
- package/dist/components/Container/Container.module.css.esm.js.map +1 -1
- package/dist/components/Container/definition.esm.js.map +1 -1
- package/dist/components/DatePicker/DatePicker.esm.js.map +1 -1
- package/dist/components/DatePicker/DatePicker.module.css.esm.js.map +1 -1
- package/dist/components/DatePicker/DatePickerCalendar.esm.js.map +1 -1
- package/dist/components/DatePicker/DatePickerGroup.esm.js.map +1 -1
- package/dist/components/DatePicker/definition.esm.js.map +1 -1
- package/dist/components/DateRangePicker/DateRangePicker.esm.js.map +1 -1
- package/dist/components/DateRangePicker/DateRangePicker.module.css.esm.js.map +1 -1
- package/dist/components/DateRangePicker/DateRangePickerCalendar.esm.js.map +1 -1
- package/dist/components/DateRangePicker/DateRangePickerGroup.esm.js.map +1 -1
- package/dist/components/DateRangePicker/definition.esm.js.map +1 -1
- package/dist/components/Dialog/Dialog.esm.js.map +1 -1
- package/dist/components/Dialog/Dialog.module.css.esm.js.map +1 -1
- package/dist/components/Dialog/definition.esm.js.map +1 -1
- package/dist/components/FieldError/FieldError.esm.js.map +1 -1
- package/dist/components/FieldError/FieldError.module.css.esm.js.map +1 -1
- package/dist/components/FieldError/definition.esm.js.map +1 -1
- package/dist/components/FieldLabel/FieldLabel.esm.js.map +1 -1
- package/dist/components/FieldLabel/FieldLabel.module.css.esm.js.map +1 -1
- package/dist/components/FieldLabel/definition.esm.js.map +1 -1
- package/dist/components/Flex/Flex.esm.js.map +1 -1
- package/dist/components/Flex/Flex.module.css.esm.js.map +1 -1
- package/dist/components/Flex/definition.esm.js.map +1 -1
- package/dist/components/FullPage/FullPage.esm.js.map +1 -1
- package/dist/components/FullPage/FullPage.module.css.esm.js.map +1 -1
- package/dist/components/FullPage/definition.esm.js.map +1 -1
- package/dist/components/Grid/Grid.esm.js.map +1 -1
- package/dist/components/Grid/Grid.module.css.esm.js.map +1 -1
- package/dist/components/Grid/definition.esm.js.map +1 -1
- package/dist/components/Header/Header.esm.js.map +1 -1
- package/dist/components/Header/Header.module.css.esm.js.map +1 -1
- package/dist/components/Header/HeaderMetadataStatus.esm.js.map +1 -1
- package/dist/components/Header/HeaderMetadataStatus.module.css.esm.js.map +1 -1
- package/dist/components/Header/HeaderMetadataUsers.esm.js.map +1 -1
- package/dist/components/Header/HeaderMetadataUsers.module.css.esm.js.map +1 -1
- package/dist/components/Header/HeaderNav.esm.js.map +1 -1
- package/dist/components/Header/HeaderNav.module.css.esm.js.map +1 -1
- package/dist/components/Header/HeaderNavDefinition.esm.js.map +1 -1
- package/dist/components/Header/HeaderNavIndicators.esm.js.map +1 -1
- package/dist/components/Header/definition.esm.js.map +1 -1
- package/dist/components/Link/Link.esm.js.map +1 -1
- package/dist/components/Link/Link.module.css.esm.js.map +1 -1
- package/dist/components/Link/definition.esm.js.map +1 -1
- package/dist/components/List/List.esm.js.map +1 -1
- package/dist/components/List/List.module.css.esm.js.map +1 -1
- package/dist/components/List/definition.esm.js.map +1 -1
- package/dist/components/Menu/Menu.esm.js.map +1 -1
- package/dist/components/Menu/Menu.module.css.esm.js.map +1 -1
- package/dist/components/Menu/definition.esm.js.map +1 -1
- package/dist/components/NumberField/NumberField.esm.js.map +1 -1
- package/dist/components/NumberField/NumberField.module.css.esm.js.map +1 -1
- package/dist/components/NumberField/definition.esm.js.map +1 -1
- package/dist/components/PasswordField/PasswordField.esm.js.map +1 -1
- package/dist/components/PasswordField/PasswordField.module.css.esm.js.map +1 -1
- package/dist/components/PasswordField/definition.esm.js.map +1 -1
- package/dist/components/PluginHeader/PluginHeader.esm.js.map +1 -1
- package/dist/components/PluginHeader/PluginHeader.module.css.esm.js.map +1 -1
- package/dist/components/PluginHeader/PluginHeaderBreadcrumbs.esm.js.map +1 -1
- package/dist/components/PluginHeader/definition.esm.js.map +1 -1
- package/dist/components/PluginHeader/useIsTruncated.esm.js.map +1 -1
- package/dist/components/Popover/Popover.esm.js.map +1 -1
- package/dist/components/Popover/Popover.module.css.esm.js.map +1 -1
- package/dist/components/Popover/definition.esm.js.map +1 -1
- package/dist/components/RadioGroup/RadioGroup.esm.js.map +1 -1
- package/dist/components/RadioGroup/RadioGroup.module.css.esm.js.map +1 -1
- package/dist/components/RadioGroup/definition.esm.js.map +1 -1
- package/dist/components/SearchAutocomplete/SearchAutocomplete.esm.js.map +1 -1
- package/dist/components/SearchAutocomplete/SearchAutocomplete.module.css.esm.js.map +1 -1
- package/dist/components/SearchAutocomplete/definition.esm.js.map +1 -1
- package/dist/components/SearchField/SearchField.esm.js.map +1 -1
- package/dist/components/SearchField/SearchField.module.css.esm.js.map +1 -1
- package/dist/components/SearchField/definition.esm.js.map +1 -1
- package/dist/components/Select/Select.esm.js.map +1 -1
- package/dist/components/Select/Select.module.css.esm.js.map +1 -1
- package/dist/components/Select/SelectContent.esm.js.map +1 -1
- package/dist/components/Select/SelectItem.esm.js.map +1 -1
- package/dist/components/Select/SelectListBox.esm.js.map +1 -1
- package/dist/components/Select/SelectTrigger.esm.js.map +1 -1
- package/dist/components/Select/definition.esm.js.map +1 -1
- package/dist/components/Skeleton/Skeleton.esm.js.map +1 -1
- package/dist/components/Skeleton/Skeleton.module.css.esm.js.map +1 -1
- package/dist/components/Skeleton/definition.esm.js.map +1 -1
- package/dist/components/Slider/Slider.esm.js.map +1 -1
- package/dist/components/Slider/Slider.module.css.esm.js.map +1 -1
- package/dist/components/Slider/definition.esm.js.map +1 -1
- package/dist/components/Switch/Switch.esm.js.map +1 -1
- package/dist/components/Switch/Switch.module.css.esm.js.map +1 -1
- package/dist/components/Switch/definition.esm.js.map +1 -1
- package/dist/components/Table/Table.module.css.esm.js.map +1 -1
- package/dist/components/Table/components/Cell.esm.js.map +1 -1
- package/dist/components/Table/components/CellProfile.esm.js.map +1 -1
- package/dist/components/Table/components/CellText.esm.js.map +1 -1
- package/dist/components/Table/components/Column.esm.js.map +1 -1
- package/dist/components/Table/components/Row.esm.js.map +1 -1
- package/dist/components/Table/components/Table.esm.js.map +1 -1
- package/dist/components/Table/components/TableBody.esm.js.map +1 -1
- package/dist/components/Table/components/TableBodySkeleton.esm.js.map +1 -1
- package/dist/components/Table/components/TableHeader.esm.js.map +1 -1
- package/dist/components/Table/components/TableRoot.esm.js.map +1 -1
- package/dist/components/Table/definition.esm.js.map +1 -1
- package/dist/components/Table/hooks/getEffectivePageSize.esm.js.map +1 -1
- package/dist/components/Table/hooks/useCompletePagination.esm.js.map +1 -1
- package/dist/components/Table/hooks/useCursorPagination.esm.js.map +1 -1
- package/dist/components/Table/hooks/useDebouncedReload.esm.js.map +1 -1
- package/dist/components/Table/hooks/useDebouncedValue.esm.js.map +1 -1
- package/dist/components/Table/hooks/useOffsetPagination.esm.js.map +1 -1
- package/dist/components/Table/hooks/usePageCache.esm.js.map +1 -1
- package/dist/components/Table/hooks/useQueryState.esm.js.map +1 -1
- package/dist/components/Table/hooks/useStableCallback.esm.js.map +1 -1
- package/dist/components/Table/hooks/useTable.esm.js.map +1 -1
- package/dist/components/TablePagination/TablePagination.esm.js.map +1 -1
- package/dist/components/TablePagination/TablePagination.module.css.esm.js.map +1 -1
- package/dist/components/TablePagination/definition.esm.js.map +1 -1
- package/dist/components/Tabs/Tabs.esm.js.map +1 -1
- package/dist/components/Tabs/Tabs.module.css.esm.js.map +1 -1
- package/dist/components/Tabs/TabsIndicators.esm.js.map +1 -1
- package/dist/components/Tabs/definition.esm.js.map +1 -1
- package/dist/components/TagGroup/TagGroup.esm.js.map +1 -1
- package/dist/components/TagGroup/TagGroup.module.css.esm.js.map +1 -1
- package/dist/components/TagGroup/definition.esm.js.map +1 -1
- package/dist/components/Text/Text.esm.js.map +1 -1
- package/dist/components/Text/Text.module.css.esm.js.map +1 -1
- package/dist/components/Text/definition.esm.js.map +1 -1
- package/dist/components/TextAreaField/TextAreaField.esm.js.map +1 -1
- package/dist/components/TextAreaField/TextAreaField.module.css.esm.js.map +1 -1
- package/dist/components/TextAreaField/definition.esm.js.map +1 -1
- package/dist/components/TextField/TextField.esm.js.map +1 -1
- package/dist/components/TextField/TextField.module.css.esm.js.map +1 -1
- package/dist/components/TextField/definition.esm.js.map +1 -1
- package/dist/components/ToggleButton/ToggleButton.esm.js.map +1 -1
- package/dist/components/ToggleButton/ToggleButton.module.css.esm.js.map +1 -1
- package/dist/components/ToggleButton/definition.esm.js.map +1 -1
- package/dist/components/ToggleButtonGroup/ToggleButtonGroup.esm.js.map +1 -1
- package/dist/components/ToggleButtonGroup/ToggleButtonGroup.module.css.esm.js.map +1 -1
- package/dist/components/ToggleButtonGroup/definition.esm.js.map +1 -1
- package/dist/components/Tooltip/Tooltip.esm.js.map +1 -1
- package/dist/components/Tooltip/Tooltip.module.css.esm.js.map +1 -1
- package/dist/components/Tooltip/definition.esm.js.map +1 -1
- package/dist/components/VisuallyHidden/VisuallyHidden.esm.js.map +1 -1
- package/dist/components/VisuallyHidden/VisuallyHidden.module.css.esm.js.map +1 -1
- package/dist/components/VisuallyHidden/definition.esm.js.map +1 -1
- package/dist/css/styles.css +23 -1
- package/dist/hooks/useBg.esm.js.map +1 -1
- package/dist/hooks/useBreakpoint.esm.js.map +1 -1
- package/dist/hooks/useCollectionAdapter.esm.js.map +1 -1
- package/dist/hooks/useDefinition/defineComponent.esm.js.map +1 -1
- package/dist/hooks/useDefinition/helpers.esm.js.map +1 -1
- package/dist/hooks/useDefinition/useDefinition.esm.js.map +1 -1
- package/dist/hooks/useDefinition/useDefinitionNavigation.esm.js.map +1 -1
- package/dist/hooks/useDelayedVisibility.esm.js.map +1 -1
- package/dist/hooks/useIsomorphicLayoutEffect.esm.js.map +1 -1
- package/dist/hooks/useResolvedHref.esm.js.map +1 -1
- package/dist/hooks/useTrackedSelectionKeys.esm.js.map +1 -1
- package/dist/index.d.ts +7 -2
- package/dist/navigation/BUIRoutingProvider.esm.js.map +1 -1
- package/dist/navigation/useNavigation.esm.js.map +1 -1
- package/dist/navigation/useRouting.esm.js.map +1 -1
- package/dist/node_modules_dist/style-inject/dist/style-inject.es.esm.js.map +1 -1
- package/dist/provider/BUIContext.esm.js.map +1 -1
- package/dist/provider/BUIProvider.esm.js.map +1 -1
- package/dist/utils/linkUtils.esm.js.map +1 -1
- package/dist/utils/selectableCollection.esm.js +13 -1
- package/dist/utils/selectableCollection.esm.js.map +1 -1
- package/dist/utils/utilityClassMap.esm.js.map +1 -1
- package/package.json +7 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCompletePagination.esm.js","sources":["../../../../src/components/Table/hooks/useCompletePagination.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\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 */\n\nimport { useState, useCallback, useMemo, useEffect, useRef } from 'react';\nimport type { TableItem } from '../types';\nimport type {\n PaginationResult,\n QueryState,\n UseTableCompleteOptions,\n} from './types';\nimport { useStableCallback } from './useStableCallback';\nimport { useDebouncedValue } from './useDebouncedValue';\nimport { getEffectivePageSize } from './getEffectivePageSize';\n\n/** @internal */\nexport function useCompletePagination<T extends TableItem, TFilter>(\n options: UseTableCompleteOptions<T, TFilter>,\n query: QueryState<TFilter>,\n): PaginationResult<T> & { reload: () => void } {\n const {\n data,\n getData: getDataProp = () => [],\n paginationOptions = {},\n sortFn,\n filterFn,\n searchFn,\n searchDebounceMs = 0,\n filterDebounceMs = 0,\n } = options;\n const hasGetData = 'getData' in options;\n const noPagination = paginationOptions.type === 'none';\n const { initialOffset = 0 } = paginationOptions;\n const defaultPageSize = noPagination\n ? Infinity\n : getEffectivePageSize(paginationOptions);\n\n const getData = useStableCallback(getDataProp);\n const { sort, filter, search } = query;\n\n const [items, setItems] = useState<T[] | undefined>(undefined);\n const [isPending, setIsPending] = useState(!data);\n const [error, setError] = useState<Error | undefined>(undefined);\n const [loadCount, setLoadCount] = useState(0);\n\n const [offset, setOffset] = useState(initialOffset);\n const [pageSize, setPageSize] = useState(defaultPageSize);\n\n // Sync pageSize when the caller changes paginationOptions.pageSize\n const previousDefaultPageSize = useRef(defaultPageSize);\n useEffect(() => {\n if (previousDefaultPageSize.current !== defaultPageSize) {\n previousDefaultPageSize.current = defaultPageSize;\n setPageSize(defaultPageSize);\n setOffset(0);\n }\n }, [defaultPageSize]);\n\n // Load data on mount and when loadCount changes (reload trigger)\n useEffect(() => {\n if (data) {\n setIsPending(false);\n return;\n }\n\n if (!hasGetData) {\n setIsPending(true);\n return;\n }\n\n let cancelled = false;\n setIsPending(true);\n setError(undefined);\n\n (async () => {\n try {\n const result = getData();\n const resolvedData = result instanceof Promise ? await result : result;\n if (!cancelled) {\n setItems(resolvedData);\n setIsPending(false);\n }\n } catch (err) {\n if (!cancelled) {\n setError(err instanceof Error ? err : new Error(String(err)));\n setIsPending(false);\n }\n }\n })();\n\n return () => {\n cancelled = true;\n };\n }, [data, getData, hasGetData, loadCount]);\n\n // Debounced surrogates of search and filter feed the processing pipeline.\n // At delayMs === 0 (the default) these are referentially equal to the live\n // values, so behavior is identical to before this refactor.\n const debouncedSearch = useDebouncedValue(search, searchDebounceMs);\n const debouncedFilter = useDebouncedValue(filter, filterDebounceMs);\n\n // Reset offset when the *debounced* query changes — keying on the live query\n // would briefly flash page 1 of unfiltered data while the debounce settles.\n const debouncedQuery = useMemo(\n () => ({ sort, filter: debouncedFilter, search: debouncedSearch }),\n [sort, debouncedFilter, debouncedSearch],\n );\n const prevDebouncedQueryRef = useRef(debouncedQuery);\n useEffect(() => {\n if (prevDebouncedQueryRef.current !== debouncedQuery) {\n prevDebouncedQueryRef.current = debouncedQuery;\n setOffset(0);\n }\n }, [debouncedQuery]);\n\n const resolvedItems = useMemo(() => data ?? items, [data, items]);\n\n // Process data client-side (filter, search, sort)\n const processedData = useMemo(() => {\n if (!resolvedItems) {\n return undefined;\n }\n let result = [...resolvedItems];\n if (debouncedFilter !== undefined && filterFn) {\n result = filterFn(result, debouncedFilter);\n }\n if (debouncedSearch && searchFn) {\n result = searchFn(result, debouncedSearch);\n }\n if (sort && sortFn) {\n result = sortFn(result, sort);\n }\n return result;\n }, [\n resolvedItems,\n sort,\n debouncedFilter,\n debouncedSearch,\n filterFn,\n searchFn,\n sortFn,\n ]);\n\n const previousProcessedDataRef = useRef(processedData);\n if (processedData !== undefined) {\n previousProcessedDataRef.current = processedData;\n }\n const retainedProcessedData =\n processedData ?? previousProcessedDataRef.current;\n\n const totalCount = retainedProcessedData?.length ?? 0;\n\n const effectiveOffset = useMemo(() => {\n if (noPagination) {\n return 0;\n }\n if (retainedProcessedData === undefined) {\n return offset;\n }\n if (totalCount === 0) {\n return 0;\n }\n return Math.min(offset, Math.floor((totalCount - 1) / pageSize) * pageSize);\n }, [noPagination, offset, pageSize, retainedProcessedData, totalCount]);\n\n // Persist the corrected offset so later data growth does not restore it.\n useEffect(() => {\n if (offset !== effectiveOffset) {\n setOffset(effectiveOffset);\n }\n }, [effectiveOffset, offset]);\n\n // Paginate the processed data\n const paginatedData = useMemo(\n () =>\n noPagination\n ? retainedProcessedData\n : retainedProcessedData?.slice(\n effectiveOffset,\n effectiveOffset + pageSize,\n ),\n [retainedProcessedData, effectiveOffset, pageSize, noPagination],\n );\n\n const hasNextPage = !noPagination && effectiveOffset + pageSize < totalCount;\n const hasPreviousPage = !noPagination && effectiveOffset > 0;\n\n const onNextPage = useCallback(() => {\n if (effectiveOffset + pageSize < totalCount) {\n setOffset(effectiveOffset + pageSize);\n }\n }, [effectiveOffset, pageSize, totalCount]);\n\n const onPreviousPage = useCallback(() => {\n if (effectiveOffset > 0) {\n setOffset(Math.max(0, effectiveOffset - pageSize));\n }\n }, [effectiveOffset, pageSize]);\n\n const onPageSizeChange = useCallback((newSize: number) => {\n setPageSize(newSize);\n setOffset(0);\n }, []);\n\n const reload = useCallback(() => {\n setOffset(0);\n setLoadCount(c => c + 1);\n }, []);\n\n return {\n data: paginatedData,\n isPending: isPending,\n error,\n totalCount,\n offset: effectiveOffset,\n pageSize,\n hasNextPage,\n hasPreviousPage,\n onNextPage,\n onPreviousPage,\n onPageSizeChange,\n reload,\n };\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useCompletePagination.esm.js","sources":["../../../../src/components/Table/hooks/useCompletePagination.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\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 */\n\nimport { useState, useCallback, useMemo, useEffect, useRef } from 'react';\nimport type { TableItem } from '../types';\nimport type {\n PaginationResult,\n QueryState,\n UseTableCompleteOptions,\n} from './types';\nimport { useStableCallback } from './useStableCallback';\nimport { useDebouncedValue } from './useDebouncedValue';\nimport { getEffectivePageSize } from './getEffectivePageSize';\n\n/** @internal */\nexport function useCompletePagination<T extends TableItem, TFilter>(\n options: UseTableCompleteOptions<T, TFilter>,\n query: QueryState<TFilter>,\n): PaginationResult<T> & { reload: () => void } {\n const {\n data,\n getData: getDataProp = () => [],\n paginationOptions = {},\n sortFn,\n filterFn,\n searchFn,\n searchDebounceMs = 0,\n filterDebounceMs = 0,\n } = options;\n const hasGetData = 'getData' in options;\n const noPagination = paginationOptions.type === 'none';\n const { initialOffset = 0 } = paginationOptions;\n const defaultPageSize = noPagination\n ? Infinity\n : getEffectivePageSize(paginationOptions);\n\n const getData = useStableCallback(getDataProp);\n const { sort, filter, search } = query;\n\n const [items, setItems] = useState<T[] | undefined>(undefined);\n const [isPending, setIsPending] = useState(!data);\n const [error, setError] = useState<Error | undefined>(undefined);\n const [loadCount, setLoadCount] = useState(0);\n\n const [offset, setOffset] = useState(initialOffset);\n const [pageSize, setPageSize] = useState(defaultPageSize);\n\n // Sync pageSize when the caller changes paginationOptions.pageSize\n const previousDefaultPageSize = useRef(defaultPageSize);\n useEffect(() => {\n if (previousDefaultPageSize.current !== defaultPageSize) {\n previousDefaultPageSize.current = defaultPageSize;\n setPageSize(defaultPageSize);\n setOffset(0);\n }\n }, [defaultPageSize]);\n\n // Load data on mount and when loadCount changes (reload trigger)\n useEffect(() => {\n if (data) {\n setIsPending(false);\n return;\n }\n\n if (!hasGetData) {\n setIsPending(true);\n return;\n }\n\n let cancelled = false;\n setIsPending(true);\n setError(undefined);\n\n (async () => {\n try {\n const result = getData();\n const resolvedData = result instanceof Promise ? await result : result;\n if (!cancelled) {\n setItems(resolvedData);\n setIsPending(false);\n }\n } catch (err) {\n if (!cancelled) {\n setError(err instanceof Error ? err : new Error(String(err)));\n setIsPending(false);\n }\n }\n })();\n\n return () => {\n cancelled = true;\n };\n }, [data, getData, hasGetData, loadCount]);\n\n // Debounced surrogates of search and filter feed the processing pipeline.\n // At delayMs === 0 (the default) these are referentially equal to the live\n // values, so behavior is identical to before this refactor.\n const debouncedSearch = useDebouncedValue(search, searchDebounceMs);\n const debouncedFilter = useDebouncedValue(filter, filterDebounceMs);\n\n // Reset offset when the *debounced* query changes — keying on the live query\n // would briefly flash page 1 of unfiltered data while the debounce settles.\n const debouncedQuery = useMemo(\n () => ({ sort, filter: debouncedFilter, search: debouncedSearch }),\n [sort, debouncedFilter, debouncedSearch],\n );\n const prevDebouncedQueryRef = useRef(debouncedQuery);\n useEffect(() => {\n if (prevDebouncedQueryRef.current !== debouncedQuery) {\n prevDebouncedQueryRef.current = debouncedQuery;\n setOffset(0);\n }\n }, [debouncedQuery]);\n\n const resolvedItems = useMemo(() => data ?? items, [data, items]);\n\n // Process data client-side (filter, search, sort)\n const processedData = useMemo(() => {\n if (!resolvedItems) {\n return undefined;\n }\n let result = [...resolvedItems];\n if (debouncedFilter !== undefined && filterFn) {\n result = filterFn(result, debouncedFilter);\n }\n if (debouncedSearch && searchFn) {\n result = searchFn(result, debouncedSearch);\n }\n if (sort && sortFn) {\n result = sortFn(result, sort);\n }\n return result;\n }, [\n resolvedItems,\n sort,\n debouncedFilter,\n debouncedSearch,\n filterFn,\n searchFn,\n sortFn,\n ]);\n\n const previousProcessedDataRef = useRef(processedData);\n if (processedData !== undefined) {\n previousProcessedDataRef.current = processedData;\n }\n const retainedProcessedData =\n processedData ?? previousProcessedDataRef.current;\n\n const totalCount = retainedProcessedData?.length ?? 0;\n\n const effectiveOffset = useMemo(() => {\n if (noPagination) {\n return 0;\n }\n if (retainedProcessedData === undefined) {\n return offset;\n }\n if (totalCount === 0) {\n return 0;\n }\n return Math.min(offset, Math.floor((totalCount - 1) / pageSize) * pageSize);\n }, [noPagination, offset, pageSize, retainedProcessedData, totalCount]);\n\n // Persist the corrected offset so later data growth does not restore it.\n useEffect(() => {\n if (offset !== effectiveOffset) {\n setOffset(effectiveOffset);\n }\n }, [effectiveOffset, offset]);\n\n // Paginate the processed data\n const paginatedData = useMemo(\n () =>\n noPagination\n ? retainedProcessedData\n : retainedProcessedData?.slice(\n effectiveOffset,\n effectiveOffset + pageSize,\n ),\n [retainedProcessedData, effectiveOffset, pageSize, noPagination],\n );\n\n const hasNextPage = !noPagination && effectiveOffset + pageSize < totalCount;\n const hasPreviousPage = !noPagination && effectiveOffset > 0;\n\n const onNextPage = useCallback(() => {\n if (effectiveOffset + pageSize < totalCount) {\n setOffset(effectiveOffset + pageSize);\n }\n }, [effectiveOffset, pageSize, totalCount]);\n\n const onPreviousPage = useCallback(() => {\n if (effectiveOffset > 0) {\n setOffset(Math.max(0, effectiveOffset - pageSize));\n }\n }, [effectiveOffset, pageSize]);\n\n const onPageSizeChange = useCallback((newSize: number) => {\n setPageSize(newSize);\n setOffset(0);\n }, []);\n\n const reload = useCallback(() => {\n setOffset(0);\n setLoadCount(c => c + 1);\n }, []);\n\n return {\n data: paginatedData,\n isPending: isPending,\n error,\n totalCount,\n offset: effectiveOffset,\n pageSize,\n hasNextPage,\n hasPreviousPage,\n onNextPage,\n onPreviousPage,\n onPageSizeChange,\n reload,\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCursorPagination.esm.js","sources":["../../../../src/components/Table/hooks/useCursorPagination.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\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 { useState, useCallback } from 'react';\nimport type { TableItem } from '../types';\nimport type {\n UseTableCursorOptions,\n CursorParams,\n QueryState,\n PaginationResult,\n} from './types';\nimport { usePageCache } from './usePageCache';\nimport { useStableCallback } from './useStableCallback';\nimport { useDebouncedReload } from './useDebouncedReload';\nimport { getEffectivePageSize } from './getEffectivePageSize';\n\nexport function useCursorPagination<T extends TableItem, TFilter>(\n options: UseTableCursorOptions<T, TFilter>,\n query: QueryState<TFilter>,\n): PaginationResult<T> & { reload: () => void } {\n const { getData: getDataProp, paginationOptions = {} } = options;\n const defaultPageSize = getEffectivePageSize(paginationOptions);\n\n const getData = useStableCallback(getDataProp);\n const { sort, filter, search } = query;\n\n const [pageSize, setPageSize] = useState(defaultPageSize);\n\n const wrappedGetData = useCallback(\n async ({\n cursor,\n signal,\n }: {\n cursor: string | undefined;\n signal: AbortSignal;\n }) => {\n const params: CursorParams<TFilter> = {\n cursor,\n pageSize,\n sort,\n filter,\n search,\n signal,\n };\n\n const response = await getData(params);\n\n return {\n data: response.data,\n prevCursor: response.prevCursor,\n nextCursor: response.nextCursor,\n totalCount: response.totalCount,\n };\n },\n [getData, pageSize, sort, filter, search],\n );\n\n const cache = usePageCache<T, string>({ getData: wrappedGetData });\n\n useDebouncedReload(query, pageSize, cache.reload);\n\n const onPageSizeChange = useCallback(\n (newSize: number) => setPageSize(newSize),\n [],\n );\n\n return {\n data: cache.data,\n isPending: cache.isPending,\n error: cache.error,\n totalCount: cache.totalCount,\n offset: undefined,\n pageSize,\n hasNextPage: cache.hasNextPage,\n hasPreviousPage: cache.hasPreviousPage,\n onNextPage: cache.onNextPage,\n onPreviousPage: cache.onPreviousPage,\n onPageSizeChange,\n reload: cache.reload,\n };\n}\n"],"names":[],"mappings":";;;;;;AA4BO,SAAS,mBAAA,CACd,SACA,KAAA,EAC8C;AAC9C,EAAA,MAAM,EAAE,OAAA,EAAS,WAAA,EAAa,iBAAA,GAAoB,IAAG,GAAI,OAAA;AACzD,EAAA,MAAM,eAAA,GAAkB,qBAAqB,iBAAiB,CAAA;AAE9D,EAAA,MAAM,OAAA,GAAU,kBAAkB,WAAW,CAAA;AAC7C,EAAA,MAAM,EAAE,IAAA,EAAM,MAAA,EAAQ,MAAA,EAAO,GAAI,KAAA;AAEjC,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAAS,eAAe,CAAA;AAExD,EAAA,MAAM,cAAA,GAAiB,WAAA;AAAA,IACrB,OAAO;AAAA,MACL,MAAA;AAAA,MACA;AAAA,KACF,KAGM;AACJ,MAAA,MAAM,MAAA,GAAgC;AAAA,QACpC,MAAA;AAAA,QACA,QAAA;AAAA,QACA,IAAA;AAAA,QACA,MAAA;AAAA,QACA,MAAA;AAAA,QACA;AAAA,OACF;AAEA,MAAA,MAAM,QAAA,GAAW,MAAM,OAAA,CAAQ,MAAM,CAAA;AAErC,MAAA,OAAO;AAAA,QACL,MAAM,QAAA,CAAS,IAAA;AAAA,QACf,YAAY,QAAA,CAAS,UAAA;AAAA,QACrB,YAAY,QAAA,CAAS,UAAA;AAAA,QACrB,YAAY,QAAA,CAAS;AAAA,OACvB;AAAA,IACF,CAAA;AAAA,IACA,CAAC,OAAA,EAAS,QAAA,EAAU,IAAA,EAAM,QAAQ,MAAM;AAAA,GAC1C;AAEA,EAAA,MAAM,KAAA,GAAQ,YAAA,CAAwB,EAAE,OAAA,EAAS,gBAAgB,CAAA;AAEjE,EAAA,kBAAA,CAAmB,KAAA,EAAO,QAAA,EAAU,KAAA,CAAM,MAAM,CAAA;AAEhD,EAAA,MAAM,gBAAA,GAAmB,WAAA;AAAA,IACvB,CAAC,OAAA,KAAoB,WAAA,CAAY,OAAO,CAAA;AAAA,IACxC;AAAC,GACH;AAEA,EAAA,OAAO;AAAA,IACL,MAAM,KAAA,CAAM,IAAA;AAAA,IACZ,WAAW,KAAA,CAAM,SAAA;AAAA,IACjB,OAAO,KAAA,CAAM,KAAA;AAAA,IACb,YAAY,KAAA,CAAM,UAAA;AAAA,IAClB,MAAA,EAAQ,MAAA;AAAA,IACR,QAAA;AAAA,IACA,aAAa,KAAA,CAAM,WAAA;AAAA,IACnB,iBAAiB,KAAA,CAAM,eAAA;AAAA,IACvB,YAAY,KAAA,CAAM,UAAA;AAAA,IAClB,gBAAgB,KAAA,CAAM,cAAA;AAAA,IACtB,gBAAA;AAAA,IACA,QAAQ,KAAA,CAAM;AAAA,GAChB;AACF
|
|
1
|
+
{"version":3,"file":"useCursorPagination.esm.js","sources":["../../../../src/components/Table/hooks/useCursorPagination.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\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 { useState, useCallback } from 'react';\nimport type { TableItem } from '../types';\nimport type {\n UseTableCursorOptions,\n CursorParams,\n QueryState,\n PaginationResult,\n} from './types';\nimport { usePageCache } from './usePageCache';\nimport { useStableCallback } from './useStableCallback';\nimport { useDebouncedReload } from './useDebouncedReload';\nimport { getEffectivePageSize } from './getEffectivePageSize';\n\nexport function useCursorPagination<T extends TableItem, TFilter>(\n options: UseTableCursorOptions<T, TFilter>,\n query: QueryState<TFilter>,\n): PaginationResult<T> & { reload: () => void } {\n const { getData: getDataProp, paginationOptions = {} } = options;\n const defaultPageSize = getEffectivePageSize(paginationOptions);\n\n const getData = useStableCallback(getDataProp);\n const { sort, filter, search } = query;\n\n const [pageSize, setPageSize] = useState(defaultPageSize);\n\n const wrappedGetData = useCallback(\n async ({\n cursor,\n signal,\n }: {\n cursor: string | undefined;\n signal: AbortSignal;\n }) => {\n const params: CursorParams<TFilter> = {\n cursor,\n pageSize,\n sort,\n filter,\n search,\n signal,\n };\n\n const response = await getData(params);\n\n return {\n data: response.data,\n prevCursor: response.prevCursor,\n nextCursor: response.nextCursor,\n totalCount: response.totalCount,\n };\n },\n [getData, pageSize, sort, filter, search],\n );\n\n const cache = usePageCache<T, string>({ getData: wrappedGetData });\n\n useDebouncedReload(query, pageSize, cache.reload);\n\n const onPageSizeChange = useCallback(\n (newSize: number) => setPageSize(newSize),\n [],\n );\n\n return {\n data: cache.data,\n isPending: cache.isPending,\n error: cache.error,\n totalCount: cache.totalCount,\n offset: undefined,\n pageSize,\n hasNextPage: cache.hasNextPage,\n hasPreviousPage: cache.hasPreviousPage,\n onNextPage: cache.onNextPage,\n onPreviousPage: cache.onPreviousPage,\n onPageSizeChange,\n reload: cache.reload,\n };\n}\n"],"names":[],"mappings":";;;;;;AA4BO,SAAS,mBAAA,CACd,SACA,KAAA,EAC8C;AAC9C,EAAA,MAAM,EAAE,OAAA,EAAS,WAAA,EAAa,iBAAA,GAAoB,IAAG,GAAI,OAAA;AACzD,EAAA,MAAM,eAAA,GAAkB,qBAAqB,iBAAiB,CAAA;AAE9D,EAAA,MAAM,OAAA,GAAU,kBAAkB,WAAW,CAAA;AAC7C,EAAA,MAAM,EAAE,IAAA,EAAM,MAAA,EAAQ,MAAA,EAAO,GAAI,KAAA;AAEjC,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAAS,eAAe,CAAA;AAExD,EAAA,MAAM,cAAA,GAAiB,WAAA;AAAA,IACrB,OAAO;AAAA,MACL,MAAA;AAAA,MACA;AAAA,KACF,KAGM;AACJ,MAAA,MAAM,MAAA,GAAgC;AAAA,QACpC,MAAA;AAAA,QACA,QAAA;AAAA,QACA,IAAA;AAAA,QACA,MAAA;AAAA,QACA,MAAA;AAAA,QACA;AAAA,OACF;AAEA,MAAA,MAAM,QAAA,GAAW,MAAM,OAAA,CAAQ,MAAM,CAAA;AAErC,MAAA,OAAO;AAAA,QACL,MAAM,QAAA,CAAS,IAAA;AAAA,QACf,YAAY,QAAA,CAAS,UAAA;AAAA,QACrB,YAAY,QAAA,CAAS,UAAA;AAAA,QACrB,YAAY,QAAA,CAAS;AAAA,OACvB;AAAA,IACF,CAAA;AAAA,IACA,CAAC,OAAA,EAAS,QAAA,EAAU,IAAA,EAAM,QAAQ,MAAM;AAAA,GAC1C;AAEA,EAAA,MAAM,KAAA,GAAQ,YAAA,CAAwB,EAAE,OAAA,EAAS,gBAAgB,CAAA;AAEjE,EAAA,kBAAA,CAAmB,KAAA,EAAO,QAAA,EAAU,KAAA,CAAM,MAAM,CAAA;AAEhD,EAAA,MAAM,gBAAA,GAAmB,WAAA;AAAA,IACvB,CAAC,OAAA,KAAoB,WAAA,CAAY,OAAO,CAAA;AAAA,IACxC;AAAC,GACH;AAEA,EAAA,OAAO;AAAA,IACL,MAAM,KAAA,CAAM,IAAA;AAAA,IACZ,WAAW,KAAA,CAAM,SAAA;AAAA,IACjB,OAAO,KAAA,CAAM,KAAA;AAAA,IACb,YAAY,KAAA,CAAM,UAAA;AAAA,IAClB,MAAA,EAAQ,MAAA;AAAA,IACR,QAAA;AAAA,IACA,aAAa,KAAA,CAAM,WAAA;AAAA,IACnB,iBAAiB,KAAA,CAAM,eAAA;AAAA,IACvB,YAAY,KAAA,CAAM,UAAA;AAAA,IAClB,gBAAgB,KAAA,CAAM,cAAA;AAAA,IACtB,gBAAA;AAAA,IACA,QAAQ,KAAA,CAAM;AAAA,GAChB;AACF;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDebouncedReload.esm.js","sources":["../../../../src/components/Table/hooks/useDebouncedReload.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\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 */\n\nimport { useEffect, useRef } from 'react';\nimport type { QueryState } from './types';\n\n/**\n * Triggers a debounced reload when query or pageSize changes.\n * Debouncing reduces backend load during rapid changes (e.g., typing in search).\n */\n/** @internal */\nexport function useDebouncedReload<TFilter>(\n query: QueryState<TFilter>,\n pageSize: number,\n reload: () => void,\n delay: number = 200,\n): void {\n const { sort, filter, search } = query;\n const prevDepsRef = useRef({ sort, filter, search, pageSize });\n\n useEffect(() => {\n const prev = prevDepsRef.current;\n if (\n prev.sort !== sort ||\n prev.filter !== filter ||\n prev.search !== search ||\n prev.pageSize !== pageSize\n ) {\n prevDepsRef.current = { sort, filter, search, pageSize };\n const timer = setTimeout(reload, delay);\n return () => clearTimeout(timer);\n }\n return undefined;\n }, [sort, filter, search, pageSize, reload, delay]);\n}\n"],"names":[],"mappings":";;AAwBO,SAAS,kBAAA,CACd,KAAA,EACA,QAAA,EACA,MAAA,EACA,QAAgB,GAAA,EACV;AACN,EAAA,MAAM,EAAE,IAAA,EAAM,MAAA,EAAQ,MAAA,EAAO,GAAI,KAAA;AACjC,EAAA,MAAM,cAAc,MAAA,CAAO,EAAE,MAAM,MAAA,EAAQ,MAAA,EAAQ,UAAU,CAAA;AAE7D,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,OAAO,WAAA,CAAY,OAAA;AACzB,IAAA,IACE,IAAA,CAAK,IAAA,KAAS,IAAA,IACd,IAAA,CAAK,MAAA,KAAW,MAAA,IAChB,IAAA,CAAK,MAAA,KAAW,MAAA,IAChB,IAAA,CAAK,QAAA,KAAa,QAAA,EAClB;AACA,MAAA,WAAA,CAAY,OAAA,GAAU,EAAE,IAAA,EAAM,MAAA,EAAQ,QAAQ,QAAA,EAAS;AACvD,MAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,MAAA,EAAQ,KAAK,CAAA;AACtC,MAAA,OAAO,MAAM,aAAa,KAAK,CAAA;AAAA,IACjC;AACA,IAAA,OAAO,MAAA;AAAA,EACT,CAAA,EAAG,CAAC,IAAA,EAAM,MAAA,EAAQ,QAAQ,QAAA,EAAU,MAAA,EAAQ,KAAK,CAAC,CAAA;AACpD
|
|
1
|
+
{"version":3,"file":"useDebouncedReload.esm.js","sources":["../../../../src/components/Table/hooks/useDebouncedReload.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\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 */\n\nimport { useEffect, useRef } from 'react';\nimport type { QueryState } from './types';\n\n/**\n * Triggers a debounced reload when query or pageSize changes.\n * Debouncing reduces backend load during rapid changes (e.g., typing in search).\n */\n/** @internal */\nexport function useDebouncedReload<TFilter>(\n query: QueryState<TFilter>,\n pageSize: number,\n reload: () => void,\n delay: number = 200,\n): void {\n const { sort, filter, search } = query;\n const prevDepsRef = useRef({ sort, filter, search, pageSize });\n\n useEffect(() => {\n const prev = prevDepsRef.current;\n if (\n prev.sort !== sort ||\n prev.filter !== filter ||\n prev.search !== search ||\n prev.pageSize !== pageSize\n ) {\n prevDepsRef.current = { sort, filter, search, pageSize };\n const timer = setTimeout(reload, delay);\n return () => clearTimeout(timer);\n }\n return undefined;\n }, [sort, filter, search, pageSize, reload, delay]);\n}\n"],"names":[],"mappings":";;AAwBO,SAAS,kBAAA,CACd,KAAA,EACA,QAAA,EACA,MAAA,EACA,QAAgB,GAAA,EACV;AACN,EAAA,MAAM,EAAE,IAAA,EAAM,MAAA,EAAQ,MAAA,EAAO,GAAI,KAAA;AACjC,EAAA,MAAM,cAAc,MAAA,CAAO,EAAE,MAAM,MAAA,EAAQ,MAAA,EAAQ,UAAU,CAAA;AAE7D,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,OAAO,WAAA,CAAY,OAAA;AACzB,IAAA,IACE,IAAA,CAAK,IAAA,KAAS,IAAA,IACd,IAAA,CAAK,MAAA,KAAW,MAAA,IAChB,IAAA,CAAK,MAAA,KAAW,MAAA,IAChB,IAAA,CAAK,QAAA,KAAa,QAAA,EAClB;AACA,MAAA,WAAA,CAAY,OAAA,GAAU,EAAE,IAAA,EAAM,MAAA,EAAQ,QAAQ,QAAA,EAAS;AACvD,MAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,MAAA,EAAQ,KAAK,CAAA;AACtC,MAAA,OAAO,MAAM,aAAa,KAAK,CAAA;AAAA,IACjC;AACA,IAAA,OAAO,MAAA;AAAA,EACT,CAAA,EAAG,CAAC,IAAA,EAAM,MAAA,EAAQ,QAAQ,QAAA,EAAU,MAAA,EAAQ,KAAK,CAAC,CAAA;AACpD;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDebouncedValue.esm.js","sources":["../../../../src/components/Table/hooks/useDebouncedValue.ts"],"sourcesContent":["/*\n * Copyright 2026 The Backstage Authors\n *\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 */\n\nimport { useEffect, useState } from 'react';\n\n/**\n * Returns a trailing-edge debounced surrogate of `value`.\n *\n * - When `delayMs <= 0`, the live `value` is returned directly without arming\n * a timer — a true bypass with no observable change relative to using\n * `value` itself.\n * - When `delayMs > 0`, the returned value lags behind `value` by `delayMs`\n * of stability. The timer is cleared on `value` change, `delayMs` change,\n * and on unmount.\n *\n * @internal\n */\nexport function useDebouncedValue<T>(value: T, delayMs: number): T {\n const [debounced, setDebounced] = useState<T>(value);\n\n useEffect(() => {\n if (delayMs <= 0) {\n return undefined;\n }\n const timer = setTimeout(() => setDebounced(value), delayMs);\n return () => clearTimeout(timer);\n }, [value, delayMs]);\n\n return delayMs <= 0 ? value : debounced;\n}\n"],"names":[],"mappings":";;AA8BO,SAAS,iBAAA,CAAqB,OAAU,OAAA,EAAoB;AACjE,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAY,KAAK,CAAA;AAEnD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,WAAW,CAAA,EAAG;AAChB,MAAA,OAAO,MAAA;AAAA,IACT;AACA,IAAA,MAAM,QAAQ,UAAA,CAAW,MAAM,YAAA,CAAa,KAAK,GAAG,OAAO,CAAA;AAC3D,IAAA,OAAO,MAAM,aAAa,KAAK,CAAA;AAAA,EACjC,CAAA,EAAG,CAAC,KAAA,EAAO,OAAO,CAAC,CAAA;AAEnB,EAAA,OAAO,OAAA,IAAW,IAAI,KAAA,GAAQ,SAAA;AAChC
|
|
1
|
+
{"version":3,"file":"useDebouncedValue.esm.js","sources":["../../../../src/components/Table/hooks/useDebouncedValue.ts"],"sourcesContent":["/*\n * Copyright 2026 The Backstage Authors\n *\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 */\n\nimport { useEffect, useState } from 'react';\n\n/**\n * Returns a trailing-edge debounced surrogate of `value`.\n *\n * - When `delayMs <= 0`, the live `value` is returned directly without arming\n * a timer — a true bypass with no observable change relative to using\n * `value` itself.\n * - When `delayMs > 0`, the returned value lags behind `value` by `delayMs`\n * of stability. The timer is cleared on `value` change, `delayMs` change,\n * and on unmount.\n *\n * @internal\n */\nexport function useDebouncedValue<T>(value: T, delayMs: number): T {\n const [debounced, setDebounced] = useState<T>(value);\n\n useEffect(() => {\n if (delayMs <= 0) {\n return undefined;\n }\n const timer = setTimeout(() => setDebounced(value), delayMs);\n return () => clearTimeout(timer);\n }, [value, delayMs]);\n\n return delayMs <= 0 ? value : debounced;\n}\n"],"names":[],"mappings":";;AA8BO,SAAS,iBAAA,CAAqB,OAAU,OAAA,EAAoB;AACjE,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAY,KAAK,CAAA;AAEnD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,WAAW,CAAA,EAAG;AAChB,MAAA,OAAO,MAAA;AAAA,IACT;AACA,IAAA,MAAM,QAAQ,UAAA,CAAW,MAAM,YAAA,CAAa,KAAK,GAAG,OAAO,CAAA;AAC3D,IAAA,OAAO,MAAM,aAAa,KAAK,CAAA;AAAA,EACjC,CAAA,EAAG,CAAC,KAAA,EAAO,OAAO,CAAC,CAAA;AAEnB,EAAA,OAAO,OAAA,IAAW,IAAI,KAAA,GAAQ,SAAA;AAChC;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useOffsetPagination.esm.js","sources":["../../../../src/components/Table/hooks/useOffsetPagination.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\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 { useState, useCallback } from 'react';\nimport type { TableItem } from '../types';\nimport type {\n UseTableOffsetOptions,\n OffsetParams,\n QueryState,\n PaginationResult,\n} from './types';\nimport { usePageCache } from './usePageCache';\nimport { useStableCallback } from './useStableCallback';\nimport { useDebouncedReload } from './useDebouncedReload';\nimport { getEffectivePageSize } from './getEffectivePageSize';\n\nexport function useOffsetPagination<T extends TableItem, TFilter>(\n options: UseTableOffsetOptions<T, TFilter>,\n query: QueryState<TFilter>,\n): PaginationResult<T> & { reload: () => void } {\n const { getData: getDataProp, paginationOptions = {} } = options;\n const { initialOffset = 0 } = paginationOptions;\n const defaultPageSize = getEffectivePageSize(paginationOptions);\n\n const getData = useStableCallback(getDataProp);\n const { sort, filter, search } = query;\n\n const [pageSize, setPageSize] = useState(defaultPageSize);\n\n const wrappedGetData = useCallback(\n async ({\n cursor,\n signal,\n }: {\n cursor: number | undefined;\n signal: AbortSignal;\n }) => {\n const currentOffset = cursor ?? 0;\n\n const params: OffsetParams<TFilter> = {\n offset: currentOffset,\n pageSize,\n sort,\n filter,\n search,\n signal,\n };\n\n const response = await getData(params);\n\n const prevCursor =\n currentOffset > 0 ? Math.max(0, currentOffset - pageSize) : undefined;\n const nextCursor =\n currentOffset + pageSize < response.totalCount\n ? currentOffset + pageSize\n : undefined;\n\n return {\n data: response.data,\n prevCursor,\n nextCursor,\n totalCount: response.totalCount,\n };\n },\n [getData, pageSize, sort, filter, search],\n );\n\n const cache = usePageCache<T, number>({\n getData: wrappedGetData,\n initialCurrentCursor: initialOffset > 0 ? initialOffset : undefined,\n });\n\n useDebouncedReload(query, pageSize, cache.reload);\n\n const onPageSizeChange = useCallback(\n (newSize: number) => setPageSize(newSize),\n [],\n );\n\n return {\n data: cache.data,\n isPending: cache.isPending,\n error: cache.error,\n totalCount: cache.totalCount,\n offset: cache.currentCursor ?? 0,\n pageSize,\n hasNextPage: cache.hasNextPage,\n hasPreviousPage: cache.hasPreviousPage,\n onNextPage: cache.onNextPage,\n onPreviousPage: cache.onPreviousPage,\n onPageSizeChange,\n reload: cache.reload,\n };\n}\n"],"names":[],"mappings":";;;;;;AA4BO,SAAS,mBAAA,CACd,SACA,KAAA,EAC8C;AAC9C,EAAA,MAAM,EAAE,OAAA,EAAS,WAAA,EAAa,iBAAA,GAAoB,IAAG,GAAI,OAAA;AACzD,EAAA,MAAM,EAAE,aAAA,GAAgB,CAAA,EAAE,GAAI,iBAAA;AAC9B,EAAA,MAAM,eAAA,GAAkB,qBAAqB,iBAAiB,CAAA;AAE9D,EAAA,MAAM,OAAA,GAAU,kBAAkB,WAAW,CAAA;AAC7C,EAAA,MAAM,EAAE,IAAA,EAAM,MAAA,EAAQ,MAAA,EAAO,GAAI,KAAA;AAEjC,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAAS,eAAe,CAAA;AAExD,EAAA,MAAM,cAAA,GAAiB,WAAA;AAAA,IACrB,OAAO;AAAA,MACL,MAAA;AAAA,MACA;AAAA,KACF,KAGM;AACJ,MAAA,MAAM,gBAAgB,MAAA,IAAU,CAAA;AAEhC,MAAA,MAAM,MAAA,GAAgC;AAAA,QACpC,MAAA,EAAQ,aAAA;AAAA,QACR,QAAA;AAAA,QACA,IAAA;AAAA,QACA,MAAA;AAAA,QACA,MAAA;AAAA,QACA;AAAA,OACF;AAEA,MAAA,MAAM,QAAA,GAAW,MAAM,OAAA,CAAQ,MAAM,CAAA;AAErC,MAAA,MAAM,UAAA,GACJ,gBAAgB,CAAA,GAAI,IAAA,CAAK,IAAI,CAAA,EAAG,aAAA,GAAgB,QAAQ,CAAA,GAAI,MAAA;AAC9D,MAAA,MAAM,aACJ,aAAA,GAAgB,QAAA,GAAW,QAAA,CAAS,UAAA,GAChC,gBAAgB,QAAA,GAChB,MAAA;AAEN,MAAA,OAAO;AAAA,QACL,MAAM,QAAA,CAAS,IAAA;AAAA,QACf,UAAA;AAAA,QACA,UAAA;AAAA,QACA,YAAY,QAAA,CAAS;AAAA,OACvB;AAAA,IACF,CAAA;AAAA,IACA,CAAC,OAAA,EAAS,QAAA,EAAU,IAAA,EAAM,QAAQ,MAAM;AAAA,GAC1C;AAEA,EAAA,MAAM,QAAQ,YAAA,CAAwB;AAAA,IACpC,OAAA,EAAS,cAAA;AAAA,IACT,oBAAA,EAAsB,aAAA,GAAgB,CAAA,GAAI,aAAA,GAAgB;AAAA,GAC3D,CAAA;AAED,EAAA,kBAAA,CAAmB,KAAA,EAAO,QAAA,EAAU,KAAA,CAAM,MAAM,CAAA;AAEhD,EAAA,MAAM,gBAAA,GAAmB,WAAA;AAAA,IACvB,CAAC,OAAA,KAAoB,WAAA,CAAY,OAAO,CAAA;AAAA,IACxC;AAAC,GACH;AAEA,EAAA,OAAO;AAAA,IACL,MAAM,KAAA,CAAM,IAAA;AAAA,IACZ,WAAW,KAAA,CAAM,SAAA;AAAA,IACjB,OAAO,KAAA,CAAM,KAAA;AAAA,IACb,YAAY,KAAA,CAAM,UAAA;AAAA,IAClB,MAAA,EAAQ,MAAM,aAAA,IAAiB,CAAA;AAAA,IAC/B,QAAA;AAAA,IACA,aAAa,KAAA,CAAM,WAAA;AAAA,IACnB,iBAAiB,KAAA,CAAM,eAAA;AAAA,IACvB,YAAY,KAAA,CAAM,UAAA;AAAA,IAClB,gBAAgB,KAAA,CAAM,cAAA;AAAA,IACtB,gBAAA;AAAA,IACA,QAAQ,KAAA,CAAM;AAAA,GAChB;AACF
|
|
1
|
+
{"version":3,"file":"useOffsetPagination.esm.js","sources":["../../../../src/components/Table/hooks/useOffsetPagination.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\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 { useState, useCallback } from 'react';\nimport type { TableItem } from '../types';\nimport type {\n UseTableOffsetOptions,\n OffsetParams,\n QueryState,\n PaginationResult,\n} from './types';\nimport { usePageCache } from './usePageCache';\nimport { useStableCallback } from './useStableCallback';\nimport { useDebouncedReload } from './useDebouncedReload';\nimport { getEffectivePageSize } from './getEffectivePageSize';\n\nexport function useOffsetPagination<T extends TableItem, TFilter>(\n options: UseTableOffsetOptions<T, TFilter>,\n query: QueryState<TFilter>,\n): PaginationResult<T> & { reload: () => void } {\n const { getData: getDataProp, paginationOptions = {} } = options;\n const { initialOffset = 0 } = paginationOptions;\n const defaultPageSize = getEffectivePageSize(paginationOptions);\n\n const getData = useStableCallback(getDataProp);\n const { sort, filter, search } = query;\n\n const [pageSize, setPageSize] = useState(defaultPageSize);\n\n const wrappedGetData = useCallback(\n async ({\n cursor,\n signal,\n }: {\n cursor: number | undefined;\n signal: AbortSignal;\n }) => {\n const currentOffset = cursor ?? 0;\n\n const params: OffsetParams<TFilter> = {\n offset: currentOffset,\n pageSize,\n sort,\n filter,\n search,\n signal,\n };\n\n const response = await getData(params);\n\n const prevCursor =\n currentOffset > 0 ? Math.max(0, currentOffset - pageSize) : undefined;\n const nextCursor =\n currentOffset + pageSize < response.totalCount\n ? currentOffset + pageSize\n : undefined;\n\n return {\n data: response.data,\n prevCursor,\n nextCursor,\n totalCount: response.totalCount,\n };\n },\n [getData, pageSize, sort, filter, search],\n );\n\n const cache = usePageCache<T, number>({\n getData: wrappedGetData,\n initialCurrentCursor: initialOffset > 0 ? initialOffset : undefined,\n });\n\n useDebouncedReload(query, pageSize, cache.reload);\n\n const onPageSizeChange = useCallback(\n (newSize: number) => setPageSize(newSize),\n [],\n );\n\n return {\n data: cache.data,\n isPending: cache.isPending,\n error: cache.error,\n totalCount: cache.totalCount,\n offset: cache.currentCursor ?? 0,\n pageSize,\n hasNextPage: cache.hasNextPage,\n hasPreviousPage: cache.hasPreviousPage,\n onNextPage: cache.onNextPage,\n onPreviousPage: cache.onPreviousPage,\n onPageSizeChange,\n reload: cache.reload,\n };\n}\n"],"names":[],"mappings":";;;;;;AA4BO,SAAS,mBAAA,CACd,SACA,KAAA,EAC8C;AAC9C,EAAA,MAAM,EAAE,OAAA,EAAS,WAAA,EAAa,iBAAA,GAAoB,IAAG,GAAI,OAAA;AACzD,EAAA,MAAM,EAAE,aAAA,GAAgB,CAAA,EAAE,GAAI,iBAAA;AAC9B,EAAA,MAAM,eAAA,GAAkB,qBAAqB,iBAAiB,CAAA;AAE9D,EAAA,MAAM,OAAA,GAAU,kBAAkB,WAAW,CAAA;AAC7C,EAAA,MAAM,EAAE,IAAA,EAAM,MAAA,EAAQ,MAAA,EAAO,GAAI,KAAA;AAEjC,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAAS,eAAe,CAAA;AAExD,EAAA,MAAM,cAAA,GAAiB,WAAA;AAAA,IACrB,OAAO;AAAA,MACL,MAAA;AAAA,MACA;AAAA,KACF,KAGM;AACJ,MAAA,MAAM,gBAAgB,MAAA,IAAU,CAAA;AAEhC,MAAA,MAAM,MAAA,GAAgC;AAAA,QACpC,MAAA,EAAQ,aAAA;AAAA,QACR,QAAA;AAAA,QACA,IAAA;AAAA,QACA,MAAA;AAAA,QACA,MAAA;AAAA,QACA;AAAA,OACF;AAEA,MAAA,MAAM,QAAA,GAAW,MAAM,OAAA,CAAQ,MAAM,CAAA;AAErC,MAAA,MAAM,UAAA,GACJ,gBAAgB,CAAA,GAAI,IAAA,CAAK,IAAI,CAAA,EAAG,aAAA,GAAgB,QAAQ,CAAA,GAAI,MAAA;AAC9D,MAAA,MAAM,aACJ,aAAA,GAAgB,QAAA,GAAW,QAAA,CAAS,UAAA,GAChC,gBAAgB,QAAA,GAChB,MAAA;AAEN,MAAA,OAAO;AAAA,QACL,MAAM,QAAA,CAAS,IAAA;AAAA,QACf,UAAA;AAAA,QACA,UAAA;AAAA,QACA,YAAY,QAAA,CAAS;AAAA,OACvB;AAAA,IACF,CAAA;AAAA,IACA,CAAC,OAAA,EAAS,QAAA,EAAU,IAAA,EAAM,QAAQ,MAAM;AAAA,GAC1C;AAEA,EAAA,MAAM,QAAQ,YAAA,CAAwB;AAAA,IACpC,OAAA,EAAS,cAAA;AAAA,IACT,oBAAA,EAAsB,aAAA,GAAgB,CAAA,GAAI,aAAA,GAAgB;AAAA,GAC3D,CAAA;AAED,EAAA,kBAAA,CAAmB,KAAA,EAAO,QAAA,EAAU,KAAA,CAAM,MAAM,CAAA;AAEhD,EAAA,MAAM,gBAAA,GAAmB,WAAA;AAAA,IACvB,CAAC,OAAA,KAAoB,WAAA,CAAY,OAAO,CAAA;AAAA,IACxC;AAAC,GACH;AAEA,EAAA,OAAO;AAAA,IACL,MAAM,KAAA,CAAM,IAAA;AAAA,IACZ,WAAW,KAAA,CAAM,SAAA;AAAA,IACjB,OAAO,KAAA,CAAM,KAAA;AAAA,IACb,YAAY,KAAA,CAAM,UAAA;AAAA,IAClB,MAAA,EAAQ,MAAM,aAAA,IAAiB,CAAA;AAAA,IAC/B,QAAA;AAAA,IACA,aAAa,KAAA,CAAM,WAAA;AAAA,IACnB,iBAAiB,KAAA,CAAM,eAAA;AAAA,IACvB,YAAY,KAAA,CAAM,UAAA;AAAA,IAClB,gBAAgB,KAAA,CAAM,cAAA;AAAA,IACtB,gBAAA;AAAA,IACA,QAAQ,KAAA,CAAM;AAAA,GAChB;AACF;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePageCache.esm.js","sources":["../../../../src/components/Table/hooks/usePageCache.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\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 */\n\nimport { useState, useCallback, useRef, useEffect, useReducer } from 'react';\n\nconst FIRST_PAGE_CURSOR = Symbol('firstPage');\n\ntype CursorType = string | number;\n\ntype InternalCursor<TCursor extends CursorType> =\n | TCursor\n | typeof FIRST_PAGE_CURSOR;\n\ninterface PageEntry<T, TCursor extends CursorType> {\n data: T[] | undefined;\n nextCursor: InternalCursor<TCursor> | undefined;\n prevCursor: InternalCursor<TCursor> | undefined;\n}\n\ninterface GetDataResult<T, TCursor extends CursorType> {\n data: T[];\n nextCursor?: TCursor;\n prevCursor?: TCursor;\n totalCount?: number;\n}\n\n/** @internal */\nexport interface UsePageCacheOptions<T, TCursor extends CursorType = string> {\n getData: (params: {\n cursor: TCursor | undefined;\n signal: AbortSignal;\n }) => Promise<GetDataResult<T, TCursor>>;\n initialCurrentCursor?: TCursor;\n}\n\n/** @internal */\nexport interface UsePageCacheResult<T, TCursor extends CursorType = string> {\n isPending: boolean;\n error: Error | undefined;\n data: T[] | undefined;\n totalCount: number | undefined;\n currentCursor: TCursor | undefined;\n hasPreviousPage: boolean;\n onPreviousPage: () => void;\n hasNextPage: boolean;\n onNextPage: () => void;\n reload: (options?: { keepCurrentCursor?: boolean }) => void;\n}\n\ntype Direction = 'mount' | 'reset' | 'refresh' | 'next' | 'prev';\n\nclass PageCacheStore<T, TCursor extends CursorType> {\n private cache = new Map<InternalCursor<TCursor>, PageEntry<T, TCursor>>();\n\n get(cursor: InternalCursor<TCursor>): PageEntry<T, TCursor> | undefined {\n return this.cache.get(cursor);\n }\n\n getOrCreate(cursor: InternalCursor<TCursor>): PageEntry<T, TCursor> {\n const existing = this.cache.get(cursor);\n if (existing) {\n return existing;\n }\n const entry: PageEntry<T, TCursor> = {\n data: undefined,\n nextCursor: undefined,\n prevCursor: undefined,\n };\n this.cache.set(cursor, entry);\n return entry;\n }\n\n clear() {\n this.cache.clear();\n }\n\n getTargetCursor(\n direction: Direction,\n currentCursor: InternalCursor<TCursor>,\n initialCurrentCursor: TCursor | undefined,\n ): InternalCursor<TCursor> | undefined {\n if (direction === 'mount') {\n return toInternalCursor(initialCurrentCursor);\n }\n if (direction === 'reset') {\n return FIRST_PAGE_CURSOR;\n }\n if (direction === 'refresh') {\n return currentCursor;\n }\n const currentEntry = this.cache.get(currentCursor);\n\n if (!currentEntry) {\n return;\n }\n\n return direction === 'next'\n ? currentEntry.nextCursor\n : currentEntry.prevCursor;\n }\n\n linkEntryToSource(\n entry: PageEntry<T, TCursor>,\n direction: Direction,\n currentCursor: InternalCursor<TCursor>,\n ) {\n if (direction === 'next') {\n entry.prevCursor = currentCursor;\n } else if (direction === 'prev') {\n entry.nextCursor = currentCursor;\n }\n }\n}\n\nfunction toInternalCursor<TCursor extends CursorType>(\n cursor: TCursor | undefined,\n): InternalCursor<TCursor> {\n return cursor === undefined ? FIRST_PAGE_CURSOR : cursor;\n}\n\nfunction toExternalCursor<TCursor extends CursorType>(\n cursor: InternalCursor<TCursor>,\n): TCursor | undefined {\n return cursor === FIRST_PAGE_CURSOR ? undefined : cursor;\n}\n\n/** @internal */\nexport function usePageCache<T, TCursor extends CursorType = string>(\n options: UsePageCacheOptions<T, TCursor>,\n): UsePageCacheResult<T, TCursor> {\n const { getData, initialCurrentCursor } = options;\n\n const [currentCursor, setCurrentCursor] = useState<InternalCursor<TCursor>>(\n () => toInternalCursor(initialCurrentCursor),\n );\n\n const cacheStore = useRef(new PageCacheStore<T, TCursor>()).current;\n\n const [isPending, setIsPending] = useState(true);\n const [error, setError] = useState<Error | undefined>(undefined);\n const [totalCount, setTotalCount] = useState<number | undefined>(undefined);\n const [, notifyCacheUpdate] = useReducer(version => version + 1, 0);\n\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const currentPage = cacheStore.get(currentCursor);\n const data = currentPage?.data;\n const hasNextPage = currentPage?.nextCursor !== undefined;\n const hasPreviousPage = currentPage?.prevCursor !== undefined;\n\n const goToPage = useCallback(\n async (direction: Direction) => {\n const targetCursor = cacheStore.getTargetCursor(\n direction,\n currentCursor,\n initialCurrentCursor,\n );\n\n if (targetCursor === undefined) {\n return;\n }\n\n const existingEntry = cacheStore.get(targetCursor);\n if (existingEntry?.data !== undefined) {\n setCurrentCursor(targetCursor);\n setError(undefined);\n return;\n }\n\n const entry = cacheStore.getOrCreate(targetCursor);\n cacheStore.linkEntryToSource(entry, direction, currentCursor);\n setCurrentCursor(targetCursor);\n\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n setIsPending(true);\n setError(undefined);\n\n try {\n const result = await getData({\n cursor: toExternalCursor(targetCursor),\n signal: abortController.signal,\n });\n\n if (abortController.signal.aborted) {\n return;\n }\n\n entry.data = result.data;\n\n if (entry.nextCursor === undefined && result.nextCursor !== undefined) {\n entry.nextCursor = result.nextCursor;\n }\n if (entry.prevCursor === undefined && result.prevCursor !== undefined) {\n entry.prevCursor = result.prevCursor;\n }\n\n if (result.totalCount !== undefined) {\n setTotalCount(result.totalCount);\n }\n\n notifyCacheUpdate();\n setIsPending(false);\n } catch (err) {\n if (abortController.signal.aborted) {\n return;\n }\n\n setError(err instanceof Error ? err : new Error(String(err)));\n setIsPending(false);\n }\n },\n [getData, initialCurrentCursor, currentCursor, cacheStore],\n );\n\n useEffect(() => {\n goToPage('mount');\n\n return () => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n };\n }, []);\n\n const onNextPage = useCallback(() => {\n if (isPending) return;\n const page = cacheStore.get(currentCursor);\n if (page?.nextCursor === undefined) return;\n goToPage('next');\n }, [isPending, currentCursor, goToPage, cacheStore]);\n\n const onPreviousPage = useCallback(() => {\n if (isPending) return;\n const page = cacheStore.get(currentCursor);\n if (page?.prevCursor === undefined) return;\n goToPage('prev');\n }, [isPending, currentCursor, goToPage, cacheStore]);\n\n const reload = useCallback(\n (reloadOptions?: { keepCurrentCursor?: boolean }) => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n\n cacheStore.clear();\n\n goToPage(reloadOptions?.keepCurrentCursor ? 'refresh' : 'reset');\n },\n [goToPage, cacheStore],\n );\n\n return {\n isPending,\n error,\n data,\n totalCount,\n currentCursor: toExternalCursor(currentCursor),\n hasPreviousPage,\n onPreviousPage,\n hasNextPage,\n onNextPage,\n reload,\n };\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"usePageCache.esm.js","sources":["../../../../src/components/Table/hooks/usePageCache.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\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 */\n\nimport { useState, useCallback, useRef, useEffect, useReducer } from 'react';\n\nconst FIRST_PAGE_CURSOR = Symbol('firstPage');\n\ntype CursorType = string | number;\n\ntype InternalCursor<TCursor extends CursorType> =\n | TCursor\n | typeof FIRST_PAGE_CURSOR;\n\ninterface PageEntry<T, TCursor extends CursorType> {\n data: T[] | undefined;\n nextCursor: InternalCursor<TCursor> | undefined;\n prevCursor: InternalCursor<TCursor> | undefined;\n}\n\ninterface GetDataResult<T, TCursor extends CursorType> {\n data: T[];\n nextCursor?: TCursor;\n prevCursor?: TCursor;\n totalCount?: number;\n}\n\n/** @internal */\nexport interface UsePageCacheOptions<T, TCursor extends CursorType = string> {\n getData: (params: {\n cursor: TCursor | undefined;\n signal: AbortSignal;\n }) => Promise<GetDataResult<T, TCursor>>;\n initialCurrentCursor?: TCursor;\n}\n\n/** @internal */\nexport interface UsePageCacheResult<T, TCursor extends CursorType = string> {\n isPending: boolean;\n error: Error | undefined;\n data: T[] | undefined;\n totalCount: number | undefined;\n currentCursor: TCursor | undefined;\n hasPreviousPage: boolean;\n onPreviousPage: () => void;\n hasNextPage: boolean;\n onNextPage: () => void;\n reload: (options?: { keepCurrentCursor?: boolean }) => void;\n}\n\ntype Direction = 'mount' | 'reset' | 'refresh' | 'next' | 'prev';\n\nclass PageCacheStore<T, TCursor extends CursorType> {\n private cache = new Map<InternalCursor<TCursor>, PageEntry<T, TCursor>>();\n\n get(cursor: InternalCursor<TCursor>): PageEntry<T, TCursor> | undefined {\n return this.cache.get(cursor);\n }\n\n getOrCreate(cursor: InternalCursor<TCursor>): PageEntry<T, TCursor> {\n const existing = this.cache.get(cursor);\n if (existing) {\n return existing;\n }\n const entry: PageEntry<T, TCursor> = {\n data: undefined,\n nextCursor: undefined,\n prevCursor: undefined,\n };\n this.cache.set(cursor, entry);\n return entry;\n }\n\n clear() {\n this.cache.clear();\n }\n\n getTargetCursor(\n direction: Direction,\n currentCursor: InternalCursor<TCursor>,\n initialCurrentCursor: TCursor | undefined,\n ): InternalCursor<TCursor> | undefined {\n if (direction === 'mount') {\n return toInternalCursor(initialCurrentCursor);\n }\n if (direction === 'reset') {\n return FIRST_PAGE_CURSOR;\n }\n if (direction === 'refresh') {\n return currentCursor;\n }\n const currentEntry = this.cache.get(currentCursor);\n\n if (!currentEntry) {\n return;\n }\n\n return direction === 'next'\n ? currentEntry.nextCursor\n : currentEntry.prevCursor;\n }\n\n linkEntryToSource(\n entry: PageEntry<T, TCursor>,\n direction: Direction,\n currentCursor: InternalCursor<TCursor>,\n ) {\n if (direction === 'next') {\n entry.prevCursor = currentCursor;\n } else if (direction === 'prev') {\n entry.nextCursor = currentCursor;\n }\n }\n}\n\nfunction toInternalCursor<TCursor extends CursorType>(\n cursor: TCursor | undefined,\n): InternalCursor<TCursor> {\n return cursor === undefined ? FIRST_PAGE_CURSOR : cursor;\n}\n\nfunction toExternalCursor<TCursor extends CursorType>(\n cursor: InternalCursor<TCursor>,\n): TCursor | undefined {\n return cursor === FIRST_PAGE_CURSOR ? undefined : cursor;\n}\n\n/** @internal */\nexport function usePageCache<T, TCursor extends CursorType = string>(\n options: UsePageCacheOptions<T, TCursor>,\n): UsePageCacheResult<T, TCursor> {\n const { getData, initialCurrentCursor } = options;\n\n const [currentCursor, setCurrentCursor] = useState<InternalCursor<TCursor>>(\n () => toInternalCursor(initialCurrentCursor),\n );\n\n const cacheStore = useRef(new PageCacheStore<T, TCursor>()).current;\n\n const [isPending, setIsPending] = useState(true);\n const [error, setError] = useState<Error | undefined>(undefined);\n const [totalCount, setTotalCount] = useState<number | undefined>(undefined);\n const [, notifyCacheUpdate] = useReducer(version => version + 1, 0);\n\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const currentPage = cacheStore.get(currentCursor);\n const data = currentPage?.data;\n const hasNextPage = currentPage?.nextCursor !== undefined;\n const hasPreviousPage = currentPage?.prevCursor !== undefined;\n\n const goToPage = useCallback(\n async (direction: Direction) => {\n const targetCursor = cacheStore.getTargetCursor(\n direction,\n currentCursor,\n initialCurrentCursor,\n );\n\n if (targetCursor === undefined) {\n return;\n }\n\n const existingEntry = cacheStore.get(targetCursor);\n if (existingEntry?.data !== undefined) {\n setCurrentCursor(targetCursor);\n setError(undefined);\n return;\n }\n\n const entry = cacheStore.getOrCreate(targetCursor);\n cacheStore.linkEntryToSource(entry, direction, currentCursor);\n setCurrentCursor(targetCursor);\n\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n setIsPending(true);\n setError(undefined);\n\n try {\n const result = await getData({\n cursor: toExternalCursor(targetCursor),\n signal: abortController.signal,\n });\n\n if (abortController.signal.aborted) {\n return;\n }\n\n entry.data = result.data;\n\n if (entry.nextCursor === undefined && result.nextCursor !== undefined) {\n entry.nextCursor = result.nextCursor;\n }\n if (entry.prevCursor === undefined && result.prevCursor !== undefined) {\n entry.prevCursor = result.prevCursor;\n }\n\n if (result.totalCount !== undefined) {\n setTotalCount(result.totalCount);\n }\n\n notifyCacheUpdate();\n setIsPending(false);\n } catch (err) {\n if (abortController.signal.aborted) {\n return;\n }\n\n setError(err instanceof Error ? err : new Error(String(err)));\n setIsPending(false);\n }\n },\n [getData, initialCurrentCursor, currentCursor, cacheStore],\n );\n\n useEffect(() => {\n goToPage('mount');\n\n return () => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n };\n }, []);\n\n const onNextPage = useCallback(() => {\n if (isPending) return;\n const page = cacheStore.get(currentCursor);\n if (page?.nextCursor === undefined) return;\n goToPage('next');\n }, [isPending, currentCursor, goToPage, cacheStore]);\n\n const onPreviousPage = useCallback(() => {\n if (isPending) return;\n const page = cacheStore.get(currentCursor);\n if (page?.prevCursor === undefined) return;\n goToPage('prev');\n }, [isPending, currentCursor, goToPage, cacheStore]);\n\n const reload = useCallback(\n (reloadOptions?: { keepCurrentCursor?: boolean }) => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n\n cacheStore.clear();\n\n goToPage(reloadOptions?.keepCurrentCursor ? 'refresh' : 'reset');\n },\n [goToPage, cacheStore],\n );\n\n return {\n isPending,\n error,\n data,\n totalCount,\n currentCursor: toExternalCursor(currentCursor),\n hasPreviousPage,\n onPreviousPage,\n hasNextPage,\n onNextPage,\n reload,\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useQueryState.esm.js","sources":["../../../../src/components/Table/hooks/useQueryState.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\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 */\n\nimport { useMemo, useState, useCallback } from 'react';\nimport type { QueryOptions, QueryState } from './types';\n\nfunction useControlledStateHelper<T, TControlled = T, TInitial = TControlled>(\n initialValue: TInitial,\n controlledValue: TControlled | undefined,\n onChange: ((value: T) => void) | undefined,\n) {\n const [internalValue, setInternalValue] = useState<TInitial>(initialValue);\n\n const value = controlledValue !== undefined ? controlledValue : internalValue;\n\n const setValue = useCallback(\n (newValue: T) => {\n if (controlledValue === undefined) {\n setInternalValue(newValue as unknown as TInitial);\n }\n if (onChange) {\n onChange(newValue);\n }\n },\n [controlledValue, onChange],\n );\n\n return [value, setValue] as const;\n}\n\n/** @internal */\nexport function useQueryState<TFilter>(\n options: QueryOptions<TFilter>,\n): QueryState<TFilter> {\n const [sort, setSort] = useControlledStateHelper(\n options.initialSort ?? null,\n options.sort,\n options.onSortChange,\n );\n const [filter, setFilter] = useControlledStateHelper(\n options.initialFilter,\n options.filter,\n options.onFilterChange,\n );\n const [search, setSearch] = useControlledStateHelper(\n options.initialSearch ?? '',\n options.search,\n options.onSearchChange,\n );\n\n return useMemo(\n () => ({ sort, setSort, filter, setFilter, search, setSearch }),\n [sort, setSort, filter, setFilter, search, setSearch],\n );\n}\n"],"names":[],"mappings":";;AAmBA,SAAS,wBAAA,CACP,YAAA,EACA,eAAA,EACA,QAAA,EACA;AACA,EAAA,MAAM,CAAC,aAAA,EAAe,gBAAgB,CAAA,GAAI,SAAmB,YAAY,CAAA;AAEzE,EAAA,MAAM,KAAA,GAAQ,eAAA,KAAoB,MAAA,GAAY,eAAA,GAAkB,aAAA;AAEhE,EAAA,MAAM,QAAA,GAAW,WAAA;AAAA,IACf,CAAC,QAAA,KAAgB;AACf,MAAA,IAAI,oBAAoB,MAAA,EAAW;AACjC,QAAA,gBAAA,CAAiB,QAA+B,CAAA;AAAA,MAClD;AACA,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,QAAA,CAAS,QAAQ,CAAA;AAAA,MACnB;AAAA,IACF,CAAA;AAAA,IACA,CAAC,iBAAiB,QAAQ;AAAA,GAC5B;AAEA,EAAA,OAAO,CAAC,OAAO,QAAQ,CAAA;AACzB;AAGO,SAAS,cACd,OAAA,EACqB;AACrB,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAI,wBAAA;AAAA,IACtB,QAAQ,WAAA,IAAe,IAAA;AAAA,IACvB,OAAA,CAAQ,IAAA;AAAA,IACR,OAAA,CAAQ;AAAA,GACV;AACA,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,wBAAA;AAAA,IAC1B,OAAA,CAAQ,aAAA;AAAA,IACR,OAAA,CAAQ,MAAA;AAAA,IACR,OAAA,CAAQ;AAAA,GACV;AACA,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,wBAAA;AAAA,IAC1B,QAAQ,aAAA,IAAiB,EAAA;AAAA,IACzB,OAAA,CAAQ,MAAA;AAAA,IACR,OAAA,CAAQ;AAAA,GACV;AAEA,EAAA,OAAO,OAAA;AAAA,IACL,OAAO,EAAE,IAAA,EAAM,SAAS,MAAA,EAAQ,SAAA,EAAW,QAAQ,SAAA,EAAU,CAAA;AAAA,IAC7D,CAAC,IAAA,EAAM,OAAA,EAAS,MAAA,EAAQ,SAAA,EAAW,QAAQ,SAAS;AAAA,GACtD;AACF
|
|
1
|
+
{"version":3,"file":"useQueryState.esm.js","sources":["../../../../src/components/Table/hooks/useQueryState.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\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 */\n\nimport { useMemo, useState, useCallback } from 'react';\nimport type { QueryOptions, QueryState } from './types';\n\nfunction useControlledStateHelper<T, TControlled = T, TInitial = TControlled>(\n initialValue: TInitial,\n controlledValue: TControlled | undefined,\n onChange: ((value: T) => void) | undefined,\n) {\n const [internalValue, setInternalValue] = useState<TInitial>(initialValue);\n\n const value = controlledValue !== undefined ? controlledValue : internalValue;\n\n const setValue = useCallback(\n (newValue: T) => {\n if (controlledValue === undefined) {\n setInternalValue(newValue as unknown as TInitial);\n }\n if (onChange) {\n onChange(newValue);\n }\n },\n [controlledValue, onChange],\n );\n\n return [value, setValue] as const;\n}\n\n/** @internal */\nexport function useQueryState<TFilter>(\n options: QueryOptions<TFilter>,\n): QueryState<TFilter> {\n const [sort, setSort] = useControlledStateHelper(\n options.initialSort ?? null,\n options.sort,\n options.onSortChange,\n );\n const [filter, setFilter] = useControlledStateHelper(\n options.initialFilter,\n options.filter,\n options.onFilterChange,\n );\n const [search, setSearch] = useControlledStateHelper(\n options.initialSearch ?? '',\n options.search,\n options.onSearchChange,\n );\n\n return useMemo(\n () => ({ sort, setSort, filter, setFilter, search, setSearch }),\n [sort, setSort, filter, setFilter, search, setSearch],\n );\n}\n"],"names":[],"mappings":";;AAmBA,SAAS,wBAAA,CACP,YAAA,EACA,eAAA,EACA,QAAA,EACA;AACA,EAAA,MAAM,CAAC,aAAA,EAAe,gBAAgB,CAAA,GAAI,SAAmB,YAAY,CAAA;AAEzE,EAAA,MAAM,KAAA,GAAQ,eAAA,KAAoB,MAAA,GAAY,eAAA,GAAkB,aAAA;AAEhE,EAAA,MAAM,QAAA,GAAW,WAAA;AAAA,IACf,CAAC,QAAA,KAAgB;AACf,MAAA,IAAI,oBAAoB,MAAA,EAAW;AACjC,QAAA,gBAAA,CAAiB,QAA+B,CAAA;AAAA,MAClD;AACA,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,QAAA,CAAS,QAAQ,CAAA;AAAA,MACnB;AAAA,IACF,CAAA;AAAA,IACA,CAAC,iBAAiB,QAAQ;AAAA,GAC5B;AAEA,EAAA,OAAO,CAAC,OAAO,QAAQ,CAAA;AACzB;AAGO,SAAS,cACd,OAAA,EACqB;AACrB,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAI,wBAAA;AAAA,IACtB,QAAQ,WAAA,IAAe,IAAA;AAAA,IACvB,OAAA,CAAQ,IAAA;AAAA,IACR,OAAA,CAAQ;AAAA,GACV;AACA,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,wBAAA;AAAA,IAC1B,OAAA,CAAQ,aAAA;AAAA,IACR,OAAA,CAAQ,MAAA;AAAA,IACR,OAAA,CAAQ;AAAA,GACV;AACA,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,wBAAA;AAAA,IAC1B,QAAQ,aAAA,IAAiB,EAAA;AAAA,IACzB,OAAA,CAAQ,MAAA;AAAA,IACR,OAAA,CAAQ;AAAA,GACV;AAEA,EAAA,OAAO,OAAA;AAAA,IACL,OAAO,EAAE,IAAA,EAAM,SAAS,MAAA,EAAQ,SAAA,EAAW,QAAQ,SAAA,EAAU,CAAA;AAAA,IAC7D,CAAC,IAAA,EAAM,OAAA,EAAS,MAAA,EAAQ,SAAA,EAAW,QAAQ,SAAS;AAAA,GACtD;AACF;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useStableCallback.esm.js","sources":["../../../../src/components/Table/hooks/useStableCallback.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\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 */\n\nimport { useRef, useCallback } from 'react';\n\n/**\n * Returns a stable callback reference that always calls the latest version\n * of the provided function. Useful for callbacks passed as props that may\n * change on every render but shouldn't trigger effect re-runs.\n *\n * @internal\n */\nexport function useStableCallback<T extends (...args: any[]) => any>(fn: T): T {\n const ref = useRef(fn);\n ref.current = fn;\n\n return useCallback((...args: Parameters<T>) => ref.current(...args), []) as T;\n}\n"],"names":[],"mappings":";;AAyBO,SAAS,kBAAqD,EAAA,EAAU;AAC7E,EAAA,MAAM,GAAA,GAAM,OAAO,EAAE,CAAA;AACrB,EAAA,GAAA,CAAI,OAAA,GAAU,EAAA;AAEd,EAAA,OAAO,WAAA,CAAY,IAAI,IAAA,KAAwB,GAAA,CAAI,QAAQ,GAAG,IAAI,CAAA,EAAG,EAAE,CAAA;AACzE
|
|
1
|
+
{"version":3,"file":"useStableCallback.esm.js","sources":["../../../../src/components/Table/hooks/useStableCallback.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\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 */\n\nimport { useRef, useCallback } from 'react';\n\n/**\n * Returns a stable callback reference that always calls the latest version\n * of the provided function. Useful for callbacks passed as props that may\n * change on every render but shouldn't trigger effect re-runs.\n *\n * @internal\n */\nexport function useStableCallback<T extends (...args: any[]) => any>(fn: T): T {\n const ref = useRef(fn);\n ref.current = fn;\n\n return useCallback((...args: Parameters<T>) => ref.current(...args), []) as T;\n}\n"],"names":[],"mappings":";;AAyBO,SAAS,kBAAqD,EAAA,EAAU;AAC7E,EAAA,MAAM,GAAA,GAAM,OAAO,EAAE,CAAA;AACrB,EAAA,GAAA,CAAI,OAAA,GAAU,EAAA;AAEd,EAAA,OAAO,WAAA,CAAY,IAAI,IAAA,KAAwB,GAAA,CAAI,QAAQ,GAAG,IAAI,CAAA,EAAG,EAAE,CAAA;AACzE;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTable.esm.js","sources":["../../../../src/components/Table/hooks/useTable.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\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 { useMemo, useRef } from 'react';\nimport type { SortState, TableItem, TableProps } from '../types';\nimport type {\n PaginationResult,\n UseTableCompleteOptions,\n UseTableCursorOptions,\n UseTableOffsetOptions,\n UseTableOptions,\n UseTableResult,\n} from './types';\nimport { useQueryState } from './useQueryState';\nimport { useCompletePagination } from './useCompletePagination';\nimport { useCursorPagination } from './useCursorPagination';\nimport { useOffsetPagination } from './useOffsetPagination';\n\nfunction useTableProps<T extends TableItem>(\n paginationResult: PaginationResult<T>,\n sortState: SortState,\n paginationOptions: UseTableCompleteOptions<T>['paginationOptions'] = {},\n): Omit<\n TableProps<T>,\n 'columnConfig' | 'rowConfig' | 'selection' | 'emptyState'\n> {\n const {\n showPageSizeOptions = true,\n pageSizeOptions,\n onPageSizeChange: onPageSizeChangeCallback,\n onNextPage: onNextPageCallback,\n onPreviousPage: onPreviousPageCallback,\n getLabel,\n showPaginationLabel,\n } = paginationOptions;\n\n const previousDataRef = useRef(paginationResult.data);\n if (paginationResult.data) {\n previousDataRef.current = paginationResult.data;\n }\n\n const displayData = paginationResult.data ?? previousDataRef.current;\n const isStale = paginationResult.isPending && displayData !== undefined;\n\n const pagination = useMemo(() => {\n if (paginationOptions.type === 'none') {\n return { type: 'none' as const };\n }\n return {\n type: 'page' as const,\n pageSize: paginationResult.pageSize,\n pageSizeOptions,\n offset: paginationResult.offset,\n totalCount: paginationResult.totalCount,\n hasNextPage: paginationResult.hasNextPage,\n hasPreviousPage: paginationResult.hasPreviousPage,\n onNextPage: () => {\n paginationResult.onNextPage();\n onNextPageCallback?.();\n },\n onPreviousPage: () => {\n paginationResult.onPreviousPage();\n onPreviousPageCallback?.();\n },\n onPageSizeChange: (size: number) => {\n paginationResult.onPageSizeChange(size);\n onPageSizeChangeCallback?.(size);\n },\n showPageSizeOptions,\n getLabel,\n showPaginationLabel,\n };\n }, [\n paginationOptions.type,\n paginationResult.pageSize,\n pageSizeOptions,\n paginationResult.offset,\n paginationResult.totalCount,\n paginationResult.hasNextPage,\n paginationResult.hasPreviousPage,\n paginationResult.onNextPage,\n paginationResult.onPreviousPage,\n paginationResult.onPageSizeChange,\n onNextPageCallback,\n onPreviousPageCallback,\n onPageSizeChangeCallback,\n showPageSizeOptions,\n getLabel,\n showPaginationLabel,\n ]);\n\n return useMemo(\n () => ({\n data: displayData,\n isPending: paginationResult.isPending,\n loading: paginationResult.isPending,\n isStale,\n error: paginationResult.error,\n pagination,\n sort: sortState,\n }),\n [\n displayData,\n paginationResult.isPending,\n isStale,\n paginationResult.error,\n pagination,\n sortState,\n ],\n );\n}\n\n/**\n * A hook that manages table data fetching, pagination, sorting, search, and filtering.\n * Supports three modes: `complete` for client-side data, `offset` for server-side offset pagination, and `cursor` for server-side cursor pagination.\n *\n * @public\n */\nexport function useTable<T extends TableItem, TFilter = unknown>(\n options: UseTableCompleteOptions<T, TFilter>,\n): UseTableResult<T, TFilter>;\n/** @public */\nexport function useTable<T extends TableItem, TFilter = unknown>(\n options: UseTableOffsetOptions<T, TFilter>,\n): UseTableResult<T, TFilter>;\n/** @public */\nexport function useTable<T extends TableItem, TFilter = unknown>(\n options: UseTableCursorOptions<T, TFilter>,\n): UseTableResult<T, TFilter>;\nexport function useTable<T extends TableItem, TFilter = unknown>(\n options: UseTableOptions<T, TFilter>,\n): UseTableResult<T, TFilter> {\n const query = useQueryState<TFilter>(options);\n\n const initialModeRef = useRef(options.mode);\n if (initialModeRef.current !== options.mode) {\n throw new Error(\n `useTable mode cannot change from '${initialModeRef.current}' to '${options.mode}'. ` +\n `The mode must remain stable for the lifetime of the component.`,\n );\n }\n\n let pagination: PaginationResult<T> & { reload: () => void };\n\n if (options.mode === 'complete') {\n pagination = useCompletePagination(options, query);\n } else if (options.mode === 'offset') {\n pagination = useOffsetPagination(options, query);\n } else if (options.mode === 'cursor') {\n pagination = useCursorPagination(options, query);\n } else {\n throw new Error('Invalid mode');\n }\n\n const sortState: SortState = useMemo(\n () => ({ descriptor: query.sort, onSortChange: query.setSort }),\n [query.sort, query.setSort],\n );\n\n const tableProps = useTableProps(\n pagination,\n sortState,\n options.paginationOptions ?? {},\n );\n\n return {\n tableProps,\n reload: pagination.reload,\n filter: { value: query.filter, onChange: query.setFilter },\n search: { value: query.search, onChange: query.setSearch },\n };\n}\n"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"useTable.esm.js","sources":["../../../../src/components/Table/hooks/useTable.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\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 { useMemo, useRef } from 'react';\nimport type { SortState, TableItem, TableProps } from '../types';\nimport type {\n PaginationResult,\n UseTableCompleteOptions,\n UseTableCursorOptions,\n UseTableOffsetOptions,\n UseTableOptions,\n UseTableResult,\n} from './types';\nimport { useQueryState } from './useQueryState';\nimport { useCompletePagination } from './useCompletePagination';\nimport { useCursorPagination } from './useCursorPagination';\nimport { useOffsetPagination } from './useOffsetPagination';\n\nfunction useTableProps<T extends TableItem>(\n paginationResult: PaginationResult<T>,\n sortState: SortState,\n paginationOptions: UseTableCompleteOptions<T>['paginationOptions'] = {},\n): Omit<\n TableProps<T>,\n 'columnConfig' | 'rowConfig' | 'selection' | 'emptyState'\n> {\n const {\n showPageSizeOptions = true,\n pageSizeOptions,\n onPageSizeChange: onPageSizeChangeCallback,\n onNextPage: onNextPageCallback,\n onPreviousPage: onPreviousPageCallback,\n getLabel,\n showPaginationLabel,\n } = paginationOptions;\n\n const previousDataRef = useRef(paginationResult.data);\n if (paginationResult.data) {\n previousDataRef.current = paginationResult.data;\n }\n\n const displayData = paginationResult.data ?? previousDataRef.current;\n const isStale = paginationResult.isPending && displayData !== undefined;\n\n const pagination = useMemo(() => {\n if (paginationOptions.type === 'none') {\n return { type: 'none' as const };\n }\n return {\n type: 'page' as const,\n pageSize: paginationResult.pageSize,\n pageSizeOptions,\n offset: paginationResult.offset,\n totalCount: paginationResult.totalCount,\n hasNextPage: paginationResult.hasNextPage,\n hasPreviousPage: paginationResult.hasPreviousPage,\n onNextPage: () => {\n paginationResult.onNextPage();\n onNextPageCallback?.();\n },\n onPreviousPage: () => {\n paginationResult.onPreviousPage();\n onPreviousPageCallback?.();\n },\n onPageSizeChange: (size: number) => {\n paginationResult.onPageSizeChange(size);\n onPageSizeChangeCallback?.(size);\n },\n showPageSizeOptions,\n getLabel,\n showPaginationLabel,\n };\n }, [\n paginationOptions.type,\n paginationResult.pageSize,\n pageSizeOptions,\n paginationResult.offset,\n paginationResult.totalCount,\n paginationResult.hasNextPage,\n paginationResult.hasPreviousPage,\n paginationResult.onNextPage,\n paginationResult.onPreviousPage,\n paginationResult.onPageSizeChange,\n onNextPageCallback,\n onPreviousPageCallback,\n onPageSizeChangeCallback,\n showPageSizeOptions,\n getLabel,\n showPaginationLabel,\n ]);\n\n return useMemo(\n () => ({\n data: displayData,\n isPending: paginationResult.isPending,\n loading: paginationResult.isPending,\n isStale,\n error: paginationResult.error,\n pagination,\n sort: sortState,\n }),\n [\n displayData,\n paginationResult.isPending,\n isStale,\n paginationResult.error,\n pagination,\n sortState,\n ],\n );\n}\n\n/**\n * A hook that manages table data fetching, pagination, sorting, search, and filtering.\n * Supports three modes: `complete` for client-side data, `offset` for server-side offset pagination, and `cursor` for server-side cursor pagination.\n *\n * @public\n */\nexport function useTable<T extends TableItem, TFilter = unknown>(\n options: UseTableCompleteOptions<T, TFilter>,\n): UseTableResult<T, TFilter>;\n/** @public */\nexport function useTable<T extends TableItem, TFilter = unknown>(\n options: UseTableOffsetOptions<T, TFilter>,\n): UseTableResult<T, TFilter>;\n/** @public */\nexport function useTable<T extends TableItem, TFilter = unknown>(\n options: UseTableCursorOptions<T, TFilter>,\n): UseTableResult<T, TFilter>;\nexport function useTable<T extends TableItem, TFilter = unknown>(\n options: UseTableOptions<T, TFilter>,\n): UseTableResult<T, TFilter> {\n const query = useQueryState<TFilter>(options);\n\n const initialModeRef = useRef(options.mode);\n if (initialModeRef.current !== options.mode) {\n throw new Error(\n `useTable mode cannot change from '${initialModeRef.current}' to '${options.mode}'. ` +\n `The mode must remain stable for the lifetime of the component.`,\n );\n }\n\n let pagination: PaginationResult<T> & { reload: () => void };\n\n if (options.mode === 'complete') {\n pagination = useCompletePagination(options, query);\n } else if (options.mode === 'offset') {\n pagination = useOffsetPagination(options, query);\n } else if (options.mode === 'cursor') {\n pagination = useCursorPagination(options, query);\n } else {\n throw new Error('Invalid mode');\n }\n\n const sortState: SortState = useMemo(\n () => ({ descriptor: query.sort, onSortChange: query.setSort }),\n [query.sort, query.setSort],\n );\n\n const tableProps = useTableProps(\n pagination,\n sortState,\n options.paginationOptions ?? {},\n );\n\n return {\n tableProps,\n reload: pagination.reload,\n filter: { value: query.filter, onChange: query.setFilter },\n search: { value: query.search, onChange: query.setSearch },\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TablePagination.esm.js","sources":["../../../src/components/TablePagination/TablePagination.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\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 */\n\nimport { useId } from 'react-aria';\nimport { Text } from '../Text';\nimport { ButtonIcon } from '../ButtonIcon';\nimport { Select } from '../Select';\nimport type { TablePaginationProps, PageSizeOption } from './types';\nimport { useDefinition } from '../../hooks/useDefinition';\nimport { TablePaginationDefinition } from './definition';\nimport { RiArrowLeftSLine, RiArrowRightSLine } from '@remixicon/react';\nimport { useMemo } from 'react';\n\nfunction getOptionValue(option: number | PageSizeOption): number {\n return typeof option === 'number' ? option : option.value;\n}\n\nfunction isNumberArray(\n options: number[] | PageSizeOption[],\n): options is number[] {\n return options.length > 0 && typeof options[0] === 'number';\n}\n\nfunction normalizePageSizeOptions(\n options: number[] | PageSizeOption[],\n): PageSizeOption[] {\n if (isNumberArray(options)) {\n return options.map(value => ({\n label: `Show ${value} results`,\n value,\n }));\n }\n return options;\n}\n\n/**\n * Pagination controls for Table components with page navigation and size selection.\n *\n * @public\n */\nexport function TablePagination(props: TablePaginationProps) {\n const { ownProps } = useDefinition(TablePaginationDefinition, props);\n const {\n classes,\n pageSize,\n pageSizeOptions,\n offset,\n totalCount,\n hasNextPage,\n hasPreviousPage,\n onNextPage,\n onPreviousPage,\n onPageSizeChange,\n showPageSizeOptions,\n getLabel,\n showPaginationLabel,\n } = ownProps;\n\n const labelId = useId();\n const normalizedOptions = useMemo(\n () => normalizePageSizeOptions(pageSizeOptions),\n [pageSizeOptions],\n );\n\n const effectivePageSize = useMemo(() => {\n if (pageSizeOptions.length === 0) {\n return pageSize;\n }\n const isValid = pageSizeOptions.some(\n opt => getOptionValue(opt) === pageSize,\n );\n if (isValid) {\n return pageSize;\n }\n const firstValue = getOptionValue(pageSizeOptions[0]);\n console.warn(\n `TablePagination: pageSize ${pageSize} is not in pageSizeOptions, using ${firstValue} instead`,\n );\n return firstValue;\n }, [pageSize, pageSizeOptions]);\n\n const hasItems = totalCount !== undefined && totalCount !== 0;\n\n const showLabel = hasItems && showPaginationLabel !== false;\n\n let label = `${totalCount} items`;\n if (getLabel) {\n label = getLabel({ pageSize: effectivePageSize, offset, totalCount });\n } else if (offset !== undefined) {\n const fromCount = offset + 1;\n const toCount = Math.min(offset + effectivePageSize, totalCount ?? 0);\n label = `${fromCount} - ${toCount} of ${totalCount}`;\n }\n\n return (\n <div className={classes.root}>\n <div className={classes.left}>\n {showPageSizeOptions && normalizedOptions.length > 0 && (\n <Select\n name=\"pageSize\"\n size=\"small\"\n aria-label=\"Select table page size\"\n options={normalizedOptions.map(opt => ({\n label: opt.label,\n value: String(opt.value),\n }))}\n value={effectivePageSize.toString()}\n onChange={value => {\n const newPageSize = Number(value);\n onPageSizeChange?.(newPageSize);\n }}\n className={classes.select}\n />\n )}\n </div>\n <div className={classes.right}>\n {showLabel && (\n <Text as=\"p\" variant=\"body-medium\" id={labelId}>\n {label}\n </Text>\n )}\n <ButtonIcon\n variant=\"secondary\"\n size=\"small\"\n onClick={onPreviousPage}\n isDisabled={!hasPreviousPage}\n icon={<RiArrowLeftSLine />}\n aria-label=\"Previous table page\"\n aria-describedby={showLabel ? labelId : undefined}\n />\n <ButtonIcon\n variant=\"secondary\"\n size=\"small\"\n onClick={onNextPage}\n isDisabled={!hasNextPage}\n icon={<RiArrowRightSLine />}\n aria-label=\"Next table page\"\n aria-describedby={showLabel ? labelId : undefined}\n />\n </div>\n </div>\n );\n}\n"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"TablePagination.esm.js","sources":["../../../src/components/TablePagination/TablePagination.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\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 */\n\nimport { useId } from 'react-aria';\nimport { Text } from '../Text';\nimport { ButtonIcon } from '../ButtonIcon';\nimport { Select } from '../Select';\nimport type { TablePaginationProps, PageSizeOption } from './types';\nimport { useDefinition } from '../../hooks/useDefinition';\nimport { TablePaginationDefinition } from './definition';\nimport { RiArrowLeftSLine, RiArrowRightSLine } from '@remixicon/react';\nimport { useMemo } from 'react';\n\nfunction getOptionValue(option: number | PageSizeOption): number {\n return typeof option === 'number' ? option : option.value;\n}\n\nfunction isNumberArray(\n options: number[] | PageSizeOption[],\n): options is number[] {\n return options.length > 0 && typeof options[0] === 'number';\n}\n\nfunction normalizePageSizeOptions(\n options: number[] | PageSizeOption[],\n): PageSizeOption[] {\n if (isNumberArray(options)) {\n return options.map(value => ({\n label: `Show ${value} results`,\n value,\n }));\n }\n return options;\n}\n\n/**\n * Pagination controls for Table components with page navigation and size selection.\n *\n * @public\n */\nexport function TablePagination(props: TablePaginationProps) {\n const { ownProps } = useDefinition(TablePaginationDefinition, props);\n const {\n classes,\n pageSize,\n pageSizeOptions,\n offset,\n totalCount,\n hasNextPage,\n hasPreviousPage,\n onNextPage,\n onPreviousPage,\n onPageSizeChange,\n showPageSizeOptions,\n getLabel,\n showPaginationLabel,\n } = ownProps;\n\n const labelId = useId();\n const normalizedOptions = useMemo(\n () => normalizePageSizeOptions(pageSizeOptions),\n [pageSizeOptions],\n );\n\n const effectivePageSize = useMemo(() => {\n if (pageSizeOptions.length === 0) {\n return pageSize;\n }\n const isValid = pageSizeOptions.some(\n opt => getOptionValue(opt) === pageSize,\n );\n if (isValid) {\n return pageSize;\n }\n const firstValue = getOptionValue(pageSizeOptions[0]);\n console.warn(\n `TablePagination: pageSize ${pageSize} is not in pageSizeOptions, using ${firstValue} instead`,\n );\n return firstValue;\n }, [pageSize, pageSizeOptions]);\n\n const hasItems = totalCount !== undefined && totalCount !== 0;\n\n const showLabel = hasItems && showPaginationLabel !== false;\n\n let label = `${totalCount} items`;\n if (getLabel) {\n label = getLabel({ pageSize: effectivePageSize, offset, totalCount });\n } else if (offset !== undefined) {\n const fromCount = offset + 1;\n const toCount = Math.min(offset + effectivePageSize, totalCount ?? 0);\n label = `${fromCount} - ${toCount} of ${totalCount}`;\n }\n\n return (\n <div className={classes.root}>\n <div className={classes.left}>\n {showPageSizeOptions && normalizedOptions.length > 0 && (\n <Select\n name=\"pageSize\"\n size=\"small\"\n aria-label=\"Select table page size\"\n options={normalizedOptions.map(opt => ({\n label: opt.label,\n value: String(opt.value),\n }))}\n value={effectivePageSize.toString()}\n onChange={value => {\n const newPageSize = Number(value);\n onPageSizeChange?.(newPageSize);\n }}\n className={classes.select}\n />\n )}\n </div>\n <div className={classes.right}>\n {showLabel && (\n <Text as=\"p\" variant=\"body-medium\" id={labelId}>\n {label}\n </Text>\n )}\n <ButtonIcon\n variant=\"secondary\"\n size=\"small\"\n onClick={onPreviousPage}\n isDisabled={!hasPreviousPage}\n icon={<RiArrowLeftSLine />}\n aria-label=\"Previous table page\"\n aria-describedby={showLabel ? labelId : undefined}\n />\n <ButtonIcon\n variant=\"secondary\"\n size=\"small\"\n onClick={onNextPage}\n isDisabled={!hasNextPage}\n icon={<RiArrowRightSLine />}\n aria-label=\"Next table page\"\n aria-describedby={showLabel ? labelId : undefined}\n />\n </div>\n </div>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TablePagination.module.css.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TablePagination.module.css.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definition.esm.js","sources":["../../../src/components/TablePagination/definition.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\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 */\n\nimport { defineComponent } from '../../hooks/useDefinition';\nimport type { TablePaginationOwnProps, PageSizeOption } from './types';\nimport styles from './TablePagination.module.css';\n\nconst DEFAULT_PAGE_SIZE_OPTIONS: PageSizeOption[] = [\n { label: 'Show 5 results', value: 5 },\n { label: 'Show 10 results', value: 10 },\n { label: 'Show 20 results', value: 20 },\n { label: 'Show 30 results', value: 30 },\n { label: 'Show 40 results', value: 40 },\n { label: 'Show 50 results', value: 50 },\n];\n\n/**\n * Component definition for TablePagination\n * @public\n */\nexport const TablePaginationDefinition =\n defineComponent<TablePaginationOwnProps>()({\n styles,\n classNames: {\n root: 'bui-TablePagination',\n left: 'bui-TablePaginationLeft',\n right: 'bui-TablePaginationRight',\n select: 'bui-TablePaginationSelect',\n },\n propDefs: {\n pageSize: {},\n pageSizeOptions: { default: DEFAULT_PAGE_SIZE_OPTIONS },\n offset: {},\n totalCount: {},\n hasNextPage: {},\n hasPreviousPage: {},\n onNextPage: {},\n onPreviousPage: {},\n onPageSizeChange: {},\n showPageSizeOptions: { default: true },\n getLabel: {},\n showPaginationLabel: { default: true },\n },\n });\n"],"names":[],"mappings":";;;;;;;;;;;;AAoBA,MAAM,yBAAA,GAA8C;AAAA,EAClD,EAAE,KAAA,EAAO,gBAAA,EAAkB,KAAA,EAAO,CAAA,EAAE;AAAA,EACpC,EAAE,KAAA,EAAO,iBAAA,EAAmB,KAAA,EAAO,EAAA,EAAG;AAAA,EACtC,EAAE,KAAA,EAAO,iBAAA,EAAmB,KAAA,EAAO,EAAA,EAAG;AAAA,EACtC,EAAE,KAAA,EAAO,iBAAA,EAAmB,KAAA,EAAO,EAAA,EAAG;AAAA,EACtC,EAAE,KAAA,EAAO,iBAAA,EAAmB,KAAA,EAAO,EAAA,EAAG;AAAA,EACtC,EAAE,KAAA,EAAO,iBAAA,EAAmB,KAAA,EAAO,EAAA;AACrC,CAAA;AAMO,MAAM,yBAAA,GACX,iBAAyC,CAAE;AAAA,EACzC,MAAA;AAAA,EACA,UAAA,EAAY;AAAA,IACV,IAAA,EAAM,qBAAA;AAAA,IACN,IAAA,EAAM,yBAAA;AAAA,IACN,KAAA,EAAO,0BAAA;AAAA,IACP,MAAA,EAAQ;AAAA,GACV;AAAA,EACA,QAAA,EAAU;AAAA,IACR,UAAU,EAAC;AAAA,IACX,eAAA,EAAiB,EAAE,OAAA,EAAS,yBAAA,EAA0B;AAAA,IACtD,QAAQ,EAAC;AAAA,IACT,YAAY,EAAC;AAAA,IACb,aAAa,EAAC;AAAA,IACd,iBAAiB,EAAC;AAAA,IAClB,YAAY,EAAC;AAAA,IACb,gBAAgB,EAAC;AAAA,IACjB,kBAAkB,EAAC;AAAA,IACnB,mBAAA,EAAqB,EAAE,OAAA,EAAS,IAAA,EAAK;AAAA,IACrC,UAAU,EAAC;AAAA,IACX,mBAAA,EAAqB,EAAE,OAAA,EAAS,IAAA;AAAK;AAEzC,CAAC
|
|
1
|
+
{"version":3,"file":"definition.esm.js","sources":["../../../src/components/TablePagination/definition.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\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 */\n\nimport { defineComponent } from '../../hooks/useDefinition';\nimport type { TablePaginationOwnProps, PageSizeOption } from './types';\nimport styles from './TablePagination.module.css';\n\nconst DEFAULT_PAGE_SIZE_OPTIONS: PageSizeOption[] = [\n { label: 'Show 5 results', value: 5 },\n { label: 'Show 10 results', value: 10 },\n { label: 'Show 20 results', value: 20 },\n { label: 'Show 30 results', value: 30 },\n { label: 'Show 40 results', value: 40 },\n { label: 'Show 50 results', value: 50 },\n];\n\n/**\n * Component definition for TablePagination\n * @public\n */\nexport const TablePaginationDefinition =\n defineComponent<TablePaginationOwnProps>()({\n styles,\n classNames: {\n root: 'bui-TablePagination',\n left: 'bui-TablePaginationLeft',\n right: 'bui-TablePaginationRight',\n select: 'bui-TablePaginationSelect',\n },\n propDefs: {\n pageSize: {},\n pageSizeOptions: { default: DEFAULT_PAGE_SIZE_OPTIONS },\n offset: {},\n totalCount: {},\n hasNextPage: {},\n hasPreviousPage: {},\n onNextPage: {},\n onPreviousPage: {},\n onPageSizeChange: {},\n showPageSizeOptions: { default: true },\n getLabel: {},\n showPaginationLabel: { default: true },\n },\n });\n"],"names":[],"mappings":";;;;;;;;;;;;AAoBA,MAAM,yBAAA,GAA8C;AAAA,EAClD,EAAE,KAAA,EAAO,gBAAA,EAAkB,KAAA,EAAO,CAAA,EAAE;AAAA,EACpC,EAAE,KAAA,EAAO,iBAAA,EAAmB,KAAA,EAAO,EAAA,EAAG;AAAA,EACtC,EAAE,KAAA,EAAO,iBAAA,EAAmB,KAAA,EAAO,EAAA,EAAG;AAAA,EACtC,EAAE,KAAA,EAAO,iBAAA,EAAmB,KAAA,EAAO,EAAA,EAAG;AAAA,EACtC,EAAE,KAAA,EAAO,iBAAA,EAAmB,KAAA,EAAO,EAAA,EAAG;AAAA,EACtC,EAAE,KAAA,EAAO,iBAAA,EAAmB,KAAA,EAAO,EAAA;AACrC,CAAA;AAMO,MAAM,yBAAA,GACX,iBAAyC,CAAE;AAAA,EACzC,MAAA;AAAA,EACA,UAAA,EAAY;AAAA,IACV,IAAA,EAAM,qBAAA;AAAA,IACN,IAAA,EAAM,yBAAA;AAAA,IACN,KAAA,EAAO,0BAAA;AAAA,IACP,MAAA,EAAQ;AAAA,GACV;AAAA,EACA,QAAA,EAAU;AAAA,IACR,UAAU,EAAC;AAAA,IACX,eAAA,EAAiB,EAAE,OAAA,EAAS,yBAAA,EAA0B;AAAA,IACtD,QAAQ,EAAC;AAAA,IACT,YAAY,EAAC;AAAA,IACb,aAAa,EAAC;AAAA,IACd,iBAAiB,EAAC;AAAA,IAClB,YAAY,EAAC;AAAA,IACb,gBAAgB,EAAC;AAAA,IACjB,kBAAkB,EAAC;AAAA,IACnB,mBAAA,EAAqB,EAAE,OAAA,EAAS,IAAA,EAAK;AAAA,IACrC,UAAU,EAAC;AAAA,IACX,mBAAA,EAAqB,EAAE,OAAA,EAAS,IAAA;AAAK;AAEzC,CAAC;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tabs.esm.js","sources":["../../../src/components/Tabs/Tabs.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\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 */\n\nimport {\n useRef,\n useState,\n useMemo,\n Children,\n cloneElement,\n isValidElement,\n createContext,\n useContext,\n useEffect,\n useCallback,\n} from 'react';\nimport type { ReactNode } from 'react';\nimport type {\n TabsProps,\n TabListProps,\n TabPanelProps,\n TabsContextValue,\n TabProps,\n} from './types';\nimport { TabsIndicators } from './TabsIndicators';\nimport {\n Tabs as AriaTabs,\n TabList as AriaTabList,\n Tab as AriaTab,\n TabPanel as AriaTabPanel,\n TabProps as AriaTabProps,\n} from 'react-aria-components';\nimport {\n useDefinition,\n type UseDefinitionResult,\n} from '../../hooks/useDefinition';\nimport {\n TabsDefinition,\n TabListDefinition,\n TabDefinition,\n TabPanelDefinition,\n} from './definition';\nimport { getNodeText } from '../../analytics/getNodeText';\nimport { useRoutingIntegration } from '../../navigation/useRouting';\nimport {\n getReactAriaAnchorProps,\n type AnchorNavigation,\n} from '../../navigation/useNavigation';\n\nconst TabsContext = createContext<TabsContextValue | undefined>(undefined);\n\nconst useTabsContext = () => {\n const context = useContext(TabsContext);\n if (!context) {\n throw new Error('Tab components must be used within a Tabs component');\n }\n return context;\n};\n\ntype TabSelectionContextValue = {\n registerRoutedTab: (id: string) => void;\n unregisterRoutedTab: (id: string) => void;\n registerActiveTab: (id: string, segmentCount: number) => void;\n unregisterActiveTab: (id: string) => void;\n};\n\nconst TabSelectionContext = createContext<TabSelectionContextValue | null>(\n null,\n);\n\n/**\n * Strips query params and hash from a href, leaving only the pathname.\n * Tab matching always compares against location.pathname which never includes them.\n */\nconst hrefPathname = (href: string) => href.split('?')[0].split('#')[0];\n\n/**\n * Utility function to determine if a tab should be active based on the matching strategy.\n * This follows the pattern used in WorkaroundNavLink from the sidebar.\n */\nconst isTabActive = (\n tabHref: string,\n currentPathname: string,\n matchStrategy: 'exact' | 'prefix',\n): boolean => {\n const pathname = hrefPathname(tabHref);\n\n if (matchStrategy === 'exact') {\n return pathname === currentPathname;\n }\n\n // Prefix matching - similar to WorkaroundNavLink behavior\n if (pathname === currentPathname) {\n return true;\n }\n\n // Check if current path starts with tab href followed by a slash\n // This prevents /foo matching /foobar\n return currentPathname.startsWith(`${pathname}/`);\n};\n\n/**\n * A component that renders a list of tabs.\n *\n * @public\n */\nexport const Tabs = (props: TabsProps) => {\n const { ownProps, restProps } = useDefinition(TabsDefinition, props);\n const { classes, children } = ownProps;\n const tabsRef = useRef<HTMLDivElement>(null);\n const tabRefs = useRef<Map<string, HTMLDivElement>>(new Map());\n const [hoveredKey, setHoveredKey] = useState<string | null>(null);\n const prevHoveredKey = useRef<string | null>(null);\n\n // State for tracking routed tabs (tabs with hrefs)\n const [routedTabs, setRoutedTabs] = useState<Set<string>>(() => new Set());\n\n // State for tracking active tabs reported by TabRouteRegistration components\n const [activeTabs, setActiveTabs] = useState<Map<string, number>>(\n () => new Map(),\n );\n\n const setTabRef = (key: string, element: HTMLDivElement | null) => {\n if (element) {\n tabRefs.current.set(key, element);\n } else {\n tabRefs.current.delete(key);\n }\n };\n\n // Compute the selected tab based on active tabs with highest segment count\n const selectedTabId = useMemo(() => {\n // No routed tabs - let React Aria handle selection (uncontrolled mode)\n if (routedTabs.size === 0) {\n return undefined;\n }\n\n // Has routed tabs but none are active - use empty string for no selection\n // (React Aria has a bug with null that causes infinite loops)\n if (activeTabs.size === 0) {\n return '';\n }\n\n let selectedId: string | undefined;\n let maxSegments = -1;\n\n activeTabs.forEach((segmentCount, id) => {\n // Pick tab with highest segment count, first one wins on tie\n if (segmentCount > maxSegments) {\n maxSegments = segmentCount;\n selectedId = id;\n }\n });\n\n return selectedId;\n }, [routedTabs, activeTabs]);\n\n const registerRoutedTab = useCallback((id: string) => {\n setRoutedTabs(prev => new Set(prev).add(id));\n }, []);\n\n const unregisterRoutedTab = useCallback((id: string) => {\n setRoutedTabs(prev => {\n const next = new Set(prev);\n next.delete(id);\n return next;\n });\n }, []);\n\n const registerActiveTab = useCallback((id: string, segmentCount: number) => {\n setActiveTabs(prev => new Map(prev).set(id, segmentCount));\n }, []);\n\n const unregisterActiveTab = useCallback((id: string) => {\n setActiveTabs(prev => {\n const next = new Map(prev);\n next.delete(id);\n return next;\n });\n }, []);\n\n if (!children) return null;\n\n const tabsContextValue: TabsContextValue = {\n tabsRef,\n tabRefs,\n hoveredKey,\n prevHoveredKey,\n setHoveredKey,\n setTabRef,\n };\n\n const selectionContextValue: TabSelectionContextValue = useMemo(\n () => ({\n registerRoutedTab,\n unregisterRoutedTab,\n registerActiveTab,\n unregisterActiveTab,\n }),\n [\n registerRoutedTab,\n unregisterRoutedTab,\n registerActiveTab,\n unregisterActiveTab,\n ],\n );\n\n return (\n <TabsContext.Provider value={tabsContextValue}>\n <TabSelectionContext.Provider value={selectionContextValue}>\n <AriaTabs\n className={classes.root}\n keyboardActivation=\"manual\"\n selectedKey={selectedTabId}\n ref={tabsRef}\n {...restProps}\n >\n {children as ReactNode}\n </AriaTabs>\n </TabSelectionContext.Provider>\n </TabsContext.Provider>\n );\n};\n\n/**\n * A component that renders a list of tabs.\n *\n * @public\n */\nexport const TabList = (props: TabListProps) => {\n const { ownProps, restProps } = useDefinition(TabListDefinition, props);\n const { classes, children } = ownProps;\n const { setHoveredKey, tabRefs, tabsRef, hoveredKey, prevHoveredKey } =\n useTabsContext();\n\n const handleHover = (key: string | null) => {\n setHoveredKey(key);\n };\n\n // Clone children with additional props for hover and ref management\n const enhancedChildren = Children.map(children as ReactNode, child => {\n if (isValidElement(child)) {\n return cloneElement(child, {\n onHoverStart: () => handleHover(child.props.id as string),\n onHoverEnd: () => handleHover(null),\n } as Partial<AriaTabProps>);\n }\n return child;\n });\n\n return (\n <div className={classes.root}>\n <AriaTabList\n className={classes.tabList}\n aria-label=\"Toolbar tabs\"\n {...restProps}\n >\n {enhancedChildren}\n </AriaTabList>\n <TabsIndicators\n tabRefs={tabRefs}\n tabsRef={tabsRef}\n hoveredKey={hoveredKey}\n prevHoveredKey={prevHoveredKey}\n />\n </div>\n );\n};\n\n/**\n * Internal component for tabs with internal hrefs.\n * Handles routing registration and active tab tracking.\n * Separated to avoid conditional hook usage in Tab component.\n * @internal\n */\nfunction RoutedTabEffects({\n id,\n href,\n matchStrategy = 'exact',\n}: {\n id: string;\n href: string;\n matchStrategy?: 'exact' | 'prefix';\n}) {\n const selectionCtx = useContext(TabSelectionContext);\n const routing = useRoutingIntegration({ fallback: true });\n const location = routing.useLocation();\n const resolvedPath = routing.useResolvedPath(href);\n\n // Register as a routed tab (for controlled vs uncontrolled mode)\n useEffect(() => {\n if (selectionCtx) {\n selectionCtx.registerRoutedTab(id);\n return () => selectionCtx.unregisterRoutedTab(id);\n }\n return undefined;\n }, [id, selectionCtx]);\n\n // Register as active tab when URL matches (for tab selection)\n const isActive = isTabActive(\n resolvedPath.pathname,\n location.pathname,\n matchStrategy,\n );\n const segmentCount = resolvedPath.pathname.split('/').filter(Boolean).length;\n\n useEffect(() => {\n if (isActive && selectionCtx) {\n selectionCtx.registerActiveTab(id, segmentCount);\n return () => selectionCtx.unregisterActiveTab(id);\n }\n return undefined;\n }, [isActive, id, segmentCount, selectionCtx]);\n\n return null;\n}\n\ntype TabViewProps = {\n definitionResult: UseDefinitionResult<typeof TabDefinition, TabProps>;\n navigation: AnchorNavigation;\n};\n\nconst TabView = ({ definitionResult, navigation }: TabViewProps) => {\n const { ownProps, restProps, analytics } = definitionResult;\n const { classes, matchStrategy, id } = ownProps;\n const { href } = ownProps;\n const { setTabRef } = useTabsContext();\n const navigationProps = getReactAriaAnchorProps(navigation, {\n href,\n routerOptions: restProps.routerOptions,\n });\n\n const handlePress = () => {\n if (href) {\n const text =\n restProps['aria-label'] ??\n getNodeText(restProps.children) ??\n String(href);\n analytics.captureEvent('click', text, {\n attributes: { to: String(href) },\n });\n }\n };\n\n return (\n <>\n {navigation.canMatchRoute && href && (\n <RoutedTabEffects\n id={id as string}\n href={href}\n matchStrategy={matchStrategy}\n />\n )}\n <AriaTab\n id={id}\n className={classes.root}\n ref={el => setTabRef(id as string, el as HTMLDivElement)}\n {...restProps}\n {...navigationProps}\n onPress={e => {\n restProps.onPress?.(e);\n handlePress();\n }}\n />\n </>\n );\n};\n\n/**\n * A component that renders a tab.\n *\n * @public\n */\nexport const Tab = (props: TabProps) => {\n const definitionResult = useDefinition(TabDefinition, props);\n const Navigation = definitionResult.navigation;\n\n return (\n <Navigation\n props={{\n ...definitionResult.restProps,\n href: definitionResult.ownProps.href,\n }}\n view={TabView}\n viewProps={{ definitionResult }}\n />\n );\n};\n\n/**\n * A component that renders the content of a tab.\n *\n * @public\n */\nexport const TabPanel = (props: TabPanelProps) => {\n const { ownProps, restProps } = useDefinition(TabPanelDefinition, props);\n\n return <AriaTabPanel className={ownProps.classes.root} {...restProps} />;\n};\n"],"names":["AriaTabs","AriaTabList","AriaTab","AriaTabPanel"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Tabs.esm.js","sources":["../../../src/components/Tabs/Tabs.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\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 */\n\nimport {\n useRef,\n useState,\n useMemo,\n Children,\n cloneElement,\n isValidElement,\n createContext,\n useContext,\n useEffect,\n useCallback,\n} from 'react';\nimport type { ReactNode } from 'react';\nimport type {\n TabsProps,\n TabListProps,\n TabPanelProps,\n TabsContextValue,\n TabProps,\n} from './types';\nimport { TabsIndicators } from './TabsIndicators';\nimport {\n Tabs as AriaTabs,\n TabList as AriaTabList,\n Tab as AriaTab,\n TabPanel as AriaTabPanel,\n TabProps as AriaTabProps,\n} from 'react-aria-components';\nimport {\n useDefinition,\n type UseDefinitionResult,\n} from '../../hooks/useDefinition';\nimport {\n TabsDefinition,\n TabListDefinition,\n TabDefinition,\n TabPanelDefinition,\n} from './definition';\nimport { getNodeText } from '../../analytics/getNodeText';\nimport { useRoutingIntegration } from '../../navigation/useRouting';\nimport {\n getReactAriaAnchorProps,\n type AnchorNavigation,\n} from '../../navigation/useNavigation';\n\nconst TabsContext = createContext<TabsContextValue | undefined>(undefined);\n\nconst useTabsContext = () => {\n const context = useContext(TabsContext);\n if (!context) {\n throw new Error('Tab components must be used within a Tabs component');\n }\n return context;\n};\n\ntype TabSelectionContextValue = {\n registerRoutedTab: (id: string) => void;\n unregisterRoutedTab: (id: string) => void;\n registerActiveTab: (id: string, segmentCount: number) => void;\n unregisterActiveTab: (id: string) => void;\n};\n\nconst TabSelectionContext = createContext<TabSelectionContextValue | null>(\n null,\n);\n\n/**\n * Strips query params and hash from a href, leaving only the pathname.\n * Tab matching always compares against location.pathname which never includes them.\n */\nconst hrefPathname = (href: string) => href.split('?')[0].split('#')[0];\n\n/**\n * Utility function to determine if a tab should be active based on the matching strategy.\n * This follows the pattern used in WorkaroundNavLink from the sidebar.\n */\nconst isTabActive = (\n tabHref: string,\n currentPathname: string,\n matchStrategy: 'exact' | 'prefix',\n): boolean => {\n const pathname = hrefPathname(tabHref);\n\n if (matchStrategy === 'exact') {\n return pathname === currentPathname;\n }\n\n // Prefix matching - similar to WorkaroundNavLink behavior\n if (pathname === currentPathname) {\n return true;\n }\n\n // Check if current path starts with tab href followed by a slash\n // This prevents /foo matching /foobar\n return currentPathname.startsWith(`${pathname}/`);\n};\n\n/**\n * A component that renders a list of tabs.\n *\n * @public\n */\nexport const Tabs = (props: TabsProps) => {\n const { ownProps, restProps } = useDefinition(TabsDefinition, props);\n const { classes, children } = ownProps;\n const tabsRef = useRef<HTMLDivElement>(null);\n const tabRefs = useRef<Map<string, HTMLDivElement>>(new Map());\n const [hoveredKey, setHoveredKey] = useState<string | null>(null);\n const prevHoveredKey = useRef<string | null>(null);\n\n // State for tracking routed tabs (tabs with hrefs)\n const [routedTabs, setRoutedTabs] = useState<Set<string>>(() => new Set());\n\n // State for tracking active tabs reported by TabRouteRegistration components\n const [activeTabs, setActiveTabs] = useState<Map<string, number>>(\n () => new Map(),\n );\n\n const setTabRef = (key: string, element: HTMLDivElement | null) => {\n if (element) {\n tabRefs.current.set(key, element);\n } else {\n tabRefs.current.delete(key);\n }\n };\n\n // Compute the selected tab based on active tabs with highest segment count\n const selectedTabId = useMemo(() => {\n // No routed tabs - let React Aria handle selection (uncontrolled mode)\n if (routedTabs.size === 0) {\n return undefined;\n }\n\n // Has routed tabs but none are active - use empty string for no selection\n // (React Aria has a bug with null that causes infinite loops)\n if (activeTabs.size === 0) {\n return '';\n }\n\n let selectedId: string | undefined;\n let maxSegments = -1;\n\n activeTabs.forEach((segmentCount, id) => {\n // Pick tab with highest segment count, first one wins on tie\n if (segmentCount > maxSegments) {\n maxSegments = segmentCount;\n selectedId = id;\n }\n });\n\n return selectedId;\n }, [routedTabs, activeTabs]);\n\n const registerRoutedTab = useCallback((id: string) => {\n setRoutedTabs(prev => new Set(prev).add(id));\n }, []);\n\n const unregisterRoutedTab = useCallback((id: string) => {\n setRoutedTabs(prev => {\n const next = new Set(prev);\n next.delete(id);\n return next;\n });\n }, []);\n\n const registerActiveTab = useCallback((id: string, segmentCount: number) => {\n setActiveTabs(prev => new Map(prev).set(id, segmentCount));\n }, []);\n\n const unregisterActiveTab = useCallback((id: string) => {\n setActiveTabs(prev => {\n const next = new Map(prev);\n next.delete(id);\n return next;\n });\n }, []);\n\n if (!children) return null;\n\n const tabsContextValue: TabsContextValue = {\n tabsRef,\n tabRefs,\n hoveredKey,\n prevHoveredKey,\n setHoveredKey,\n setTabRef,\n };\n\n const selectionContextValue: TabSelectionContextValue = useMemo(\n () => ({\n registerRoutedTab,\n unregisterRoutedTab,\n registerActiveTab,\n unregisterActiveTab,\n }),\n [\n registerRoutedTab,\n unregisterRoutedTab,\n registerActiveTab,\n unregisterActiveTab,\n ],\n );\n\n return (\n <TabsContext.Provider value={tabsContextValue}>\n <TabSelectionContext.Provider value={selectionContextValue}>\n <AriaTabs\n className={classes.root}\n keyboardActivation=\"manual\"\n selectedKey={selectedTabId}\n ref={tabsRef}\n {...restProps}\n >\n {children as ReactNode}\n </AriaTabs>\n </TabSelectionContext.Provider>\n </TabsContext.Provider>\n );\n};\n\n/**\n * A component that renders a list of tabs.\n *\n * @public\n */\nexport const TabList = (props: TabListProps) => {\n const { ownProps, restProps } = useDefinition(TabListDefinition, props);\n const { classes, children } = ownProps;\n const { setHoveredKey, tabRefs, tabsRef, hoveredKey, prevHoveredKey } =\n useTabsContext();\n\n const handleHover = (key: string | null) => {\n setHoveredKey(key);\n };\n\n // Clone children with additional props for hover and ref management\n const enhancedChildren = Children.map(children as ReactNode, child => {\n if (isValidElement(child)) {\n return cloneElement(child, {\n onHoverStart: () => handleHover(child.props.id as string),\n onHoverEnd: () => handleHover(null),\n } as Partial<AriaTabProps>);\n }\n return child;\n });\n\n return (\n <div className={classes.root}>\n <AriaTabList\n className={classes.tabList}\n aria-label=\"Toolbar tabs\"\n {...restProps}\n >\n {enhancedChildren}\n </AriaTabList>\n <TabsIndicators\n tabRefs={tabRefs}\n tabsRef={tabsRef}\n hoveredKey={hoveredKey}\n prevHoveredKey={prevHoveredKey}\n />\n </div>\n );\n};\n\n/**\n * Internal component for tabs with internal hrefs.\n * Handles routing registration and active tab tracking.\n * Separated to avoid conditional hook usage in Tab component.\n * @internal\n */\nfunction RoutedTabEffects({\n id,\n href,\n matchStrategy = 'exact',\n}: {\n id: string;\n href: string;\n matchStrategy?: 'exact' | 'prefix';\n}) {\n const selectionCtx = useContext(TabSelectionContext);\n const routing = useRoutingIntegration({ fallback: true });\n const location = routing.useLocation();\n const resolvedPath = routing.useResolvedPath(href);\n\n // Register as a routed tab (for controlled vs uncontrolled mode)\n useEffect(() => {\n if (selectionCtx) {\n selectionCtx.registerRoutedTab(id);\n return () => selectionCtx.unregisterRoutedTab(id);\n }\n return undefined;\n }, [id, selectionCtx]);\n\n // Register as active tab when URL matches (for tab selection)\n const isActive = isTabActive(\n resolvedPath.pathname,\n location.pathname,\n matchStrategy,\n );\n const segmentCount = resolvedPath.pathname.split('/').filter(Boolean).length;\n\n useEffect(() => {\n if (isActive && selectionCtx) {\n selectionCtx.registerActiveTab(id, segmentCount);\n return () => selectionCtx.unregisterActiveTab(id);\n }\n return undefined;\n }, [isActive, id, segmentCount, selectionCtx]);\n\n return null;\n}\n\ntype TabViewProps = {\n definitionResult: UseDefinitionResult<typeof TabDefinition, TabProps>;\n navigation: AnchorNavigation;\n};\n\nconst TabView = ({ definitionResult, navigation }: TabViewProps) => {\n const { ownProps, restProps, analytics } = definitionResult;\n const { classes, matchStrategy, id } = ownProps;\n const { href } = ownProps;\n const { setTabRef } = useTabsContext();\n const navigationProps = getReactAriaAnchorProps(navigation, {\n href,\n routerOptions: restProps.routerOptions,\n });\n\n const handlePress = () => {\n if (href) {\n const text =\n restProps['aria-label'] ??\n getNodeText(restProps.children) ??\n String(href);\n analytics.captureEvent('click', text, {\n attributes: { to: String(href) },\n });\n }\n };\n\n return (\n <>\n {navigation.canMatchRoute && href && (\n <RoutedTabEffects\n id={id as string}\n href={href}\n matchStrategy={matchStrategy}\n />\n )}\n <AriaTab\n id={id}\n className={classes.root}\n ref={el => setTabRef(id as string, el as HTMLDivElement)}\n {...restProps}\n {...navigationProps}\n onPress={e => {\n restProps.onPress?.(e);\n handlePress();\n }}\n />\n </>\n );\n};\n\n/**\n * A component that renders a tab.\n *\n * @public\n */\nexport const Tab = (props: TabProps) => {\n const definitionResult = useDefinition(TabDefinition, props);\n const Navigation = definitionResult.navigation;\n\n return (\n <Navigation\n props={{\n ...definitionResult.restProps,\n href: definitionResult.ownProps.href,\n }}\n view={TabView}\n viewProps={{ definitionResult }}\n />\n );\n};\n\n/**\n * A component that renders the content of a tab.\n *\n * @public\n */\nexport const TabPanel = (props: TabPanelProps) => {\n const { ownProps, restProps } = useDefinition(TabPanelDefinition, props);\n\n return <AriaTabPanel className={ownProps.classes.root} {...restProps} />;\n};\n"],"names":["AriaTabs","AriaTabList","AriaTab","AriaTabPanel"],"mappings":";;;;;;;;;;AA6DA,MAAM,WAAA,GAAc,cAA4C,MAAS,CAAA;AAEzE,MAAM,iBAAiB,MAAM;AAC3B,EAAA,MAAM,OAAA,GAAU,WAAW,WAAW,CAAA;AACtC,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,MAAM,IAAI,MAAM,qDAAqD,CAAA;AAAA,EACvE;AACA,EAAA,OAAO,OAAA;AACT,CAAA;AASA,MAAM,mBAAA,GAAsB,aAAA;AAAA,EAC1B;AACF,CAAA;AAMA,MAAM,YAAA,GAAe,CAAC,IAAA,KAAiB,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA,CAAE,CAAC,CAAA,CAAE,KAAA,CAAM,GAAG,CAAA,CAAE,CAAC,CAAA;AAMtE,MAAM,WAAA,GAAc,CAClB,OAAA,EACA,eAAA,EACA,aAAA,KACY;AACZ,EAAA,MAAM,QAAA,GAAW,aAAa,OAAO,CAAA;AAErC,EAAA,IAAI,kBAAkB,OAAA,EAAS;AAC7B,IAAA,OAAO,QAAA,KAAa,eAAA;AAAA,EACtB;AAGA,EAAA,IAAI,aAAa,eAAA,EAAiB;AAChC,IAAA,OAAO,IAAA;AAAA,EACT;AAIA,EAAA,OAAO,eAAA,CAAgB,UAAA,CAAW,CAAA,EAAG,QAAQ,CAAA,CAAA,CAAG,CAAA;AAClD,CAAA;AAOO,MAAM,IAAA,GAAO,CAAC,KAAA,KAAqB;AACxC,EAAA,MAAM,EAAE,QAAA,EAAU,SAAA,EAAU,GAAI,aAAA,CAAc,gBAAgB,KAAK,CAAA;AACnE,EAAA,MAAM,EAAE,OAAA,EAAS,QAAA,EAAS,GAAI,QAAA;AAC9B,EAAA,MAAM,OAAA,GAAU,OAAuB,IAAI,CAAA;AAC3C,EAAA,MAAM,OAAA,GAAU,MAAA,iBAAoC,IAAI,GAAA,EAAK,CAAA;AAC7D,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAI,SAAwB,IAAI,CAAA;AAChE,EAAA,MAAM,cAAA,GAAiB,OAAsB,IAAI,CAAA;AAGjD,EAAA,MAAM,CAAC,YAAY,aAAa,CAAA,GAAI,SAAsB,sBAAM,IAAI,KAAK,CAAA;AAGzE,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAI,QAAA;AAAA,IAClC,0BAAU,GAAA;AAAI,GAChB;AAEA,EAAA,MAAM,SAAA,GAAY,CAAC,GAAA,EAAa,OAAA,KAAmC;AACjE,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,OAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,GAAA,EAAK,OAAO,CAAA;AAAA,IAClC,CAAA,MAAO;AACL,MAAA,OAAA,CAAQ,OAAA,CAAQ,OAAO,GAAG,CAAA;AAAA,IAC5B;AAAA,EACF,CAAA;AAGA,EAAA,MAAM,aAAA,GAAgB,QAAQ,MAAM;AAElC,IAAA,IAAI,UAAA,CAAW,SAAS,CAAA,EAAG;AACzB,MAAA,OAAO,MAAA;AAAA,IACT;AAIA,IAAA,IAAI,UAAA,CAAW,SAAS,CAAA,EAAG;AACzB,MAAA,OAAO,EAAA;AAAA,IACT;AAEA,IAAA,IAAI,UAAA;AACJ,IAAA,IAAI,WAAA,GAAc,EAAA;AAElB,IAAA,UAAA,CAAW,OAAA,CAAQ,CAAC,YAAA,EAAc,EAAA,KAAO;AAEvC,MAAA,IAAI,eAAe,WAAA,EAAa;AAC9B,QAAA,WAAA,GAAc,YAAA;AACd,QAAA,UAAA,GAAa,EAAA;AAAA,MACf;AAAA,IACF,CAAC,CAAA;AAED,IAAA,OAAO,UAAA;AAAA,EACT,CAAA,EAAG,CAAC,UAAA,EAAY,UAAU,CAAC,CAAA;AAE3B,EAAA,MAAM,iBAAA,GAAoB,WAAA,CAAY,CAAC,EAAA,KAAe;AACpD,IAAA,aAAA,CAAc,UAAQ,IAAI,GAAA,CAAI,IAAI,CAAA,CAAE,GAAA,CAAI,EAAE,CAAC,CAAA;AAAA,EAC7C,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,mBAAA,GAAsB,WAAA,CAAY,CAAC,EAAA,KAAe;AACtD,IAAA,aAAA,CAAc,CAAA,IAAA,KAAQ;AACpB,MAAA,MAAM,IAAA,GAAO,IAAI,GAAA,CAAI,IAAI,CAAA;AACzB,MAAA,IAAA,CAAK,OAAO,EAAE,CAAA;AACd,MAAA,OAAO,IAAA;AAAA,IACT,CAAC,CAAA;AAAA,EACH,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,iBAAA,GAAoB,WAAA,CAAY,CAAC,EAAA,EAAY,YAAA,KAAyB;AAC1E,IAAA,aAAA,CAAc,CAAA,IAAA,KAAQ,IAAI,GAAA,CAAI,IAAI,EAAE,GAAA,CAAI,EAAA,EAAI,YAAY,CAAC,CAAA;AAAA,EAC3D,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,mBAAA,GAAsB,WAAA,CAAY,CAAC,EAAA,KAAe;AACtD,IAAA,aAAA,CAAc,CAAA,IAAA,KAAQ;AACpB,MAAA,MAAM,IAAA,GAAO,IAAI,GAAA,CAAI,IAAI,CAAA;AACzB,MAAA,IAAA,CAAK,OAAO,EAAE,CAAA;AACd,MAAA,OAAO,IAAA;AAAA,IACT,CAAC,CAAA;AAAA,EACH,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,IAAI,CAAC,UAAU,OAAO,IAAA;AAEtB,EAAA,MAAM,gBAAA,GAAqC;AAAA,IACzC,OAAA;AAAA,IACA,OAAA;AAAA,IACA,UAAA;AAAA,IACA,cAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,MAAM,qBAAA,GAAkD,OAAA;AAAA,IACtD,OAAO;AAAA,MACL,iBAAA;AAAA,MACA,mBAAA;AAAA,MACA,iBAAA;AAAA,MACA;AAAA,KACF,CAAA;AAAA,IACA;AAAA,MACE,iBAAA;AAAA,MACA,mBAAA;AAAA,MACA,iBAAA;AAAA,MACA;AAAA;AACF,GACF;AAEA,EAAA,uBACE,GAAA,CAAC,WAAA,CAAY,QAAA,EAAZ,EAAqB,KAAA,EAAO,gBAAA,EAC3B,QAAA,kBAAA,GAAA,CAAC,mBAAA,CAAoB,QAAA,EAApB,EAA6B,KAAA,EAAO,qBAAA,EACnC,QAAA,kBAAA,GAAA;AAAA,IAACA,MAAA;AAAA,IAAA;AAAA,MACC,WAAW,OAAA,CAAQ,IAAA;AAAA,MACnB,kBAAA,EAAmB,QAAA;AAAA,MACnB,WAAA,EAAa,aAAA;AAAA,MACb,GAAA,EAAK,OAAA;AAAA,MACJ,GAAG,SAAA;AAAA,MAEH;AAAA;AAAA,KAEL,CAAA,EACF,CAAA;AAEJ;AAOO,MAAM,OAAA,GAAU,CAAC,KAAA,KAAwB;AAC9C,EAAA,MAAM,EAAE,QAAA,EAAU,SAAA,EAAU,GAAI,aAAA,CAAc,mBAAmB,KAAK,CAAA;AACtE,EAAA,MAAM,EAAE,OAAA,EAAS,QAAA,EAAS,GAAI,QAAA;AAC9B,EAAA,MAAM,EAAE,aAAA,EAAe,OAAA,EAAS,SAAS,UAAA,EAAY,cAAA,KACnD,cAAA,EAAe;AAEjB,EAAA,MAAM,WAAA,GAAc,CAAC,GAAA,KAAuB;AAC1C,IAAA,aAAA,CAAc,GAAG,CAAA;AAAA,EACnB,CAAA;AAGA,EAAA,MAAM,gBAAA,GAAmB,QAAA,CAAS,GAAA,CAAI,QAAA,EAAuB,CAAA,KAAA,KAAS;AACpE,IAAA,IAAI,cAAA,CAAe,KAAK,CAAA,EAAG;AACzB,MAAA,OAAO,aAAa,KAAA,EAAO;AAAA,QACzB,YAAA,EAAc,MAAM,WAAA,CAAY,KAAA,CAAM,MAAM,EAAY,CAAA;AAAA,QACxD,UAAA,EAAY,MAAM,WAAA,CAAY,IAAI;AAAA,OACV,CAAA;AAAA,IAC5B;AACA,IAAA,OAAO,KAAA;AAAA,EACT,CAAC,CAAA;AAED,EAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,OAAA,CAAQ,IAAA,EACtB,QAAA,EAAA;AAAA,oBAAA,GAAA;AAAA,MAACC,SAAA;AAAA,MAAA;AAAA,QACC,WAAW,OAAA,CAAQ,OAAA;AAAA,QACnB,YAAA,EAAW,cAAA;AAAA,QACV,GAAG,SAAA;AAAA,QAEH,QAAA,EAAA;AAAA;AAAA,KACH;AAAA,oBACA,GAAA;AAAA,MAAC,cAAA;AAAA,MAAA;AAAA,QACC,OAAA;AAAA,QACA,OAAA;AAAA,QACA,UAAA;AAAA,QACA;AAAA;AAAA;AACF,GAAA,EACF,CAAA;AAEJ;AAQA,SAAS,gBAAA,CAAiB;AAAA,EACxB,EAAA;AAAA,EACA,IAAA;AAAA,EACA,aAAA,GAAgB;AAClB,CAAA,EAIG;AACD,EAAA,MAAM,YAAA,GAAe,WAAW,mBAAmB,CAAA;AACnD,EAAA,MAAM,OAAA,GAAU,qBAAA,CAAsB,EAAE,QAAA,EAAU,MAAM,CAAA;AACxD,EAAA,MAAM,QAAA,GAAW,QAAQ,WAAA,EAAY;AACrC,EAAA,MAAM,YAAA,GAAe,OAAA,CAAQ,eAAA,CAAgB,IAAI,CAAA;AAGjD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,YAAA,EAAc;AAChB,MAAA,YAAA,CAAa,kBAAkB,EAAE,CAAA;AACjC,MAAA,OAAO,MAAM,YAAA,CAAa,mBAAA,CAAoB,EAAE,CAAA;AAAA,IAClD;AACA,IAAA,OAAO,MAAA;AAAA,EACT,CAAA,EAAG,CAAC,EAAA,EAAI,YAAY,CAAC,CAAA;AAGrB,EAAA,MAAM,QAAA,GAAW,WAAA;AAAA,IACf,YAAA,CAAa,QAAA;AAAA,IACb,QAAA,CAAS,QAAA;AAAA,IACT;AAAA,GACF;AACA,EAAA,MAAM,YAAA,GAAe,aAAa,QAAA,CAAS,KAAA,CAAM,GAAG,CAAA,CAAE,MAAA,CAAO,OAAO,CAAA,CAAE,MAAA;AAEtE,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,YAAY,YAAA,EAAc;AAC5B,MAAA,YAAA,CAAa,iBAAA,CAAkB,IAAI,YAAY,CAAA;AAC/C,MAAA,OAAO,MAAM,YAAA,CAAa,mBAAA,CAAoB,EAAE,CAAA;AAAA,IAClD;AACA,IAAA,OAAO,MAAA;AAAA,EACT,GAAG,CAAC,QAAA,EAAU,EAAA,EAAI,YAAA,EAAc,YAAY,CAAC,CAAA;AAE7C,EAAA,OAAO,IAAA;AACT;AAOA,MAAM,OAAA,GAAU,CAAC,EAAE,gBAAA,EAAkB,YAAW,KAAoB;AAClE,EAAA,MAAM,EAAE,QAAA,EAAU,SAAA,EAAW,SAAA,EAAU,GAAI,gBAAA;AAC3C,EAAA,MAAM,EAAE,OAAA,EAAS,aAAA,EAAe,EAAA,EAAG,GAAI,QAAA;AACvC,EAAA,MAAM,EAAE,MAAK,GAAI,QAAA;AACjB,EAAA,MAAM,EAAE,SAAA,EAAU,GAAI,cAAA,EAAe;AACrC,EAAA,MAAM,eAAA,GAAkB,wBAAwB,UAAA,EAAY;AAAA,IAC1D,IAAA;AAAA,IACA,eAAe,SAAA,CAAU;AAAA,GAC1B,CAAA;AAED,EAAA,MAAM,cAAc,MAAM;AACxB,IAAA,IAAI,IAAA,EAAM;AACR,MAAA,MAAM,IAAA,GACJ,UAAU,YAAY,CAAA,IACtB,YAAY,SAAA,CAAU,QAAQ,CAAA,IAC9B,MAAA,CAAO,IAAI,CAAA;AACb,MAAA,SAAA,CAAU,YAAA,CAAa,SAAS,IAAA,EAAM;AAAA,QACpC,UAAA,EAAY,EAAE,EAAA,EAAI,MAAA,CAAO,IAAI,CAAA;AAAE,OAChC,CAAA;AAAA,IACH;AAAA,EACF,CAAA;AAEA,EAAA,uBACE,IAAA,CAAA,QAAA,EAAA,EACG,QAAA,EAAA;AAAA,IAAA,UAAA,CAAW,iBAAiB,IAAA,oBAC3B,GAAA;AAAA,MAAC,gBAAA;AAAA,MAAA;AAAA,QACC,EAAA;AAAA,QACA,IAAA;AAAA,QACA;AAAA;AAAA,KACF;AAAA,oBAEF,GAAA;AAAA,MAACC,KAAA;AAAA,MAAA;AAAA,QACC,EAAA;AAAA,QACA,WAAW,OAAA,CAAQ,IAAA;AAAA,QACnB,GAAA,EAAK,CAAA,EAAA,KAAM,SAAA,CAAU,EAAA,EAAc,EAAoB,CAAA;AAAA,QACtD,GAAG,SAAA;AAAA,QACH,GAAG,eAAA;AAAA,QACJ,SAAS,CAAA,CAAA,KAAK;AACZ,UAAA,SAAA,CAAU,UAAU,CAAC,CAAA;AACrB,UAAA,WAAA,EAAY;AAAA,QACd;AAAA;AAAA;AACF,GAAA,EACF,CAAA;AAEJ,CAAA;AAOO,MAAM,GAAA,GAAM,CAAC,KAAA,KAAoB;AACtC,EAAA,MAAM,gBAAA,GAAmB,aAAA,CAAc,aAAA,EAAe,KAAK,CAAA;AAC3D,EAAA,MAAM,aAAa,gBAAA,CAAiB,UAAA;AAEpC,EAAA,uBACE,GAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO;AAAA,QACL,GAAG,gBAAA,CAAiB,SAAA;AAAA,QACpB,IAAA,EAAM,iBAAiB,QAAA,CAAS;AAAA,OAClC;AAAA,MACA,IAAA,EAAM,OAAA;AAAA,MACN,SAAA,EAAW,EAAE,gBAAA;AAAiB;AAAA,GAChC;AAEJ;AAOO,MAAM,QAAA,GAAW,CAAC,KAAA,KAAyB;AAChD,EAAA,MAAM,EAAE,QAAA,EAAU,SAAA,EAAU,GAAI,aAAA,CAAc,oBAAoB,KAAK,CAAA;AAEvE,EAAA,2BAAQC,UAAA,EAAA,EAAa,SAAA,EAAW,SAAS,OAAA,CAAQ,IAAA,EAAO,GAAG,SAAA,EAAW,CAAA;AACxE;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tabs.module.css.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Tabs.module.css.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TabsIndicators.esm.js","sources":["../../../src/components/Tabs/TabsIndicators.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\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 */\n\nimport { TabListStateContext } from 'react-aria-components';\nimport { useDefinition } from '../../hooks/useDefinition';\nimport { TabsIndicatorsDefinition } from './definition';\nimport { useContext, useEffect, useCallback, useRef } from 'react';\nimport type { TabsIndicatorsProps } from './types';\n\n/**\n * A component that renders the indicators for the toolbar.\n *\n * @internal\n */\nexport const TabsIndicators = (props: TabsIndicatorsProps) => {\n const { ownProps } = useDefinition(TabsIndicatorsDefinition, props);\n const { classes, tabRefs, tabsRef, hoveredKey, prevHoveredKey } = ownProps;\n const state = useContext(TabListStateContext);\n const prevSelectedKey = useRef<string | null>(null);\n\n const updateCSSVariables = useCallback(\n (animate = true) => {\n // When rendered inside CollectionBuilder's hidden tree (for collection\n // building), there is no TabListStateContext provider, so state is null.\n // Bail out to avoid overwriting CSS variables on the shared tabsRef DOM\n // element that the real instance also writes to.\n if (state == null) return;\n\n if (!tabsRef.current) return;\n\n const tabsRect = tabsRef.current.getBoundingClientRect();\n\n // Set active tab variables\n if (state?.selectedKey != null && state.selectedKey !== '') {\n const activeTab = tabRefs.current.get(state.selectedKey.toString());\n\n if (activeTab) {\n const activeRect = activeTab.getBoundingClientRect();\n const relativeLeft = activeRect.left - tabsRect.left;\n const relativeTop = activeRect.top - tabsRect.top;\n\n // Control transition timing based on whether this is the first time setting active tab\n const isFirstActiveTab = prevSelectedKey.current === null;\n\n if (isFirstActiveTab || !animate) {\n // First time setting active tab or non-animated reposition (e.g.\n // tab resize): no transitions for position\n tabsRef.current.style.setProperty(\n '--active-transition-duration',\n '0s',\n );\n // Enable transitions on next frame for future tab switches, unless\n // more non-animated updates may follow (e.g. a resize in progress)\n if (animate) {\n requestAnimationFrame(() => {\n if (tabsRef.current) {\n tabsRef.current.style.setProperty(\n '--active-transition-duration',\n '0.25s',\n );\n }\n });\n }\n } else {\n // Switching between tabs: full transitions\n tabsRef.current.style.setProperty(\n '--active-transition-duration',\n '0.25s',\n );\n }\n\n // Update previous selected key for next time\n prevSelectedKey.current = state.selectedKey.toString();\n\n tabsRef.current.style.setProperty(\n '--active-tab-left',\n `${relativeLeft}px`,\n );\n tabsRef.current.style.setProperty(\n '--active-tab-right',\n `${relativeLeft + activeRect.width}px`,\n );\n tabsRef.current.style.setProperty(\n '--active-tab-top',\n `${relativeTop}px`,\n );\n tabsRef.current.style.setProperty(\n '--active-tab-bottom',\n `${relativeTop + activeRect.height}px`,\n );\n tabsRef.current.style.setProperty(\n '--active-tab-width',\n `${activeRect.width}px`,\n );\n tabsRef.current.style.setProperty(\n '--active-tab-height',\n `${activeRect.height}px`,\n );\n tabsRef.current.style.setProperty('--active-tab-opacity', '1');\n }\n } else {\n tabsRef.current.style.setProperty('--active-tab-opacity', '0');\n prevSelectedKey.current = null;\n }\n\n // Set hovered tab variables\n if (hoveredKey) {\n const hoveredTab = tabRefs.current.get(hoveredKey);\n if (hoveredTab) {\n const hoveredRect = hoveredTab.getBoundingClientRect();\n const relativeLeft = hoveredRect.left - tabsRect.left;\n const relativeTop = hoveredRect.top - tabsRect.top;\n\n tabsRef.current.style.setProperty(\n '--hovered-tab-left',\n `${relativeLeft}px`,\n );\n tabsRef.current.style.setProperty(\n '--hovered-tab-right',\n `${relativeLeft + hoveredRect.width}px`,\n );\n tabsRef.current.style.setProperty(\n '--hovered-tab-top',\n `${relativeTop}px`,\n );\n tabsRef.current.style.setProperty(\n '--hovered-tab-bottom',\n `${relativeTop + hoveredRect.height}px`,\n );\n tabsRef.current.style.setProperty(\n '--hovered-tab-width',\n `${hoveredRect.width}px`,\n );\n tabsRef.current.style.setProperty(\n '--hovered-tab-height',\n `${hoveredRect.height}px`,\n );\n // Control transition timing based on whether this is a new hover session\n const isNewHoverSession = prevHoveredKey.current === null;\n\n if (isNewHoverSession || !animate) {\n // Starting new hover session or non-animated reposition (e.g. tab\n // resize): no transitions for position\n tabsRef.current.style.setProperty(\n '--hovered-transition-duration',\n '0s',\n );\n // Enable transitions on next frame for future tab switches, unless\n // more non-animated updates may follow (e.g. a resize in progress)\n if (animate) {\n requestAnimationFrame(() => {\n if (tabsRef.current) {\n tabsRef.current.style.setProperty(\n '--hovered-transition-duration',\n '0.2s',\n );\n }\n });\n }\n } else {\n // Moving between tabs in same session: full transitions\n tabsRef.current.style.setProperty(\n '--hovered-transition-duration',\n '0.2s',\n );\n }\n\n // Update previous hover key for next time\n prevHoveredKey.current = hoveredKey;\n\n tabsRef.current.style.setProperty('--hovered-tab-opacity', '1');\n }\n } else {\n // When not hovering, hide with opacity and reset for next hover session\n tabsRef.current.style.setProperty('--hovered-tab-opacity', '0');\n\n // Reset previous hover key so next hover is treated as new session\n prevHoveredKey.current = null;\n }\n },\n [state?.selectedKey, hoveredKey, tabRefs.current],\n );\n\n useEffect(() => {\n updateCSSVariables();\n }, [updateCSSVariables, tabRefs.current.size]);\n\n useEffect(() => {\n const handleResize = () => updateCSSVariables(false);\n window.addEventListener('resize', handleResize);\n return () => window.removeEventListener('resize', handleResize);\n }, [updateCSSVariables]);\n\n useEffect(() => {\n // ResizeObserver is not available in some environments (e.g. Jest/jsdom)\n if (typeof ResizeObserver === 'undefined') {\n return undefined;\n }\n\n let frame: number | null = null;\n const scheduleUpdate = () => {\n if (frame !== null) {\n return;\n }\n\n frame = requestAnimationFrame(() => {\n frame = null;\n updateCSSVariables(false);\n });\n };\n\n const resizeObserver = new ResizeObserver(scheduleUpdate);\n const observeTabs = () => {\n resizeObserver.disconnect();\n for (const tab of tabRefs.current.values()) {\n resizeObserver.observe(tab);\n }\n };\n observeTabs();\n\n // Tab elements can be added, removed, or replaced without this component\n // re-rendering, so watch the DOM to keep the observed set in sync.\n const mutationObserver = new MutationObserver(() => {\n observeTabs();\n scheduleUpdate();\n });\n\n if (tabsRef.current) {\n mutationObserver.observe(tabsRef.current, {\n childList: true,\n subtree: true,\n });\n }\n\n return () => {\n if (frame !== null) {\n cancelAnimationFrame(frame);\n }\n resizeObserver.disconnect();\n mutationObserver.disconnect();\n };\n }, [updateCSSVariables, tabRefs, tabsRef]);\n\n return (\n <>\n <div className={classes.root} />\n <div className={classes.hovered} />\n </>\n );\n};\n"],"names":[],"mappings":";;;;;;AA2BO,MAAM,cAAA,GAAiB,CAAC,KAAA,KAA+B;AAC5D,EAAA,MAAM,EAAE,QAAA,EAAS,GAAI,aAAA,CAAc,0BAA0B,KAAK,CAAA;AAClE,EAAA,MAAM,EAAE,OAAA,EAAS,OAAA,EAAS,OAAA,EAAS,UAAA,EAAY,gBAAe,GAAI,QAAA;AAClE,EAAA,MAAM,KAAA,GAAQ,WAAW,mBAAmB,CAAA;AAC5C,EAAA,MAAM,eAAA,GAAkB,OAAsB,IAAI,CAAA;AAElD,EAAA,MAAM,kBAAA,GAAqB,WAAA;AAAA,IACzB,CAAC,UAAU,IAAA,KAAS;AAKlB,MAAA,IAAI,SAAS,IAAA,EAAM;AAEnB,MAAA,IAAI,CAAC,QAAQ,OAAA,EAAS;AAEtB,MAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,OAAA,CAAQ,qBAAA,EAAsB;AAGvD,MAAA,IAAI,KAAA,EAAO,WAAA,IAAe,IAAA,IAAQ,KAAA,CAAM,gBAAgB,EAAA,EAAI;AAC1D,QAAA,MAAM,YAAY,OAAA,CAAQ,OAAA,CAAQ,IAAI,KAAA,CAAM,WAAA,CAAY,UAAU,CAAA;AAElE,QAAA,IAAI,SAAA,EAAW;AACb,UAAA,MAAM,UAAA,GAAa,UAAU,qBAAA,EAAsB;AACnD,UAAA,MAAM,YAAA,GAAe,UAAA,CAAW,IAAA,GAAO,QAAA,CAAS,IAAA;AAChD,UAAA,MAAM,WAAA,GAAc,UAAA,CAAW,GAAA,GAAM,QAAA,CAAS,GAAA;AAG9C,UAAA,MAAM,gBAAA,GAAmB,gBAAgB,OAAA,KAAY,IAAA;AAErD,UAAA,IAAI,gBAAA,IAAoB,CAAC,OAAA,EAAS;AAGhC,YAAA,OAAA,CAAQ,QAAQ,KAAA,CAAM,WAAA;AAAA,cACpB,8BAAA;AAAA,cACA;AAAA,aACF;AAGA,YAAA,IAAI,OAAA,EAAS;AACX,cAAA,qBAAA,CAAsB,MAAM;AAC1B,gBAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,kBAAA,OAAA,CAAQ,QAAQ,KAAA,CAAM,WAAA;AAAA,oBACpB,8BAAA;AAAA,oBACA;AAAA,mBACF;AAAA,gBACF;AAAA,cACF,CAAC,CAAA;AAAA,YACH;AAAA,UACF,CAAA,MAAO;AAEL,YAAA,OAAA,CAAQ,QAAQ,KAAA,CAAM,WAAA;AAAA,cACpB,8BAAA;AAAA,cACA;AAAA,aACF;AAAA,UACF;AAGA,UAAA,eAAA,CAAgB,OAAA,GAAU,KAAA,CAAM,WAAA,CAAY,QAAA,EAAS;AAErD,UAAA,OAAA,CAAQ,QAAQ,KAAA,CAAM,WAAA;AAAA,YACpB,mBAAA;AAAA,YACA,GAAG,YAAY,CAAA,EAAA;AAAA,WACjB;AACA,UAAA,OAAA,CAAQ,QAAQ,KAAA,CAAM,WAAA;AAAA,YACpB,oBAAA;AAAA,YACA,CAAA,EAAG,YAAA,GAAe,UAAA,CAAW,KAAK,CAAA,EAAA;AAAA,WACpC;AACA,UAAA,OAAA,CAAQ,QAAQ,KAAA,CAAM,WAAA;AAAA,YACpB,kBAAA;AAAA,YACA,GAAG,WAAW,CAAA,EAAA;AAAA,WAChB;AACA,UAAA,OAAA,CAAQ,QAAQ,KAAA,CAAM,WAAA;AAAA,YACpB,qBAAA;AAAA,YACA,CAAA,EAAG,WAAA,GAAc,UAAA,CAAW,MAAM,CAAA,EAAA;AAAA,WACpC;AACA,UAAA,OAAA,CAAQ,QAAQ,KAAA,CAAM,WAAA;AAAA,YACpB,oBAAA;AAAA,YACA,CAAA,EAAG,WAAW,KAAK,CAAA,EAAA;AAAA,WACrB;AACA,UAAA,OAAA,CAAQ,QAAQ,KAAA,CAAM,WAAA;AAAA,YACpB,qBAAA;AAAA,YACA,CAAA,EAAG,WAAW,MAAM,CAAA,EAAA;AAAA,WACtB;AACA,UAAA,OAAA,CAAQ,OAAA,CAAQ,KAAA,CAAM,WAAA,CAAY,sBAAA,EAAwB,GAAG,CAAA;AAAA,QAC/D;AAAA,MACF,CAAA,MAAO;AACL,QAAA,OAAA,CAAQ,OAAA,CAAQ,KAAA,CAAM,WAAA,CAAY,sBAAA,EAAwB,GAAG,CAAA;AAC7D,QAAA,eAAA,CAAgB,OAAA,GAAU,IAAA;AAAA,MAC5B;AAGA,MAAA,IAAI,UAAA,EAAY;AACd,QAAA,MAAM,UAAA,GAAa,OAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,UAAU,CAAA;AACjD,QAAA,IAAI,UAAA,EAAY;AACd,UAAA,MAAM,WAAA,GAAc,WAAW,qBAAA,EAAsB;AACrD,UAAA,MAAM,YAAA,GAAe,WAAA,CAAY,IAAA,GAAO,QAAA,CAAS,IAAA;AACjD,UAAA,MAAM,WAAA,GAAc,WAAA,CAAY,GAAA,GAAM,QAAA,CAAS,GAAA;AAE/C,UAAA,OAAA,CAAQ,QAAQ,KAAA,CAAM,WAAA;AAAA,YACpB,oBAAA;AAAA,YACA,GAAG,YAAY,CAAA,EAAA;AAAA,WACjB;AACA,UAAA,OAAA,CAAQ,QAAQ,KAAA,CAAM,WAAA;AAAA,YACpB,qBAAA;AAAA,YACA,CAAA,EAAG,YAAA,GAAe,WAAA,CAAY,KAAK,CAAA,EAAA;AAAA,WACrC;AACA,UAAA,OAAA,CAAQ,QAAQ,KAAA,CAAM,WAAA;AAAA,YACpB,mBAAA;AAAA,YACA,GAAG,WAAW,CAAA,EAAA;AAAA,WAChB;AACA,UAAA,OAAA,CAAQ,QAAQ,KAAA,CAAM,WAAA;AAAA,YACpB,sBAAA;AAAA,YACA,CAAA,EAAG,WAAA,GAAc,WAAA,CAAY,MAAM,CAAA,EAAA;AAAA,WACrC;AACA,UAAA,OAAA,CAAQ,QAAQ,KAAA,CAAM,WAAA;AAAA,YACpB,qBAAA;AAAA,YACA,CAAA,EAAG,YAAY,KAAK,CAAA,EAAA;AAAA,WACtB;AACA,UAAA,OAAA,CAAQ,QAAQ,KAAA,CAAM,WAAA;AAAA,YACpB,sBAAA;AAAA,YACA,CAAA,EAAG,YAAY,MAAM,CAAA,EAAA;AAAA,WACvB;AAEA,UAAA,MAAM,iBAAA,GAAoB,eAAe,OAAA,KAAY,IAAA;AAErD,UAAA,IAAI,iBAAA,IAAqB,CAAC,OAAA,EAAS;AAGjC,YAAA,OAAA,CAAQ,QAAQ,KAAA,CAAM,WAAA;AAAA,cACpB,+BAAA;AAAA,cACA;AAAA,aACF;AAGA,YAAA,IAAI,OAAA,EAAS;AACX,cAAA,qBAAA,CAAsB,MAAM;AAC1B,gBAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,kBAAA,OAAA,CAAQ,QAAQ,KAAA,CAAM,WAAA;AAAA,oBACpB,+BAAA;AAAA,oBACA;AAAA,mBACF;AAAA,gBACF;AAAA,cACF,CAAC,CAAA;AAAA,YACH;AAAA,UACF,CAAA,MAAO;AAEL,YAAA,OAAA,CAAQ,QAAQ,KAAA,CAAM,WAAA;AAAA,cACpB,+BAAA;AAAA,cACA;AAAA,aACF;AAAA,UACF;AAGA,UAAA,cAAA,CAAe,OAAA,GAAU,UAAA;AAEzB,UAAA,OAAA,CAAQ,OAAA,CAAQ,KAAA,CAAM,WAAA,CAAY,uBAAA,EAAyB,GAAG,CAAA;AAAA,QAChE;AAAA,MACF,CAAA,MAAO;AAEL,QAAA,OAAA,CAAQ,OAAA,CAAQ,KAAA,CAAM,WAAA,CAAY,uBAAA,EAAyB,GAAG,CAAA;AAG9D,QAAA,cAAA,CAAe,OAAA,GAAU,IAAA;AAAA,MAC3B;AAAA,IACF,CAAA;AAAA,IACA,CAAC,KAAA,EAAO,WAAA,EAAa,UAAA,EAAY,QAAQ,OAAO;AAAA,GAClD;AAEA,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,kBAAA,EAAmB;AAAA,EACrB,GAAG,CAAC,kBAAA,EAAoB,OAAA,CAAQ,OAAA,CAAQ,IAAI,CAAC,CAAA;AAE7C,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,YAAA,GAAe,MAAM,kBAAA,CAAmB,KAAK,CAAA;AACnD,IAAA,MAAA,CAAO,gBAAA,CAAiB,UAAU,YAAY,CAAA;AAC9C,IAAA,OAAO,MAAM,MAAA,CAAO,mBAAA,CAAoB,QAAA,EAAU,YAAY,CAAA;AAAA,EAChE,CAAA,EAAG,CAAC,kBAAkB,CAAC,CAAA;AAEvB,EAAA,SAAA,CAAU,MAAM;AAEd,IAAA,IAAI,OAAO,mBAAmB,WAAA,EAAa;AACzC,MAAA,OAAO,MAAA;AAAA,IACT;AAEA,IAAA,IAAI,KAAA,GAAuB,IAAA;AAC3B,IAAA,MAAM,iBAAiB,MAAM;AAC3B,MAAA,IAAI,UAAU,IAAA,EAAM;AAClB,QAAA;AAAA,MACF;AAEA,MAAA,KAAA,GAAQ,sBAAsB,MAAM;AAClC,QAAA,KAAA,GAAQ,IAAA;AACR,QAAA,kBAAA,CAAmB,KAAK,CAAA;AAAA,MAC1B,CAAC,CAAA;AAAA,IACH,CAAA;AAEA,IAAA,MAAM,cAAA,GAAiB,IAAI,cAAA,CAAe,cAAc,CAAA;AACxD,IAAA,MAAM,cAAc,MAAM;AACxB,MAAA,cAAA,CAAe,UAAA,EAAW;AAC1B,MAAA,KAAA,MAAW,GAAA,IAAO,OAAA,CAAQ,OAAA,CAAQ,MAAA,EAAO,EAAG;AAC1C,QAAA,cAAA,CAAe,QAAQ,GAAG,CAAA;AAAA,MAC5B;AAAA,IACF,CAAA;AACA,IAAA,WAAA,EAAY;AAIZ,IAAA,MAAM,gBAAA,GAAmB,IAAI,gBAAA,CAAiB,MAAM;AAClD,MAAA,WAAA,EAAY;AACZ,MAAA,cAAA,EAAe;AAAA,IACjB,CAAC,CAAA;AAED,IAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,MAAA,gBAAA,CAAiB,OAAA,CAAQ,QAAQ,OAAA,EAAS;AAAA,QACxC,SAAA,EAAW,IAAA;AAAA,QACX,OAAA,EAAS;AAAA,OACV,CAAA;AAAA,IACH;AAEA,IAAA,OAAO,MAAM;AACX,MAAA,IAAI,UAAU,IAAA,EAAM;AAClB,QAAA,oBAAA,CAAqB,KAAK,CAAA;AAAA,MAC5B;AACA,MAAA,cAAA,CAAe,UAAA,EAAW;AAC1B,MAAA,gBAAA,CAAiB,UAAA,EAAW;AAAA,IAC9B,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,kBAAA,EAAoB,OAAA,EAAS,OAAO,CAAC,CAAA;AAEzC,EAAA,uBACE,IAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,OAAA,CAAQ,IAAA,EAAM,CAAA;AAAA,oBAC9B,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,OAAA,CAAQ,OAAA,EAAS;AAAA,GAAA,EACnC,CAAA;AAEJ;;;;"}
|
|
1
|
+
{"version":3,"file":"TabsIndicators.esm.js","sources":["../../../src/components/Tabs/TabsIndicators.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\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 */\n\nimport { TabListStateContext } from 'react-aria-components';\nimport { useDefinition } from '../../hooks/useDefinition';\nimport { TabsIndicatorsDefinition } from './definition';\nimport { useContext, useEffect, useCallback, useRef } from 'react';\nimport type { TabsIndicatorsProps } from './types';\n\n/**\n * A component that renders the indicators for the toolbar.\n *\n * @internal\n */\nexport const TabsIndicators = (props: TabsIndicatorsProps) => {\n const { ownProps } = useDefinition(TabsIndicatorsDefinition, props);\n const { classes, tabRefs, tabsRef, hoveredKey, prevHoveredKey } = ownProps;\n const state = useContext(TabListStateContext);\n const prevSelectedKey = useRef<string | null>(null);\n\n const updateCSSVariables = useCallback(\n (animate = true) => {\n // When rendered inside CollectionBuilder's hidden tree (for collection\n // building), there is no TabListStateContext provider, so state is null.\n // Bail out to avoid overwriting CSS variables on the shared tabsRef DOM\n // element that the real instance also writes to.\n if (state == null) return;\n\n if (!tabsRef.current) return;\n\n const tabsRect = tabsRef.current.getBoundingClientRect();\n\n // Set active tab variables\n if (state?.selectedKey != null && state.selectedKey !== '') {\n const activeTab = tabRefs.current.get(state.selectedKey.toString());\n\n if (activeTab) {\n const activeRect = activeTab.getBoundingClientRect();\n const relativeLeft = activeRect.left - tabsRect.left;\n const relativeTop = activeRect.top - tabsRect.top;\n\n // Control transition timing based on whether this is the first time setting active tab\n const isFirstActiveTab = prevSelectedKey.current === null;\n\n if (isFirstActiveTab || !animate) {\n // First time setting active tab or non-animated reposition (e.g.\n // tab resize): no transitions for position\n tabsRef.current.style.setProperty(\n '--active-transition-duration',\n '0s',\n );\n // Enable transitions on next frame for future tab switches, unless\n // more non-animated updates may follow (e.g. a resize in progress)\n if (animate) {\n requestAnimationFrame(() => {\n if (tabsRef.current) {\n tabsRef.current.style.setProperty(\n '--active-transition-duration',\n '0.25s',\n );\n }\n });\n }\n } else {\n // Switching between tabs: full transitions\n tabsRef.current.style.setProperty(\n '--active-transition-duration',\n '0.25s',\n );\n }\n\n // Update previous selected key for next time\n prevSelectedKey.current = state.selectedKey.toString();\n\n tabsRef.current.style.setProperty(\n '--active-tab-left',\n `${relativeLeft}px`,\n );\n tabsRef.current.style.setProperty(\n '--active-tab-right',\n `${relativeLeft + activeRect.width}px`,\n );\n tabsRef.current.style.setProperty(\n '--active-tab-top',\n `${relativeTop}px`,\n );\n tabsRef.current.style.setProperty(\n '--active-tab-bottom',\n `${relativeTop + activeRect.height}px`,\n );\n tabsRef.current.style.setProperty(\n '--active-tab-width',\n `${activeRect.width}px`,\n );\n tabsRef.current.style.setProperty(\n '--active-tab-height',\n `${activeRect.height}px`,\n );\n tabsRef.current.style.setProperty('--active-tab-opacity', '1');\n }\n } else {\n tabsRef.current.style.setProperty('--active-tab-opacity', '0');\n prevSelectedKey.current = null;\n }\n\n // Set hovered tab variables\n if (hoveredKey) {\n const hoveredTab = tabRefs.current.get(hoveredKey);\n if (hoveredTab) {\n const hoveredRect = hoveredTab.getBoundingClientRect();\n const relativeLeft = hoveredRect.left - tabsRect.left;\n const relativeTop = hoveredRect.top - tabsRect.top;\n\n tabsRef.current.style.setProperty(\n '--hovered-tab-left',\n `${relativeLeft}px`,\n );\n tabsRef.current.style.setProperty(\n '--hovered-tab-right',\n `${relativeLeft + hoveredRect.width}px`,\n );\n tabsRef.current.style.setProperty(\n '--hovered-tab-top',\n `${relativeTop}px`,\n );\n tabsRef.current.style.setProperty(\n '--hovered-tab-bottom',\n `${relativeTop + hoveredRect.height}px`,\n );\n tabsRef.current.style.setProperty(\n '--hovered-tab-width',\n `${hoveredRect.width}px`,\n );\n tabsRef.current.style.setProperty(\n '--hovered-tab-height',\n `${hoveredRect.height}px`,\n );\n // Control transition timing based on whether this is a new hover session\n const isNewHoverSession = prevHoveredKey.current === null;\n\n if (isNewHoverSession || !animate) {\n // Starting new hover session or non-animated reposition (e.g. tab\n // resize): no transitions for position\n tabsRef.current.style.setProperty(\n '--hovered-transition-duration',\n '0s',\n );\n // Enable transitions on next frame for future tab switches, unless\n // more non-animated updates may follow (e.g. a resize in progress)\n if (animate) {\n requestAnimationFrame(() => {\n if (tabsRef.current) {\n tabsRef.current.style.setProperty(\n '--hovered-transition-duration',\n '0.2s',\n );\n }\n });\n }\n } else {\n // Moving between tabs in same session: full transitions\n tabsRef.current.style.setProperty(\n '--hovered-transition-duration',\n '0.2s',\n );\n }\n\n // Update previous hover key for next time\n prevHoveredKey.current = hoveredKey;\n\n tabsRef.current.style.setProperty('--hovered-tab-opacity', '1');\n }\n } else {\n // When not hovering, hide with opacity and reset for next hover session\n tabsRef.current.style.setProperty('--hovered-tab-opacity', '0');\n\n // Reset previous hover key so next hover is treated as new session\n prevHoveredKey.current = null;\n }\n },\n [state?.selectedKey, hoveredKey, tabRefs.current],\n );\n\n useEffect(() => {\n updateCSSVariables();\n }, [updateCSSVariables, tabRefs.current.size]);\n\n useEffect(() => {\n const handleResize = () => updateCSSVariables(false);\n window.addEventListener('resize', handleResize);\n return () => window.removeEventListener('resize', handleResize);\n }, [updateCSSVariables]);\n\n useEffect(() => {\n // ResizeObserver is not available in some environments (e.g. Jest/jsdom)\n if (typeof ResizeObserver === 'undefined') {\n return undefined;\n }\n\n let frame: number | null = null;\n const scheduleUpdate = () => {\n if (frame !== null) {\n return;\n }\n\n frame = requestAnimationFrame(() => {\n frame = null;\n updateCSSVariables(false);\n });\n };\n\n const resizeObserver = new ResizeObserver(scheduleUpdate);\n const observeTabs = () => {\n resizeObserver.disconnect();\n for (const tab of tabRefs.current.values()) {\n resizeObserver.observe(tab);\n }\n };\n observeTabs();\n\n // Tab elements can be added, removed, or replaced without this component\n // re-rendering, so watch the DOM to keep the observed set in sync.\n const mutationObserver = new MutationObserver(() => {\n observeTabs();\n scheduleUpdate();\n });\n\n if (tabsRef.current) {\n mutationObserver.observe(tabsRef.current, {\n childList: true,\n subtree: true,\n });\n }\n\n return () => {\n if (frame !== null) {\n cancelAnimationFrame(frame);\n }\n resizeObserver.disconnect();\n mutationObserver.disconnect();\n };\n }, [updateCSSVariables, tabRefs, tabsRef]);\n\n return (\n <>\n <div className={classes.root} />\n <div className={classes.hovered} />\n </>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definition.esm.js","sources":["../../../src/components/Tabs/definition.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\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 */\n\nimport { defineComponent } from '../../hooks/useDefinition';\nimport type {\n TabsOwnProps,\n TabListOwnProps,\n TabOwnProps,\n TabPanelOwnProps,\n TabsIndicatorsOwnProps,\n} from './types';\nimport styles from './Tabs.module.css';\n\n/**\n * Component definition for Tabs\n * @public\n */\nexport const TabsDefinition = defineComponent<TabsOwnProps>()({\n styles,\n classNames: {\n root: 'bui-Tabs',\n },\n propDefs: {\n className: {},\n children: {},\n },\n});\n\n/** @internal */\nexport const TabListDefinition = defineComponent<TabListOwnProps>()({\n styles,\n classNames: {\n root: 'bui-TabListWrapper',\n tabList: 'bui-TabList',\n },\n propDefs: {\n className: {},\n children: {},\n },\n});\n\n/** @internal */\nexport const TabDefinition = defineComponent<TabOwnProps>()({\n styles,\n classNames: {\n root: 'bui-Tab',\n },\n analytics: true,\n navigation: { type: 'anchor' },\n propDefs: {\n className: {},\n matchStrategy: {},\n href: {},\n id: {},\n noTrack: {},\n },\n});\n\n/** @internal */\nexport const TabPanelDefinition = defineComponent<TabPanelOwnProps>()({\n styles,\n classNames: {\n root: 'bui-TabPanel',\n },\n propDefs: {\n className: {},\n },\n});\n\n/** @internal */\nexport const TabsIndicatorsDefinition =\n defineComponent<TabsIndicatorsOwnProps>()({\n styles,\n classNames: {\n root: 'bui-TabActive',\n hovered: 'bui-TabHovered',\n },\n propDefs: {\n tabRefs: {},\n tabsRef: {},\n hoveredKey: {},\n prevHoveredKey: {},\n },\n });\n"],"names":[],"mappings":";;;;;;;;;;;;AA8BO,MAAM,cAAA,GAAiB,iBAA8B,CAAE;AAAA,EAC5D,MAAA;AAAA,EACA,UAAA,EAAY;AAAA,IACV,IAAA,EAAM;AAAA,GACR;AAAA,EACA,QAAA,EAAU;AAAA,IACR,WAAW,EAAC;AAAA,IACZ,UAAU;AAAC;AAEf,CAAC;AAGM,MAAM,iBAAA,GAAoB,iBAAiC,CAAE;AAAA,EAClE,MAAA;AAAA,EACA,UAAA,EAAY;AAAA,IACV,IAAA,EAAM,oBAAA;AAAA,IACN,OAAA,EAAS;AAAA,GACX;AAAA,EACA,QAAA,EAAU;AAAA,IACR,WAAW,EAAC;AAAA,IACZ,UAAU;AAAC;AAEf,CAAC;AAGM,MAAM,aAAA,GAAgB,iBAA6B,CAAE;AAAA,EAC1D,MAAA;AAAA,EACA,UAAA,EAAY;AAAA,IACV,IAAA,EAAM;AAAA,GACR;AAAA,EACA,SAAA,EAAW,IAAA;AAAA,EACX,UAAA,EAAY,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,EAC7B,QAAA,EAAU;AAAA,IACR,WAAW,EAAC;AAAA,IACZ,eAAe,EAAC;AAAA,IAChB,MAAM,EAAC;AAAA,IACP,IAAI,EAAC;AAAA,IACL,SAAS;AAAC;AAEd,CAAC;AAGM,MAAM,kBAAA,GAAqB,iBAAkC,CAAE;AAAA,EACpE,MAAA;AAAA,EACA,UAAA,EAAY;AAAA,IACV,IAAA,EAAM;AAAA,GACR;AAAA,EACA,QAAA,EAAU;AAAA,IACR,WAAW;AAAC;AAEhB,CAAC;AAGM,MAAM,wBAAA,GACX,iBAAwC,CAAE;AAAA,EACxC,MAAA;AAAA,EACA,UAAA,EAAY;AAAA,IACV,IAAA,EAAM,eAAA;AAAA,IACN,OAAA,EAAS;AAAA,GACX;AAAA,EACA,QAAA,EAAU;AAAA,IACR,SAAS,EAAC;AAAA,IACV,SAAS,EAAC;AAAA,IACV,YAAY,EAAC;AAAA,IACb,gBAAgB;AAAC;AAErB,CAAC
|
|
1
|
+
{"version":3,"file":"definition.esm.js","sources":["../../../src/components/Tabs/definition.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\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 */\n\nimport { defineComponent } from '../../hooks/useDefinition';\nimport type {\n TabsOwnProps,\n TabListOwnProps,\n TabOwnProps,\n TabPanelOwnProps,\n TabsIndicatorsOwnProps,\n} from './types';\nimport styles from './Tabs.module.css';\n\n/**\n * Component definition for Tabs\n * @public\n */\nexport const TabsDefinition = defineComponent<TabsOwnProps>()({\n styles,\n classNames: {\n root: 'bui-Tabs',\n },\n propDefs: {\n className: {},\n children: {},\n },\n});\n\n/** @internal */\nexport const TabListDefinition = defineComponent<TabListOwnProps>()({\n styles,\n classNames: {\n root: 'bui-TabListWrapper',\n tabList: 'bui-TabList',\n },\n propDefs: {\n className: {},\n children: {},\n },\n});\n\n/** @internal */\nexport const TabDefinition = defineComponent<TabOwnProps>()({\n styles,\n classNames: {\n root: 'bui-Tab',\n },\n analytics: true,\n navigation: { type: 'anchor' },\n propDefs: {\n className: {},\n matchStrategy: {},\n href: {},\n id: {},\n noTrack: {},\n },\n});\n\n/** @internal */\nexport const TabPanelDefinition = defineComponent<TabPanelOwnProps>()({\n styles,\n classNames: {\n root: 'bui-TabPanel',\n },\n propDefs: {\n className: {},\n },\n});\n\n/** @internal */\nexport const TabsIndicatorsDefinition =\n defineComponent<TabsIndicatorsOwnProps>()({\n styles,\n classNames: {\n root: 'bui-TabActive',\n hovered: 'bui-TabHovered',\n },\n propDefs: {\n tabRefs: {},\n tabsRef: {},\n hoveredKey: {},\n prevHoveredKey: {},\n },\n });\n"],"names":[],"mappings":";;;;;;;;;;;;AA8BO,MAAM,cAAA,GAAiB,iBAA8B,CAAE;AAAA,EAC5D,MAAA;AAAA,EACA,UAAA,EAAY;AAAA,IACV,IAAA,EAAM;AAAA,GACR;AAAA,EACA,QAAA,EAAU;AAAA,IACR,WAAW,EAAC;AAAA,IACZ,UAAU;AAAC;AAEf,CAAC;AAGM,MAAM,iBAAA,GAAoB,iBAAiC,CAAE;AAAA,EAClE,MAAA;AAAA,EACA,UAAA,EAAY;AAAA,IACV,IAAA,EAAM,oBAAA;AAAA,IACN,OAAA,EAAS;AAAA,GACX;AAAA,EACA,QAAA,EAAU;AAAA,IACR,WAAW,EAAC;AAAA,IACZ,UAAU;AAAC;AAEf,CAAC;AAGM,MAAM,aAAA,GAAgB,iBAA6B,CAAE;AAAA,EAC1D,MAAA;AAAA,EACA,UAAA,EAAY;AAAA,IACV,IAAA,EAAM;AAAA,GACR;AAAA,EACA,SAAA,EAAW,IAAA;AAAA,EACX,UAAA,EAAY,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,EAC7B,QAAA,EAAU;AAAA,IACR,WAAW,EAAC;AAAA,IACZ,eAAe,EAAC;AAAA,IAChB,MAAM,EAAC;AAAA,IACP,IAAI,EAAC;AAAA,IACL,SAAS;AAAC;AAEd,CAAC;AAGM,MAAM,kBAAA,GAAqB,iBAAkC,CAAE;AAAA,EACpE,MAAA;AAAA,EACA,UAAA,EAAY;AAAA,IACV,IAAA,EAAM;AAAA,GACR;AAAA,EACA,QAAA,EAAU;AAAA,IACR,WAAW;AAAC;AAEhB,CAAC;AAGM,MAAM,wBAAA,GACX,iBAAwC,CAAE;AAAA,EACxC,MAAA;AAAA,EACA,UAAA,EAAY;AAAA,IACV,IAAA,EAAM,eAAA;AAAA,IACN,OAAA,EAAS;AAAA,GACX;AAAA,EACA,QAAA,EAAU;AAAA,IACR,SAAS,EAAC;AAAA,IACV,SAAS,EAAC;AAAA,IACV,YAAY,EAAC;AAAA,IACb,gBAAgB;AAAC;AAErB,CAAC;;"}
|