@reykjavik/hanna-react 0.10.107 → 0.10.109
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/BasicTable.js +1 -2
- package/CHANGELOG.md +17 -0
- package/HeroBlock.d.ts +3 -2
- package/Pagination.js +2 -2
- package/_abstract/_Layouts.d.ts +1 -0
- package/_abstract/_Layouts.js +9 -1
- package/_abstract/_Table.d.ts +2 -2
- package/esm/BasicTable.js +1 -2
- package/esm/HeroBlock.d.ts +3 -2
- package/esm/Pagination.js +2 -2
- package/esm/_abstract/_Layouts.d.ts +1 -0
- package/esm/_abstract/_Layouts.js +7 -0
- package/esm/_abstract/_Table.d.ts +2 -2
- package/esm/utils/useDomid.d.ts +5 -3
- package/esm/utils/useDomid.js +13 -5
- package/esm/utils/useScrollEdgeDetect.d.ts +2 -2
- package/esm/utils/useScrollEdgeDetect.js +30 -24
- package/package.json +1 -1
- package/utils/useDomid.d.ts +5 -3
- package/utils/useDomid.js +14 -6
- package/utils/useScrollEdgeDetect.d.ts +2 -2
- package/utils/useScrollEdgeDetect.js +29 -23
package/BasicTable.js
CHANGED
|
@@ -21,8 +21,7 @@ const BasicTable = (props) => {
|
|
|
21
21
|
: align === 'right'
|
|
22
22
|
? 'BasicTable--align--' + align
|
|
23
23
|
: undefined,
|
|
24
|
-
], wrapperProps: props.wrapperProps,
|
|
25
|
-
: true },
|
|
24
|
+
], wrapperProps: props.wrapperProps },
|
|
26
25
|
react_1.default.createElement(_Table_js_1.Table, Object.assign({ className: (0, classUtils_1.modifiedClass)('BasicTable', [
|
|
27
26
|
props.compact && 'compact',
|
|
28
27
|
type && tableTypes[type],
|
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,23 @@
|
|
|
4
4
|
|
|
5
5
|
- ... <!-- Add new lines here. -->
|
|
6
6
|
|
|
7
|
+
## 0.10.109
|
|
8
|
+
|
|
9
|
+
_2023-10-25_
|
|
10
|
+
|
|
11
|
+
- feat: Allow simple JSX in `HeroBlockProps.title`
|
|
12
|
+
- feat: Stop inserting `.TableWrapper__scroller` inner wrapping element
|
|
13
|
+
- fix: Conflicted/ambigious `wrapperProps` element type for `BasicTableProps`
|
|
14
|
+
- fix: Make `Pagination` root-element into a `<nav />`
|
|
15
|
+
|
|
16
|
+
## 0.10.108
|
|
17
|
+
|
|
18
|
+
_2023-10-09_
|
|
19
|
+
|
|
20
|
+
- fix: Add `rel="nofollow"` to all `Pagination` links
|
|
21
|
+
- fix: Fix esm import inside `useDomid` causing build errors in React<=v17
|
|
22
|
+
- fix: Make `useDomid` more efficient in React<=v17
|
|
23
|
+
|
|
7
24
|
## 0.10.107
|
|
8
25
|
|
|
9
26
|
_2023-10-05_
|
package/HeroBlock.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ReactElement } from 'react';
|
|
1
2
|
import { Illustration } from '@reykjavik/hanna-utils/assets';
|
|
2
3
|
import { ButtonProps } from './_abstract/_Button.js';
|
|
3
4
|
import { ImageProps } from './_abstract/_Image.js';
|
|
@@ -11,8 +12,8 @@ type HeroBlockImageProps = {
|
|
|
11
12
|
illustration?: undefined;
|
|
12
13
|
};
|
|
13
14
|
export type HeroBlockProps = {
|
|
14
|
-
title: string;
|
|
15
|
-
summary: string |
|
|
15
|
+
title: string | ReactElement;
|
|
16
|
+
summary: string | ReactElement;
|
|
16
17
|
primaryButton?: ButtonProps;
|
|
17
18
|
secondaryButton?: ButtonProps;
|
|
18
19
|
} & HeroBlockImageProps & WrapperElmProps & DeprecatedSeenProp;
|
package/Pagination.js
CHANGED
|
@@ -22,7 +22,7 @@ const PaginationButton = (props) => {
|
|
|
22
22
|
'aria-current': modifier === 'active' || undefined,
|
|
23
23
|
'aria-controls': props.ariaControls,
|
|
24
24
|
};
|
|
25
|
-
return href && !disabled ? (react_1.default.createElement(_Link_js_1.Link, Object.assign({ href: href(page) }, btnProps))) : (react_1.default.createElement("button", Object.assign({ type: props.type, disabled: disabled }, btnProps)));
|
|
25
|
+
return href && !disabled ? (react_1.default.createElement(_Link_js_1.Link, Object.assign({ href: href(page), rel: "nofollow" }, btnProps))) : (react_1.default.createElement("button", Object.assign({ type: props.type, disabled: disabled }, btnProps)));
|
|
26
26
|
};
|
|
27
27
|
// ---------------------------------------------------------------------------
|
|
28
28
|
const getBtnRenderer = (cfg) => {
|
|
@@ -74,7 +74,7 @@ exports.Pagination = (0, react_1.memo)((props) => {
|
|
|
74
74
|
const pageList = (0, Pagination_privates_js_1.generatePageList)(current, pageCount);
|
|
75
75
|
const texts = (0, i18n_1.getTexts)(props, exports.defaultPaginationTexts);
|
|
76
76
|
const btn = getBtnRenderer(props);
|
|
77
|
-
return (react_1.default.createElement("
|
|
77
|
+
return (react_1.default.createElement("nav", Object.assign({}, wrapperProps, { className: (0, classUtils_1.modifiedClass)('Pagination', null, (wrapperProps || {}).className), "aria-label": props.title || texts.defaultTitle.replace(/\$\{pageCount\}/, `${pageCount}`) }),
|
|
78
78
|
btn({
|
|
79
79
|
page: current + 1,
|
|
80
80
|
modifier: 'next',
|
package/_abstract/_Layouts.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export declare const renderLayoutHomeLink: (bem: string, logoLink: string, siteName?: string) => JSX.Element;
|
|
2
|
+
export declare const renderLegacyLayoutHomeLink: (bem: string, logoLink: string, siteName?: string) => JSX.Element;
|
|
2
3
|
export declare const issueSiteNameWarningInDev: (props: {
|
|
3
4
|
siteName?: string;
|
|
4
5
|
}) => void;
|
package/_abstract/_Layouts.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.issueSiteNameWarningInDev = exports.renderLayoutHomeLink = void 0;
|
|
3
|
+
exports.issueSiteNameWarningInDev = exports.renderLegacyLayoutHomeLink = exports.renderLayoutHomeLink = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const react_1 = tslib_1.__importDefault(require("react"));
|
|
6
6
|
const assets_1 = require("@reykjavik/hanna-utils/assets");
|
|
@@ -15,6 +15,14 @@ const renderLayoutHomeLink = (bem, logoLink, siteName) => (react_1.default.creat
|
|
|
15
15
|
' '));
|
|
16
16
|
exports.renderLayoutHomeLink = renderLayoutHomeLink;
|
|
17
17
|
// ---------------------------------------------------------------------------
|
|
18
|
+
const renderLegacyLayoutHomeLink = (bem, logoLink, siteName) => (react_1.default.createElement(_Link_js_1.Link, { className: "Layout__header__logo", href: logoLink },
|
|
19
|
+
' ',
|
|
20
|
+
react_1.default.createElement(_Image_js_1.Image, { bem: undefined, inline: true, src: (0, assets_1.getRvkLogoUrl)('reykjavik-logo.svg'), altText: "Reykjav\u00EDk" }),
|
|
21
|
+
' ',
|
|
22
|
+
siteName,
|
|
23
|
+
' '));
|
|
24
|
+
exports.renderLegacyLayoutHomeLink = renderLegacyLayoutHomeLink;
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
18
26
|
const issueSiteNameWarningInDev = (props) => {
|
|
19
27
|
if (process.env.NODE_ENV !== 'production') {
|
|
20
28
|
if (!('siteName' in props)) {
|
package/_abstract/_Table.d.ts
CHANGED
|
@@ -64,8 +64,8 @@ declare const TableSection: ({ section, cols, Tag, getRowProps }: TableSectionPr
|
|
|
64
64
|
export type TableProps = TableData & {
|
|
65
65
|
cols?: TableCols;
|
|
66
66
|
rowProps?: HTMLProps<'tr'> | RowPropsFunction;
|
|
67
|
-
}
|
|
67
|
+
};
|
|
68
68
|
export declare const Table: React.MemoExoticComponent<(props: TableProps & {
|
|
69
69
|
className?: string;
|
|
70
|
-
}) => JSX.Element>;
|
|
70
|
+
} & WrapperElmProps<'table'>) => JSX.Element>;
|
|
71
71
|
export {};
|
package/esm/BasicTable.js
CHANGED
|
@@ -17,8 +17,7 @@ export const BasicTable = (props) => {
|
|
|
17
17
|
: align === 'right'
|
|
18
18
|
? 'BasicTable--align--' + align
|
|
19
19
|
: undefined,
|
|
20
|
-
], wrapperProps: props.wrapperProps,
|
|
21
|
-
: true },
|
|
20
|
+
], wrapperProps: props.wrapperProps },
|
|
22
21
|
React.createElement(Table, Object.assign({ className: modifiedClass('BasicTable', [
|
|
23
22
|
props.compact && 'compact',
|
|
24
23
|
type && tableTypes[type],
|
package/esm/HeroBlock.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ReactElement } from 'react';
|
|
1
2
|
import { Illustration } from '@reykjavik/hanna-utils/assets';
|
|
2
3
|
import { ButtonProps } from './_abstract/_Button.js';
|
|
3
4
|
import { ImageProps } from './_abstract/_Image.js';
|
|
@@ -11,8 +12,8 @@ type HeroBlockImageProps = {
|
|
|
11
12
|
illustration?: undefined;
|
|
12
13
|
};
|
|
13
14
|
export type HeroBlockProps = {
|
|
14
|
-
title: string;
|
|
15
|
-
summary: string |
|
|
15
|
+
title: string | ReactElement;
|
|
16
|
+
summary: string | ReactElement;
|
|
16
17
|
primaryButton?: ButtonProps;
|
|
17
18
|
secondaryButton?: ButtonProps;
|
|
18
19
|
} & HeroBlockImageProps & WrapperElmProps & DeprecatedSeenProp;
|
package/esm/Pagination.js
CHANGED
|
@@ -18,7 +18,7 @@ const PaginationButton = (props) => {
|
|
|
18
18
|
'aria-current': modifier === 'active' || undefined,
|
|
19
19
|
'aria-controls': props.ariaControls,
|
|
20
20
|
};
|
|
21
|
-
return href && !disabled ? (React.createElement(Link, Object.assign({ href: href(page) }, btnProps))) : (React.createElement("button", Object.assign({ type: props.type, disabled: disabled }, btnProps)));
|
|
21
|
+
return href && !disabled ? (React.createElement(Link, Object.assign({ href: href(page), rel: "nofollow" }, btnProps))) : (React.createElement("button", Object.assign({ type: props.type, disabled: disabled }, btnProps)));
|
|
22
22
|
};
|
|
23
23
|
// ---------------------------------------------------------------------------
|
|
24
24
|
const getBtnRenderer = (cfg) => {
|
|
@@ -70,7 +70,7 @@ export const Pagination = memo((props) => {
|
|
|
70
70
|
const pageList = generatePageList(current, pageCount);
|
|
71
71
|
const texts = getTexts(props, defaultPaginationTexts);
|
|
72
72
|
const btn = getBtnRenderer(props);
|
|
73
|
-
return (React.createElement("
|
|
73
|
+
return (React.createElement("nav", Object.assign({}, wrapperProps, { className: modifiedClass('Pagination', null, (wrapperProps || {}).className), "aria-label": props.title || texts.defaultTitle.replace(/\$\{pageCount\}/, `${pageCount}`) }),
|
|
74
74
|
btn({
|
|
75
75
|
page: current + 1,
|
|
76
76
|
modifier: 'next',
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export declare const renderLayoutHomeLink: (bem: string, logoLink: string, siteName?: string) => JSX.Element;
|
|
2
|
+
export declare const renderLegacyLayoutHomeLink: (bem: string, logoLink: string, siteName?: string) => JSX.Element;
|
|
2
3
|
export declare const issueSiteNameWarningInDev: (props: {
|
|
3
4
|
siteName?: string;
|
|
4
5
|
}) => void;
|
|
@@ -10,6 +10,13 @@ export const renderLayoutHomeLink = (bem, logoLink, siteName) => (React.createEl
|
|
|
10
10
|
siteName && React.createElement("span", { className: `${bem}__header__sitename` }, siteName),
|
|
11
11
|
' '));
|
|
12
12
|
// ---------------------------------------------------------------------------
|
|
13
|
+
export const renderLegacyLayoutHomeLink = (bem, logoLink, siteName) => (React.createElement(Link, { className: "Layout__header__logo", href: logoLink },
|
|
14
|
+
' ',
|
|
15
|
+
React.createElement(Image, { bem: undefined, inline: true, src: getRvkLogoUrl('reykjavik-logo.svg'), altText: "Reykjav\u00EDk" }),
|
|
16
|
+
' ',
|
|
17
|
+
siteName,
|
|
18
|
+
' '));
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
13
20
|
export const issueSiteNameWarningInDev = (props) => {
|
|
14
21
|
if (process.env.NODE_ENV !== 'production') {
|
|
15
22
|
if (!('siteName' in props)) {
|
|
@@ -64,8 +64,8 @@ declare const TableSection: ({ section, cols, Tag, getRowProps }: TableSectionPr
|
|
|
64
64
|
export type TableProps = TableData & {
|
|
65
65
|
cols?: TableCols;
|
|
66
66
|
rowProps?: HTMLProps<'tr'> | RowPropsFunction;
|
|
67
|
-
}
|
|
67
|
+
};
|
|
68
68
|
export declare const Table: React.MemoExoticComponent<(props: TableProps & {
|
|
69
69
|
className?: string;
|
|
70
|
-
}) => JSX.Element>;
|
|
70
|
+
} & WrapperElmProps<'table'>) => JSX.Element>;
|
|
71
71
|
export {};
|
package/esm/utils/useDomid.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Returns a stable, unique ID string.
|
|
3
3
|
*
|
|
4
|
-
* Uses useId from React
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Uses useId from React (v18+) when available, falling back on a custom
|
|
5
|
+
* unique id generator.
|
|
6
|
+
*
|
|
7
|
+
* (NOTE: The custom generator causes angry hydration warnings in dev
|
|
8
|
+
* mode and there's nothing we can do about it.)
|
|
7
9
|
*/
|
|
8
10
|
export declare const useDomid: (staticId?: string) => string;
|
package/esm/utils/useDomid.js
CHANGED
|
@@ -1,17 +1,25 @@
|
|
|
1
|
-
import
|
|
1
|
+
import React from 'react';
|
|
2
2
|
import domid from '@hugsmidjan/qj/domid';
|
|
3
3
|
// @ts-expect-error (transparently feature-detect useId hook, which is introduced in React@18)
|
|
4
4
|
const useId = React.useId;
|
|
5
5
|
/**
|
|
6
6
|
* Returns a stable, unique ID string.
|
|
7
7
|
*
|
|
8
|
-
* Uses useId from React
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* Uses useId from React (v18+) when available, falling back on a custom
|
|
9
|
+
* unique id generator.
|
|
10
|
+
*
|
|
11
|
+
* (NOTE: The custom generator causes angry hydration warnings in dev
|
|
12
|
+
* mode and there's nothing we can do about it.)
|
|
11
13
|
*/
|
|
12
14
|
export const useDomid = useId
|
|
13
15
|
? (staticId) => {
|
|
14
16
|
const id = useId();
|
|
15
17
|
return staticId || id;
|
|
16
18
|
}
|
|
17
|
-
: (staticId) =>
|
|
19
|
+
: (staticId) => {
|
|
20
|
+
const idRef = React.useRef();
|
|
21
|
+
if (!idRef.current) {
|
|
22
|
+
idRef.current = staticId || domid();
|
|
23
|
+
}
|
|
24
|
+
return idRef.current;
|
|
25
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RefObject } from 'react';
|
|
1
|
+
import { LegacyRef, RefObject } from 'react';
|
|
2
2
|
type ScrollAxis = 'horizontal' | 'vertical';
|
|
3
3
|
type AtState = {
|
|
4
4
|
start: boolean;
|
|
@@ -11,5 +11,5 @@ export type ScrollEdgeDetectOptions<RefElm extends HTMLElement = HTMLElement> =
|
|
|
11
11
|
/** Initial `at` status */
|
|
12
12
|
startAt?: AtState;
|
|
13
13
|
};
|
|
14
|
-
export declare const useScrollEdgeDetect: <RefElm extends HTMLElement = HTMLElement>(options: ScrollAxis | ScrollEdgeDetectOptions<RefElm>, scrollerRef?: RefObject<RefElm> | undefined) => [scrollElmRef:
|
|
14
|
+
export declare const useScrollEdgeDetect: <RefElm extends HTMLElement = HTMLElement>(options: ScrollAxis | ScrollEdgeDetectOptions<RefElm>, scrollerRef?: RefObject<RefElm> | undefined) => [scrollElmRef: LegacyRef<RefElm>, at: AtState];
|
|
15
15
|
export {};
|
|
@@ -1,38 +1,44 @@
|
|
|
1
|
-
import { useEffect,
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
2
|
import throttle from '@hugsmidjan/qj/throttle';
|
|
3
3
|
const tolerance = 8; // px
|
|
4
4
|
const throttleMs = 100;
|
|
5
5
|
export const useScrollEdgeDetect = (options, scrollerRef) => {
|
|
6
6
|
const opts = typeof options === 'string' ? { axis: options } : options;
|
|
7
|
-
const _scrollerRef = useRef(null);
|
|
8
|
-
scrollerRef = scrollerRef || _scrollerRef;
|
|
9
7
|
const [at, setAt] = useState(opts.startAt || { start: true, end: true });
|
|
10
|
-
const scrollerRefElm =
|
|
8
|
+
const [scrollerRefElm, _setScrollerRefElm] = useState(null);
|
|
9
|
+
const setScrollerRefElm = (elm) => {
|
|
10
|
+
if (scrollerRef && elm) {
|
|
11
|
+
scrollerRef.current = elm;
|
|
12
|
+
}
|
|
13
|
+
_setScrollerRefElm(elm);
|
|
14
|
+
};
|
|
11
15
|
const { getElm, axis } = opts;
|
|
12
16
|
useEffect(() => {
|
|
13
17
|
const scrollerElm = scrollerRefElm && getElm ? getElm(scrollerRefElm) : scrollerRefElm;
|
|
14
18
|
if (!(scrollerElm instanceof HTMLElement)) {
|
|
15
19
|
return;
|
|
16
20
|
}
|
|
17
|
-
const checkScroll = throttle(() =>
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
21
|
+
const checkScroll = throttle(() => {
|
|
22
|
+
setAt((at) => {
|
|
23
|
+
let scroll, offsetSize, totalSize;
|
|
24
|
+
if (axis === 'horizontal') {
|
|
25
|
+
scroll = scrollerElm.scrollLeft;
|
|
26
|
+
offsetSize = scrollerElm.offsetWidth;
|
|
27
|
+
totalSize = scrollerElm.scrollWidth;
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
scroll = scrollerElm.scrollTop;
|
|
31
|
+
offsetSize = scrollerElm.offsetHeight;
|
|
32
|
+
totalSize = scrollerElm.scrollHeight;
|
|
33
|
+
}
|
|
34
|
+
const start = scroll < tolerance;
|
|
35
|
+
const end = totalSize - (offsetSize + scroll) < tolerance;
|
|
36
|
+
if (at.start === start && at.end === end) {
|
|
37
|
+
return at;
|
|
38
|
+
}
|
|
39
|
+
return { start, end };
|
|
40
|
+
});
|
|
41
|
+
}, throttleMs);
|
|
36
42
|
scrollerElm.addEventListener('scroll', checkScroll);
|
|
37
43
|
window.addEventListener('resize', checkScroll);
|
|
38
44
|
checkScroll();
|
|
@@ -41,5 +47,5 @@ export const useScrollEdgeDetect = (options, scrollerRef) => {
|
|
|
41
47
|
window.removeEventListener('resize', checkScroll);
|
|
42
48
|
};
|
|
43
49
|
}, [scrollerRefElm, getElm, axis]);
|
|
44
|
-
return [
|
|
50
|
+
return [setScrollerRefElm, at];
|
|
45
51
|
};
|
package/package.json
CHANGED
package/utils/useDomid.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Returns a stable, unique ID string.
|
|
3
3
|
*
|
|
4
|
-
* Uses useId from React
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Uses useId from React (v18+) when available, falling back on a custom
|
|
5
|
+
* unique id generator.
|
|
6
|
+
*
|
|
7
|
+
* (NOTE: The custom generator causes angry hydration warnings in dev
|
|
8
|
+
* mode and there's nothing we can do about it.)
|
|
7
9
|
*/
|
|
8
10
|
export declare const useDomid: (staticId?: string) => string;
|
package/utils/useDomid.js
CHANGED
|
@@ -2,20 +2,28 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.useDomid = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
-
const
|
|
5
|
+
const react_1 = tslib_1.__importDefault(require("react"));
|
|
6
6
|
const domid_1 = tslib_1.__importDefault(require("@hugsmidjan/qj/domid"));
|
|
7
7
|
// @ts-expect-error (transparently feature-detect useId hook, which is introduced in React@18)
|
|
8
|
-
const useId =
|
|
8
|
+
const useId = react_1.default.useId;
|
|
9
9
|
/**
|
|
10
10
|
* Returns a stable, unique ID string.
|
|
11
11
|
*
|
|
12
|
-
* Uses useId from React
|
|
13
|
-
*
|
|
14
|
-
*
|
|
12
|
+
* Uses useId from React (v18+) when available, falling back on a custom
|
|
13
|
+
* unique id generator.
|
|
14
|
+
*
|
|
15
|
+
* (NOTE: The custom generator causes angry hydration warnings in dev
|
|
16
|
+
* mode and there's nothing we can do about it.)
|
|
15
17
|
*/
|
|
16
18
|
exports.useDomid = useId
|
|
17
19
|
? (staticId) => {
|
|
18
20
|
const id = useId();
|
|
19
21
|
return staticId || id;
|
|
20
22
|
}
|
|
21
|
-
: (staticId) =>
|
|
23
|
+
: (staticId) => {
|
|
24
|
+
const idRef = react_1.default.useRef();
|
|
25
|
+
if (!idRef.current) {
|
|
26
|
+
idRef.current = staticId || (0, domid_1.default)();
|
|
27
|
+
}
|
|
28
|
+
return idRef.current;
|
|
29
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RefObject } from 'react';
|
|
1
|
+
import { LegacyRef, RefObject } from 'react';
|
|
2
2
|
type ScrollAxis = 'horizontal' | 'vertical';
|
|
3
3
|
type AtState = {
|
|
4
4
|
start: boolean;
|
|
@@ -11,5 +11,5 @@ export type ScrollEdgeDetectOptions<RefElm extends HTMLElement = HTMLElement> =
|
|
|
11
11
|
/** Initial `at` status */
|
|
12
12
|
startAt?: AtState;
|
|
13
13
|
};
|
|
14
|
-
export declare const useScrollEdgeDetect: <RefElm extends HTMLElement = HTMLElement>(options: ScrollAxis | ScrollEdgeDetectOptions<RefElm>, scrollerRef?: RefObject<RefElm> | undefined) => [scrollElmRef:
|
|
14
|
+
export declare const useScrollEdgeDetect: <RefElm extends HTMLElement = HTMLElement>(options: ScrollAxis | ScrollEdgeDetectOptions<RefElm>, scrollerRef?: RefObject<RefElm> | undefined) => [scrollElmRef: LegacyRef<RefElm>, at: AtState];
|
|
15
15
|
export {};
|
|
@@ -8,35 +8,41 @@ const tolerance = 8; // px
|
|
|
8
8
|
const throttleMs = 100;
|
|
9
9
|
const useScrollEdgeDetect = (options, scrollerRef) => {
|
|
10
10
|
const opts = typeof options === 'string' ? { axis: options } : options;
|
|
11
|
-
const _scrollerRef = (0, react_1.useRef)(null);
|
|
12
|
-
scrollerRef = scrollerRef || _scrollerRef;
|
|
13
11
|
const [at, setAt] = (0, react_1.useState)(opts.startAt || { start: true, end: true });
|
|
14
|
-
const scrollerRefElm =
|
|
12
|
+
const [scrollerRefElm, _setScrollerRefElm] = (0, react_1.useState)(null);
|
|
13
|
+
const setScrollerRefElm = (elm) => {
|
|
14
|
+
if (scrollerRef && elm) {
|
|
15
|
+
scrollerRef.current = elm;
|
|
16
|
+
}
|
|
17
|
+
_setScrollerRefElm(elm);
|
|
18
|
+
};
|
|
15
19
|
const { getElm, axis } = opts;
|
|
16
20
|
(0, react_1.useEffect)(() => {
|
|
17
21
|
const scrollerElm = scrollerRefElm && getElm ? getElm(scrollerRefElm) : scrollerRefElm;
|
|
18
22
|
if (!(scrollerElm instanceof HTMLElement)) {
|
|
19
23
|
return;
|
|
20
24
|
}
|
|
21
|
-
const checkScroll = (0, throttle_1.default)(() =>
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
25
|
+
const checkScroll = (0, throttle_1.default)(() => {
|
|
26
|
+
setAt((at) => {
|
|
27
|
+
let scroll, offsetSize, totalSize;
|
|
28
|
+
if (axis === 'horizontal') {
|
|
29
|
+
scroll = scrollerElm.scrollLeft;
|
|
30
|
+
offsetSize = scrollerElm.offsetWidth;
|
|
31
|
+
totalSize = scrollerElm.scrollWidth;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
scroll = scrollerElm.scrollTop;
|
|
35
|
+
offsetSize = scrollerElm.offsetHeight;
|
|
36
|
+
totalSize = scrollerElm.scrollHeight;
|
|
37
|
+
}
|
|
38
|
+
const start = scroll < tolerance;
|
|
39
|
+
const end = totalSize - (offsetSize + scroll) < tolerance;
|
|
40
|
+
if (at.start === start && at.end === end) {
|
|
41
|
+
return at;
|
|
42
|
+
}
|
|
43
|
+
return { start, end };
|
|
44
|
+
});
|
|
45
|
+
}, throttleMs);
|
|
40
46
|
scrollerElm.addEventListener('scroll', checkScroll);
|
|
41
47
|
window.addEventListener('resize', checkScroll);
|
|
42
48
|
checkScroll();
|
|
@@ -45,6 +51,6 @@ const useScrollEdgeDetect = (options, scrollerRef) => {
|
|
|
45
51
|
window.removeEventListener('resize', checkScroll);
|
|
46
52
|
};
|
|
47
53
|
}, [scrollerRefElm, getElm, axis]);
|
|
48
|
-
return [
|
|
54
|
+
return [setScrollerRefElm, at];
|
|
49
55
|
};
|
|
50
56
|
exports.useScrollEdgeDetect = useScrollEdgeDetect;
|