@pega/cosmos-react-core 9.14.0 → 9.15.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/lib/components/AppShell/AppHeader.styles.js +1 -1
- package/lib/components/AppShell/AppHeader.styles.js.map +1 -1
- package/lib/components/AppShell/AppNavigationPanel.d.ts.map +1 -1
- package/lib/components/AppShell/AppNavigationPanel.js +3 -3
- package/lib/components/AppShell/AppNavigationPanel.js.map +1 -1
- package/lib/components/AppShell/AppShell.d.ts.map +1 -1
- package/lib/components/AppShell/AppShell.js +7 -17
- package/lib/components/AppShell/AppShell.js.map +1 -1
- package/lib/components/AppShell/AppShell.styles.d.ts +4 -6
- package/lib/components/AppShell/AppShell.styles.d.ts.map +1 -1
- package/lib/components/AppShell/AppShell.styles.js +42 -81
- package/lib/components/AppShell/AppShell.styles.js.map +1 -1
- package/lib/components/AppShell/AppTopNav.styles.d.ts.map +1 -1
- package/lib/components/AppShell/AppTopNav.styles.js +2 -2
- package/lib/components/AppShell/AppTopNav.styles.js.map +1 -1
- package/lib/components/AppShell/Drawer.d.ts +1 -2
- package/lib/components/AppShell/Drawer.d.ts.map +1 -1
- package/lib/components/AppShell/Drawer.js +4 -4
- package/lib/components/AppShell/Drawer.js.map +1 -1
- package/lib/components/AppShell/Drawer.styles.d.ts +1 -13
- package/lib/components/AppShell/Drawer.styles.d.ts.map +1 -1
- package/lib/components/AppShell/Drawer.styles.js +15 -31
- package/lib/components/AppShell/Drawer.styles.js.map +1 -1
- package/lib/components/Backdrop/Backdrop.js +1 -1
- package/lib/components/Backdrop/Backdrop.js.map +1 -1
- package/lib/components/ClassificationMarking/ClassificationMarking.styles.d.ts.map +1 -1
- package/lib/components/ClassificationMarking/ClassificationMarking.styles.js +5 -32
- package/lib/components/ClassificationMarking/ClassificationMarking.styles.js.map +1 -1
- package/lib/components/Fullscreen/Fullscreen.js +2 -2
- package/lib/components/Fullscreen/Fullscreen.js.map +1 -1
- package/lib/components/PageTemplates/CategorySubPage.styles.js +1 -1
- package/lib/components/PageTemplates/CategorySubPage.styles.js.map +1 -1
- package/lib/components/PageTemplates/DashboardPage.js +1 -1
- package/lib/components/PageTemplates/DashboardPage.js.map +1 -1
- package/lib/components/Preview/PreviewPanel.js +1 -1
- package/lib/components/Preview/PreviewPanel.js.map +1 -1
- package/lib/components/Progress/Progress.d.ts.map +1 -1
- package/lib/components/Progress/Progress.js +39 -7
- package/lib/components/Progress/Progress.js.map +1 -1
- package/lib/components/Progress/Progress.types.d.ts +10 -4
- package/lib/components/Progress/Progress.types.d.ts.map +1 -1
- package/lib/components/Progress/Progress.types.js.map +1 -1
- package/lib/components/Scanner/Scanner.d.ts +21 -0
- package/lib/components/Scanner/Scanner.d.ts.map +1 -0
- package/lib/components/Scanner/Scanner.js +177 -0
- package/lib/components/Scanner/Scanner.js.map +1 -0
- package/lib/components/Scanner/Scanner.styles.d.ts +4 -0
- package/lib/components/Scanner/Scanner.styles.d.ts.map +1 -0
- package/lib/components/Scanner/Scanner.styles.js +17 -0
- package/lib/components/Scanner/Scanner.styles.js.map +1 -0
- package/lib/components/Scanner/Scanner.test-ids.d.ts +2 -0
- package/lib/components/Scanner/Scanner.test-ids.d.ts.map +1 -0
- package/lib/components/Scanner/Scanner.test-ids.js +3 -0
- package/lib/components/Scanner/Scanner.test-ids.js.map +1 -0
- package/lib/components/Scanner/index.d.ts +3 -0
- package/lib/components/Scanner/index.d.ts.map +1 -0
- package/lib/components/Scanner/index.js +2 -0
- package/lib/components/Scanner/index.js.map +1 -0
- package/lib/hooks/index.d.ts +1 -0
- package/lib/hooks/index.d.ts.map +1 -1
- package/lib/hooks/index.js +1 -0
- package/lib/hooks/index.js.map +1 -1
- package/lib/hooks/useComputedLengthPx.d.ts +10 -0
- package/lib/hooks/useComputedLengthPx.d.ts.map +1 -0
- package/lib/hooks/useComputedLengthPx.js +46 -0
- package/lib/hooks/useComputedLengthPx.js.map +1 -0
- package/lib/hooks/useI18n.d.ts +7 -0
- package/lib/hooks/useI18n.d.ts.map +1 -1
- package/lib/i18n/default.d.ts +7 -0
- package/lib/i18n/default.d.ts.map +1 -1
- package/lib/i18n/default.js +7 -0
- package/lib/i18n/default.js.map +1 -1
- package/lib/i18n/i18n.d.ts +7 -0
- package/lib/i18n/i18n.d.ts.map +1 -1
- package/lib/index.d.ts +2 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -0
- package/lib/index.js.map +1 -1
- package/package.json +2 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PreviewPanel.js","sourceRoot":"","sources":["../../../src/components/Preview/PreviewPanel.tsx"],"names":[],"mappings":"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","sourcesContent":["import { forwardRef, useState, useEffect } from 'react';\nimport type { PropsWithoutRef, Ref } from 'react';\nimport styled, { css } from 'styled-components';\n\nimport Button from '../Button';\nimport { defaultThemeProp } from '../../theme';\nimport Drawer from '../Drawer';\nimport Flex from '../Flex';\nimport getFocusables from '../../utils/getFocusables';\nimport Icon, { registerIcon } from '../Icon';\nimport Progress from '../Progress';\nimport { readableHue } from '../../styles/utils';\nimport {\n resizeDrawerDefaultWidth,\n resizeDrawerMaxWidth,\n resizeDrawerMinWidth\n} from '../../styles/constants';\nimport { StyledResizeHandle } from '../Drawer/ResizeHandle';\nimport * as timesIcon from '../Icon/icons/times.icon';\nimport useConsolidatedRef from '../../hooks/useConsolidatedRef';\nimport useDirection from '../../hooks/useDirection';\nimport useElement from '../../hooks/useElement';\nimport useFocusTrap from '../../hooks/useFocusTrap';\nimport useI18n from '../../hooks/useI18n';\nimport usePreviewContext from '../../hooks/usePreviewContext';\nimport useTestIds from '../../hooks/useTestIds';\nimport { withTestIds } from '../../utils';\n\nimport { getPreviewPanelTestIds } from './PreviewPanel.test-ids';\nimport type { PreviewPanelProps } from './Preview.types';\n\nregisterIcon(timesIcon);\n\nexport const StyledPreviewDrawer = styled(Drawer)(({ theme }) => {\n return css`\n min-width: ${resizeDrawerMinWidth};\n max-width: ${resizeDrawerMaxWidth};\n width: var(--resize-drawer-width);\n background: ${theme.base.palette['app-background']};\n height: auto;\n inset-block-start: calc(var(--app-header-height, 0rem) + var(--appshell-top-offset, 0rem));\n inset-block-end: var(--appshell-bottom-offset, 0);\n z-index: calc(${theme.base['z-index'].backdrop} - 1);\n transition-property: transform, box-shadow, opacity, border-inline-start;\n transition-duration: max(${theme.base.animation.speed}, 1ms);\n transition-timing-function: ${theme.base.animation.timing.ease};\n\n ${StyledResizeHandle} {\n z-index: calc(${theme.base['z-index'].max - 1});\n }\n\n @media (width >= ${theme.base.breakpoints.md}) {\n box-shadow: none;\n border-inline-start: 0.0625rem solid\n ${readableHue(theme.base.palette['border-line'], theme.base.palette['app-background'], {\n mode: 'both',\n level: 'AANonText'\n })};\n }\n `;\n});\n\nStyledPreviewDrawer.defaultProps = defaultThemeProp;\n\nconst StyledCloseButton = styled(Button)(({ theme }) => {\n return css`\n --half-btn-compact-difference: calc(\n (${theme.base['hit-area'].mouse} - ${theme.base['hit-area'].compact}) / 2\n );\n @media (pointer: coarse) {\n --half-btn-compact-difference: calc(\n (${theme.base['hit-area'].finger} - ${theme.base['hit-area'].compact}) / 2\n );\n }\n position: absolute;\n border: none;\n\n /* Places above resize handle */\n z-index: ${theme.base['z-index'].max};\n box-shadow: ${theme.base.shadow.low};\n inset-inline-start: calc(-${theme.base['hit-area'].compact} / 2);\n inset-block-start: calc(2 * ${theme.base.spacing} + var(--half-btn-compact-difference));\n `;\n});\n\nStyledCloseButton.defaultProps = defaultThemeProp;\n\nconst PreviewPanel = forwardRef(function PreviewPanel(\n {\n testId,\n previewLabel,\n open,\n children,\n progress,\n onBeforeOpen,\n onAfterOpen,\n onBeforeClose,\n onAfterClose,\n ...restProps\n }: PropsWithoutRef<PreviewPanelProps>,\n ref: Ref<HTMLDivElement>\n) {\n const testIds = useTestIds(testId, getPreviewPanelTestIds);\n\n const t = useI18n();\n const direction = useDirection();\n const previewRef = useConsolidatedRef(ref);\n const { previewTriggerRef } = usePreviewContext();\n\n const [closeButtonEl, setCloseButtonEl] = useElement<HTMLButtonElement>();\n const [progressVisible, setProgressVisible] = useState(false);\n\n const setFocus = () => {\n if (progressVisible) return;\n\n const focusables = getFocusables(previewRef).filter(el => el !== closeButtonEl);\n const focusable = focusables[0] ?? closeButtonEl;\n focusable?.focus();\n };\n\n useEffect(() => {\n if (!progressVisible) {\n setFocus();\n }\n }, [progressVisible]);\n\n useFocusTrap(previewRef, true, [], false);\n\n return (\n <Drawer\n data-testid={testIds.root}\n onBeforeOpen={() => {\n onBeforeOpen?.();\n }}\n onAfterOpen={() => {\n setFocus();\n onAfterOpen?.();\n }}\n as={StyledPreviewDrawer}\n role='complementary'\n forwardedAs={Flex}\n container={{ direction: 'column' }}\n ref={previewRef}\n position='fixed'\n placement={direction.end}\n size={resizeDrawerDefaultWidth}\n aria-label={previewLabel ? t('preview_of_noun', [previewLabel]) : t('preview')}\n open={open}\n resizeable\n shadow\n nullWhenClosed\n {...restProps}\n >\n <StyledCloseButton\n data-testid={testIds.close}\n icon\n compact\n onClick={() => {\n onBeforeClose?.();\n onAfterClose?.();\n previewTriggerRef.current?.focus();\n }}\n ref={setCloseButtonEl}\n label={t('close_preview')}\n >\n <Icon name='times' size='font-size' />\n </StyledCloseButton>\n\n <Progress\n data-testid={testIds.progress}\n placement='local'\n visible={!!progress}\n focusOnVisible\n delay\n onTransitionStartIn={() => {\n setProgressVisible(true);\n }}\n onTransitionEndOut={() => setProgressVisible(false)}\n />\n {!progress && children}\n </Drawer>\n );\n});\n\nexport default withTestIds(PreviewPanel, getPreviewPanelTestIds);\n"]}
|
|
1
|
+
{"version":3,"file":"PreviewPanel.js","sourceRoot":"","sources":["../../../src/components/Preview/PreviewPanel.tsx"],"names":[],"mappings":"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","sourcesContent":["import { forwardRef, useState, useEffect } from 'react';\nimport type { PropsWithoutRef, Ref } from 'react';\nimport styled, { css } from 'styled-components';\n\nimport Button from '../Button';\nimport { defaultThemeProp } from '../../theme';\nimport Drawer from '../Drawer';\nimport Flex from '../Flex';\nimport getFocusables from '../../utils/getFocusables';\nimport Icon, { registerIcon } from '../Icon';\nimport Progress from '../Progress';\nimport { readableHue } from '../../styles/utils';\nimport {\n resizeDrawerDefaultWidth,\n resizeDrawerMaxWidth,\n resizeDrawerMinWidth\n} from '../../styles/constants';\nimport { StyledResizeHandle } from '../Drawer/ResizeHandle';\nimport * as timesIcon from '../Icon/icons/times.icon';\nimport useConsolidatedRef from '../../hooks/useConsolidatedRef';\nimport useDirection from '../../hooks/useDirection';\nimport useElement from '../../hooks/useElement';\nimport useFocusTrap from '../../hooks/useFocusTrap';\nimport useI18n from '../../hooks/useI18n';\nimport usePreviewContext from '../../hooks/usePreviewContext';\nimport useTestIds from '../../hooks/useTestIds';\nimport { withTestIds } from '../../utils';\n\nimport { getPreviewPanelTestIds } from './PreviewPanel.test-ids';\nimport type { PreviewPanelProps } from './Preview.types';\n\nregisterIcon(timesIcon);\n\nexport const StyledPreviewDrawer = styled(Drawer)(({ theme }) => {\n return css`\n min-width: ${resizeDrawerMinWidth};\n max-width: ${resizeDrawerMaxWidth};\n width: var(--resize-drawer-width);\n background: ${theme.base.palette['app-background']};\n height: auto;\n inset-block-start: var(--appshell-top-offset, 0);\n inset-block-end: var(--appshell-bottom-offset, 0);\n z-index: calc(${theme.base['z-index'].backdrop} - 1);\n transition-property: transform, box-shadow, opacity, border-inline-start;\n transition-duration: max(${theme.base.animation.speed}, 1ms);\n transition-timing-function: ${theme.base.animation.timing.ease};\n\n ${StyledResizeHandle} {\n z-index: calc(${theme.base['z-index'].max - 1});\n }\n\n @media (width >= ${theme.base.breakpoints.md}) {\n box-shadow: none;\n border-inline-start: 0.0625rem solid\n ${readableHue(theme.base.palette['border-line'], theme.base.palette['app-background'], {\n mode: 'both',\n level: 'AANonText'\n })};\n }\n `;\n});\n\nStyledPreviewDrawer.defaultProps = defaultThemeProp;\n\nconst StyledCloseButton = styled(Button)(({ theme }) => {\n return css`\n --half-btn-compact-difference: calc(\n (${theme.base['hit-area'].mouse} - ${theme.base['hit-area'].compact}) / 2\n );\n @media (pointer: coarse) {\n --half-btn-compact-difference: calc(\n (${theme.base['hit-area'].finger} - ${theme.base['hit-area'].compact}) / 2\n );\n }\n position: absolute;\n border: none;\n\n /* Places above resize handle */\n z-index: ${theme.base['z-index'].max};\n box-shadow: ${theme.base.shadow.low};\n inset-inline-start: calc(-${theme.base['hit-area'].compact} / 2);\n inset-block-start: calc(2 * ${theme.base.spacing} + var(--half-btn-compact-difference));\n `;\n});\n\nStyledCloseButton.defaultProps = defaultThemeProp;\n\nconst PreviewPanel = forwardRef(function PreviewPanel(\n {\n testId,\n previewLabel,\n open,\n children,\n progress,\n onBeforeOpen,\n onAfterOpen,\n onBeforeClose,\n onAfterClose,\n ...restProps\n }: PropsWithoutRef<PreviewPanelProps>,\n ref: Ref<HTMLDivElement>\n) {\n const testIds = useTestIds(testId, getPreviewPanelTestIds);\n\n const t = useI18n();\n const direction = useDirection();\n const previewRef = useConsolidatedRef(ref);\n const { previewTriggerRef } = usePreviewContext();\n\n const [closeButtonEl, setCloseButtonEl] = useElement<HTMLButtonElement>();\n const [progressVisible, setProgressVisible] = useState(false);\n\n const setFocus = () => {\n if (progressVisible) return;\n\n const focusables = getFocusables(previewRef).filter(el => el !== closeButtonEl);\n const focusable = focusables[0] ?? closeButtonEl;\n focusable?.focus();\n };\n\n useEffect(() => {\n if (!progressVisible) {\n setFocus();\n }\n }, [progressVisible]);\n\n useFocusTrap(previewRef, true, [], false);\n\n return (\n <Drawer\n data-testid={testIds.root}\n onBeforeOpen={() => {\n onBeforeOpen?.();\n }}\n onAfterOpen={() => {\n setFocus();\n onAfterOpen?.();\n }}\n as={StyledPreviewDrawer}\n role='complementary'\n forwardedAs={Flex}\n container={{ direction: 'column' }}\n ref={previewRef}\n position='fixed'\n placement={direction.end}\n size={resizeDrawerDefaultWidth}\n aria-label={previewLabel ? t('preview_of_noun', [previewLabel]) : t('preview')}\n open={open}\n resizeable\n shadow\n nullWhenClosed\n {...restProps}\n >\n <StyledCloseButton\n data-testid={testIds.close}\n icon\n compact\n onClick={() => {\n onBeforeClose?.();\n onAfterClose?.();\n previewTriggerRef.current?.focus();\n }}\n ref={setCloseButtonEl}\n label={t('close_preview')}\n >\n <Icon name='times' size='font-size' />\n </StyledCloseButton>\n\n <Progress\n data-testid={testIds.progress}\n placement='local'\n visible={!!progress}\n focusOnVisible\n delay\n onTransitionStartIn={() => {\n setProgressVisible(true);\n }}\n onTransitionEndOut={() => setProgressVisible(false)}\n />\n {!progress && children}\n </Drawer>\n );\n});\n\nexport default withTestIds(PreviewPanel, getPreviewPanelTestIds);\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Progress.d.ts","sourceRoot":"","sources":["../../../src/components/Progress/Progress.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,aAAa,CAAC;AAKnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAetD,QAAA,MAAM,QAAQ,EAAE,+BAA+B,CAAC,aAAa,
|
|
1
|
+
{"version":3,"file":"Progress.d.ts","sourceRoot":"","sources":["../../../src/components/Progress/Progress.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,aAAa,CAAC;AAKnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAetD,QAAA,MAAM,QAAQ,EAAE,+BAA+B,CAAC,aAAa,CAgO3D,CAAC;AAEH,eAAe,QAAQ,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { forwardRef, useState, useEffect, useRef } from 'react';
|
|
2
|
+
import { forwardRef, useState, useEffect, useRef, useLayoutEffect } from 'react';
|
|
3
3
|
import { createPortal } from 'react-dom';
|
|
4
4
|
import { getLuminance } from 'polished';
|
|
5
5
|
import Text from '../Text';
|
|
@@ -14,14 +14,16 @@ const variantMap = {
|
|
|
14
14
|
bar: Bar,
|
|
15
15
|
ellipsis: Ellipsis
|
|
16
16
|
};
|
|
17
|
-
const
|
|
17
|
+
const defaultDelayDuration = 100;
|
|
18
18
|
const minVisibleDuration = 1000;
|
|
19
|
-
const Progress = forwardRef(function Progress({ variant = 'ring', placement = 'global', visible: visibleProp = true, focusOnVisible = false, delay = false, onTransitionStartIn, onTransitionEndIn, onTransitionStartOut, onTransitionEndOut, value, message, liveConfig, ...restProps }, ref) {
|
|
19
|
+
const Progress = forwardRef(function Progress({ variant = 'ring', placement = 'global', visible: visibleProp = true, focusOnVisible = false, delay = false, onTransitionStartIn, onTransitionEndIn, onTransitionStartOut, onTransitionEndOut, value, message, liveConfig, offsetContainer, ...restProps }, ref) {
|
|
20
20
|
const t = useI18n();
|
|
21
21
|
const { portalTarget } = useConfiguration();
|
|
22
22
|
const { announcePolite } = useLiveLog();
|
|
23
23
|
const theme = useTheme();
|
|
24
24
|
const progressEl = useConsolidatedRef(ref);
|
|
25
|
+
const backdropRef = useRef(null);
|
|
26
|
+
const [indicatorOffsetTop, setIndicatorOffsetTop] = useState();
|
|
25
27
|
// Rendering states. Both are needed due to Backdrop's transition phase where isVisibleState is false but nullRender is true until onAfterTransitionOut.
|
|
26
28
|
const [isVisibleState, setIsVisibleState] = useState(delay ? false : visibleProp);
|
|
27
29
|
const [nullRender, setNullRender] = useState(!isVisibleState);
|
|
@@ -33,6 +35,7 @@ const Progress = forwardRef(function Progress({ variant = 'ring', placement = 'g
|
|
|
33
35
|
const hasBackdrop = placement === 'global' || placement === 'local';
|
|
34
36
|
const valString = typeof value === 'number' ? `${value}%` : undefined;
|
|
35
37
|
const label = message && valString ? `${message} - ${valString}` : message || valString;
|
|
38
|
+
const hasOffsetContainer = !!offsetContainer;
|
|
36
39
|
const renderVisible = () => {
|
|
37
40
|
setIsVisibleState(true);
|
|
38
41
|
setNullRender(false);
|
|
@@ -44,12 +47,30 @@ const Progress = forwardRef(function Progress({ variant = 'ring', placement = 'g
|
|
|
44
47
|
setNullRender(true);
|
|
45
48
|
}
|
|
46
49
|
};
|
|
50
|
+
useLayoutEffect(() => {
|
|
51
|
+
if (!isVisibleState || nullRender || !backdropRef.current || !offsetContainer?.current) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const backdropRect = backdropRef.current.getBoundingClientRect();
|
|
55
|
+
const refRect = offsetContainer.current.getBoundingClientRect();
|
|
56
|
+
const viewportHeight = document.documentElement.clientHeight;
|
|
57
|
+
// Visible portion of the reference element within the viewport
|
|
58
|
+
const visibleTop = Math.max(refRect.top, 0);
|
|
59
|
+
const visibleBottom = Math.min(refRect.bottom, viewportHeight);
|
|
60
|
+
if (visibleBottom <= visibleTop) {
|
|
61
|
+
setIndicatorOffsetTop(NaN);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
// Center of the visible portion, relative to the backdrop
|
|
65
|
+
setIndicatorOffsetTop((visibleTop + visibleBottom) / 2 - backdropRect.top);
|
|
66
|
+
}, [isVisibleState, nullRender, offsetContainer]);
|
|
47
67
|
// Handle render and visible state.
|
|
48
68
|
useEffect(() => {
|
|
49
69
|
if (visibleProp) {
|
|
50
70
|
// Capture a timestamp for additional timers.
|
|
51
71
|
timeBeforeVisibleRender.current = Date.now();
|
|
52
72
|
if (delay) {
|
|
73
|
+
const delayDuration = typeof delay === 'number' ? delay : defaultDelayDuration;
|
|
53
74
|
delayTimer.current = window.setTimeout(renderVisible, delayDuration);
|
|
54
75
|
}
|
|
55
76
|
else {
|
|
@@ -99,23 +120,34 @@ const Progress = forwardRef(function Progress({ variant = 'ring', placement = 'g
|
|
|
99
120
|
if (!nullRender && isVisibleState) {
|
|
100
121
|
// After a visible render set a timestamp for timers above.
|
|
101
122
|
timeAfterVisibleRender.current = Date.now();
|
|
102
|
-
|
|
123
|
+
// If there is no offsetContainer focus immediately.
|
|
124
|
+
// Otherwise wait until a render has applied offset to avoid the indicator being pulled out of view.
|
|
125
|
+
if ((focusOnVisible && !hasOffsetContainer) || indicatorOffsetTop) {
|
|
103
126
|
progressEl.current?.focus();
|
|
127
|
+
}
|
|
104
128
|
}
|
|
105
129
|
},
|
|
106
130
|
// nullRender is the only triggerable dependency. Others values will be captured.
|
|
107
|
-
[nullRender]);
|
|
131
|
+
[nullRender, hasOffsetContainer, indicatorOffsetTop]);
|
|
108
132
|
if (nullRender)
|
|
109
133
|
return null;
|
|
110
134
|
const CompVariant = variantMap[variant];
|
|
111
135
|
let indicator = (_jsx(CompVariant, { "aria-label": typeof value !== 'number' && label ? label : t('loading'), as: placement === 'inline' ? 'span' : undefined, ...restProps, placement: placement, value: value, "aria-valuetext": typeof value === 'number' ? label : undefined, ref: progressEl, tabIndex: -1 }));
|
|
112
136
|
if (placement !== 'inline') {
|
|
113
|
-
indicator = (_jsxs(Flex, { container: { direction: 'column', alignItems: 'center', gap: 0.5 }, as: StyledProgress, placement: placement,
|
|
137
|
+
indicator = (_jsxs(Flex, { container: { direction: 'column', alignItems: 'center', gap: 0.5 }, as: StyledProgress, placement: placement,
|
|
138
|
+
/*
|
|
139
|
+
Inline style justification:
|
|
140
|
+
Highly variable values will generate new classes every time.
|
|
141
|
+
Not using CSS var since can not conditionally set property, only value.
|
|
142
|
+
marginTop is used vs logical property since value is based on client rect which is not logical.
|
|
143
|
+
*/
|
|
144
|
+
style: indicatorOffsetTop ? { marginTop: `${indicatorOffsetTop}px` } : undefined, children: [indicator, message && (_jsx(Text, { as: StyledMessage, variant: 'secondary', "aria-hidden": true, children: message }))] }));
|
|
114
145
|
}
|
|
115
146
|
// generate background variant based on theme text color
|
|
116
147
|
const progressBackdropVariant = getLuminance(theme.base.palette['foreground-color']) > 0.5 ? 'dark' : 'light';
|
|
117
|
-
const content = hasBackdrop ? (_jsx(StyledProgressBackdrop, { open: isVisibleState, container: { direction: 'column' }, position: placement === 'global' ? 'fixed' : 'absolute', variant: progressBackdropVariant, alpha: 0.6, onBeforeTransitionIn: onTransitionStartIn, onAfterTransitionIn: onTransitionEndIn, onBeforeTransitionOut: onTransitionStartOut, onAfterTransitionOut: () => {
|
|
148
|
+
const content = hasBackdrop ? (_jsx(StyledProgressBackdrop, { ref: backdropRef, open: isVisibleState, container: { direction: 'column', justify: indicatorOffsetTop ? 'start' : 'center' }, position: placement === 'global' ? 'fixed' : 'absolute', variant: progressBackdropVariant, alpha: 0.6, onBeforeTransitionIn: onTransitionStartIn, onAfterTransitionIn: onTransitionEndIn, onBeforeTransitionOut: onTransitionStartOut, onAfterTransitionOut: () => {
|
|
118
149
|
setNullRender(true);
|
|
150
|
+
setIndicatorOffsetTop(undefined);
|
|
119
151
|
onTransitionEndOut?.();
|
|
120
152
|
}, children: indicator })) : (indicator);
|
|
121
153
|
return placement === 'global' && portalTarget ? createPortal(content, portalTarget) : content;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Progress.js","sourceRoot":"","sources":["../../../src/components/Progress/Progress.tsx"],"names":[],"mappings":"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","sourcesContent":["import { forwardRef, useState, useEffect, useRef } from 'react';\nimport type { PropsWithoutRef } from 'react';\nimport { createPortal } from 'react-dom';\nimport { getLuminance } from 'polished';\n\nimport type { ForwardRefForwardPropsComponent } from '../../types';\nimport Text from '../Text';\nimport { useConfiguration, useConsolidatedRef, useI18n, useLiveLog, useTheme } from '../../hooks';\nimport Flex from '../Flex';\n\nimport type { ProgressProps } from './Progress.types';\nimport Bar from './Bar';\nimport Ellipsis from './Ellipsis';\nimport Ring from './Ring';\nimport { StyledMessage, StyledProgress, StyledProgressBackdrop } from './Progress.styles';\n\nconst variantMap = {\n ring: Ring,\n bar: Bar,\n ellipsis: Ellipsis\n} as const;\n\nconst delayDuration = 100;\nconst minVisibleDuration = 1000;\n\nconst Progress: ForwardRefForwardPropsComponent<ProgressProps> = forwardRef(function Progress(\n {\n variant = 'ring',\n placement = 'global',\n visible: visibleProp = true,\n focusOnVisible = false,\n delay = false,\n onTransitionStartIn,\n onTransitionEndIn,\n onTransitionStartOut,\n onTransitionEndOut,\n value,\n message,\n liveConfig,\n ...restProps\n }: PropsWithoutRef<ProgressProps>,\n ref: ProgressProps['ref']\n) {\n const t = useI18n();\n const { portalTarget } = useConfiguration();\n const { announcePolite } = useLiveLog();\n const theme = useTheme();\n const progressEl = useConsolidatedRef<HTMLDivElement>(ref);\n\n // Rendering states. Both are needed due to Backdrop's transition phase where isVisibleState is false but nullRender is true until onAfterTransitionOut.\n const [isVisibleState, setIsVisibleState] = useState(delay ? false : visibleProp);\n const [nullRender, setNullRender] = useState(!isVisibleState);\n\n // Refs for timestamps and timeout ids.\n const timeBeforeVisibleRender = useRef<number>();\n const timeAfterVisibleRender = useRef<number>();\n const delayTimer = useRef<number>();\n const minVisibleTimer = useRef<number>();\n\n const hasBackdrop = placement === 'global' || placement === 'local';\n const valString = typeof value === 'number' ? `${value}%` : undefined;\n const label = message && valString ? `${message} - ${valString}` : message || valString;\n\n const renderVisible = () => {\n setIsVisibleState(true);\n setNullRender(false);\n };\n\n const renderNotVisible = () => {\n setIsVisibleState(false);\n // With a transition, setNullRender needs to be called in Backdrop's onAfterTransitionOut.\n if (!hasBackdrop) {\n setNullRender(true);\n }\n };\n\n // Handle render and visible state.\n useEffect(\n () => {\n if (visibleProp) {\n // Capture a timestamp for additional timers.\n timeBeforeVisibleRender.current = Date.now();\n\n if (delay) {\n delayTimer.current = window.setTimeout(renderVisible, delayDuration);\n } else {\n renderVisible();\n }\n } else if (\n // A timer was started to render visible either avoid it or render null.\n delayTimer.current !== undefined\n ) {\n // If a timeout has started to render visible, clear it.\n clearTimeout(delayTimer.current);\n\n // If the indicator has already rendered visible.\n if (timeAfterVisibleRender.current !== undefined) {\n const timeElapsedSinceLastVisibleRender = Date.now() - timeAfterVisibleRender.current;\n\n // If the indicator has been visible for long enough we can remove it.\n if (timeElapsedSinceLastVisibleRender >= minVisibleDuration) {\n renderNotVisible();\n } else {\n // Hold off removing until we hit the minimum visible time.\n minVisibleTimer.current = window.setTimeout(\n renderNotVisible,\n minVisibleDuration - timeElapsedSinceLastVisibleRender\n );\n }\n } else {\n renderNotVisible();\n }\n } else {\n renderNotVisible();\n }\n },\n // visibleProp is the only triggerable dependency. Others values will be captured.\n [visibleProp]\n );\n\n // Live announcement\n useEffect(\n () => {\n if (liveConfig?.contextualLabel && isVisibleState) {\n announcePolite({\n message: `${liveConfig.contextualLabel}, ${label ?? t('loading')}`,\n type: 'status'\n });\n }\n },\n // isVisibleState is the only triggerable dependency. Others values will be captured.\n [isVisibleState]\n );\n\n // Auto focusing and render timestamping.\n useEffect(\n () => {\n if (!nullRender && isVisibleState) {\n // After a visible render set a timestamp for timers above.\n timeAfterVisibleRender.current = Date.now();\n\n if (focusOnVisible) progressEl.current?.focus();\n }\n },\n // nullRender is the only triggerable dependency. Others values will be captured.\n [nullRender]\n );\n\n if (nullRender) return null;\n\n const CompVariant = variantMap[variant];\n\n let indicator = (\n <CompVariant\n aria-label={typeof value !== 'number' && label ? label : t('loading')}\n as={placement === 'inline' ? 'span' : undefined}\n {...restProps}\n placement={placement}\n value={value}\n aria-valuetext={typeof value === 'number' ? label : undefined}\n ref={progressEl}\n tabIndex={-1}\n />\n );\n\n if (placement !== 'inline') {\n indicator = (\n <Flex\n container={{ direction: 'column', alignItems: 'center', gap: 0.5 }}\n as={StyledProgress}\n placement={placement}\n >\n {indicator}\n {message && (\n <Text as={StyledMessage} variant='secondary' aria-hidden>\n {message}\n </Text>\n )}\n </Flex>\n );\n }\n\n // generate background variant based on theme text color\n const progressBackdropVariant =\n getLuminance(theme.base.palette['foreground-color']) > 0.5 ? 'dark' : 'light';\n\n const content = hasBackdrop ? (\n <StyledProgressBackdrop\n open={isVisibleState}\n container={{ direction: 'column' }}\n position={placement === 'global' ? 'fixed' : 'absolute'}\n variant={progressBackdropVariant}\n alpha={0.6}\n onBeforeTransitionIn={onTransitionStartIn}\n onAfterTransitionIn={onTransitionEndIn}\n onBeforeTransitionOut={onTransitionStartOut}\n onAfterTransitionOut={() => {\n setNullRender(true);\n onTransitionEndOut?.();\n }}\n >\n {indicator}\n </StyledProgressBackdrop>\n ) : (\n indicator\n );\n\n return placement === 'global' && portalTarget ? createPortal(content, portalTarget) : content;\n});\n\nexport default Progress;\n"]}
|
|
1
|
+
{"version":3,"file":"Progress.js","sourceRoot":"","sources":["../../../src/components/Progress/Progress.tsx"],"names":[],"mappings":"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","sourcesContent":["import { forwardRef, useState, useEffect, useRef, useLayoutEffect } from 'react';\nimport type { PropsWithoutRef } from 'react';\nimport { createPortal } from 'react-dom';\nimport { getLuminance } from 'polished';\n\nimport type { ForwardRefForwardPropsComponent } from '../../types';\nimport Text from '../Text';\nimport { useConfiguration, useConsolidatedRef, useI18n, useLiveLog, useTheme } from '../../hooks';\nimport Flex from '../Flex';\n\nimport type { ProgressProps } from './Progress.types';\nimport Bar from './Bar';\nimport Ellipsis from './Ellipsis';\nimport Ring from './Ring';\nimport { StyledMessage, StyledProgress, StyledProgressBackdrop } from './Progress.styles';\n\nconst variantMap = {\n ring: Ring,\n bar: Bar,\n ellipsis: Ellipsis\n} as const;\n\nconst defaultDelayDuration = 100;\nconst minVisibleDuration = 1000;\n\nconst Progress: ForwardRefForwardPropsComponent<ProgressProps> = forwardRef(function Progress(\n {\n variant = 'ring',\n placement = 'global',\n visible: visibleProp = true,\n focusOnVisible = false,\n delay = false,\n onTransitionStartIn,\n onTransitionEndIn,\n onTransitionStartOut,\n onTransitionEndOut,\n value,\n message,\n liveConfig,\n offsetContainer,\n ...restProps\n }: PropsWithoutRef<ProgressProps>,\n ref: ProgressProps['ref']\n) {\n const t = useI18n();\n const { portalTarget } = useConfiguration();\n const { announcePolite } = useLiveLog();\n const theme = useTheme();\n const progressEl = useConsolidatedRef<HTMLDivElement>(ref);\n const backdropRef = useRef<HTMLDivElement>(null);\n const [indicatorOffsetTop, setIndicatorOffsetTop] = useState<number | undefined>();\n\n // Rendering states. Both are needed due to Backdrop's transition phase where isVisibleState is false but nullRender is true until onAfterTransitionOut.\n const [isVisibleState, setIsVisibleState] = useState(delay ? false : visibleProp);\n const [nullRender, setNullRender] = useState(!isVisibleState);\n\n // Refs for timestamps and timeout ids.\n const timeBeforeVisibleRender = useRef<number>();\n const timeAfterVisibleRender = useRef<number>();\n const delayTimer = useRef<number>();\n const minVisibleTimer = useRef<number>();\n\n const hasBackdrop = placement === 'global' || placement === 'local';\n const valString = typeof value === 'number' ? `${value}%` : undefined;\n const label = message && valString ? `${message} - ${valString}` : message || valString;\n\n const hasOffsetContainer = !!offsetContainer;\n\n const renderVisible = () => {\n setIsVisibleState(true);\n setNullRender(false);\n };\n\n const renderNotVisible = () => {\n setIsVisibleState(false);\n // With a transition, setNullRender needs to be called in Backdrop's onAfterTransitionOut.\n if (!hasBackdrop) {\n setNullRender(true);\n }\n };\n\n useLayoutEffect(() => {\n if (!isVisibleState || nullRender || !backdropRef.current || !offsetContainer?.current) {\n return;\n }\n\n const backdropRect = backdropRef.current.getBoundingClientRect();\n const refRect = offsetContainer.current.getBoundingClientRect();\n const viewportHeight = document.documentElement.clientHeight;\n\n // Visible portion of the reference element within the viewport\n const visibleTop = Math.max(refRect.top, 0);\n const visibleBottom = Math.min(refRect.bottom, viewportHeight);\n\n if (visibleBottom <= visibleTop) {\n setIndicatorOffsetTop(NaN);\n return;\n }\n\n // Center of the visible portion, relative to the backdrop\n setIndicatorOffsetTop((visibleTop + visibleBottom) / 2 - backdropRect.top);\n }, [isVisibleState, nullRender, offsetContainer]);\n\n // Handle render and visible state.\n useEffect(\n () => {\n if (visibleProp) {\n // Capture a timestamp for additional timers.\n timeBeforeVisibleRender.current = Date.now();\n\n if (delay) {\n const delayDuration = typeof delay === 'number' ? delay : defaultDelayDuration;\n delayTimer.current = window.setTimeout(renderVisible, delayDuration);\n } else {\n renderVisible();\n }\n } else if (\n // A timer was started to render visible either avoid it or render null.\n delayTimer.current !== undefined\n ) {\n // If a timeout has started to render visible, clear it.\n clearTimeout(delayTimer.current);\n\n // If the indicator has already rendered visible.\n if (timeAfterVisibleRender.current !== undefined) {\n const timeElapsedSinceLastVisibleRender = Date.now() - timeAfterVisibleRender.current;\n\n // If the indicator has been visible for long enough we can remove it.\n if (timeElapsedSinceLastVisibleRender >= minVisibleDuration) {\n renderNotVisible();\n } else {\n // Hold off removing until we hit the minimum visible time.\n minVisibleTimer.current = window.setTimeout(\n renderNotVisible,\n minVisibleDuration - timeElapsedSinceLastVisibleRender\n );\n }\n } else {\n renderNotVisible();\n }\n } else {\n renderNotVisible();\n }\n },\n // visibleProp is the only triggerable dependency. Others values will be captured.\n [visibleProp]\n );\n\n // Live announcement\n useEffect(\n () => {\n if (liveConfig?.contextualLabel && isVisibleState) {\n announcePolite({\n message: `${liveConfig.contextualLabel}, ${label ?? t('loading')}`,\n type: 'status'\n });\n }\n },\n // isVisibleState is the only triggerable dependency. Others values will be captured.\n [isVisibleState]\n );\n\n // Auto focusing and render timestamping.\n useEffect(\n () => {\n if (!nullRender && isVisibleState) {\n // After a visible render set a timestamp for timers above.\n timeAfterVisibleRender.current = Date.now();\n\n // If there is no offsetContainer focus immediately.\n // Otherwise wait until a render has applied offset to avoid the indicator being pulled out of view.\n if ((focusOnVisible && !hasOffsetContainer) || indicatorOffsetTop) {\n progressEl.current?.focus();\n }\n }\n },\n // nullRender is the only triggerable dependency. Others values will be captured.\n [nullRender, hasOffsetContainer, indicatorOffsetTop]\n );\n\n if (nullRender) return null;\n\n const CompVariant = variantMap[variant];\n\n let indicator = (\n <CompVariant\n aria-label={typeof value !== 'number' && label ? label : t('loading')}\n as={placement === 'inline' ? 'span' : undefined}\n {...restProps}\n placement={placement}\n value={value}\n aria-valuetext={typeof value === 'number' ? label : undefined}\n ref={progressEl}\n tabIndex={-1}\n />\n );\n\n if (placement !== 'inline') {\n indicator = (\n <Flex\n container={{ direction: 'column', alignItems: 'center', gap: 0.5 }}\n as={StyledProgress}\n placement={placement}\n /*\n Inline style justification:\n Highly variable values will generate new classes every time.\n Not using CSS var since can not conditionally set property, only value.\n marginTop is used vs logical property since value is based on client rect which is not logical.\n */\n style={indicatorOffsetTop ? { marginTop: `${indicatorOffsetTop}px` } : undefined}\n >\n {indicator}\n {message && (\n <Text as={StyledMessage} variant='secondary' aria-hidden>\n {message}\n </Text>\n )}\n </Flex>\n );\n }\n\n // generate background variant based on theme text color\n const progressBackdropVariant =\n getLuminance(theme.base.palette['foreground-color']) > 0.5 ? 'dark' : 'light';\n\n const content = hasBackdrop ? (\n <StyledProgressBackdrop\n ref={backdropRef}\n open={isVisibleState}\n container={{ direction: 'column', justify: indicatorOffsetTop ? 'start' : 'center' }}\n position={placement === 'global' ? 'fixed' : 'absolute'}\n variant={progressBackdropVariant}\n alpha={0.6}\n onBeforeTransitionIn={onTransitionStartIn}\n onAfterTransitionIn={onTransitionEndIn}\n onBeforeTransitionOut={onTransitionStartOut}\n onAfterTransitionOut={() => {\n setNullRender(true);\n setIndicatorOffsetTop(undefined);\n onTransitionEndOut?.();\n }}\n >\n {indicator}\n </StyledProgressBackdrop>\n ) : (\n indicator\n );\n\n return placement === 'global' && portalTarget ? createPortal(content, portalTarget) : content;\n});\n\nexport default Progress;\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Ref } from 'react';
|
|
1
|
+
import type { Ref, RefObject } from 'react';
|
|
2
2
|
import type { BaseProps, NoChildrenProp } from '../../types';
|
|
3
3
|
import type { BackdropProps } from '../Backdrop/Backdrop';
|
|
4
4
|
export interface ProgressProps extends BaseProps, NoChildrenProp {
|
|
@@ -40,11 +40,11 @@ export interface ProgressProps extends BaseProps, NoChildrenProp {
|
|
|
40
40
|
*/
|
|
41
41
|
focusOnVisible?: boolean;
|
|
42
42
|
/**
|
|
43
|
-
* If true,
|
|
44
|
-
*
|
|
43
|
+
* If true, render is delayed to avoid unwanted flickering.
|
|
44
|
+
* Pass a number to customize the delay.
|
|
45
45
|
* @default false
|
|
46
46
|
*/
|
|
47
|
-
delay?: boolean;
|
|
47
|
+
delay?: boolean | number;
|
|
48
48
|
/** Called when the css transition starts on the way in. */
|
|
49
49
|
onTransitionStartIn?: BackdropProps['onBeforeTransitionIn'];
|
|
50
50
|
/** Called when the css transition starts on the way out. */
|
|
@@ -58,6 +58,12 @@ export interface ProgressProps extends BaseProps, NoChildrenProp {
|
|
|
58
58
|
/** Distinguishes the source of the update on the page. */
|
|
59
59
|
contextualLabel: string;
|
|
60
60
|
};
|
|
61
|
+
/**
|
|
62
|
+
* For use with "local" placement only.
|
|
63
|
+
* Reference to the relative container element for the locally placed backdrop.
|
|
64
|
+
* Enables dynamic offset of the visual indicator.
|
|
65
|
+
*/
|
|
66
|
+
offsetContainer?: RefObject<Element>;
|
|
61
67
|
/** Ref to the visual indicator element, currently a role of progressbar. */
|
|
62
68
|
ref?: Ref<HTMLDivElement>;
|
|
63
69
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Progress.types.d.ts","sourceRoot":"","sources":["../../../src/components/Progress/Progress.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"Progress.types.d.ts","sourceRoot":"","sources":["../../../src/components/Progress/Progress.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE5C,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,MAAM,WAAW,aAAc,SAAQ,SAAS,EAAE,cAAc;IAC9D;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,UAAU,CAAC;IACtC;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wFAAwF;IACxF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,SAAS,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,CAAC;IACpD;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACzB,2DAA2D;IAC3D,mBAAmB,CAAC,EAAE,aAAa,CAAC,sBAAsB,CAAC,CAAC;IAC5D,4DAA4D;IAC5D,oBAAoB,CAAC,EAAE,aAAa,CAAC,uBAAuB,CAAC,CAAC;IAC9D,yDAAyD;IACzD,iBAAiB,CAAC,EAAE,aAAa,CAAC,qBAAqB,CAAC,CAAC;IACzD,mFAAmF;IACnF,kBAAkB,CAAC,EAAE,aAAa,CAAC,sBAAsB,CAAC,CAAC;IAC3D,sEAAsE;IACtE,UAAU,CAAC,EAAE;QACX,0DAA0D;QAC1D,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;IACF;;;;OAIG;IACH,eAAe,CAAC,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;IACrC,4EAA4E;IAC5E,GAAG,CAAC,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC;CAC3B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Progress.types.js","sourceRoot":"","sources":["../../../src/components/Progress/Progress.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { Ref } from 'react';\n\nimport type { BaseProps, NoChildrenProp } from '../../types';\nimport type { BackdropProps } from '../Backdrop/Backdrop';\n\nexport interface ProgressProps extends BaseProps, NoChildrenProp {\n /**\n * Determines which variant should be rendered.\n * @default 'ring'\n */\n variant?: 'ring' | 'bar' | 'ellipsis';\n /**\n * Minimum possible value.\n * @default 0\n */\n minValue?: number;\n /**\n * Maximum possible value.\n * @default 100\n */\n maxValue?: number;\n /** Current progress value within the range specified, or the default range of 0-100. */\n value?: number;\n /** Provides a message to the user along with the component. */\n message?: string;\n /**\n * Determines the placement of the component.\n * @default 'global'\n */\n placement?: 'global' | 'local' | 'block' | 'inline';\n /**\n * When true, fade in occurs when component mounts.\n * When false, mounted component fades out then re-renders self and returns null, removing itself from the DOM.\n * This is technically not the same as unmounting via parent.\n * Applicable for all placements but the fade effect is only applicable to 'global' | 'local' placement.\n * @default true\n */\n visible?: boolean;\n /**\n * If true, upon visible render the indicator element will take focus.\n * @default false\n */\n focusOnVisible?: boolean;\n /**\n * If true,
|
|
1
|
+
{"version":3,"file":"Progress.types.js","sourceRoot":"","sources":["../../../src/components/Progress/Progress.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { Ref, RefObject } from 'react';\n\nimport type { BaseProps, NoChildrenProp } from '../../types';\nimport type { BackdropProps } from '../Backdrop/Backdrop';\n\nexport interface ProgressProps extends BaseProps, NoChildrenProp {\n /**\n * Determines which variant should be rendered.\n * @default 'ring'\n */\n variant?: 'ring' | 'bar' | 'ellipsis';\n /**\n * Minimum possible value.\n * @default 0\n */\n minValue?: number;\n /**\n * Maximum possible value.\n * @default 100\n */\n maxValue?: number;\n /** Current progress value within the range specified, or the default range of 0-100. */\n value?: number;\n /** Provides a message to the user along with the component. */\n message?: string;\n /**\n * Determines the placement of the component.\n * @default 'global'\n */\n placement?: 'global' | 'local' | 'block' | 'inline';\n /**\n * When true, fade in occurs when component mounts.\n * When false, mounted component fades out then re-renders self and returns null, removing itself from the DOM.\n * This is technically not the same as unmounting via parent.\n * Applicable for all placements but the fade effect is only applicable to 'global' | 'local' placement.\n * @default true\n */\n visible?: boolean;\n /**\n * If true, upon visible render the indicator element will take focus.\n * @default false\n */\n focusOnVisible?: boolean;\n /**\n * If true, render is delayed to avoid unwanted flickering.\n * Pass a number to customize the delay.\n * @default false\n */\n delay?: boolean | number;\n /** Called when the css transition starts on the way in. */\n onTransitionStartIn?: BackdropProps['onBeforeTransitionIn'];\n /** Called when the css transition starts on the way out. */\n onTransitionStartOut?: BackdropProps['onBeforeTransitionOut'];\n /** Called when the css transition ends on the way in. */\n onTransitionEndIn?: BackdropProps['onAfterTransitionIn'];\n /** Called when the css transition ends on the way out...A good time to unmount! */\n onTransitionEndOut?: BackdropProps['onAfterTransitionOut'];\n /** Triggers live announcement on show and value or message change. */\n liveConfig?: {\n /** Distinguishes the source of the update on the page. */\n contextualLabel: string;\n };\n /**\n * For use with \"local\" placement only.\n * Reference to the relative container element for the locally placed backdrop.\n * Enables dynamic offset of the visual indicator.\n */\n offsetContainer?: RefObject<Element>;\n /** Ref to the visual indicator element, currently a role of progressbar. */\n ref?: Ref<HTMLDivElement>;\n}\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ChangeEvent, FocusEvent } from 'react';
|
|
2
|
+
import type { InputProps } from '../Input';
|
|
3
|
+
import type { OmitStrict } from '../../types';
|
|
4
|
+
export interface ScannerProps extends OmitStrict<InputProps, 'type' | 'actions' | 'onChange' | 'value' | 'defaultValue'> {
|
|
5
|
+
/** Current value of the input. */
|
|
6
|
+
value?: string;
|
|
7
|
+
/** Called when the user types into the input. Not fired for scans — see `onScan`. */
|
|
8
|
+
onChange?: (value: string, event: ChangeEvent<HTMLInputElement>) => void;
|
|
9
|
+
/** Called when a barcode or QR code is successfully scanned. */
|
|
10
|
+
onScan?: (value: string) => void;
|
|
11
|
+
/** Called on the input's blur event. */
|
|
12
|
+
onBlur?: (event: FocusEvent<HTMLInputElement>) => void;
|
|
13
|
+
/**
|
|
14
|
+
* Optional native scan handler. When provided, it is invoked in place of the
|
|
15
|
+
* web-camera fallback — allowing host apps to wire in a platform-native
|
|
16
|
+
* barcode scanner. Should resolve with the scanned value.
|
|
17
|
+
*/
|
|
18
|
+
nativeScan?: () => Promise<string>;
|
|
19
|
+
}
|
|
20
|
+
export default function Scanner({ value, onChange, onScan, onBlur, disabled, readOnly, info, status, nativeScan, ...inputProps }: ScannerProps): import("react/jsx-runtime").JSX.Element;
|
|
21
|
+
//# sourceMappingURL=Scanner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Scanner.d.ts","sourceRoot":"","sources":["../../../src/components/Scanner/Scanner.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAOrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAG3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAO9C,MAAM,WAAW,YACf,SAAQ,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,OAAO,GAAG,cAAc,CAAC;IAC1F,kCAAkC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qFAAqF;IACrF,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;IACzE,gEAAgE;IAChE,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,wCAAwC;IACxC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;IACvD;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;CACpC;AAyJD,MAAM,CAAC,OAAO,UAAU,OAAO,CAAC,EAC9B,KAAK,EACL,QAAQ,EACR,MAAM,EACN,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,IAAI,EACJ,MAAM,EACN,UAAU,EACV,GAAG,UAAU,EACd,EAAE,YAAY,2CAuEd"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
3
|
+
import { Html5Qrcode } from 'html5-qrcode';
|
|
4
|
+
import Modal from '../Modal';
|
|
5
|
+
import Flex from '../Flex';
|
|
6
|
+
import Text from '../Text';
|
|
7
|
+
import Input from '../Input';
|
|
8
|
+
import { registerIcon } from '../Icon';
|
|
9
|
+
import * as qrIcon from '../Icon/icons/qr.icon';
|
|
10
|
+
import { useI18n, useModalContext, useModalManager, useUID } from '../../hooks';
|
|
11
|
+
import { StyledVideo, StyledHiddenCanvas, StyledHiddenDiv } from './Scanner.styles';
|
|
12
|
+
registerIcon(qrIcon);
|
|
13
|
+
const CameraScanModal = ({ onScan, onError }) => {
|
|
14
|
+
const t = useI18n();
|
|
15
|
+
const { dismiss } = useModalContext();
|
|
16
|
+
const scannerId = useUID();
|
|
17
|
+
const videoRef = useRef(null);
|
|
18
|
+
const canvasRef = useRef(null);
|
|
19
|
+
const streamRef = useRef(null);
|
|
20
|
+
const html5QrcodeRef = useRef(null);
|
|
21
|
+
const [cameraReady, setCameraReady] = useState(false);
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
let cancelled = false;
|
|
24
|
+
const start = async () => {
|
|
25
|
+
try {
|
|
26
|
+
let stream;
|
|
27
|
+
try {
|
|
28
|
+
stream = await navigator.mediaDevices.getUserMedia({
|
|
29
|
+
video: { facingMode: 'environment' }
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
stream = await navigator.mediaDevices.getUserMedia({ video: true });
|
|
34
|
+
}
|
|
35
|
+
if (cancelled) {
|
|
36
|
+
stream.getTracks().forEach(track => track.stop());
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
streamRef.current = stream;
|
|
40
|
+
if (videoRef.current) {
|
|
41
|
+
videoRef.current.srcObject = stream;
|
|
42
|
+
await videoRef.current.play();
|
|
43
|
+
if (!cancelled)
|
|
44
|
+
setCameraReady(true);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
if (cancelled)
|
|
49
|
+
return;
|
|
50
|
+
onError();
|
|
51
|
+
dismiss();
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
start();
|
|
55
|
+
return () => {
|
|
56
|
+
cancelled = true;
|
|
57
|
+
if (videoRef.current) {
|
|
58
|
+
videoRef.current.pause();
|
|
59
|
+
videoRef.current.srcObject = null;
|
|
60
|
+
}
|
|
61
|
+
if (streamRef.current) {
|
|
62
|
+
streamRef.current.getTracks().forEach(track => track.stop());
|
|
63
|
+
streamRef.current = null;
|
|
64
|
+
}
|
|
65
|
+
html5QrcodeRef.current = null;
|
|
66
|
+
};
|
|
67
|
+
}, [dismiss, onError]);
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
if (!cameraReady)
|
|
70
|
+
return;
|
|
71
|
+
let active = true;
|
|
72
|
+
let timeoutId;
|
|
73
|
+
const scanFrame = async () => {
|
|
74
|
+
if (!active || !videoRef.current || !canvasRef.current)
|
|
75
|
+
return;
|
|
76
|
+
const video = videoRef.current;
|
|
77
|
+
const canvas = canvasRef.current;
|
|
78
|
+
if (video.videoWidth === 0 || video.videoHeight === 0) {
|
|
79
|
+
timeoutId = setTimeout(scanFrame, 200);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
canvas.width = video.videoWidth;
|
|
83
|
+
canvas.height = video.videoHeight;
|
|
84
|
+
const ctx = canvas.getContext('2d');
|
|
85
|
+
if (!ctx) {
|
|
86
|
+
timeoutId = setTimeout(scanFrame, 200);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
|
|
90
|
+
try {
|
|
91
|
+
const blob = await new Promise(resolve => {
|
|
92
|
+
canvas.toBlob(resolve, 'image/png');
|
|
93
|
+
});
|
|
94
|
+
if (blob && active) {
|
|
95
|
+
const file = new File([blob], 'scan.png', { type: 'image/png' });
|
|
96
|
+
if (!html5QrcodeRef.current) {
|
|
97
|
+
html5QrcodeRef.current = new Html5Qrcode(scannerId, { verbose: false });
|
|
98
|
+
}
|
|
99
|
+
try {
|
|
100
|
+
const result = await html5QrcodeRef.current.scanFileV2(file, false);
|
|
101
|
+
if (result?.decodedText && active) {
|
|
102
|
+
active = false;
|
|
103
|
+
onScan(result.decodedText);
|
|
104
|
+
dismiss();
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
// No barcode found in this frame; keep scanning.
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
// Capture failed; keep scanning.
|
|
115
|
+
}
|
|
116
|
+
if (active)
|
|
117
|
+
timeoutId = setTimeout(scanFrame, 200);
|
|
118
|
+
};
|
|
119
|
+
scanFrame();
|
|
120
|
+
return () => {
|
|
121
|
+
active = false;
|
|
122
|
+
if (timeoutId)
|
|
123
|
+
clearTimeout(timeoutId);
|
|
124
|
+
};
|
|
125
|
+
}, [cameraReady, dismiss, onScan, scannerId]);
|
|
126
|
+
return (_jsxs(Modal, { heading: t('scan'), progress: cameraReady ? undefined : { message: t('starting_camera') }, onRequestDismiss: () => {
|
|
127
|
+
dismiss();
|
|
128
|
+
return true;
|
|
129
|
+
}, children: [_jsxs(Flex, { container: { direction: 'column', alignItems: 'center', gap: 1 }, children: [_jsx(StyledVideo, { ref: videoRef, autoPlay: true, playsInline: true, muted: true }), cameraReady && _jsx(Text, { variant: 'secondary', children: t('point_camera_at_barcode') })] }), _jsx(StyledHiddenCanvas, { ref: canvasRef }), _jsx(StyledHiddenDiv, { id: scannerId })] }));
|
|
130
|
+
};
|
|
131
|
+
export default function Scanner({ value, onChange, onScan, onBlur, disabled, readOnly, info, status, nativeScan, ...inputProps }) {
|
|
132
|
+
const t = useI18n();
|
|
133
|
+
const { create } = useModalManager();
|
|
134
|
+
const [scanning, setScanning] = useState(false);
|
|
135
|
+
const [scanError, setScanError] = useState();
|
|
136
|
+
const isWebCameraAvailable = typeof navigator !== 'undefined' &&
|
|
137
|
+
'mediaDevices' in navigator &&
|
|
138
|
+
typeof navigator.mediaDevices.getUserMedia === 'function';
|
|
139
|
+
const canScan = !!nativeScan || isWebCameraAvailable;
|
|
140
|
+
const commitScan = useCallback((scanned) => {
|
|
141
|
+
onScan?.(scanned);
|
|
142
|
+
}, [onScan]);
|
|
143
|
+
const handleScanClick = useCallback(() => {
|
|
144
|
+
setScanError(undefined);
|
|
145
|
+
if (nativeScan) {
|
|
146
|
+
setScanning(true);
|
|
147
|
+
Promise.resolve()
|
|
148
|
+
.then(() => nativeScan())
|
|
149
|
+
.then(scanned => commitScan(scanned))
|
|
150
|
+
.catch(() => setScanError(t('barcode_scan_failed')))
|
|
151
|
+
.finally(() => setScanning(false));
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
create(CameraScanModal, {
|
|
155
|
+
onScan: commitScan,
|
|
156
|
+
onError: () => setScanError(t('camera_access_denied'))
|
|
157
|
+
});
|
|
158
|
+
}, [commitScan, create, nativeScan, t]);
|
|
159
|
+
const inputActions = canScan
|
|
160
|
+
? [
|
|
161
|
+
{
|
|
162
|
+
id: 'scan',
|
|
163
|
+
icon: 'qr',
|
|
164
|
+
text: scanning ? t('scanning') : t('scan_barcode_or_qr_code'),
|
|
165
|
+
onClick: handleScanClick,
|
|
166
|
+
disabled: !!disabled || !!readOnly || scanning
|
|
167
|
+
}
|
|
168
|
+
]
|
|
169
|
+
: undefined;
|
|
170
|
+
const resolvedInfo = scanError ?? info;
|
|
171
|
+
const resolvedStatus = scanError ? 'error' : status;
|
|
172
|
+
return (_jsx(Input, { ...inputProps, type: 'text', value: value, disabled: disabled, readOnly: readOnly, info: resolvedInfo, status: resolvedStatus, actions: inputActions, onChange: (e) => {
|
|
173
|
+
setScanError(undefined);
|
|
174
|
+
onChange?.(e.currentTarget.value, e);
|
|
175
|
+
}, onBlur: onBlur }));
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=Scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Scanner.js","sourceRoot":"","sources":["../../../src/components/Scanner/Scanner.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\nimport type { ChangeEvent, FocusEvent } from 'react';\nimport { Html5Qrcode } from 'html5-qrcode';\n\nimport Modal from '../Modal';\nimport Flex from '../Flex';\nimport Text from '../Text';\nimport Input from '../Input';\nimport type { InputProps } from '../Input';\nimport { registerIcon } from '../Icon';\nimport * as qrIcon from '../Icon/icons/qr.icon';\nimport type { OmitStrict } from '../../types';\nimport { useI18n, useModalContext, useModalManager, useUID } from '../../hooks';\n\nimport { StyledVideo, StyledHiddenCanvas, StyledHiddenDiv } from './Scanner.styles';\n\nregisterIcon(qrIcon);\n\nexport interface ScannerProps\n extends OmitStrict<InputProps, 'type' | 'actions' | 'onChange' | 'value' | 'defaultValue'> {\n /** Current value of the input. */\n value?: string;\n /** Called when the user types into the input. Not fired for scans — see `onScan`. */\n onChange?: (value: string, event: ChangeEvent<HTMLInputElement>) => void;\n /** Called when a barcode or QR code is successfully scanned. */\n onScan?: (value: string) => void;\n /** Called on the input's blur event. */\n onBlur?: (event: FocusEvent<HTMLInputElement>) => void;\n /**\n * Optional native scan handler. When provided, it is invoked in place of the\n * web-camera fallback — allowing host apps to wire in a platform-native\n * barcode scanner. Should resolve with the scanned value.\n */\n nativeScan?: () => Promise<string>;\n}\n\ninterface CameraScanModalProps {\n onScan: (value: string) => void;\n onError: () => void;\n}\n\nconst CameraScanModal = ({ onScan, onError }: CameraScanModalProps) => {\n const t = useI18n();\n const { dismiss } = useModalContext();\n const scannerId = useUID();\n\n const videoRef = useRef<HTMLVideoElement | null>(null);\n const canvasRef = useRef<HTMLCanvasElement | null>(null);\n const streamRef = useRef<MediaStream | null>(null);\n const html5QrcodeRef = useRef<Html5Qrcode | null>(null);\n\n const [cameraReady, setCameraReady] = useState(false);\n\n useEffect(() => {\n let cancelled = false;\n\n const start = async () => {\n try {\n let stream: MediaStream;\n try {\n stream = await navigator.mediaDevices.getUserMedia({\n video: { facingMode: 'environment' }\n });\n } catch {\n stream = await navigator.mediaDevices.getUserMedia({ video: true });\n }\n\n if (cancelled) {\n stream.getTracks().forEach(track => track.stop());\n return;\n }\n\n streamRef.current = stream;\n\n if (videoRef.current) {\n videoRef.current.srcObject = stream;\n await videoRef.current.play();\n if (!cancelled) setCameraReady(true);\n }\n } catch {\n if (cancelled) return;\n onError();\n dismiss();\n }\n };\n\n start();\n\n return () => {\n cancelled = true;\n if (videoRef.current) {\n videoRef.current.pause();\n videoRef.current.srcObject = null;\n }\n if (streamRef.current) {\n streamRef.current.getTracks().forEach(track => track.stop());\n streamRef.current = null;\n }\n html5QrcodeRef.current = null;\n };\n }, [dismiss, onError]);\n\n useEffect(() => {\n if (!cameraReady) return;\n\n let active = true;\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n\n const scanFrame = async () => {\n if (!active || !videoRef.current || !canvasRef.current) return;\n\n const video = videoRef.current;\n const canvas = canvasRef.current;\n\n if (video.videoWidth === 0 || video.videoHeight === 0) {\n timeoutId = setTimeout(scanFrame, 200);\n return;\n }\n\n canvas.width = video.videoWidth;\n canvas.height = video.videoHeight;\n\n const ctx = canvas.getContext('2d');\n if (!ctx) {\n timeoutId = setTimeout(scanFrame, 200);\n return;\n }\n\n ctx.drawImage(video, 0, 0, canvas.width, canvas.height);\n\n try {\n const blob = await new Promise<Blob | null>(resolve => {\n canvas.toBlob(resolve, 'image/png');\n });\n\n if (blob && active) {\n const file = new File([blob], 'scan.png', { type: 'image/png' });\n if (!html5QrcodeRef.current) {\n html5QrcodeRef.current = new Html5Qrcode(scannerId, { verbose: false });\n }\n\n try {\n const result = await html5QrcodeRef.current.scanFileV2(file, false);\n if (result?.decodedText && active) {\n active = false;\n onScan(result.decodedText);\n dismiss();\n return;\n }\n } catch {\n // No barcode found in this frame; keep scanning.\n }\n }\n } catch {\n // Capture failed; keep scanning.\n }\n\n if (active) timeoutId = setTimeout(scanFrame, 200);\n };\n\n scanFrame();\n\n return () => {\n active = false;\n if (timeoutId) clearTimeout(timeoutId);\n };\n }, [cameraReady, dismiss, onScan, scannerId]);\n\n return (\n <Modal\n heading={t('scan')}\n progress={cameraReady ? undefined : { message: t('starting_camera') }}\n onRequestDismiss={() => {\n dismiss();\n return true;\n }}\n >\n <Flex container={{ direction: 'column', alignItems: 'center', gap: 1 }}>\n <StyledVideo ref={videoRef} autoPlay playsInline muted />\n {cameraReady && <Text variant='secondary'>{t('point_camera_at_barcode')}</Text>}\n </Flex>\n <StyledHiddenCanvas ref={canvasRef} />\n <StyledHiddenDiv id={scannerId} />\n </Modal>\n );\n};\n\nexport default function Scanner({\n value,\n onChange,\n onScan,\n onBlur,\n disabled,\n readOnly,\n info,\n status,\n nativeScan,\n ...inputProps\n}: ScannerProps) {\n const t = useI18n();\n const { create } = useModalManager();\n\n const [scanning, setScanning] = useState(false);\n const [scanError, setScanError] = useState<string | undefined>();\n\n const isWebCameraAvailable =\n typeof navigator !== 'undefined' &&\n 'mediaDevices' in navigator &&\n typeof navigator.mediaDevices.getUserMedia === 'function';\n const canScan = !!nativeScan || isWebCameraAvailable;\n\n const commitScan = useCallback(\n (scanned: string) => {\n onScan?.(scanned);\n },\n [onScan]\n );\n\n const handleScanClick = useCallback(() => {\n setScanError(undefined);\n\n if (nativeScan) {\n setScanning(true);\n Promise.resolve()\n .then(() => nativeScan())\n .then(scanned => commitScan(scanned))\n .catch(() => setScanError(t('barcode_scan_failed')))\n .finally(() => setScanning(false));\n return;\n }\n\n create(CameraScanModal, {\n onScan: commitScan,\n onError: () => setScanError(t('camera_access_denied'))\n });\n }, [commitScan, create, nativeScan, t]);\n\n const inputActions = canScan\n ? [\n {\n id: 'scan',\n icon: 'qr',\n text: scanning ? t('scanning') : t('scan_barcode_or_qr_code'),\n onClick: handleScanClick,\n disabled: !!disabled || !!readOnly || scanning\n }\n ]\n : undefined;\n\n const resolvedInfo = scanError ?? info;\n const resolvedStatus = scanError ? 'error' : status;\n\n return (\n <Input\n {...inputProps}\n type='text'\n value={value}\n disabled={disabled}\n readOnly={readOnly}\n info={resolvedInfo}\n status={resolvedStatus}\n actions={inputActions}\n onChange={(e: ChangeEvent<HTMLInputElement>) => {\n setScanError(undefined);\n onChange?.(e.currentTarget.value, e);\n }}\n onBlur={onBlur}\n />\n );\n}\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare const StyledVideo: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").VideoHTMLAttributes<HTMLVideoElement>, HTMLVideoElement>, never>> & string;
|
|
2
|
+
export declare const StyledHiddenCanvas: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").CanvasHTMLAttributes<HTMLCanvasElement>, HTMLCanvasElement>, never>> & string;
|
|
3
|
+
export declare const StyledHiddenDiv: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
4
|
+
//# sourceMappingURL=Scanner.styles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Scanner.styles.d.ts","sourceRoot":"","sources":["../../../src/components/Scanner/Scanner.styles.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,WAAW,sOAMvB,CAAC;AAIF,eAAO,MAAM,kBAAkB,yOAE9B,CAAC;AAIF,eAAO,MAAM,eAAe,6NAE3B,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import styled, { css } from 'styled-components';
|
|
2
|
+
import { defaultThemeProp } from '../../theme';
|
|
3
|
+
export const StyledVideo = styled.video(({ theme }) => css `
|
|
4
|
+
width: 100%;
|
|
5
|
+
display: block;
|
|
6
|
+
border-radius: ${theme.base['border-radius']};
|
|
7
|
+
`);
|
|
8
|
+
StyledVideo.defaultProps = defaultThemeProp;
|
|
9
|
+
export const StyledHiddenCanvas = styled.canvas `
|
|
10
|
+
display: none;
|
|
11
|
+
`;
|
|
12
|
+
StyledHiddenCanvas.defaultProps = defaultThemeProp;
|
|
13
|
+
export const StyledHiddenDiv = styled.div `
|
|
14
|
+
display: none;
|
|
15
|
+
`;
|
|
16
|
+
StyledHiddenDiv.defaultProps = defaultThemeProp;
|
|
17
|
+
//# sourceMappingURL=Scanner.styles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Scanner.styles.js","sourceRoot":"","sources":["../../../src/components/Scanner/Scanner.styles.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CACrC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,GAAG,CAAA;;;qBAGC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC;GAC7C,CACF,CAAC;AAEF,WAAW,CAAC,YAAY,GAAG,gBAAgB,CAAC;AAE5C,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,CAAA;;CAE9C,CAAC;AAEF,kBAAkB,CAAC,YAAY,GAAG,gBAAgB,CAAC;AAEnD,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,GAAG,CAAA;;CAExC,CAAC;AAEF,eAAe,CAAC,YAAY,GAAG,gBAAgB,CAAC","sourcesContent":["import styled, { css } from 'styled-components';\n\nimport { defaultThemeProp } from '../../theme';\n\nexport const StyledVideo = styled.video(\n ({ theme }) => css`\n width: 100%;\n display: block;\n border-radius: ${theme.base['border-radius']};\n `\n);\n\nStyledVideo.defaultProps = defaultThemeProp;\n\nexport const StyledHiddenCanvas = styled.canvas`\n display: none;\n`;\n\nStyledHiddenCanvas.defaultProps = defaultThemeProp;\n\nexport const StyledHiddenDiv = styled.div`\n display: none;\n`;\n\nStyledHiddenDiv.defaultProps = defaultThemeProp;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Scanner.test-ids.d.ts","sourceRoot":"","sources":["../../../src/components/Scanner/Scanner.test-ids.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,iBAAiB,mGAAwC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Scanner.test-ids.js","sourceRoot":"","sources":["../../../src/components/Scanner/Scanner.test-ids.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,CAAC,MAAM,iBAAiB,GAAG,aAAa,CAAC,SAAS,EAAE,EAAW,CAAC,CAAC","sourcesContent":["import { createTestIds } from '../../utils';\n\nexport const getScannerTestIds = createTestIds('scanner', [] as const);\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Scanner/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/Scanner/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC","sourcesContent":["export { default } from './Scanner';\nexport type { ScannerProps } from './Scanner';\n"]}
|
package/lib/hooks/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export { default as useArrows } from './useArrows';
|
|
|
7
7
|
export { default as useAutoResize } from './useAutoResize';
|
|
8
8
|
export { default as useBreakpoint } from './useBreakpoint';
|
|
9
9
|
export { default as useChToPxConversionFactor } from './useChToPxConversionFactor';
|
|
10
|
+
export { default as useComputedLengthPx } from './useComputedLengthPx';
|
|
10
11
|
export { default as useConfiguration } from './useConfiguration';
|
|
11
12
|
export { default as useConsolidatedRef } from './useConsolidatedRef';
|
|
12
13
|
export { default as useContentTabIndex } from './useContentTabIndex';
|