@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,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Divider Component Helpers
|
|
3
|
+
*
|
|
4
|
+
* Pure functions for computing divider values, colors, and styles.
|
|
5
|
+
*
|
|
6
|
+
* ## Thickness Mapping
|
|
7
|
+
* | Thickness | Value |
|
|
8
|
+
* |-----------|-------|
|
|
9
|
+
* | thin | 1px |
|
|
10
|
+
* | medium | 2px |
|
|
11
|
+
* | thick | 4px |
|
|
12
|
+
*
|
|
13
|
+
* ## Color Mapping
|
|
14
|
+
* | Color | Token |
|
|
15
|
+
* |---------|--------------|
|
|
16
|
+
* | subtle | borderSubtle |
|
|
17
|
+
* | default | borderDefault|
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { RestyleTheme } from "../../../core/restyle";
|
|
21
|
+
import {
|
|
22
|
+
DividerColor,
|
|
23
|
+
DividerSpacing,
|
|
24
|
+
DividerThickness,
|
|
25
|
+
} from "./Divider.types";
|
|
26
|
+
|
|
27
|
+
// =============================================================================
|
|
28
|
+
// THICKNESS CONSTANTS
|
|
29
|
+
// =============================================================================
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Thickness value mapping in pixels.
|
|
33
|
+
*/
|
|
34
|
+
export const DIVIDER_THICKNESS: Record<DividerThickness, number> = {
|
|
35
|
+
thin: 1,
|
|
36
|
+
medium: 2,
|
|
37
|
+
thick: 4,
|
|
38
|
+
} as const;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Get thickness value for a thickness variant.
|
|
42
|
+
*
|
|
43
|
+
* @param thickness - Divider thickness variant
|
|
44
|
+
* @returns Thickness in pixels
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* getThicknessValue("thin") // 1
|
|
48
|
+
* getThicknessValue("thick") // 4
|
|
49
|
+
*/
|
|
50
|
+
export function getThicknessValue(thickness: DividerThickness): number {
|
|
51
|
+
return DIVIDER_THICKNESS[thickness];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// =============================================================================
|
|
55
|
+
// COLOR RESOLUTION
|
|
56
|
+
// =============================================================================
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Color token mapping by variant.
|
|
60
|
+
*/
|
|
61
|
+
const DIVIDER_COLOR_MAP: Record<DividerColor, keyof RestyleTheme["colors"]> = {
|
|
62
|
+
subtle: "borderSubtle",
|
|
63
|
+
default: "borderDefault",
|
|
64
|
+
strong: "borderStrong",
|
|
65
|
+
} as const;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Get color token for a color variant.
|
|
69
|
+
*
|
|
70
|
+
* @param color - Divider color variant
|
|
71
|
+
* @returns Color token key
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* getColorToken("subtle") // "borderSubtle"
|
|
75
|
+
* getColorToken("default") // "borderDefault"
|
|
76
|
+
*/
|
|
77
|
+
export function getColorToken(
|
|
78
|
+
color: DividerColor
|
|
79
|
+
): keyof RestyleTheme["colors"] {
|
|
80
|
+
return DIVIDER_COLOR_MAP[color];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// =============================================================================
|
|
84
|
+
// SPACING RESOLUTION
|
|
85
|
+
// =============================================================================
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Spacing token mapping.
|
|
89
|
+
*/
|
|
90
|
+
const DIVIDER_SPACING_MAP: Record<
|
|
91
|
+
DividerSpacing,
|
|
92
|
+
keyof RestyleTheme["spacing"]
|
|
93
|
+
> = {
|
|
94
|
+
none: "none",
|
|
95
|
+
xs: "xs",
|
|
96
|
+
sm: "sm",
|
|
97
|
+
md: "md",
|
|
98
|
+
lg: "lg",
|
|
99
|
+
xl: "xl",
|
|
100
|
+
} as const;
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Get spacing token for a spacing variant.
|
|
104
|
+
*
|
|
105
|
+
* @param spacing - Divider spacing variant
|
|
106
|
+
* @returns Spacing token key
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* getSpacingToken("md") // "md"
|
|
110
|
+
*/
|
|
111
|
+
export function getSpacingToken(
|
|
112
|
+
spacing: DividerSpacing
|
|
113
|
+
): keyof RestyleTheme["spacing"] {
|
|
114
|
+
return DIVIDER_SPACING_MAP[spacing];
|
|
115
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Divider Component
|
|
3
|
+
*
|
|
4
|
+
* @description Visual separator for content sections - Atom
|
|
5
|
+
*
|
|
6
|
+
* Dividers separate content into distinct sections with a thin line.
|
|
7
|
+
* Supports horizontal and vertical orientations, multiple thicknesses,
|
|
8
|
+
* and optional labels for semantic separation (e.g., "OR" dividers).
|
|
9
|
+
*
|
|
10
|
+
* ## Thickness Scale
|
|
11
|
+
* | Thickness | Value | Use Case |
|
|
12
|
+
* |-----------|-------|----------|
|
|
13
|
+
* | thin | 1px | Subtle separation (default) |
|
|
14
|
+
* | medium | 2px | Standard separation |
|
|
15
|
+
* | thick | 4px | Prominent separation |
|
|
16
|
+
*
|
|
17
|
+
* ## Color Variants
|
|
18
|
+
* - `subtle`: borderSubtle - light separator (default)
|
|
19
|
+
* - `default`: borderDefault - standard separator
|
|
20
|
+
*
|
|
21
|
+
* ## Features
|
|
22
|
+
* - Horizontal and vertical orientation
|
|
23
|
+
* - Three thickness options
|
|
24
|
+
* - Theme-aware colors
|
|
25
|
+
* - Spacing props using theme tokens
|
|
26
|
+
* - Optional label support for "OR" style dividers
|
|
27
|
+
* - Full accessibility support
|
|
28
|
+
* - Memoized for performance
|
|
29
|
+
*
|
|
30
|
+
* @see Divider.types.ts - Type definitions
|
|
31
|
+
* @see Divider.helpers.ts - Pure calculation functions
|
|
32
|
+
* @see Divider.a11y.ts - Accessibility prop generation
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* // Basic horizontal divider
|
|
36
|
+
* <Divider />
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* // Vertical divider in a row
|
|
40
|
+
* <Box flexDirection="row">
|
|
41
|
+
* <Text>Left</Text>
|
|
42
|
+
* <Divider orientation="vertical" spacing="sm" />
|
|
43
|
+
* <Text>Right</Text>
|
|
44
|
+
* </Box>
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* // "OR" divider between sign-in options
|
|
48
|
+
* <Divider label="OR" spacing="lg" />
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
import React, { memo } from "react";
|
|
52
|
+
import { Text } from "../../typography";
|
|
53
|
+
import { Box } from "../Box";
|
|
54
|
+
import { DividerProps } from "./Divider.types";
|
|
55
|
+
import { useDividerLogic } from "./useDividerLogic";
|
|
56
|
+
|
|
57
|
+
// =============================================================================
|
|
58
|
+
// DIVIDER COMPONENT
|
|
59
|
+
// =============================================================================
|
|
60
|
+
|
|
61
|
+
function DividerComponent({
|
|
62
|
+
orientation = "horizontal",
|
|
63
|
+
thickness = "thin",
|
|
64
|
+
color = "subtle",
|
|
65
|
+
spacing = "none",
|
|
66
|
+
label,
|
|
67
|
+
accessibilityLabel,
|
|
68
|
+
testID,
|
|
69
|
+
style,
|
|
70
|
+
...rest
|
|
71
|
+
}: DividerProps) {
|
|
72
|
+
const { thicknessValue, colorToken, spacingToken, hasLabel, a11yProps } =
|
|
73
|
+
useDividerLogic({
|
|
74
|
+
orientation,
|
|
75
|
+
thickness,
|
|
76
|
+
color,
|
|
77
|
+
spacing,
|
|
78
|
+
label,
|
|
79
|
+
accessibilityLabel,
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
const isHorizontal = orientation === "horizontal";
|
|
83
|
+
|
|
84
|
+
// Horizontal divider with optional label
|
|
85
|
+
if (isHorizontal) {
|
|
86
|
+
if (hasLabel) {
|
|
87
|
+
return (
|
|
88
|
+
<Box
|
|
89
|
+
flexDirection="row"
|
|
90
|
+
alignItems="center"
|
|
91
|
+
marginVertical={spacingToken}
|
|
92
|
+
testID={testID}
|
|
93
|
+
style={style}
|
|
94
|
+
{...a11yProps}
|
|
95
|
+
{...rest}
|
|
96
|
+
>
|
|
97
|
+
<Box flex={1} height={thicknessValue} backgroundColor={colorToken} />
|
|
98
|
+
<Text
|
|
99
|
+
variant="labelSmall"
|
|
100
|
+
color="textSecondary"
|
|
101
|
+
paddingHorizontal="md"
|
|
102
|
+
>
|
|
103
|
+
{label}
|
|
104
|
+
</Text>
|
|
105
|
+
<Box flex={1} height={thicknessValue} backgroundColor={colorToken} />
|
|
106
|
+
</Box>
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return (
|
|
111
|
+
<Box
|
|
112
|
+
height={thicknessValue}
|
|
113
|
+
backgroundColor={colorToken}
|
|
114
|
+
marginVertical={spacingToken}
|
|
115
|
+
testID={testID}
|
|
116
|
+
style={style}
|
|
117
|
+
{...a11yProps}
|
|
118
|
+
{...rest}
|
|
119
|
+
/>
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Vertical divider
|
|
124
|
+
return (
|
|
125
|
+
<Box
|
|
126
|
+
width={thicknessValue}
|
|
127
|
+
alignSelf="stretch"
|
|
128
|
+
backgroundColor={colorToken}
|
|
129
|
+
marginHorizontal={spacingToken}
|
|
130
|
+
testID={testID}
|
|
131
|
+
style={style}
|
|
132
|
+
{...a11yProps}
|
|
133
|
+
{...rest}
|
|
134
|
+
/>
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export const Divider = memo(DividerComponent);
|
|
139
|
+
Divider.displayName = "Divider";
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Divider Component Types
|
|
3
|
+
*
|
|
4
|
+
* Type definitions for the Divider component and its related hooks/helpers.
|
|
5
|
+
*
|
|
6
|
+
* @see Divider.tsx - Component implementation
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { BoxProps } from "@shopify/restyle";
|
|
10
|
+
import { ViewProps, ViewStyle } from "react-native";
|
|
11
|
+
import { RestyleTheme } from "../../../core/restyle";
|
|
12
|
+
|
|
13
|
+
// =============================================================================
|
|
14
|
+
// VARIANT TYPES
|
|
15
|
+
// =============================================================================
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Orientation of the Divider.
|
|
19
|
+
*
|
|
20
|
+
* - `horizontal`: Horizontal line (default) - separates content vertically
|
|
21
|
+
* - `vertical`: Vertical line - separates content horizontally
|
|
22
|
+
*/
|
|
23
|
+
export type DividerOrientation = "horizontal" | "vertical";
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Thickness variant for the Divider.
|
|
27
|
+
* Derived from the restyle theme's `dividerSizes` keys.
|
|
28
|
+
*
|
|
29
|
+
* - `thin`: 1px - subtle separator
|
|
30
|
+
* - `medium`: 2px - standard separator (default)
|
|
31
|
+
* - `thick`: 4px - prominent separator
|
|
32
|
+
*/
|
|
33
|
+
export type DividerThickness = Exclude<keyof RestyleTheme["dividerSizes"], "defaults">;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Color variant for the Divider.
|
|
37
|
+
* Derived from the restyle theme's `dividerVariants` keys.
|
|
38
|
+
*/
|
|
39
|
+
export type DividerColor = Exclude<
|
|
40
|
+
keyof RestyleTheme["dividerVariants"],
|
|
41
|
+
"defaults"
|
|
42
|
+
>;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Spacing around the Divider using theme spacing tokens.
|
|
46
|
+
*
|
|
47
|
+
* - `none`: 0 - no spacing
|
|
48
|
+
* - `xs`: 4px - tight spacing
|
|
49
|
+
* - `sm`: 8px - compact spacing
|
|
50
|
+
* - `md`: 12px - comfortable spacing
|
|
51
|
+
* - `lg`: 16px - standard spacing
|
|
52
|
+
* - `xl`: 20px - comfortable spacing
|
|
53
|
+
*/
|
|
54
|
+
export type DividerSpacing = "none" | "xs" | "sm" | "md" | "lg" | "xl";
|
|
55
|
+
|
|
56
|
+
// =============================================================================
|
|
57
|
+
// COMPONENT PROPS
|
|
58
|
+
// =============================================================================
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Props for the Divider component.
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* // Basic horizontal divider
|
|
65
|
+
* <Divider />
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* // Vertical divider with custom thickness
|
|
69
|
+
* <Divider orientation="vertical" thickness="thick" />
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* // Divider with label
|
|
73
|
+
* <Divider label="OR" spacing="lg" />
|
|
74
|
+
*/
|
|
75
|
+
export interface DividerProps
|
|
76
|
+
extends Omit<BoxProps<RestyleTheme>, "style">,
|
|
77
|
+
ViewProps {
|
|
78
|
+
/**
|
|
79
|
+
* Orientation of the divider.
|
|
80
|
+
* @default "horizontal"
|
|
81
|
+
*/
|
|
82
|
+
orientation?: DividerOrientation;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Thickness of the divider line.
|
|
86
|
+
* @default "thin"
|
|
87
|
+
*/
|
|
88
|
+
thickness?: DividerThickness;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Color variant of the divider.
|
|
92
|
+
* @default "subtle"
|
|
93
|
+
*/
|
|
94
|
+
color?: DividerColor;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Spacing around the divider using theme spacing tokens.
|
|
98
|
+
* For horizontal: vertical margin (marginVertical)
|
|
99
|
+
* For vertical: horizontal margin (marginHorizontal)
|
|
100
|
+
* @default "none"
|
|
101
|
+
*/
|
|
102
|
+
spacing?: DividerSpacing;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Optional label to display in the middle of the divider.
|
|
106
|
+
* Common use case: "OR" between sign-in options.
|
|
107
|
+
*/
|
|
108
|
+
label?: string;
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Custom style overrides for the container.
|
|
112
|
+
*/
|
|
113
|
+
style?: ViewStyle;
|
|
114
|
+
|
|
115
|
+
/** Test ID for testing frameworks */
|
|
116
|
+
testID?: string;
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Accessibility label for screen readers.
|
|
120
|
+
* @example "Section divider"
|
|
121
|
+
*/
|
|
122
|
+
accessibilityLabel?: string;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// =============================================================================
|
|
126
|
+
// HOOK TYPES
|
|
127
|
+
// =============================================================================
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Parameters for the useDividerLogic hook.
|
|
131
|
+
*/
|
|
132
|
+
export interface UseDividerLogicParams {
|
|
133
|
+
orientation: DividerOrientation;
|
|
134
|
+
thickness: DividerThickness;
|
|
135
|
+
color: DividerColor;
|
|
136
|
+
spacing: DividerSpacing;
|
|
137
|
+
label?: string;
|
|
138
|
+
accessibilityLabel?: string;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Return value from the useDividerLogic hook.
|
|
143
|
+
*/
|
|
144
|
+
export interface UseDividerLogicReturn {
|
|
145
|
+
/** Resolved thickness value in pixels */
|
|
146
|
+
thicknessValue: number;
|
|
147
|
+
/** Color token key for the divider line */
|
|
148
|
+
colorToken: keyof RestyleTheme["colors"];
|
|
149
|
+
/** Spacing token key for margin */
|
|
150
|
+
spacingToken: keyof RestyleTheme["spacing"];
|
|
151
|
+
/** Whether the divider has a label */
|
|
152
|
+
hasLabel: boolean;
|
|
153
|
+
/** Accessibility props */
|
|
154
|
+
a11yProps: DividerA11yProps;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// =============================================================================
|
|
158
|
+
// ACCESSIBILITY TYPES
|
|
159
|
+
// =============================================================================
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Parameters for getDividerA11y function.
|
|
163
|
+
*/
|
|
164
|
+
export interface DividerA11yParams {
|
|
165
|
+
orientation: DividerOrientation;
|
|
166
|
+
label?: string;
|
|
167
|
+
accessibilityLabel?: string;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Accessibility props returned by getDividerA11y.
|
|
172
|
+
* Implements WCAG 4.1.2 Name, Role, Value for separator elements.
|
|
173
|
+
*/
|
|
174
|
+
export interface DividerA11yProps {
|
|
175
|
+
accessibilityRole: "none";
|
|
176
|
+
accessible: boolean;
|
|
177
|
+
accessibilityLabel?: string;
|
|
178
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Divider Module
|
|
3
|
+
*
|
|
4
|
+
* Atom component for visually separating content sections with theme integration.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* import { Divider } from "@/design-system/primitives/layout/Divider";
|
|
8
|
+
*
|
|
9
|
+
* // Basic divider
|
|
10
|
+
* <Divider />
|
|
11
|
+
*
|
|
12
|
+
* // "OR" divider
|
|
13
|
+
* <Divider label="OR" spacing="lg" />
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
export { Divider } from "./Divider";
|
|
17
|
+
export type {
|
|
18
|
+
DividerColor,
|
|
19
|
+
DividerOrientation,
|
|
20
|
+
DividerProps,
|
|
21
|
+
DividerSpacing,
|
|
22
|
+
DividerThickness,
|
|
23
|
+
} from "./Divider.types";
|
|
24
|
+
export * from "./Divider.a11y";
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Divider Logic Hook
|
|
3
|
+
*
|
|
4
|
+
* Extracts all computational logic from the Divider component.
|
|
5
|
+
* Returns memoized values for optimal render performance.
|
|
6
|
+
*
|
|
7
|
+
* Responsibilities:
|
|
8
|
+
* - Resolve thickness value
|
|
9
|
+
* - Resolve color token
|
|
10
|
+
* - Resolve spacing token
|
|
11
|
+
* - Generate accessibility props
|
|
12
|
+
*
|
|
13
|
+
* @see Divider.tsx - Component consuming this hook
|
|
14
|
+
* @see Divider.helpers.ts - Pure calculation functions
|
|
15
|
+
* @see Divider.a11y.ts - Accessibility prop generation
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { useMemo } from "react";
|
|
19
|
+
import { getDividerA11y } from "./Divider.a11y";
|
|
20
|
+
import {
|
|
21
|
+
getColorToken,
|
|
22
|
+
getSpacingToken,
|
|
23
|
+
getThicknessValue,
|
|
24
|
+
} from "./Divider.helpers";
|
|
25
|
+
import {
|
|
26
|
+
UseDividerLogicParams,
|
|
27
|
+
UseDividerLogicReturn,
|
|
28
|
+
} from "./Divider.types";
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Orchestrates Divider rendering logic and state management.
|
|
32
|
+
*
|
|
33
|
+
* Handles:
|
|
34
|
+
* - Thickness value resolution ('thin' | 'medium' | 'thick')
|
|
35
|
+
* - Color token resolution ('default' | 'subtle' | 'strong')
|
|
36
|
+
* - Spacing token resolution for margins
|
|
37
|
+
* - Label presence detection
|
|
38
|
+
* - Accessibility props generation
|
|
39
|
+
*
|
|
40
|
+
* @param params - Configuration object for divider behavior
|
|
41
|
+
* @param params.orientation - Orientation ('horizontal' | 'vertical')
|
|
42
|
+
* @param params.thickness - Thickness variant ('thin' | 'medium' | 'thick')
|
|
43
|
+
* @param params.color - Color variant ('default' | 'subtle' | 'strong')
|
|
44
|
+
* @param params.spacing - Spacing variant ('none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl')
|
|
45
|
+
* @param params.label - Optional label text
|
|
46
|
+
* @param params.accessibilityLabel - Custom a11y label
|
|
47
|
+
*
|
|
48
|
+
* @returns Computed values for rendering Divider
|
|
49
|
+
* @returns {number} thicknessValue - Thickness in pixels (1-3px)
|
|
50
|
+
* @returns {string} colorToken - Color token for divider line
|
|
51
|
+
* @returns {string} spacingToken - Spacing token for margins
|
|
52
|
+
* @returns {boolean} hasLabel - Whether label is present
|
|
53
|
+
* @returns {object} a11yProps - Accessibility props
|
|
54
|
+
*
|
|
55
|
+
* @performance This hook uses useMemo() for token resolution
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* const {
|
|
59
|
+
* thicknessValue,
|
|
60
|
+
* colorToken,
|
|
61
|
+
* spacingToken,
|
|
62
|
+
* hasLabel,
|
|
63
|
+
* a11yProps,
|
|
64
|
+
* } = useDividerLogic({
|
|
65
|
+
* orientation: "horizontal",
|
|
66
|
+
* thickness: "thin",
|
|
67
|
+
* color: "subtle",
|
|
68
|
+
* spacing: "md",
|
|
69
|
+
* });
|
|
70
|
+
*/
|
|
71
|
+
export function useDividerLogic({
|
|
72
|
+
orientation,
|
|
73
|
+
thickness,
|
|
74
|
+
color,
|
|
75
|
+
spacing,
|
|
76
|
+
label,
|
|
77
|
+
accessibilityLabel,
|
|
78
|
+
}: UseDividerLogicParams): UseDividerLogicReturn {
|
|
79
|
+
// Memoized thickness value
|
|
80
|
+
const thicknessValue = getThicknessValue(thickness);
|
|
81
|
+
|
|
82
|
+
// Memoized color token
|
|
83
|
+
const colorToken = getColorToken(color);
|
|
84
|
+
|
|
85
|
+
// Memoized spacing token
|
|
86
|
+
const spacingToken = getSpacingToken(spacing);
|
|
87
|
+
|
|
88
|
+
// Check if label exists
|
|
89
|
+
const hasLabel = Boolean(label);
|
|
90
|
+
|
|
91
|
+
// Accessibility props
|
|
92
|
+
const a11yProps = useMemo(
|
|
93
|
+
() =>
|
|
94
|
+
getDividerA11y({
|
|
95
|
+
orientation,
|
|
96
|
+
label,
|
|
97
|
+
accessibilityLabel,
|
|
98
|
+
}),
|
|
99
|
+
[orientation, label, accessibilityLabel]
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
return {
|
|
103
|
+
thicknessValue,
|
|
104
|
+
colorToken,
|
|
105
|
+
spacingToken,
|
|
106
|
+
hasLabel,
|
|
107
|
+
a11yProps,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import React, { forwardRef } from "react";
|
|
2
|
+
import {
|
|
3
|
+
FlatList as RNFlatList,
|
|
4
|
+
FlatListProps as RNFlatListProps,
|
|
5
|
+
} from "react-native";
|
|
6
|
+
import {
|
|
7
|
+
backgroundColor,
|
|
8
|
+
BackgroundColorProps,
|
|
9
|
+
composeRestyleFunctions,
|
|
10
|
+
layout,
|
|
11
|
+
LayoutProps,
|
|
12
|
+
spacing,
|
|
13
|
+
SpacingProps,
|
|
14
|
+
useRestyle,
|
|
15
|
+
} from "@shopify/restyle";
|
|
16
|
+
import { RestyleTheme } from "../../core/restyle";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Restyle props that can be applied to FlatList
|
|
20
|
+
*/
|
|
21
|
+
export type FlatListRestyleProps = SpacingProps<RestyleTheme> &
|
|
22
|
+
LayoutProps<RestyleTheme> &
|
|
23
|
+
BackgroundColorProps<RestyleTheme>;
|
|
24
|
+
|
|
25
|
+
export type FlatListProps<T = any> = FlatListRestyleProps & RNFlatListProps<T>;
|
|
26
|
+
|
|
27
|
+
/** Ref type for the FlatList component — the underlying React Native FlatList instance. */
|
|
28
|
+
export type FlatListRef<T = any> = RNFlatList<T>;
|
|
29
|
+
|
|
30
|
+
const restyleFunctions = composeRestyleFunctions<
|
|
31
|
+
RestyleTheme,
|
|
32
|
+
FlatListRestyleProps
|
|
33
|
+
>([spacing, layout, backgroundColor]);
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* FlatList — Restyled FlatList component
|
|
37
|
+
*
|
|
38
|
+
* A FlatList wrapper that accepts Restyle props (padding, margin, flex, backgroundColor)
|
|
39
|
+
* while preserving all native FlatList functionality and supporting ref forwarding.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```tsx
|
|
43
|
+
* <FlatList
|
|
44
|
+
* ref={listRef}
|
|
45
|
+
* data={items}
|
|
46
|
+
* renderItem={({ item }) => <Text>{item.name}</Text>}
|
|
47
|
+
* keyExtractor={(item) => item.id}
|
|
48
|
+
* padding="md"
|
|
49
|
+
* flex={1}
|
|
50
|
+
* backgroundColor="backgroundPrimary"
|
|
51
|
+
* />
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
function FlatListInner<T = any>(
|
|
55
|
+
props: FlatListProps<T>,
|
|
56
|
+
ref: React.ForwardedRef<RNFlatList<T>>,
|
|
57
|
+
) {
|
|
58
|
+
const { style, ...rest } = useRestyle(restyleFunctions, props as any);
|
|
59
|
+
return <RNFlatList<T> ref={ref} style={style} {...(rest as any)} />;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export const FlatList = forwardRef(FlatListInner) as <T = any>(
|
|
63
|
+
props: FlatListProps<T> & { ref?: React.Ref<RNFlatList<T>> },
|
|
64
|
+
) => React.ReactElement;
|
|
65
|
+
|
|
66
|
+
(FlatList as any).displayName = "FlatList";
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import {
|
|
2
|
+
backgroundColor,
|
|
3
|
+
BackgroundColorProps,
|
|
4
|
+
border,
|
|
5
|
+
BorderProps,
|
|
6
|
+
createRestyleComponent,
|
|
7
|
+
layout,
|
|
8
|
+
LayoutProps,
|
|
9
|
+
opacity,
|
|
10
|
+
OpacityProps,
|
|
11
|
+
spacing,
|
|
12
|
+
SpacingProps,
|
|
13
|
+
} from "@shopify/restyle";
|
|
14
|
+
import {
|
|
15
|
+
Pressable as RNPressable,
|
|
16
|
+
PressableProps as RNPressableProps,
|
|
17
|
+
} from "react-native";
|
|
18
|
+
|
|
19
|
+
import { RestyleTheme } from "../../core/restyle";
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Restyle props that can be applied to Pressable
|
|
23
|
+
*/
|
|
24
|
+
export type PressableRestyleProps = SpacingProps<RestyleTheme> &
|
|
25
|
+
LayoutProps<RestyleTheme> &
|
|
26
|
+
BackgroundColorProps<RestyleTheme> &
|
|
27
|
+
BorderProps<RestyleTheme> &
|
|
28
|
+
OpacityProps<RestyleTheme>;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Pressable — Restyled Pressable component
|
|
32
|
+
*
|
|
33
|
+
* A Pressable wrapper that accepts Restyle props (padding, margin, flex, backgroundColor, borderRadius, opacity)
|
|
34
|
+
* while preserving all native Pressable functionality.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```tsx
|
|
38
|
+
* <Pressable
|
|
39
|
+
* onPress={() => console.log('Pressed')}
|
|
40
|
+
* padding="md"
|
|
41
|
+
* backgroundColor="accentPrimary"
|
|
42
|
+
* borderRadius="md"
|
|
43
|
+
* opacity={0.8}
|
|
44
|
+
* >
|
|
45
|
+
* <Text>Press me</Text>
|
|
46
|
+
* </Pressable>
|
|
47
|
+
* ```
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* // With press state styling
|
|
51
|
+
* ```tsx
|
|
52
|
+
* <Pressable
|
|
53
|
+
* onPress={handlePress}
|
|
54
|
+
* padding="lg"
|
|
55
|
+
* backgroundColor="surfacePrimary"
|
|
56
|
+
* borderRadius="lg"
|
|
57
|
+
* style={({ pressed }) => ({
|
|
58
|
+
* opacity: pressed ? 0.7 : 1,
|
|
59
|
+
* })}
|
|
60
|
+
* >
|
|
61
|
+
* <Text>Interactive Card</Text>
|
|
62
|
+
* </Pressable>
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
const BaseRestylePressable = createRestyleComponent<
|
|
66
|
+
PressableRestyleProps & RNPressableProps,
|
|
67
|
+
RestyleTheme
|
|
68
|
+
>([spacing, layout, backgroundColor, border, opacity], RNPressable);
|
|
69
|
+
|
|
70
|
+
export const Pressable = BaseRestylePressable as (
|
|
71
|
+
props: PressableRestyleProps & RNPressableProps,
|
|
72
|
+
) => React.ReactElement;
|
|
73
|
+
|
|
74
|
+
export type PressableProps = PressableRestyleProps & RNPressableProps;
|