@telus-uds/components-web 3.0.1 → 3.2.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 +31 -2
- package/lib/Badge/Badge.js +0 -0
- package/lib/Badge/index.js +0 -0
- package/lib/BlockQuote/BlockQuote.js +56 -10
- package/lib/BlockQuote/index.js +0 -0
- package/lib/Breadcrumbs/Breadcrumbs.js +0 -0
- package/lib/Breadcrumbs/Item/Item.js +0 -0
- package/lib/Breadcrumbs/index.js +0 -0
- package/lib/Callout/Callout.js +0 -0
- package/lib/Callout/index.js +0 -0
- package/lib/Card/Card.js +0 -0
- package/lib/Card/CardContent.js +0 -0
- package/lib/Card/CardFooter.js +0 -0
- package/lib/Card/index.js +0 -0
- package/lib/Countdown/Countdown.js +78 -6
- package/lib/Countdown/Segment.js +6 -0
- package/lib/Countdown/constants.js +0 -0
- package/lib/Countdown/dictionary.js +0 -0
- package/lib/Countdown/index.js +0 -0
- package/lib/Countdown/types.js +0 -0
- package/lib/Countdown/useCountdown.js +0 -0
- package/lib/DatePicker/CalendarContainer.js +0 -0
- package/lib/DatePicker/DatePicker.js +0 -0
- package/lib/DatePicker/dictionary.js +0 -0
- package/lib/DatePicker/index.js +0 -0
- package/lib/DatePicker/reactDatesCss.js +0 -0
- package/lib/Disclaimer/Disclaimer.js +0 -0
- package/lib/Disclaimer/index.js +0 -0
- package/lib/ExpandCollapseMini/ExpandCollapseMini.js +0 -0
- package/lib/ExpandCollapseMini/ExpandCollapseMiniControl.js +0 -0
- package/lib/ExpandCollapseMini/index.js +0 -0
- package/lib/Footnote/Footnote.js +0 -0
- package/lib/Footnote/FootnoteLink.js +0 -0
- package/lib/Footnote/dictionary.js +0 -0
- package/lib/Footnote/index.js +0 -0
- package/lib/IconButton/IconButton.js +0 -0
- package/lib/IconButton/index.js +0 -0
- package/lib/Image/Image.js +0 -0
- package/lib/Image/index.js +0 -0
- package/lib/Image/server.js +0 -0
- package/lib/List/List.js +0 -0
- package/lib/List/ListItem.js +0 -0
- package/lib/List/index.js +0 -0
- package/lib/NavigationBar/NavigationBar.js +69 -15
- package/lib/NavigationBar/NavigationItem.js +0 -0
- package/lib/NavigationBar/NavigationSubMenu.js +0 -0
- package/lib/NavigationBar/collapseItems.js +0 -0
- package/lib/NavigationBar/index.js +0 -0
- package/lib/NavigationBar/resolveItemSelection.js +0 -0
- package/lib/OptimizeImage/OptimizeImage.js +0 -0
- package/lib/OptimizeImage/index.js +0 -0
- package/lib/OptimizeImage/utils/getFallbackUrl.js +0 -0
- package/lib/OptimizeImage/utils/getImageUrls.js +0 -0
- package/lib/OptimizeImage/utils/getOptimizedUrl.js +0 -0
- package/lib/OptimizeImage/utils/hasWebpSupport.js +0 -0
- package/lib/OptimizeImage/utils/index.js +0 -0
- package/lib/OptimizeImage/utils/isSvgUrl.js +0 -0
- package/lib/OrderedList/Item.js +0 -0
- package/lib/OrderedList/ItemBase.js +0 -0
- package/lib/OrderedList/OrderedList.js +0 -0
- package/lib/OrderedList/OrderedListBase.js +0 -0
- package/lib/OrderedList/constants.js +0 -0
- package/lib/OrderedList/index.js +0 -0
- package/lib/Paragraph/Paragraph.js +0 -0
- package/lib/Paragraph/index.js +0 -0
- package/lib/PreviewCard/AuthorDate.js +0 -0
- package/lib/PreviewCard/PreviewCard.js +0 -0
- package/lib/PreviewCard/index.js +0 -0
- package/lib/PriceLockup/PriceLockup.js +0 -0
- package/lib/PriceLockup/index.js +0 -0
- package/lib/PriceLockup/tokens.js +0 -0
- package/lib/Progress/ProgressBar.js +11 -1
- package/lib/Progress/index.js +0 -0
- package/lib/QuantitySelector/QuantitySelector.js +1 -1
- package/lib/QuantitySelector/SideButton.js +0 -0
- package/lib/QuantitySelector/dictionary.js +0 -0
- package/lib/QuantitySelector/index.js +0 -0
- package/lib/QuantitySelector/styles.js +0 -0
- package/lib/ResponsiveImage/ResponsiveImage.js +9 -3
- package/lib/ResponsiveImage/index.js +0 -0
- package/lib/Ribbon/Ribbon.js +0 -0
- package/lib/Ribbon/index.js +0 -0
- package/lib/SkeletonProvider/SkeletonImage.js +0 -0
- package/lib/SkeletonProvider/SkeletonProvider.js +0 -0
- package/lib/SkeletonProvider/SkeletonTypography.js +0 -0
- package/lib/SkeletonProvider/index.js +0 -0
- package/lib/Span/Span.js +0 -0
- package/lib/Span/index.js +0 -0
- package/lib/Spinner/Spinner.js +0 -0
- package/lib/Spinner/SpinnerContent.js +0 -0
- package/lib/Spinner/constants.js +0 -0
- package/lib/Spinner/index.js +0 -0
- package/lib/StoryCard/StoryCard.js +0 -0
- package/lib/StoryCard/index.js +0 -0
- package/lib/Table/Body.js +0 -0
- package/lib/Table/Cell.js +0 -0
- package/lib/Table/Header.js +0 -0
- package/lib/Table/Row.js +0 -0
- package/lib/Table/SubHeading.js +0 -0
- package/lib/Table/Table.js +0 -0
- package/lib/Table/index.js +0 -0
- package/lib/TermsAndConditions/ExpandCollapse.js +0 -0
- package/lib/TermsAndConditions/TermsAndConditions.js +0 -0
- package/lib/TermsAndConditions/dictionary.js +0 -0
- package/lib/TermsAndConditions/index.js +0 -0
- package/lib/Testimonial/Testimonial.js +0 -0
- package/lib/Testimonial/index.js +0 -0
- package/lib/Toast/Toast.js +0 -0
- package/lib/Toast/index.js +0 -0
- package/lib/Video/ControlBar/ControlBar.js +0 -0
- package/lib/Video/ControlBar/Controls/VideoButton/VideoButton.js +0 -0
- package/lib/Video/ControlBar/Controls/VideoMenu/VideoMenu.js +0 -0
- package/lib/Video/ControlBar/Controls/VideoProgressBar/VideoProgressBar.js +3 -0
- package/lib/Video/ControlBar/Controls/VolumeSlider/VolumeSlider.js +0 -0
- package/lib/Video/MiddleControlButton/MiddleControlButton.js +0 -0
- package/lib/Video/Video.js +0 -0
- package/lib/Video/index.js +0 -0
- package/lib/Video/videoText.js +0 -0
- package/lib/VideoPicker/VideoPicker.js +0 -0
- package/lib/VideoPicker/VideoPickerPlayer.js +0 -0
- package/lib/VideoPicker/VideoPickerThumbnail.js +0 -0
- package/lib/VideoPicker/VideoSlider.js +0 -0
- package/lib/VideoPicker/index.js +0 -0
- package/lib/VideoPicker/videoPropType.js +0 -0
- package/lib/WaffleGrid/WaffleGrid.js +0 -0
- package/lib/WaffleGrid/index.js +0 -0
- package/lib/WebVideo/WebVideo.js +0 -0
- package/lib/WebVideo/index.js +0 -0
- package/lib/WebVideo/utils/index.js +0 -0
- package/lib/baseExports.js +0 -0
- package/lib/index.js +0 -0
- package/lib/server.js +0 -0
- package/lib/shared/ConditionalWrapper/ConditionalWrapper.js +0 -0
- package/lib/shared/ConditionalWrapper/index.js +0 -0
- package/lib/shared/FullBleedContent/FullBleedContent.js +0 -0
- package/lib/shared/FullBleedContent/getFullBleedBorderRadius.js +0 -0
- package/lib/shared/FullBleedContent/index.js +0 -0
- package/lib/shared/FullBleedContent/useFullBleedContentProps.js +0 -0
- package/lib/shared/VideoSplash/SplashButton/SplashButton.js +0 -0
- package/lib/shared/VideoSplash/SplashButtonWithDetails/SplashButtonWithDetails.js +0 -0
- package/lib/shared/VideoSplash/VideoSplash.js +0 -0
- package/lib/shared/VideoSplash/helpers.js +0 -0
- package/lib/utils/index.js +3 -2
- package/lib/utils/isElementFocusable.js +0 -0
- package/lib/utils/logger.js +0 -0
- package/lib/utils/media.js +0 -0
- package/lib/utils/renderStructuredContent.js +0 -0
- package/lib/utils/scrollToAnchor.js +19 -0
- package/lib/utils/ssr.js +0 -0
- package/lib/utils/theming/get-theme-from-server.js +0 -0
- package/lib/utils/theming/with-client-theme.js +0 -0
- package/lib/utils/theming/with-server-theme.js +0 -0
- package/lib/utils/transforms.js +0 -0
- package/lib/utils/useOverlaidPosition.js +0 -0
- package/lib/utils/useTypographyTheme.js +0 -0
- package/package.json +3 -3
- package/src/BlockQuote/BlockQuote.jsx +73 -11
- package/src/Countdown/Countdown.jsx +90 -6
- package/src/Countdown/Segment.jsx +8 -2
- package/src/NavigationBar/NavigationBar.jsx +53 -12
- package/src/Progress/ProgressBar.jsx +11 -2
- package/src/QuantitySelector/QuantitySelector.jsx +1 -1
- package/src/ResponsiveImage/ResponsiveImage.jsx +12 -5
- package/src/Video/ControlBar/Controls/VideoProgressBar/VideoProgressBar.jsx +5 -1
- package/src/utils/index.js +5 -2
- package/src/utils/scrollToAnchor.js +18 -0
|
@@ -4,11 +4,13 @@ import {
|
|
|
4
4
|
selectSystemProps,
|
|
5
5
|
StackView,
|
|
6
6
|
Typography,
|
|
7
|
+
useHash,
|
|
8
|
+
useInputValue,
|
|
7
9
|
useResponsiveProp,
|
|
8
10
|
withLinkRouter
|
|
9
11
|
} from '@telus-uds/components-base'
|
|
10
12
|
import styled from 'styled-components'
|
|
11
|
-
import { htmlAttrs } from '../utils'
|
|
13
|
+
import { htmlAttrs, scrollToAnchor } from '../utils'
|
|
12
14
|
import NavigationItem from './NavigationItem'
|
|
13
15
|
import NavigationSubMenu from './NavigationSubMenu'
|
|
14
16
|
import collapseItems from './collapseItems'
|
|
@@ -34,16 +36,37 @@ const NavigationBar = React.forwardRef(
|
|
|
34
36
|
heading,
|
|
35
37
|
headingLevel = 'h1',
|
|
36
38
|
items,
|
|
37
|
-
onChange
|
|
39
|
+
onChange,
|
|
38
40
|
selectedId,
|
|
41
|
+
value,
|
|
39
42
|
LinkRouter,
|
|
40
43
|
linkRouterProps,
|
|
41
44
|
...rest
|
|
42
45
|
},
|
|
43
46
|
ref
|
|
44
47
|
) => {
|
|
48
|
+
const { currentValue, setValue } = useInputValue({ value, initialValue: selectedId, onChange })
|
|
49
|
+
|
|
50
|
+
useHash(
|
|
51
|
+
(hash, event) => {
|
|
52
|
+
let hashItem = hash && items.find(({ href }) => hash === href)
|
|
53
|
+
if (!hashItem) {
|
|
54
|
+
const parentItem = items.find(({ items: parentItems }) =>
|
|
55
|
+
parentItems?.some(({ href }) => hash === href)
|
|
56
|
+
)
|
|
57
|
+
hashItem = parentItem?.items.find(({ href }) => hash === href)
|
|
58
|
+
}
|
|
59
|
+
const hashId = hashItem && (hashItem.id || hashItem.label)
|
|
60
|
+
if (hashId) setValue(hashId, event)
|
|
61
|
+
},
|
|
62
|
+
[items, setValue]
|
|
63
|
+
)
|
|
64
|
+
|
|
45
65
|
const direction = useResponsiveProp({ xs: 'column', sm: 'row' })
|
|
46
|
-
const itemsForViewport = useResponsiveProp({
|
|
66
|
+
const itemsForViewport = useResponsiveProp({
|
|
67
|
+
xs: collapseItems(items, currentValue),
|
|
68
|
+
lg: items
|
|
69
|
+
})
|
|
47
70
|
const openOverlayRef = React.useRef(null)
|
|
48
71
|
const [openSubMenuId, setOpenSubMenuId] = React.useState(null)
|
|
49
72
|
const handleSubMenuClose = (event) => {
|
|
@@ -161,14 +184,28 @@ const NavigationBar = React.forwardRef(
|
|
|
161
184
|
const handleClick = (event) => {
|
|
162
185
|
if (nestedItems) {
|
|
163
186
|
setOpenSubMenuId(openSubMenuId !== itemId ? itemId : null)
|
|
187
|
+
return
|
|
188
|
+
}
|
|
189
|
+
if (href?.startsWith('#')) {
|
|
190
|
+
scrollToAnchor(href, event, () => setValue(itemId, event))
|
|
191
|
+
} else {
|
|
192
|
+
setValue(itemId, event)
|
|
164
193
|
}
|
|
165
194
|
onClick?.(event)
|
|
166
|
-
onChange?.(itemId, event)
|
|
167
195
|
}
|
|
168
196
|
|
|
169
197
|
const ItemComponent = nestedItems ? NavigationSubMenu : NavigationItem
|
|
170
198
|
const isOpen = itemId === openSubMenuId
|
|
171
199
|
|
|
200
|
+
const scrollableNestedItems =
|
|
201
|
+
nestedItems?.map((item) => ({
|
|
202
|
+
...item,
|
|
203
|
+
onPress: (event) => {
|
|
204
|
+
const nestedItemId = item.id ?? item.label
|
|
205
|
+
scrollToAnchor(item.href, event, () => setValue(nestedItemId, event))
|
|
206
|
+
}
|
|
207
|
+
})) ?? nestedItems
|
|
208
|
+
|
|
172
209
|
return (
|
|
173
210
|
<ItemComponent
|
|
174
211
|
ref={itemRef}
|
|
@@ -176,16 +213,16 @@ const NavigationBar = React.forwardRef(
|
|
|
176
213
|
href={href}
|
|
177
214
|
onClick={handleClick}
|
|
178
215
|
// TODO: refactor to pass selected ID via context
|
|
179
|
-
selectedId={
|
|
216
|
+
selectedId={currentValue}
|
|
180
217
|
index={index}
|
|
181
218
|
LinkRouter={ItemLinkRouter}
|
|
182
219
|
linkRouterProps={{ ...linkRouterProps, ...itemLinkRouterProps }}
|
|
183
|
-
items={
|
|
184
|
-
selected={itemId ===
|
|
220
|
+
items={scrollableNestedItems}
|
|
221
|
+
selected={itemId === currentValue}
|
|
185
222
|
itemsContainerRef={itemsRef}
|
|
186
223
|
{...itemRest}
|
|
187
|
-
{...(
|
|
188
|
-
{...(
|
|
224
|
+
{...(scrollableNestedItems && { isOpen })}
|
|
225
|
+
{...(scrollableNestedItems && isOpen && { openOverlayRef })}
|
|
189
226
|
>
|
|
190
227
|
{label}
|
|
191
228
|
</ItemComponent>
|
|
@@ -207,7 +244,7 @@ NavigationBar.propTypes = {
|
|
|
207
244
|
*
|
|
208
245
|
* Each `item` object must contain:
|
|
209
246
|
* - `heading` - user-facing text in the tab link
|
|
210
|
-
* - `href` - the URL of the page linked to.
|
|
247
|
+
* - `href` - the URL of the page linked to.
|
|
211
248
|
* - `id` - a stable, unique identifier of the page within the set. Not written into the HTML.
|
|
212
249
|
*/
|
|
213
250
|
items: PropTypes.arrayOf(
|
|
@@ -242,13 +279,17 @@ NavigationBar.propTypes = {
|
|
|
242
279
|
*/
|
|
243
280
|
headingLevel: PropTypes.oneOf(['h1', 'h2', 'h3', 'h4', 'h5', 'h6']),
|
|
244
281
|
/**
|
|
245
|
-
*
|
|
282
|
+
* Initial selected item ID
|
|
246
283
|
*/
|
|
247
|
-
selectedId: PropTypes.string
|
|
284
|
+
selectedId: PropTypes.string,
|
|
248
285
|
/**
|
|
249
286
|
* Optional function to be called on pressing a link
|
|
250
287
|
*/
|
|
251
288
|
onChange: PropTypes.func,
|
|
289
|
+
/**
|
|
290
|
+
* Controlled value for selected item ID
|
|
291
|
+
*/
|
|
292
|
+
value: PropTypes.string,
|
|
252
293
|
/**
|
|
253
294
|
* Accesibility role for stackview
|
|
254
295
|
*/
|
|
@@ -37,7 +37,8 @@ const Gradient = styled.div.attrs({ 'data-testid': 'ProgressBar-Gradient' })(
|
|
|
37
37
|
* `gradient` is being used here to provide gradient filling.
|
|
38
38
|
*
|
|
39
39
|
*/
|
|
40
|
-
|
|
40
|
+
|
|
41
|
+
const ProgressBar = React.forwardRef(({ percentage, tokens, variant, offset, ...rest }, ref) => {
|
|
41
42
|
const themeTokens = useThemeTokens('ProgressBar', tokens, variant)
|
|
42
43
|
const selectedProps = selectProps(rest)
|
|
43
44
|
|
|
@@ -47,6 +48,7 @@ const ProgressBar = React.forwardRef(({ percentage, tokens, variant, ...rest },
|
|
|
47
48
|
tokens={tokens}
|
|
48
49
|
variant={variant}
|
|
49
50
|
ref={ref}
|
|
51
|
+
offset={offset}
|
|
50
52
|
{...selectedProps}
|
|
51
53
|
>
|
|
52
54
|
{themeTokens.gradient && <Gradient {...themeTokens} />}
|
|
@@ -69,7 +71,14 @@ ProgressBar.propTypes = {
|
|
|
69
71
|
/**
|
|
70
72
|
* ProgressBar variant.
|
|
71
73
|
*/
|
|
72
|
-
variant: variantProp.propType
|
|
74
|
+
variant: variantProp.propType,
|
|
75
|
+
/**
|
|
76
|
+
* Offset position.
|
|
77
|
+
*/
|
|
78
|
+
offset: PropTypes.shape({
|
|
79
|
+
items: PropTypes.number,
|
|
80
|
+
current: PropTypes.number
|
|
81
|
+
})
|
|
73
82
|
}
|
|
74
83
|
|
|
75
84
|
export default ProgressBar
|
|
@@ -2,9 +2,9 @@ import React from 'react'
|
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
3
|
import { selectSystemProps } from '@telus-uds/components-base'
|
|
4
4
|
import { viewports } from '@telus-uds/system-constants'
|
|
5
|
-
import { htmlAttrs } from '../utils'
|
|
5
|
+
import { htmlAttrs, contentfulProps } from '../utils'
|
|
6
6
|
|
|
7
|
-
const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs])
|
|
7
|
+
const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs, contentfulProps])
|
|
8
8
|
|
|
9
9
|
const staticStyles = {
|
|
10
10
|
image: { display: 'block', width: '100%' }
|
|
@@ -14,9 +14,12 @@ const staticStyles = {
|
|
|
14
14
|
* Provide different image sources for different screen sizes.
|
|
15
15
|
*/
|
|
16
16
|
const ResponsiveImage = React.forwardRef(
|
|
17
|
-
(
|
|
17
|
+
(
|
|
18
|
+
{ xsSrc, smSrc, mdSrc, lgSrc, xlSrc, fallbackSrc, alt, loading = 'eager', dataSet, ...rest },
|
|
19
|
+
ref
|
|
20
|
+
) => {
|
|
18
21
|
return (
|
|
19
|
-
<picture {...selectProps(rest)} ref={ref}>
|
|
22
|
+
<picture {...selectProps(rest)} ref={ref} {...dataSet}>
|
|
20
23
|
<source srcSet={xlSrc} media={`(min-width: ${viewports.map.get(viewports.xl)}px)`} />
|
|
21
24
|
<source srcSet={lgSrc} media={`(min-width: ${viewports.map.get(viewports.lg)}px)`} />
|
|
22
25
|
<source srcSet={mdSrc} media={`(min-width: ${viewports.map.get(viewports.md)}px)`} />
|
|
@@ -65,7 +68,11 @@ ResponsiveImage.propTypes = {
|
|
|
65
68
|
* @default 'eager'
|
|
66
69
|
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-loading
|
|
67
70
|
*/
|
|
68
|
-
loading: PropTypes.oneOf(['eager', 'lazy'])
|
|
71
|
+
loading: PropTypes.oneOf(['eager', 'lazy']),
|
|
72
|
+
/**
|
|
73
|
+
* The dataSet prop allows to pass data-* attributes element to the component.
|
|
74
|
+
*/
|
|
75
|
+
dataSet: PropTypes.object
|
|
69
76
|
}
|
|
70
77
|
|
|
71
78
|
export default ResponsiveImage
|
|
@@ -119,6 +119,8 @@ const VideoProgressBar = ({
|
|
|
119
119
|
thumbBackground,
|
|
120
120
|
timestampMarginLeft,
|
|
121
121
|
timestampMarginRight,
|
|
122
|
+
remainingTimestampMarginLeft,
|
|
123
|
+
remainingTimestampMarginRight,
|
|
122
124
|
trackGradientStart,
|
|
123
125
|
trackGradientEnd,
|
|
124
126
|
rangeBackground
|
|
@@ -166,7 +168,9 @@ const VideoProgressBar = ({
|
|
|
166
168
|
tabIndex="-1"
|
|
167
169
|
{...sharedProps}
|
|
168
170
|
/>
|
|
169
|
-
<StyledTimestamp
|
|
171
|
+
<StyledTimestamp
|
|
172
|
+
margin={`0 ${remainingTimestampMarginRight}px 0 ${remainingTimestampMarginLeft}px`}
|
|
173
|
+
>
|
|
170
174
|
<Typography variant={{ inverse: true }}>{remainingTimestamp}</Typography>
|
|
171
175
|
</StyledTimestamp>
|
|
172
176
|
</ProgressBarContainer>
|
package/src/utils/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { htmlAttrs } from '@telus-uds/components-base'
|
|
1
|
+
import { htmlAttrs, contentfulProps } from '@telus-uds/components-base'
|
|
2
2
|
import { warn, deprecate } from './logger'
|
|
3
3
|
import { transformGradient } from './transforms'
|
|
4
4
|
import useTypographyTheme from './useTypographyTheme'
|
|
@@ -7,10 +7,12 @@ import ssrStyles from './ssr'
|
|
|
7
7
|
import isElementFocusable from './isElementFocusable'
|
|
8
8
|
import renderStructuredContent from './renderStructuredContent'
|
|
9
9
|
import useOverlaidPosition from './useOverlaidPosition'
|
|
10
|
+
import scrollToAnchor from './scrollToAnchor'
|
|
10
11
|
|
|
11
12
|
export {
|
|
12
13
|
deprecate,
|
|
13
14
|
htmlAttrs,
|
|
15
|
+
contentfulProps,
|
|
14
16
|
transformGradient,
|
|
15
17
|
useTypographyTheme,
|
|
16
18
|
warn,
|
|
@@ -18,5 +20,6 @@ export {
|
|
|
18
20
|
renderStructuredContent,
|
|
19
21
|
ssrStyles,
|
|
20
22
|
isElementFocusable,
|
|
21
|
-
useOverlaidPosition
|
|
23
|
+
useOverlaidPosition,
|
|
24
|
+
scrollToAnchor
|
|
22
25
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scrolls smoothly to the anchor element specified by the href.
|
|
3
|
+
*
|
|
4
|
+
* @param {string} href - The href attribute value, expected to be an anchor link starting with '#'.
|
|
5
|
+
* @param {Event} event - The event object associated with the click or navigation action.
|
|
6
|
+
* @param {Function} onAfterScroll - A callback function to be executed after the scroll action is completed.
|
|
7
|
+
*/
|
|
8
|
+
const scrollToAnchor = (href, event, onAfterScroll) => {
|
|
9
|
+
if (href?.startsWith('#')) {
|
|
10
|
+
event.preventDefault()
|
|
11
|
+
const target = document.getElementById(href.slice(1))
|
|
12
|
+
target?.scrollIntoView({ behavior: 'smooth' })
|
|
13
|
+
window.location.hash = href
|
|
14
|
+
onAfterScroll(event)
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export default scrollToAnchor
|