@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.
Files changed (187) hide show
  1. package/dist/index.d.mts +52556 -0
  2. package/dist/index.d.ts +52556 -0
  3. package/dist/index.js +8753 -0
  4. package/dist/index.mjs +8777 -0
  5. package/package.json +70 -0
  6. package/src/__test-utils__/index.tsx +39 -0
  7. package/src/components/CalendarStrip/CalendarStrip.helpers.ts +106 -0
  8. package/src/components/CalendarStrip/CalendarStrip.tsx +83 -0
  9. package/src/components/CalendarStrip/CalendarStrip.types.ts +133 -0
  10. package/src/components/CalendarStrip/DayCard/DayCard.helpers.ts +44 -0
  11. package/src/components/CalendarStrip/DayCard/DayCard.tsx +71 -0
  12. package/src/components/CalendarStrip/DayCard/DayCard.types.ts +134 -0
  13. package/src/components/CalendarStrip/DayCard/index.ts +2 -0
  14. package/src/components/CalendarStrip/DayCard/useDayCardLogic.ts +45 -0
  15. package/src/components/CalendarStrip/index.ts +9 -0
  16. package/src/components/CalendarStrip/useCalendarStripLogic.ts +53 -0
  17. package/src/components/EmptyState/EmptyState.helpers.ts +104 -0
  18. package/src/components/EmptyState/EmptyState.tsx +205 -0
  19. package/src/components/EmptyState/EmptyState.types.ts +213 -0
  20. package/src/components/EmptyState/index.ts +44 -0
  21. package/src/components/EmptyState/useEmptyStateLogic.ts +131 -0
  22. package/src/components/Header/Header.helpers.ts +93 -0
  23. package/src/components/Header/Header.tsx +185 -0
  24. package/src/components/Header/Header.types.ts +153 -0
  25. package/src/components/Header/index.ts +44 -0
  26. package/src/components/Header/useHeaderLogic.ts +146 -0
  27. package/src/components/ScheduleItem/ScheduleItem/ScheduleItem.helpers.ts +50 -0
  28. package/src/components/ScheduleItem/ScheduleItem/ScheduleItem.tsx +78 -0
  29. package/src/components/ScheduleItem/ScheduleItem/ScheduleItem.types.ts +99 -0
  30. package/src/components/ScheduleItem/ScheduleItem/index.ts +16 -0
  31. package/src/components/ScheduleItem/ScheduleItem/useScheduleItemLogic.ts +31 -0
  32. package/src/components/ScheduleItem/index.ts +15 -0
  33. package/src/components/index.ts +40 -0
  34. package/src/core/index.ts +34 -0
  35. package/src/core/restyle/RestyleThemeProviderWrapper.tsx +31 -0
  36. package/src/core/restyle/index.ts +38 -0
  37. package/src/core/restyle/restylePresetRegistry.ts +195 -0
  38. package/src/core/restyle/restyleTheme.ts +1352 -0
  39. package/src/core/restyle/restyleTypes.ts +8 -0
  40. package/src/core/restyle/useRestyleTheme.ts +10 -0
  41. package/src/hooks/animations/index.ts +3 -0
  42. package/src/hooks/animations/useAnimatedValue.ts +10 -0
  43. package/src/hooks/animations/useEntranceAnimation.ts +106 -0
  44. package/src/hooks/animations/usePulseAnimation.ts +63 -0
  45. package/src/hooks/index.ts +30 -0
  46. package/src/hooks/useReducedMotion.ts +60 -0
  47. package/src/i18n/index.ts +2 -0
  48. package/src/i18n/labels/en.ts +120 -0
  49. package/src/i18n/labels/es.ts +120 -0
  50. package/src/i18n/labels/index.ts +6 -0
  51. package/src/i18n/labels/types.ts +165 -0
  52. package/src/index.tsx +215 -0
  53. package/src/primitives/actions/Button/Button.helpers.ts +243 -0
  54. package/src/primitives/actions/Button/Button.tsx +198 -0
  55. package/src/primitives/actions/Button/Button.types.ts +207 -0
  56. package/src/primitives/actions/Button/index.ts +41 -0
  57. package/src/primitives/actions/Button/useButtonLogic.ts +160 -0
  58. package/src/primitives/actions/IconButton/IconButton.helpers.ts +235 -0
  59. package/src/primitives/actions/IconButton/IconButton.tsx +177 -0
  60. package/src/primitives/actions/IconButton/IconButton.types.ts +273 -0
  61. package/src/primitives/actions/IconButton/index.ts +30 -0
  62. package/src/primitives/actions/IconButton/useIconButtonLogic.ts +172 -0
  63. package/src/primitives/actions/index.ts +20 -0
  64. package/src/primitives/content/Avatar/Avatar.helpers.ts +177 -0
  65. package/src/primitives/content/Avatar/Avatar.tsx +199 -0
  66. package/src/primitives/content/Avatar/Avatar.types.ts +222 -0
  67. package/src/primitives/content/Avatar/index.ts +46 -0
  68. package/src/primitives/content/Avatar/useAvatarLogic.ts +149 -0
  69. package/src/primitives/content/Badge/Badge.helpers.ts +175 -0
  70. package/src/primitives/content/Badge/Badge.tsx +174 -0
  71. package/src/primitives/content/Badge/Badge.types.ts +223 -0
  72. package/src/primitives/content/Badge/index.ts +40 -0
  73. package/src/primitives/content/Badge/useBadgeLogic.ts +128 -0
  74. package/src/primitives/content/Card/Card.helpers.ts +27 -0
  75. package/src/primitives/content/Card/Card.tsx +123 -0
  76. package/src/primitives/content/Card/Card.types.ts +95 -0
  77. package/src/primitives/content/Card/index.ts +20 -0
  78. package/src/primitives/content/Card/useCardLogic.ts +48 -0
  79. package/src/primitives/content/Chip/Chip.helpers.ts +304 -0
  80. package/src/primitives/content/Chip/Chip.tsx +205 -0
  81. package/src/primitives/content/Chip/Chip.types.ts +234 -0
  82. package/src/primitives/content/Chip/index.ts +47 -0
  83. package/src/primitives/content/Chip/useChipLogic.ts +167 -0
  84. package/src/primitives/content/Icon/Icon.helpers.ts +54 -0
  85. package/src/primitives/content/Icon/Icon.tsx +110 -0
  86. package/src/primitives/content/Icon/Icon.types.ts +95 -0
  87. package/src/primitives/content/Icon/index.ts +20 -0
  88. package/src/primitives/content/Icon/useIconLogic.ts +73 -0
  89. package/src/primitives/content/index.ts +45 -0
  90. package/src/primitives/feedback/ProgressBar/ProgressBar.helpers.ts +122 -0
  91. package/src/primitives/feedback/ProgressBar/ProgressBar.tsx +154 -0
  92. package/src/primitives/feedback/ProgressBar/ProgressBar.types.ts +178 -0
  93. package/src/primitives/feedback/ProgressBar/index.ts +17 -0
  94. package/src/primitives/feedback/ProgressBar/useProgressBarLogic.ts +120 -0
  95. package/src/primitives/feedback/Skeleton/Skeleton.helpers.ts +145 -0
  96. package/src/primitives/feedback/Skeleton/Skeleton.tsx +155 -0
  97. package/src/primitives/feedback/Skeleton/Skeleton.types.ts +223 -0
  98. package/src/primitives/feedback/Skeleton/index.ts +44 -0
  99. package/src/primitives/feedback/Skeleton/useSkeletonLogic.ts +125 -0
  100. package/src/primitives/feedback/Spinner/Spinner.helpers.ts +40 -0
  101. package/src/primitives/feedback/Spinner/Spinner.tsx +105 -0
  102. package/src/primitives/feedback/Spinner/Spinner.types.ts +114 -0
  103. package/src/primitives/feedback/Spinner/index.ts +18 -0
  104. package/src/primitives/feedback/Spinner/useSpinnerLogic.ts +84 -0
  105. package/src/primitives/feedback/Toast/Toast.helpers.ts +163 -0
  106. package/src/primitives/feedback/Toast/Toast.tsx +190 -0
  107. package/src/primitives/feedback/Toast/Toast.types.ts +270 -0
  108. package/src/primitives/feedback/Toast/ToastContext.tsx +96 -0
  109. package/src/primitives/feedback/Toast/ToastProvider.tsx +241 -0
  110. package/src/primitives/feedback/Toast/index.ts +59 -0
  111. package/src/primitives/feedback/Toast/useToastLogic.ts +112 -0
  112. package/src/primitives/feedback/index.ts +45 -0
  113. package/src/primitives/index.ts +158 -0
  114. package/src/primitives/inputs/Checkbox/Checkbox.helpers.ts +132 -0
  115. package/src/primitives/inputs/Checkbox/Checkbox.tsx +150 -0
  116. package/src/primitives/inputs/Checkbox/Checkbox.types.ts +106 -0
  117. package/src/primitives/inputs/Checkbox/index.ts +30 -0
  118. package/src/primitives/inputs/Checkbox/useCheckboxLogic.ts +121 -0
  119. package/src/primitives/inputs/RadioButton/RadioButton.helpers.ts +123 -0
  120. package/src/primitives/inputs/RadioButton/RadioButton.tsx +159 -0
  121. package/src/primitives/inputs/RadioButton/RadioButton.types.ts +106 -0
  122. package/src/primitives/inputs/RadioButton/index.ts +25 -0
  123. package/src/primitives/inputs/RadioButton/useRadioButtonLogic.ts +117 -0
  124. package/src/primitives/inputs/SegmentedControl/SegmentedControl.helpers.ts +174 -0
  125. package/src/primitives/inputs/SegmentedControl/SegmentedControl.tsx +224 -0
  126. package/src/primitives/inputs/SegmentedControl/SegmentedControl.types.ts +187 -0
  127. package/src/primitives/inputs/SegmentedControl/index.ts +39 -0
  128. package/src/primitives/inputs/SegmentedControl/useSegmentedControlLogic.ts +151 -0
  129. package/src/primitives/inputs/SelectSheet/SelectSheet.helpers.ts +147 -0
  130. package/src/primitives/inputs/SelectSheet/SelectSheet.tsx +247 -0
  131. package/src/primitives/inputs/SelectSheet/SelectSheet.types.ts +196 -0
  132. package/src/primitives/inputs/SelectSheet/SelectSheetOption.tsx +177 -0
  133. package/src/primitives/inputs/SelectSheet/index.ts +48 -0
  134. package/src/primitives/inputs/SelectSheet/useSelectSheetLogic.ts +309 -0
  135. package/src/primitives/inputs/Switch/Switch.helpers.ts +109 -0
  136. package/src/primitives/inputs/Switch/Switch.tsx +191 -0
  137. package/src/primitives/inputs/Switch/Switch.types.ts +154 -0
  138. package/src/primitives/inputs/Switch/index.ts +40 -0
  139. package/src/primitives/inputs/Switch/useSwitchLogic.ts +192 -0
  140. package/src/primitives/inputs/TextInput/TextInput.helpers.ts +206 -0
  141. package/src/primitives/inputs/TextInput/TextInput.tsx +392 -0
  142. package/src/primitives/inputs/TextInput/TextInput.types.ts +216 -0
  143. package/src/primitives/inputs/TextInput/index.ts +37 -0
  144. package/src/primitives/inputs/TextInput/useTextInputLogic.ts +195 -0
  145. package/src/primitives/inputs/index.ts +52 -0
  146. package/src/primitives/layout/AnimatedBox.tsx +44 -0
  147. package/src/primitives/layout/Box.tsx +71 -0
  148. package/src/primitives/layout/Divider/Divider.helpers.ts +115 -0
  149. package/src/primitives/layout/Divider/Divider.tsx +139 -0
  150. package/src/primitives/layout/Divider/Divider.types.ts +178 -0
  151. package/src/primitives/layout/Divider/index.ts +24 -0
  152. package/src/primitives/layout/Divider/useDividerLogic.ts +109 -0
  153. package/src/primitives/layout/FlatList.tsx +66 -0
  154. package/src/primitives/layout/Pressable.tsx +74 -0
  155. package/src/primitives/layout/ScrollView.tsx +63 -0
  156. package/src/primitives/layout/Stack.tsx +69 -0
  157. package/src/primitives/layout/index.ts +40 -0
  158. package/src/primitives/navigation/index.ts +6 -0
  159. package/src/primitives/overlays/Modal/Modal.helpers.ts +31 -0
  160. package/src/primitives/overlays/Modal/Modal.tsx +264 -0
  161. package/src/primitives/overlays/Modal/Modal.types.ts +193 -0
  162. package/src/primitives/overlays/Modal/index.ts +43 -0
  163. package/src/primitives/overlays/Modal/useModalLogic.ts +103 -0
  164. package/src/primitives/overlays/index.ts +12 -0
  165. package/src/primitives/typography/Text.tsx +51 -0
  166. package/src/primitives/typography/index.ts +1 -0
  167. package/src/provider/DesignSystemContext.ts +22 -0
  168. package/src/provider/DesignSystemProvider.tsx +121 -0
  169. package/src/provider/index.ts +7 -0
  170. package/src/providers/ThemeProvider/createTheme.ts +304 -0
  171. package/src/providers/ThemeProvider/defaultTheme.ts +70 -0
  172. package/src/providers/ThemeProvider/index.ts +34 -0
  173. package/src/providers/ThemeProvider/types.ts +249 -0
  174. package/src/providers/index.ts +29 -0
  175. package/src/tokens/colors.ts +371 -0
  176. package/src/tokens/index.ts +145 -0
  177. package/src/tokens/motion.ts +176 -0
  178. package/src/tokens/radii.ts +82 -0
  179. package/src/tokens/scales.ts +588 -0
  180. package/src/tokens/shadows.ts +190 -0
  181. package/src/tokens/spacing.ts +140 -0
  182. package/src/tokens/tokens.json +207 -0
  183. package/src/tokens/typography.ts +251 -0
  184. package/src/types.ts +50 -0
  185. package/src/utils/accessibility.ts +169 -0
  186. package/src/utils/index.ts +25 -0
  187. package/src/utils/platform.ts +72 -0
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Header Logic Hook
3
+ *
4
+ * Extracts all computational logic from the Header component.
5
+ * Returns memoized values for optimal render performance.
6
+ *
7
+ * Responsibilities:
8
+ * - Resolve responsive size prop to current breakpoint value
9
+ * - Calculate header dimensions with safe area insets
10
+ * - Determine back button visibility
11
+ * - Generate container and back button accessibility props
12
+ * - Create back button press handler
13
+ *
14
+ * External Dependencies:
15
+ * - react-native-safe-area-context: Safe area insets
16
+ * - i18n: Translated accessibility labels
17
+ *
18
+ * @see Header.tsx - Component consuming this hook
19
+ * @see Header.helpers.ts - Pure calculation functions
20
+ */
21
+
22
+ import { useDesignSystem } from "../../provider";
23
+ import { useResponsiveProp } from "@shopify/restyle";
24
+ import { useCallback, useMemo } from "react";
25
+ import { useSafeAreaInsets } from "react-native-safe-area-context";
26
+ import { useRestyleTheme } from "../../core/restyle";
27
+ import { getHeaderA11y, getHeaderBackButtonA11y } from "./Header.a11y";
28
+ import {
29
+ resolveContainerStyle,
30
+ resolveHeaderDimensions,
31
+ SIZE_TO_TEXT_VARIANT,
32
+ } from "./Header.helpers";
33
+ import { HeaderSize, UseHeaderLogicParams, UseHeaderLogicReturn } from "./Header.types";
34
+
35
+ /**
36
+ * Orchestrates Header rendering logic and state management.
37
+ *
38
+ * Handles:
39
+ * - Responsive size resolution
40
+ * - Header dimension calculation with safe area insets
41
+ * - Back button visibility determination (shown when `onBackPress` is provided)
42
+ * - Back button press handling
43
+ * - Text variant selection based on size
44
+ * - Container style computation with top padding
45
+ * - Accessibility props for header and back button
46
+ * - Internationalization for back button labels
47
+ *
48
+ * @param params - Configuration object for header behavior
49
+ * @param params.accessibilityLabel - Custom a11y label for header
50
+ * @param params.accessibilityHint - Describes header purpose
51
+ * @param params.size - Size variant ('sm' | 'md' | 'lg')
52
+ * @param params.showBackButton - Whether to show back button
53
+ * @param params.safeAreaTop - Whether to add safe area top padding
54
+ * @param params.onBackPress - Optional custom back handler
55
+ *
56
+ * @returns Computed values for rendering Header
57
+ * @returns {function} handleBack - Back button press handler
58
+ * @returns {boolean} showBack - Whether to display back button
59
+ * @returns {object} dimensions - Height and padding dimensions
60
+ * @returns {ViewStyle} containerStyle - Dynamic container styles
61
+ * @returns {object} a11yContainerProps - Container accessibility props
62
+ * @returns {string} textVariant - Text variant for title
63
+ * @returns {object} backButtonA11yProps - Back button accessibility props
64
+ *
65
+ * @performance This hook uses useMemo() for expensive calculations
66
+ *
67
+ * @example
68
+ * const {
69
+ * showBack,
70
+ * textVariant,
71
+ * dimensions,
72
+ * handleBack,
73
+ * a11yContainerProps
74
+ * } = useHeaderLogic({
75
+ * size: "md",
76
+ * showBackButton: true,
77
+ * safeAreaTop: true,
78
+ * accessibilityLabel: "Profile header",
79
+ * });
80
+ */
81
+ export function useHeaderLogic(
82
+ params: UseHeaderLogicParams,
83
+ ): UseHeaderLogicReturn {
84
+ const {
85
+ accessibilityLabel,
86
+ accessibilityHint,
87
+ size,
88
+ showBackButton,
89
+ safeAreaTop,
90
+ onBackPress,
91
+ } = params;
92
+
93
+ const insets = useSafeAreaInsets();
94
+ const theme = useRestyleTheme();
95
+ const { labels: t } = useDesignSystem();
96
+
97
+ const resolvedSize = (useResponsiveProp(size) ?? "md") as HeaderSize;
98
+ const showBack = !!showBackButton && onBackPress !== undefined;
99
+
100
+ const dimensions = useMemo(
101
+ () =>
102
+ resolveHeaderDimensions({
103
+ resolvedSize,
104
+ safeAreaTop,
105
+ topInset: insets.top,
106
+ theme,
107
+ }),
108
+ [resolvedSize, safeAreaTop, insets.top, theme],
109
+ );
110
+
111
+ const containerStyle = resolveContainerStyle(dimensions.topPadding);
112
+
113
+ const handleBack = useCallback(() => {
114
+ onBackPress?.();
115
+ }, [onBackPress]);
116
+
117
+ const a11yContainerProps = useMemo(
118
+ () =>
119
+ getHeaderA11y({
120
+ accessibilityLabel,
121
+ accessibilityHint,
122
+ }),
123
+ [accessibilityLabel, accessibilityHint],
124
+ );
125
+
126
+ const textVariant = SIZE_TO_TEXT_VARIANT[resolvedSize];
127
+
128
+ const backButtonA11yProps = useMemo(
129
+ () =>
130
+ getHeaderBackButtonA11y({
131
+ accessibilityLabel: t.header.backButton.label,
132
+ accessibilityHint: t.header.backButton.hint,
133
+ }),
134
+ [t],
135
+ );
136
+
137
+ return {
138
+ handleBack,
139
+ showBack,
140
+ dimensions,
141
+ containerStyle,
142
+ a11yContainerProps,
143
+ textVariant,
144
+ backButtonA11yProps,
145
+ };
146
+ }
@@ -0,0 +1,50 @@
1
+ import type {
2
+ ScheduleItemSize,
3
+ ScheduleItemSizeConfig,
4
+ ScheduleItemSizeConfigMap,
5
+ } from "./ScheduleItem.types";
6
+
7
+ // ─── Time Formatting ─────────────────────────────────────────────────────────
8
+
9
+ export function formatTimeRange(startTime: Date, endTime: Date): string {
10
+ const startStr = startTime.toLocaleTimeString([], {
11
+ hour: "numeric",
12
+ minute: "2-digit",
13
+ hour12: true,
14
+ });
15
+ const endStr = endTime.toLocaleTimeString([], {
16
+ hour: "numeric",
17
+ minute: "2-digit",
18
+ hour12: true,
19
+ });
20
+ return `${startStr} – ${endStr}`;
21
+ }
22
+
23
+ // ─── Size Config ─────────────────────────────────────────────────────────────
24
+
25
+ const SCHEDULE_ITEM_SIZE_CONFIG: ScheduleItemSizeConfigMap = {
26
+ sm: {
27
+ indicatorHeight: 32,
28
+ contentGap: "2xs",
29
+ titleVariant: "labelSmall",
30
+ timeVariant: "captionSmall",
31
+ },
32
+ md: {
33
+ indicatorHeight: 48,
34
+ contentGap: "2xs",
35
+ titleVariant: "labelSmall",
36
+ timeVariant: "captionSmall",
37
+ },
38
+ lg: {
39
+ indicatorHeight: 64,
40
+ contentGap: "xs",
41
+ titleVariant: "labelMedium",
42
+ timeVariant: "bodySmall",
43
+ },
44
+ };
45
+
46
+ export function getScheduleItemSizeConfig(
47
+ size: ScheduleItemSize,
48
+ ): ScheduleItemSizeConfig {
49
+ return SCHEDULE_ITEM_SIZE_CONFIG[size];
50
+ }
@@ -0,0 +1,78 @@
1
+ import { RestyleTheme } from "../../../core/restyle";
2
+ import { Box, Text } from "../../../primitives";
3
+ import {
4
+ createRestyleComponent,
5
+ createVariant,
6
+ layout,
7
+ spacing,
8
+ spacingShorthand,
9
+ } from "@shopify/restyle";
10
+ import React, { memo } from "react";
11
+ import { Pressable as RNPressable } from "react-native";
12
+ import { BaseScheduleItemProps, ScheduleItemProps } from "./ScheduleItem.types";
13
+ import { useScheduleItemLogic } from "./useScheduleItemLogic";
14
+
15
+ /**
16
+ * Base ScheduleItem container with Restyle variant support.
17
+ *
18
+ * Built on RNPressable so press handling and variant styling live in one element.
19
+ * @internal
20
+ */
21
+ const BaseScheduleItemContainer = createRestyleComponent<
22
+ BaseScheduleItemProps,
23
+ RestyleTheme
24
+ >(
25
+ [
26
+ layout,
27
+ spacing,
28
+ spacingShorthand,
29
+ createVariant({ themeKey: "scheduleItemSizes", property: "size" }),
30
+ ],
31
+ RNPressable,
32
+ );
33
+
34
+ function ScheduleItemComponent({
35
+ task,
36
+ onPress,
37
+ size = "md",
38
+ testID,
39
+ ...rest
40
+ }: ScheduleItemProps) {
41
+ const { timeRange, sizeConfig, a11yProps } = useScheduleItemLogic({
42
+ task,
43
+ size,
44
+ onPress,
45
+ });
46
+
47
+ return (
48
+ <BaseScheduleItemContainer
49
+ size={size}
50
+ onPress={onPress}
51
+ disabled={!onPress}
52
+ testID={testID}
53
+ {...a11yProps}
54
+ {...rest}
55
+ >
56
+ {/* Left indicator bar */}
57
+ <Box
58
+ width={4}
59
+ height={sizeConfig.indicatorHeight}
60
+ borderRadius="full"
61
+ backgroundColor={task.indicatorColor}
62
+ />
63
+
64
+ {/* Content */}
65
+ <Box flex={1} gap={sizeConfig.contentGap}>
66
+ <Text variant={sizeConfig.titleVariant} color="textPrimary">
67
+ {task.title}
68
+ </Text>
69
+ <Text variant={sizeConfig.timeVariant} color="textSecondary">
70
+ {timeRange}
71
+ </Text>
72
+ </Box>
73
+ </BaseScheduleItemContainer>
74
+ );
75
+ }
76
+
77
+ export const ScheduleItem = memo(ScheduleItemComponent);
78
+ ScheduleItem.displayName = "ScheduleItem";
@@ -0,0 +1,99 @@
1
+ import { ResponsiveValue, SpacingShorthandProps, VariantProps } from "@shopify/restyle";
2
+ import { PressableProps as RNPressableProps } from "react-native";
3
+ import type { RestyleTheme } from "../../..";
4
+ import type { PressableRestyleProps } from "../../../primitives/layout/Pressable";
5
+
6
+ // ─── Size (derived from theme so it stays in sync) ───────────────────────────
7
+
8
+ export type ScheduleItemSize = Exclude<
9
+ keyof RestyleTheme["scheduleItemSizes"],
10
+ "defaults"
11
+ >;
12
+
13
+ // ─── Base component props (Restyle variant + Pressable) ──────────────────────
14
+
15
+ type ScheduleItemSizeVariantProps = VariantProps<
16
+ RestyleTheme,
17
+ "scheduleItemSizes",
18
+ "size"
19
+ >;
20
+
21
+ /** Base props for the Restyle container — used with createRestyleComponent. */
22
+ export type BaseScheduleItemProps = ScheduleItemSizeVariantProps &
23
+ PressableRestyleProps &
24
+ SpacingShorthandProps<RestyleTheme> &
25
+ RNPressableProps;
26
+
27
+ // ─── Size config (only values that cannot be expressed as theme tokens) ───────
28
+
29
+ export interface ScheduleItemSizeConfig {
30
+ indicatorHeight: number;
31
+ contentGap: keyof RestyleTheme["spacing"];
32
+ titleVariant: "labelSmall" | "labelMedium";
33
+ timeVariant: "captionSmall" | "bodySmall";
34
+ }
35
+
36
+ export type ScheduleItemSizeConfigMap = Record<
37
+ ScheduleItemSize,
38
+ ScheduleItemSizeConfig
39
+ >;
40
+
41
+ // ─── Data ────────────────────────────────────────────────────────────────────
42
+
43
+ /**
44
+ * Data for a single scheduled task or event
45
+ */
46
+ export interface ScheduleItemData {
47
+ /** Unique identifier */
48
+ id: string;
49
+ /** Task title (e.g., "Team Standup") */
50
+ title: string;
51
+ /** Task start time */
52
+ startTime: Date;
53
+ /** Task end time */
54
+ endTime: Date;
55
+ /** Theme color token for the left indicator bar */
56
+ indicatorColor: keyof RestyleTheme["colors"];
57
+ }
58
+
59
+ // ─── Component Props ─────────────────────────────────────────────────────────
60
+
61
+ export interface ScheduleItemProps extends Omit<BaseScheduleItemProps, "style"> {
62
+ task: ScheduleItemData;
63
+ onPress?: () => void;
64
+ /**
65
+ * Size variant — drives container padding via the `scheduleItemSizes` theme
66
+ * variant and sub-element config (indicator height, text variants).
67
+ * `VariantProps` already types this as `ResponsiveValue<ScheduleItemSize, ...>`.
68
+ * @default "md"
69
+ */
70
+ testID?: string;
71
+ }
72
+
73
+ // ─── Hook ────────────────────────────────────────────────────────────────────
74
+
75
+ export interface UseScheduleItemLogicParams {
76
+ task: ScheduleItemData;
77
+ size: ResponsiveValue<ScheduleItemSize, RestyleTheme["breakpoints"]>;
78
+ onPress?: () => void;
79
+ }
80
+
81
+ export interface UseScheduleItemLogicReturn {
82
+ timeRange: string;
83
+ sizeConfig: ScheduleItemSizeConfig;
84
+ a11yProps: ScheduleItemA11yProps;
85
+ }
86
+
87
+ // ─── Accessibility ───────────────────────────────────────────────────────────
88
+
89
+ export interface ScheduleItemA11yParams {
90
+ title: string;
91
+ timeRange: string;
92
+ onPress?: () => void;
93
+ }
94
+
95
+ export interface ScheduleItemA11yProps {
96
+ accessible: boolean;
97
+ accessibilityRole: "button" | "text";
98
+ accessibilityLabel: string;
99
+ }
@@ -0,0 +1,16 @@
1
+ export { ScheduleItem } from "./ScheduleItem";
2
+ export type {
3
+ BaseScheduleItemProps,
4
+ ScheduleItemA11yParams,
5
+ ScheduleItemA11yProps,
6
+ ScheduleItemData,
7
+ ScheduleItemProps,
8
+ ScheduleItemSize,
9
+ ScheduleItemSizeConfig,
10
+ ScheduleItemSizeConfigMap,
11
+ UseScheduleItemLogicParams,
12
+ UseScheduleItemLogicReturn,
13
+ } from "./ScheduleItem.types";
14
+ export { formatTimeRange, getScheduleItemSizeConfig } from "./ScheduleItem.helpers";
15
+ export { getScheduleItemA11y } from "./ScheduleItem.a11y";
16
+ export { useScheduleItemLogic } from "./useScheduleItemLogic";
@@ -0,0 +1,31 @@
1
+ import { useResponsiveProp } from "@shopify/restyle";
2
+ import { useMemo } from "react";
3
+ import { getScheduleItemA11y } from "./ScheduleItem.a11y";
4
+ import {
5
+ formatTimeRange,
6
+ getScheduleItemSizeConfig,
7
+ } from "./ScheduleItem.helpers";
8
+ import type {
9
+ ScheduleItemSize,
10
+ UseScheduleItemLogicParams,
11
+ UseScheduleItemLogicReturn,
12
+ } from "./ScheduleItem.types";
13
+
14
+ export function useScheduleItemLogic({
15
+ task,
16
+ size,
17
+ onPress,
18
+ }: UseScheduleItemLogicParams): UseScheduleItemLogicReturn {
19
+ const resolvedSize = (useResponsiveProp(size) ?? "md") as ScheduleItemSize;
20
+
21
+ const timeRange = formatTimeRange(task.startTime, task.endTime);
22
+
23
+ const sizeConfig = getScheduleItemSizeConfig(resolvedSize);
24
+
25
+ const a11yProps = useMemo(
26
+ () => getScheduleItemA11y({ title: task.title, timeRange, onPress }),
27
+ [task.title, timeRange, onPress],
28
+ );
29
+
30
+ return { timeRange, sizeConfig, a11yProps };
31
+ }
@@ -0,0 +1,15 @@
1
+ // ScheduleItem sub-component
2
+ export { ScheduleItem } from "./ScheduleItem/ScheduleItem";
3
+ export { getScheduleItemA11y } from "./ScheduleItem/ScheduleItem.a11y";
4
+ export {
5
+ formatTimeRange,
6
+ getScheduleItemSizeConfig,
7
+ } from "./ScheduleItem/ScheduleItem.helpers";
8
+ export type {
9
+ ScheduleItemData,
10
+ ScheduleItemProps,
11
+ ScheduleItemSize,
12
+ ScheduleItemSizeConfig,
13
+ ScheduleItemSizeConfigMap,
14
+ } from "./ScheduleItem/ScheduleItem.types";
15
+ export { useScheduleItemLogic } from "./ScheduleItem/useScheduleItemLogic";
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Design System Components
3
+ *
4
+ * Composite components that are built from primitives but are not
5
+ * considered atomic/primitive themselves.
6
+ */
7
+
8
+ // ─── CalendarStrip ───────────────────────────────────────────────────────────
9
+ export {
10
+ CalendarStrip,
11
+ DayCard,
12
+ type CalendarStripProps,
13
+ type CalendarStripSize,
14
+ type DayCardProps,
15
+ } from "./CalendarStrip";
16
+
17
+ // ─── EmptyState ─────────────────────────────────────────────────────────────
18
+ export {
19
+ EmptyState,
20
+ type EmptyStateProps,
21
+ type EmptyStateVariant,
22
+ } from "./EmptyState";
23
+
24
+ // ─── Header ──────────────────────────────────────────────────────────────────
25
+ export {
26
+ Header,
27
+ HeaderRightItems,
28
+ type HeaderProps,
29
+ type HeaderRightItemsProps,
30
+ type HeaderSize,
31
+ type HeaderVariant,
32
+ } from "./Header";
33
+
34
+ // ─── ScheduleItem ────────────────────────────────────────────────────────────
35
+ export {
36
+ ScheduleItem,
37
+ type ScheduleItemData,
38
+ type ScheduleItemProps,
39
+ type ScheduleItemSize,
40
+ } from "./ScheduleItem";
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Core Primitives Module
3
+ *
4
+ * Fundamental, low-level primitives that serve as the foundation
5
+ * for all design system components.
6
+ *
7
+ * ## Restyle Integration
8
+ * - **RestyleTheme**: Type-safe theme definition
9
+ * - **useRestyleTheme**: Hook for accessing the current Restyle theme
10
+ *
11
+ * @example
12
+ * import { Box, Text, AnimatedBox } from "@/design-system/core";
13
+ *
14
+ * <Box padding="lg" backgroundColor="surfacePrimary">
15
+ * <Text variant="headingLarge">Hello World</Text>
16
+ * </Box>
17
+ */
18
+
19
+ // Restyle Integration
20
+ export {
21
+ restyleDarkTheme,
22
+ restyleLightTheme,
23
+ restyleTheme,
24
+ ThemeProvider,
25
+ useRestyleTheme,
26
+ buildPair,
27
+ buildRestyleTheme,
28
+ buildRestyleThemeFromThemeColors,
29
+ restylePresetThemes,
30
+ type RestyleTheme,
31
+ type AppThemeColors,
32
+ type RestyleThemePair,
33
+ type SemanticColorsInput,
34
+ } from "./restyle";
@@ -0,0 +1,31 @@
1
+ /**
2
+ * El Sendero Design System - Restyle Theme Provider Wrapper
3
+ *
4
+ * Provides the correct Restyle theme (light/dark) based on the
5
+ * current design system mode.
6
+ *
7
+ * @example
8
+ * <RestyleThemeProviderWrapper>
9
+ * <YourApp />
10
+ * </RestyleThemeProviderWrapper>
11
+ */
12
+
13
+ import { ThemeProvider } from "@shopify/restyle";
14
+ import React, { ReactNode } from "react";
15
+ import { useColorScheme } from "react-native";
16
+ import { restyleDarkTheme, restyleLightTheme } from "./restyleTheme";
17
+
18
+ export interface RestyleThemeProviderWrapperProps {
19
+ children: ReactNode;
20
+ }
21
+
22
+ export function RestyleThemeProviderWrapper({
23
+ children,
24
+ }: RestyleThemeProviderWrapperProps) {
25
+ const isDark = useColorScheme() === "dark";
26
+ return (
27
+ <ThemeProvider theme={isDark ? restyleDarkTheme : restyleLightTheme}>
28
+ {children}
29
+ </ThemeProvider>
30
+ );
31
+ }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * El Sendero Design System - Restyle Exports
3
+ *
4
+ * Restyle provides type-safe, prop-based styling for React Native.
5
+ * This module exports Restyle components and utilities configured with our design system.
6
+ *
7
+ * @example
8
+ * // Basic usage
9
+ * import { RestyleTheme, ThemeProvider, restyleTheme } from '@/design-system/core/restyle';
10
+ *
11
+ * <ThemeProvider theme={restyleTheme}>
12
+ * <Box padding="lg" backgroundColor="surfacePrimary" borderRadius="md">
13
+ * <Text variant="headingLarge" color="textPrimary">
14
+ * Hello World
15
+ * </Text>
16
+ * </Box>
17
+ * </ThemeProvider>
18
+ */
19
+
20
+ export { ThemeProvider } from "@shopify/restyle";
21
+ export {
22
+ restyleDarkTheme,
23
+ restyleLightTheme,
24
+ restyleTheme,
25
+ buildRestyleTheme,
26
+ buildRestyleThemeFromThemeColors,
27
+ type RestyleTheme,
28
+ type AppThemeColors,
29
+ type SemanticColorsInput,
30
+ } from "./restyleTheme";
31
+
32
+ export { useRestyleTheme } from "./useRestyleTheme";
33
+
34
+ export {
35
+ buildPair,
36
+ restylePresetThemes,
37
+ type RestyleThemePair,
38
+ } from "./restylePresetRegistry";