@praxiis/ui 0.0.1
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/dist/index.d.mts +52556 -0
- package/dist/index.d.ts +52556 -0
- package/dist/index.js +8753 -0
- package/dist/index.mjs +8777 -0
- package/package.json +70 -0
- package/src/__test-utils__/index.tsx +39 -0
- package/src/components/CalendarStrip/CalendarStrip.helpers.ts +106 -0
- package/src/components/CalendarStrip/CalendarStrip.tsx +83 -0
- package/src/components/CalendarStrip/CalendarStrip.types.ts +133 -0
- package/src/components/CalendarStrip/DayCard/DayCard.helpers.ts +44 -0
- package/src/components/CalendarStrip/DayCard/DayCard.tsx +71 -0
- package/src/components/CalendarStrip/DayCard/DayCard.types.ts +134 -0
- package/src/components/CalendarStrip/DayCard/index.ts +2 -0
- package/src/components/CalendarStrip/DayCard/useDayCardLogic.ts +45 -0
- package/src/components/CalendarStrip/index.ts +9 -0
- package/src/components/CalendarStrip/useCalendarStripLogic.ts +53 -0
- package/src/components/EmptyState/EmptyState.helpers.ts +104 -0
- package/src/components/EmptyState/EmptyState.tsx +205 -0
- package/src/components/EmptyState/EmptyState.types.ts +213 -0
- package/src/components/EmptyState/index.ts +44 -0
- package/src/components/EmptyState/useEmptyStateLogic.ts +131 -0
- package/src/components/Header/Header.helpers.ts +93 -0
- package/src/components/Header/Header.tsx +185 -0
- package/src/components/Header/Header.types.ts +153 -0
- package/src/components/Header/index.ts +44 -0
- package/src/components/Header/useHeaderLogic.ts +146 -0
- package/src/components/ScheduleItem/ScheduleItem/ScheduleItem.helpers.ts +50 -0
- package/src/components/ScheduleItem/ScheduleItem/ScheduleItem.tsx +78 -0
- package/src/components/ScheduleItem/ScheduleItem/ScheduleItem.types.ts +99 -0
- package/src/components/ScheduleItem/ScheduleItem/index.ts +16 -0
- package/src/components/ScheduleItem/ScheduleItem/useScheduleItemLogic.ts +31 -0
- package/src/components/ScheduleItem/index.ts +15 -0
- package/src/components/index.ts +40 -0
- package/src/core/index.ts +34 -0
- package/src/core/restyle/RestyleThemeProviderWrapper.tsx +31 -0
- package/src/core/restyle/index.ts +38 -0
- package/src/core/restyle/restylePresetRegistry.ts +195 -0
- package/src/core/restyle/restyleTheme.ts +1352 -0
- package/src/core/restyle/restyleTypes.ts +8 -0
- package/src/core/restyle/useRestyleTheme.ts +10 -0
- package/src/hooks/animations/index.ts +3 -0
- package/src/hooks/animations/useAnimatedValue.ts +10 -0
- package/src/hooks/animations/useEntranceAnimation.ts +106 -0
- package/src/hooks/animations/usePulseAnimation.ts +63 -0
- package/src/hooks/index.ts +30 -0
- package/src/hooks/useReducedMotion.ts +60 -0
- package/src/i18n/index.ts +2 -0
- package/src/i18n/labels/en.ts +120 -0
- package/src/i18n/labels/es.ts +120 -0
- package/src/i18n/labels/index.ts +6 -0
- package/src/i18n/labels/types.ts +165 -0
- package/src/index.tsx +215 -0
- package/src/primitives/actions/Button/Button.helpers.ts +243 -0
- package/src/primitives/actions/Button/Button.tsx +198 -0
- package/src/primitives/actions/Button/Button.types.ts +207 -0
- package/src/primitives/actions/Button/index.ts +41 -0
- package/src/primitives/actions/Button/useButtonLogic.ts +160 -0
- package/src/primitives/actions/IconButton/IconButton.helpers.ts +235 -0
- package/src/primitives/actions/IconButton/IconButton.tsx +177 -0
- package/src/primitives/actions/IconButton/IconButton.types.ts +273 -0
- package/src/primitives/actions/IconButton/index.ts +30 -0
- package/src/primitives/actions/IconButton/useIconButtonLogic.ts +172 -0
- package/src/primitives/actions/index.ts +20 -0
- package/src/primitives/content/Avatar/Avatar.helpers.ts +177 -0
- package/src/primitives/content/Avatar/Avatar.tsx +199 -0
- package/src/primitives/content/Avatar/Avatar.types.ts +222 -0
- package/src/primitives/content/Avatar/index.ts +46 -0
- package/src/primitives/content/Avatar/useAvatarLogic.ts +149 -0
- package/src/primitives/content/Badge/Badge.helpers.ts +175 -0
- package/src/primitives/content/Badge/Badge.tsx +174 -0
- package/src/primitives/content/Badge/Badge.types.ts +223 -0
- package/src/primitives/content/Badge/index.ts +40 -0
- package/src/primitives/content/Badge/useBadgeLogic.ts +128 -0
- package/src/primitives/content/Card/Card.helpers.ts +27 -0
- package/src/primitives/content/Card/Card.tsx +123 -0
- package/src/primitives/content/Card/Card.types.ts +95 -0
- package/src/primitives/content/Card/index.ts +20 -0
- package/src/primitives/content/Card/useCardLogic.ts +48 -0
- package/src/primitives/content/Chip/Chip.helpers.ts +304 -0
- package/src/primitives/content/Chip/Chip.tsx +205 -0
- package/src/primitives/content/Chip/Chip.types.ts +234 -0
- package/src/primitives/content/Chip/index.ts +47 -0
- package/src/primitives/content/Chip/useChipLogic.ts +167 -0
- package/src/primitives/content/Icon/Icon.helpers.ts +54 -0
- package/src/primitives/content/Icon/Icon.tsx +110 -0
- package/src/primitives/content/Icon/Icon.types.ts +95 -0
- package/src/primitives/content/Icon/index.ts +20 -0
- package/src/primitives/content/Icon/useIconLogic.ts +73 -0
- package/src/primitives/content/index.ts +45 -0
- package/src/primitives/feedback/ProgressBar/ProgressBar.helpers.ts +122 -0
- package/src/primitives/feedback/ProgressBar/ProgressBar.tsx +154 -0
- package/src/primitives/feedback/ProgressBar/ProgressBar.types.ts +178 -0
- package/src/primitives/feedback/ProgressBar/index.ts +17 -0
- package/src/primitives/feedback/ProgressBar/useProgressBarLogic.ts +120 -0
- package/src/primitives/feedback/Skeleton/Skeleton.helpers.ts +145 -0
- package/src/primitives/feedback/Skeleton/Skeleton.tsx +155 -0
- package/src/primitives/feedback/Skeleton/Skeleton.types.ts +223 -0
- package/src/primitives/feedback/Skeleton/index.ts +44 -0
- package/src/primitives/feedback/Skeleton/useSkeletonLogic.ts +125 -0
- package/src/primitives/feedback/Spinner/Spinner.helpers.ts +40 -0
- package/src/primitives/feedback/Spinner/Spinner.tsx +105 -0
- package/src/primitives/feedback/Spinner/Spinner.types.ts +114 -0
- package/src/primitives/feedback/Spinner/index.ts +18 -0
- package/src/primitives/feedback/Spinner/useSpinnerLogic.ts +84 -0
- package/src/primitives/feedback/Toast/Toast.helpers.ts +163 -0
- package/src/primitives/feedback/Toast/Toast.tsx +190 -0
- package/src/primitives/feedback/Toast/Toast.types.ts +270 -0
- package/src/primitives/feedback/Toast/ToastContext.tsx +96 -0
- package/src/primitives/feedback/Toast/ToastProvider.tsx +241 -0
- package/src/primitives/feedback/Toast/index.ts +59 -0
- package/src/primitives/feedback/Toast/useToastLogic.ts +112 -0
- package/src/primitives/feedback/index.ts +45 -0
- package/src/primitives/index.ts +158 -0
- package/src/primitives/inputs/Checkbox/Checkbox.helpers.ts +132 -0
- package/src/primitives/inputs/Checkbox/Checkbox.tsx +150 -0
- package/src/primitives/inputs/Checkbox/Checkbox.types.ts +106 -0
- package/src/primitives/inputs/Checkbox/index.ts +30 -0
- package/src/primitives/inputs/Checkbox/useCheckboxLogic.ts +121 -0
- package/src/primitives/inputs/RadioButton/RadioButton.helpers.ts +123 -0
- package/src/primitives/inputs/RadioButton/RadioButton.tsx +159 -0
- package/src/primitives/inputs/RadioButton/RadioButton.types.ts +106 -0
- package/src/primitives/inputs/RadioButton/index.ts +25 -0
- package/src/primitives/inputs/RadioButton/useRadioButtonLogic.ts +117 -0
- package/src/primitives/inputs/SegmentedControl/SegmentedControl.helpers.ts +174 -0
- package/src/primitives/inputs/SegmentedControl/SegmentedControl.tsx +224 -0
- package/src/primitives/inputs/SegmentedControl/SegmentedControl.types.ts +187 -0
- package/src/primitives/inputs/SegmentedControl/index.ts +39 -0
- package/src/primitives/inputs/SegmentedControl/useSegmentedControlLogic.ts +151 -0
- package/src/primitives/inputs/SelectSheet/SelectSheet.helpers.ts +147 -0
- package/src/primitives/inputs/SelectSheet/SelectSheet.tsx +247 -0
- package/src/primitives/inputs/SelectSheet/SelectSheet.types.ts +196 -0
- package/src/primitives/inputs/SelectSheet/SelectSheetOption.tsx +177 -0
- package/src/primitives/inputs/SelectSheet/index.ts +48 -0
- package/src/primitives/inputs/SelectSheet/useSelectSheetLogic.ts +309 -0
- package/src/primitives/inputs/Switch/Switch.helpers.ts +109 -0
- package/src/primitives/inputs/Switch/Switch.tsx +191 -0
- package/src/primitives/inputs/Switch/Switch.types.ts +154 -0
- package/src/primitives/inputs/Switch/index.ts +40 -0
- package/src/primitives/inputs/Switch/useSwitchLogic.ts +192 -0
- package/src/primitives/inputs/TextInput/TextInput.helpers.ts +206 -0
- package/src/primitives/inputs/TextInput/TextInput.tsx +392 -0
- package/src/primitives/inputs/TextInput/TextInput.types.ts +216 -0
- package/src/primitives/inputs/TextInput/index.ts +37 -0
- package/src/primitives/inputs/TextInput/useTextInputLogic.ts +195 -0
- package/src/primitives/inputs/index.ts +52 -0
- package/src/primitives/layout/AnimatedBox.tsx +44 -0
- package/src/primitives/layout/Box.tsx +71 -0
- package/src/primitives/layout/Divider/Divider.helpers.ts +115 -0
- package/src/primitives/layout/Divider/Divider.tsx +139 -0
- package/src/primitives/layout/Divider/Divider.types.ts +178 -0
- package/src/primitives/layout/Divider/index.ts +24 -0
- package/src/primitives/layout/Divider/useDividerLogic.ts +109 -0
- package/src/primitives/layout/FlatList.tsx +66 -0
- package/src/primitives/layout/Pressable.tsx +74 -0
- package/src/primitives/layout/ScrollView.tsx +63 -0
- package/src/primitives/layout/Stack.tsx +69 -0
- package/src/primitives/layout/index.ts +40 -0
- package/src/primitives/navigation/index.ts +6 -0
- package/src/primitives/overlays/Modal/Modal.helpers.ts +31 -0
- package/src/primitives/overlays/Modal/Modal.tsx +264 -0
- package/src/primitives/overlays/Modal/Modal.types.ts +193 -0
- package/src/primitives/overlays/Modal/index.ts +43 -0
- package/src/primitives/overlays/Modal/useModalLogic.ts +103 -0
- package/src/primitives/overlays/index.ts +12 -0
- package/src/primitives/typography/Text.tsx +51 -0
- package/src/primitives/typography/index.ts +1 -0
- package/src/provider/DesignSystemContext.ts +22 -0
- package/src/provider/DesignSystemProvider.tsx +121 -0
- package/src/provider/index.ts +7 -0
- package/src/providers/ThemeProvider/createTheme.ts +304 -0
- package/src/providers/ThemeProvider/defaultTheme.ts +70 -0
- package/src/providers/ThemeProvider/index.ts +34 -0
- package/src/providers/ThemeProvider/types.ts +249 -0
- package/src/providers/index.ts +29 -0
- package/src/tokens/colors.ts +371 -0
- package/src/tokens/index.ts +145 -0
- package/src/tokens/motion.ts +176 -0
- package/src/tokens/radii.ts +82 -0
- package/src/tokens/scales.ts +588 -0
- package/src/tokens/shadows.ts +190 -0
- package/src/tokens/spacing.ts +140 -0
- package/src/tokens/tokens.json +207 -0
- package/src/tokens/typography.ts +251 -0
- package/src/types.ts +50 -0
- package/src/utils/accessibility.ts +169 -0
- package/src/utils/index.ts +25 -0
- package/src/utils/platform.ts +72 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Icon Module
|
|
3
|
+
*
|
|
4
|
+
* Atom component for rendering Material Icons with theme integration.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* import { Icon } from "@/design-system/primitives/Icon";
|
|
8
|
+
*
|
|
9
|
+
* <Icon name="home" size="lg" color="accentPrimary" />
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export { Icon } from "./Icon";
|
|
13
|
+
export { getIconA11y } from "./Icon.a11y";
|
|
14
|
+
|
|
15
|
+
export type {
|
|
16
|
+
IconName,
|
|
17
|
+
IconProps,
|
|
18
|
+
IconSize,
|
|
19
|
+
IconA11yProps,
|
|
20
|
+
} from "./Icon.types";
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Icon Logic Hook
|
|
3
|
+
*
|
|
4
|
+
* Extracts all computational logic from the Icon component.
|
|
5
|
+
* Returns memoized values for optimal render performance.
|
|
6
|
+
*
|
|
7
|
+
* Responsibilities:
|
|
8
|
+
* - Resolve responsive size prop to current breakpoint value
|
|
9
|
+
* - Convert size token to pixel value
|
|
10
|
+
* - Resolve color token to hex value
|
|
11
|
+
* - Generate accessibility props
|
|
12
|
+
*
|
|
13
|
+
* @see Icon.tsx - Component consuming this hook
|
|
14
|
+
* @see Icon.helpers.ts - Pure calculation functions
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { useResponsiveProp } from "@shopify/restyle";
|
|
18
|
+
import { useMemo } from "react";
|
|
19
|
+
import { useRestyleTheme } from "../../../core/restyle";
|
|
20
|
+
import { getIconA11y } from "./Icon.a11y";
|
|
21
|
+
import { resolveIconColor, resolveIconSizeValue } from "./Icon.helpers";
|
|
22
|
+
import { IconSize, UseIconLogicParams, UseIconLogicReturn } from "./Icon.types";
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Orchestrates Icon rendering logic and state management.
|
|
26
|
+
*
|
|
27
|
+
* Handles:
|
|
28
|
+
* - Responsive size resolution
|
|
29
|
+
* - Size token to pixel value conversion
|
|
30
|
+
* - Color token to hex value resolution
|
|
31
|
+
* - Accessibility props generation
|
|
32
|
+
*
|
|
33
|
+
* @param params - Configuration object for icon behavior
|
|
34
|
+
* @param params.color - Theme color token for icon
|
|
35
|
+
* @param params.size - Size variant ('xs' | 'sm' | 'md' | 'lg' | 'xl')
|
|
36
|
+
* @param params.accessibilityLabel - Screen reader label (required for standalone icons)
|
|
37
|
+
* @param params.accessibilityHint - Describes action result
|
|
38
|
+
*
|
|
39
|
+
* @returns Computed values for rendering Icon
|
|
40
|
+
* @returns {number} iconSizeValue - Icon size in pixels (12-32px)
|
|
41
|
+
* @returns {string} iconColor - Resolved hex color value
|
|
42
|
+
* @returns {object} a11yProps - Accessibility props
|
|
43
|
+
*
|
|
44
|
+
* @performance This hook uses useMemo() for size and color resolution
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* const { iconSizeValue, iconColor, a11yProps } = useIconLogic({
|
|
48
|
+
* color: "textPrimary",
|
|
49
|
+
* size: "md",
|
|
50
|
+
* accessibilityLabel: "Home",
|
|
51
|
+
* });
|
|
52
|
+
*/
|
|
53
|
+
export function useIconLogic(params: UseIconLogicParams): UseIconLogicReturn {
|
|
54
|
+
const { color, size, accessibilityLabel, accessibilityHint } = params;
|
|
55
|
+
|
|
56
|
+
const theme = useRestyleTheme();
|
|
57
|
+
const resolvedSize = (useResponsiveProp(size) ?? "md") as IconSize;
|
|
58
|
+
|
|
59
|
+
const iconSizeValue = resolveIconSizeValue({ resolvedSize, theme });
|
|
60
|
+
|
|
61
|
+
const iconColor = resolveIconColor(color, theme);
|
|
62
|
+
|
|
63
|
+
const a11yProps = useMemo(
|
|
64
|
+
() => getIconA11y({ accessibilityLabel, accessibilityHint }),
|
|
65
|
+
[accessibilityLabel, accessibilityHint],
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
return {
|
|
69
|
+
iconSizeValue,
|
|
70
|
+
iconColor,
|
|
71
|
+
a11yProps,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content Components Module
|
|
3
|
+
*
|
|
4
|
+
* Components that present information to the user.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export {
|
|
8
|
+
Avatar,
|
|
9
|
+
type AvatarProps,
|
|
10
|
+
type AvatarSize,
|
|
11
|
+
type AvatarStatus,
|
|
12
|
+
getInitials,
|
|
13
|
+
getAvatarA11y,
|
|
14
|
+
} from "./Avatar";
|
|
15
|
+
|
|
16
|
+
export {
|
|
17
|
+
Badge,
|
|
18
|
+
type BadgeProps,
|
|
19
|
+
type BadgeSize,
|
|
20
|
+
type BadgeVariant,
|
|
21
|
+
formatBadgeLabel,
|
|
22
|
+
getBadgeA11y,
|
|
23
|
+
} from "./Badge";
|
|
24
|
+
|
|
25
|
+
export {
|
|
26
|
+
Chip,
|
|
27
|
+
type ChipProps,
|
|
28
|
+
type ChipSize,
|
|
29
|
+
type ChipVariant,
|
|
30
|
+
} from "./Chip";
|
|
31
|
+
|
|
32
|
+
export {
|
|
33
|
+
Card,
|
|
34
|
+
type CardProps,
|
|
35
|
+
type CardVariant,
|
|
36
|
+
} from "./Card";
|
|
37
|
+
|
|
38
|
+
export {
|
|
39
|
+
Icon,
|
|
40
|
+
getIconA11y,
|
|
41
|
+
type IconName,
|
|
42
|
+
type IconProps,
|
|
43
|
+
type IconSize,
|
|
44
|
+
type IconA11yProps,
|
|
45
|
+
} from "./Icon";
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ProgressBar Component Helpers
|
|
3
|
+
*
|
|
4
|
+
* Pure functions for computing progress values and styles.
|
|
5
|
+
*
|
|
6
|
+
* ## Size Mapping
|
|
7
|
+
* | Size | Height | Border Radius |
|
|
8
|
+
* |------|--------|---------------|
|
|
9
|
+
* | sm | 4px | 2px (xs) |
|
|
10
|
+
* | md | 8px | 4px (sm) |
|
|
11
|
+
* | lg | 12px | 6px (md) |
|
|
12
|
+
*
|
|
13
|
+
* ## Color Model
|
|
14
|
+
* The indicator color is supplied directly via a `color` prop (RestyleColor).
|
|
15
|
+
* The track background is always `"borderSubtle"`.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { ProgressBarSize } from "./ProgressBar.types";
|
|
19
|
+
|
|
20
|
+
// =============================================================================
|
|
21
|
+
// PROGRESS VALUE UTILITIES
|
|
22
|
+
// =============================================================================
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Clamp progress value between 0 and 1.
|
|
26
|
+
*
|
|
27
|
+
* Ensures the progress value is always within valid bounds,
|
|
28
|
+
* even if invalid values are passed.
|
|
29
|
+
*
|
|
30
|
+
* @param progress - Raw progress value
|
|
31
|
+
* @returns Clamped value between 0 and 1
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* clampProgress(0.5) // 0.5
|
|
35
|
+
* clampProgress(-0.2) // 0
|
|
36
|
+
* clampProgress(1.5) // 1
|
|
37
|
+
*/
|
|
38
|
+
export function clampProgress(progress: number): number {
|
|
39
|
+
return Math.min(Math.max(progress, 0), 1);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Convert progress (0-1) to percentage (0-100).
|
|
44
|
+
*
|
|
45
|
+
* @param progress - Progress value between 0 and 1
|
|
46
|
+
* @returns Percentage as integer (0-100)
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* progressToPercent(0.5) // 50
|
|
50
|
+
* progressToPercent(0.333) // 33
|
|
51
|
+
*/
|
|
52
|
+
export function progressToPercent(progress: number): number {
|
|
53
|
+
return Math.round(clampProgress(progress) * 100);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Get width percentage string for indicator.
|
|
58
|
+
*
|
|
59
|
+
* @param progress - Progress value between 0 and 1
|
|
60
|
+
* @returns Width percentage string (e.g., "50%")
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* getWidthPercent(0.5) // "50%"
|
|
64
|
+
*/
|
|
65
|
+
export function getWidthPercent(progress: number): string {
|
|
66
|
+
return `${progressToPercent(progress)}%`;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// =============================================================================
|
|
70
|
+
// SIZE RESOLUTION
|
|
71
|
+
// =============================================================================
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Progress bar height mapping.
|
|
75
|
+
*
|
|
76
|
+
* | Size | Height |
|
|
77
|
+
* |------|--------|
|
|
78
|
+
* | sm | 4px |
|
|
79
|
+
* | md | 8px |
|
|
80
|
+
* | lg | 12px |
|
|
81
|
+
*/
|
|
82
|
+
export const PROGRESS_BAR_HEIGHTS: Record<ProgressBarSize, number> = {
|
|
83
|
+
sm: 4,
|
|
84
|
+
md: 8,
|
|
85
|
+
lg: 12,
|
|
86
|
+
} as const;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Progress bar border radius mapping.
|
|
90
|
+
* Uses half of height for pill shape.
|
|
91
|
+
*
|
|
92
|
+
* | Size | Radius |
|
|
93
|
+
* |------|--------|
|
|
94
|
+
* | sm | 2px |
|
|
95
|
+
* | md | 4px |
|
|
96
|
+
* | lg | 6px |
|
|
97
|
+
*/
|
|
98
|
+
export const PROGRESS_BAR_BORDER_RADIUS: Record<ProgressBarSize, number> = {
|
|
99
|
+
sm: 2,
|
|
100
|
+
md: 4,
|
|
101
|
+
lg: 6,
|
|
102
|
+
} as const;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Get height for a size variant.
|
|
106
|
+
*
|
|
107
|
+
* @param size - Progress bar size
|
|
108
|
+
* @returns Height in pixels
|
|
109
|
+
*/
|
|
110
|
+
export function getProgressBarHeight(size: ProgressBarSize): number {
|
|
111
|
+
return PROGRESS_BAR_HEIGHTS[size];
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Get border radius for a size variant.
|
|
116
|
+
*
|
|
117
|
+
* @param size - Progress bar size
|
|
118
|
+
* @returns Border radius in pixels
|
|
119
|
+
*/
|
|
120
|
+
export function getProgressBarBorderRadius(size: ProgressBarSize): number {
|
|
121
|
+
return PROGRESS_BAR_BORDER_RADIUS[size];
|
|
122
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ProgressBar Component
|
|
3
|
+
*
|
|
4
|
+
* @description Determinate progress indicator with theme integration - Atom
|
|
5
|
+
*
|
|
6
|
+
* ProgressBars display the completion status of a task or process.
|
|
7
|
+
* Uses a track (background) and indicator (filled portion) pattern
|
|
8
|
+
* with support for a custom `color` prop and multiple sizes.
|
|
9
|
+
*
|
|
10
|
+
* ## Ratios & Constraints
|
|
11
|
+
* - Height scales proportionally with size variant
|
|
12
|
+
* - Border radius is half of height for pill shape
|
|
13
|
+
* - Indicator smoothly fills based on progress value
|
|
14
|
+
*
|
|
15
|
+
* ## Size Scale
|
|
16
|
+
* | Size | Height | Border Radius | Use Case |
|
|
17
|
+
* |------|--------|---------------|----------|
|
|
18
|
+
* | sm | 4px | 2px | Inline, compact indicators |
|
|
19
|
+
* | md | 8px | 4px | Standard progress bars |
|
|
20
|
+
* | lg | 12px | 6px | Prominent indicators |
|
|
21
|
+
*
|
|
22
|
+
* ## Color Model
|
|
23
|
+
* The `color` prop accepts any `RestyleColor` token (base or app-extended).
|
|
24
|
+
* The track background is always `"borderSubtle"`.
|
|
25
|
+
*
|
|
26
|
+
* ## Features
|
|
27
|
+
* - Responsive size prop
|
|
28
|
+
* - Flexible color via RestyleColor token
|
|
29
|
+
* - Optional label support
|
|
30
|
+
* - Full accessibility support (progressbar role with value)
|
|
31
|
+
* - Memoized for performance
|
|
32
|
+
* - Restyle spacing prop support
|
|
33
|
+
*
|
|
34
|
+
* @see ProgressBar.types.ts - Type definitions
|
|
35
|
+
* @see ProgressBar.helpers.ts - Pure calculation functions
|
|
36
|
+
* @see ProgressBar.a11y.ts - Accessibility prop generation
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* // Basic usage
|
|
40
|
+
* <ProgressBar progress={0.5} />
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* // With color and label
|
|
44
|
+
* <ProgressBar
|
|
45
|
+
* progress={0.75}
|
|
46
|
+
* color="feedbackSuccess"
|
|
47
|
+
* label="Upload complete"
|
|
48
|
+
* accessibilityLabel="File upload 75% complete"
|
|
49
|
+
* />
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* // Responsive size with spacing
|
|
53
|
+
* <ProgressBar
|
|
54
|
+
* progress={0.3}
|
|
55
|
+
* size={{ phone: "sm", tablet: "md" }}
|
|
56
|
+
* marginBottom="lg"
|
|
57
|
+
* />
|
|
58
|
+
*/
|
|
59
|
+
|
|
60
|
+
import {
|
|
61
|
+
createRestyleComponent,
|
|
62
|
+
createVariant,
|
|
63
|
+
layout,
|
|
64
|
+
spacing,
|
|
65
|
+
spacingShorthand,
|
|
66
|
+
} from "@shopify/restyle";
|
|
67
|
+
import React, { memo } from "react";
|
|
68
|
+
import { DimensionValue } from "react-native";
|
|
69
|
+
import { RestyleTheme } from "../../../core/restyle";
|
|
70
|
+
import { BaseThemeColor } from "../../../types";
|
|
71
|
+
import { Box } from "../../layout";
|
|
72
|
+
import { Text } from "../../typography";
|
|
73
|
+
import {
|
|
74
|
+
BaseProgressBarContainerProps,
|
|
75
|
+
ProgressBarProps,
|
|
76
|
+
} from "./ProgressBar.types";
|
|
77
|
+
import { useProgressBarLogic } from "./useProgressBarLogic";
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Base container with Restyle variant support for sizing.
|
|
81
|
+
* @internal
|
|
82
|
+
*/
|
|
83
|
+
const BaseProgressBarContainer = createRestyleComponent<
|
|
84
|
+
BaseProgressBarContainerProps,
|
|
85
|
+
RestyleTheme
|
|
86
|
+
>(
|
|
87
|
+
[
|
|
88
|
+
createVariant({ themeKey: "progressBarSizes", property: "size" }),
|
|
89
|
+
layout,
|
|
90
|
+
spacing,
|
|
91
|
+
spacingShorthand,
|
|
92
|
+
],
|
|
93
|
+
Box,
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
// =============================================================================
|
|
97
|
+
// PROGRESS BAR COMPONENT
|
|
98
|
+
// =============================================================================
|
|
99
|
+
|
|
100
|
+
function ProgressBarComponent({
|
|
101
|
+
progress,
|
|
102
|
+
color = "accentPrimary",
|
|
103
|
+
size = "md",
|
|
104
|
+
label,
|
|
105
|
+
accessibilityLabel,
|
|
106
|
+
testID,
|
|
107
|
+
style,
|
|
108
|
+
...rest
|
|
109
|
+
}: ProgressBarProps) {
|
|
110
|
+
const {
|
|
111
|
+
widthPercent,
|
|
112
|
+
indicatorColorToken,
|
|
113
|
+
trackColorToken,
|
|
114
|
+
borderRadius,
|
|
115
|
+
a11yProps,
|
|
116
|
+
} = useProgressBarLogic({
|
|
117
|
+
progress,
|
|
118
|
+
color,
|
|
119
|
+
size,
|
|
120
|
+
accessibilityLabel,
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
return (
|
|
124
|
+
<BaseProgressBarContainer
|
|
125
|
+
size={size}
|
|
126
|
+
testID={testID}
|
|
127
|
+
style={style}
|
|
128
|
+
{...rest}
|
|
129
|
+
>
|
|
130
|
+
{label && (
|
|
131
|
+
<Text variant="labelSmall" color="textSecondary" marginBottom="xs">
|
|
132
|
+
{label}
|
|
133
|
+
</Text>
|
|
134
|
+
)}
|
|
135
|
+
<Box
|
|
136
|
+
width="100%"
|
|
137
|
+
overflow="hidden"
|
|
138
|
+
backgroundColor={trackColorToken}
|
|
139
|
+
style={{ borderRadius }}
|
|
140
|
+
{...a11yProps}
|
|
141
|
+
>
|
|
142
|
+
<Box
|
|
143
|
+
height="100%"
|
|
144
|
+
width={widthPercent as DimensionValue}
|
|
145
|
+
backgroundColor={indicatorColorToken as BaseThemeColor}
|
|
146
|
+
style={{ borderRadius }}
|
|
147
|
+
/>
|
|
148
|
+
</Box>
|
|
149
|
+
</BaseProgressBarContainer>
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export const ProgressBar = memo(ProgressBarComponent);
|
|
154
|
+
ProgressBar.displayName = "ProgressBar";
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ProgressBar Component Types
|
|
3
|
+
*
|
|
4
|
+
* Type definitions for the ProgressBar component and its related hooks/helpers.
|
|
5
|
+
*
|
|
6
|
+
* @see ProgressBar.tsx - Component implementation
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { BoxProps, ResponsiveValue, VariantProps } from "@shopify/restyle";
|
|
10
|
+
import { ViewProps, ViewStyle } from "react-native";
|
|
11
|
+
import { RestyleTheme } from "../../../core/restyle";
|
|
12
|
+
import { RestyleColor } from "../../../types";
|
|
13
|
+
|
|
14
|
+
// =============================================================================
|
|
15
|
+
// SIZE TYPES
|
|
16
|
+
// =============================================================================
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Size variant for the ProgressBar.
|
|
20
|
+
* Derived from the restyle theme's `progressBarSizes` keys.
|
|
21
|
+
*
|
|
22
|
+
* - `sm`: 4px height - compact inline progress
|
|
23
|
+
* - `md`: 8px height - standard progress bars (default)
|
|
24
|
+
* - `lg`: 12px height - prominent progress indicators
|
|
25
|
+
*/
|
|
26
|
+
export type ProgressBarSize = Exclude<keyof RestyleTheme["progressBarSizes"], "defaults">;
|
|
27
|
+
|
|
28
|
+
// =============================================================================
|
|
29
|
+
// RESTYLE PROP TYPES
|
|
30
|
+
// =============================================================================
|
|
31
|
+
|
|
32
|
+
type ProgressBarSizeProps = VariantProps<
|
|
33
|
+
RestyleTheme,
|
|
34
|
+
"progressBarSizes",
|
|
35
|
+
"size"
|
|
36
|
+
>;
|
|
37
|
+
type ProgressBarRestyleProps = ProgressBarSizeProps & BoxProps<RestyleTheme>;
|
|
38
|
+
|
|
39
|
+
export type BaseProgressBarProps = ProgressBarRestyleProps & ViewProps;
|
|
40
|
+
|
|
41
|
+
// =============================================================================
|
|
42
|
+
// COMPONENT PROPS
|
|
43
|
+
// =============================================================================
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Props for the ProgressBar component.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* <ProgressBar progress={0.5} />
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* <ProgressBar
|
|
53
|
+
* progress={0.75}
|
|
54
|
+
* color="feedbackSuccess"
|
|
55
|
+
* size="lg"
|
|
56
|
+
* label="Upload progress"
|
|
57
|
+
* accessibilityLabel="File upload 75% complete"
|
|
58
|
+
* />
|
|
59
|
+
*/
|
|
60
|
+
export interface ProgressBarProps extends Omit<
|
|
61
|
+
BaseProgressBarProps,
|
|
62
|
+
"variant" | "style" | "size"
|
|
63
|
+
> {
|
|
64
|
+
/**
|
|
65
|
+
* Progress value between 0 and 1.
|
|
66
|
+
* - 0 = empty
|
|
67
|
+
* - 0.5 = 50% complete
|
|
68
|
+
* - 1 = fully complete
|
|
69
|
+
*/
|
|
70
|
+
progress: number;
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Color token for the progress indicator fill.
|
|
74
|
+
* Accepts any RestyleColor — base theme tokens or app-extended tokens.
|
|
75
|
+
* The track background is always `"borderSubtle"`.
|
|
76
|
+
* @default "accentPrimary"
|
|
77
|
+
*/
|
|
78
|
+
color?: RestyleColor;
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Size of the progress bar (supports responsive values).
|
|
82
|
+
* @default "md"
|
|
83
|
+
*/
|
|
84
|
+
size?: ResponsiveValue<ProgressBarSize, RestyleTheme["breakpoints"]>;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Optional visible label displayed above the progress bar.
|
|
88
|
+
* When provided, creates a labeled progress indicator.
|
|
89
|
+
*/
|
|
90
|
+
label?: string;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Custom style overrides for the container.
|
|
94
|
+
*/
|
|
95
|
+
style?: ViewStyle;
|
|
96
|
+
|
|
97
|
+
/** Test ID for testing frameworks */
|
|
98
|
+
testID?: string;
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Accessibility label for screen readers.
|
|
102
|
+
* Should describe what the progress represents.
|
|
103
|
+
* @example "File upload progress"
|
|
104
|
+
*/
|
|
105
|
+
accessibilityLabel?: string;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// =============================================================================
|
|
109
|
+
// HOOK TYPES
|
|
110
|
+
// =============================================================================
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Parameters for the useProgressBarLogic hook.
|
|
114
|
+
*/
|
|
115
|
+
export interface UseProgressBarLogicParams {
|
|
116
|
+
progress: number;
|
|
117
|
+
color: RestyleColor;
|
|
118
|
+
size: ResponsiveValue<ProgressBarSize, RestyleTheme["breakpoints"]>;
|
|
119
|
+
accessibilityLabel?: string;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Return value from the useProgressBarLogic hook.
|
|
124
|
+
*/
|
|
125
|
+
export interface UseProgressBarLogicReturn {
|
|
126
|
+
/** Clamped progress value (0-1) */
|
|
127
|
+
clampedProgress: number;
|
|
128
|
+
/** Progress as percentage (0-100) */
|
|
129
|
+
progressPercent: number;
|
|
130
|
+
/** Width percentage string for indicator */
|
|
131
|
+
widthPercent: string;
|
|
132
|
+
/** Indicator color token (e.g., "accentPrimary") — may be an extended color */
|
|
133
|
+
indicatorColorToken: RestyleColor;
|
|
134
|
+
/** Track background color token — always "borderSubtle" */
|
|
135
|
+
trackColorToken: keyof RestyleTheme["colors"];
|
|
136
|
+
/** Resolved border radius value */
|
|
137
|
+
borderRadius: number;
|
|
138
|
+
/** Accessibility props */
|
|
139
|
+
a11yProps: ProgressBarA11yProps;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// =============================================================================
|
|
143
|
+
// ACCESSIBILITY TYPES
|
|
144
|
+
// =============================================================================
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Parameters for getProgressBarA11y function.
|
|
148
|
+
*/
|
|
149
|
+
export interface ProgressBarA11yParams {
|
|
150
|
+
progress: number;
|
|
151
|
+
accessibilityLabel?: string;
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Pre-translated fallback label from i18n.
|
|
155
|
+
* Used when accessibilityLabel is not provided.
|
|
156
|
+
*/
|
|
157
|
+
fallbackLabel: string;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Accessibility props returned by getProgressBarA11y.
|
|
161
|
+
* Implements WCAG 4.1.2 Name, Role, Value for determinate progress bars.
|
|
162
|
+
*/
|
|
163
|
+
export interface ProgressBarA11yProps {
|
|
164
|
+
accessibilityRole: "progressbar";
|
|
165
|
+
accessibilityLabel: string;
|
|
166
|
+
accessibilityValue: {
|
|
167
|
+
min: number;
|
|
168
|
+
max: number;
|
|
169
|
+
now: number;
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// =============================================================================
|
|
174
|
+
// BASE COMPONENT (Restyle-enabled container)
|
|
175
|
+
// =============================================================================
|
|
176
|
+
export type BaseProgressBarContainerProps = ProgressBarSizeProps &
|
|
177
|
+
BoxProps<RestyleTheme> &
|
|
178
|
+
ViewProps;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ProgressBar Module
|
|
3
|
+
*
|
|
4
|
+
* Atom component for displaying determinate progress with theme integration.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* import { ProgressBar } from "@/design-system/primitives/feedback/ProgressBar";
|
|
8
|
+
*
|
|
9
|
+
* <ProgressBar progress={0.75} color="feedbackSuccess" accessibilityLabel="Upload progress" />
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export { ProgressBar } from "./ProgressBar";
|
|
13
|
+
export type {
|
|
14
|
+
ProgressBarProps,
|
|
15
|
+
ProgressBarSize,
|
|
16
|
+
} from "./ProgressBar.types";
|
|
17
|
+
export * from "./ProgressBar.a11y";
|