@codewithbeto/ui 0.0.2-beta.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Code with Beto LLC
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,216 @@
1
+ # @codewithbeto/ui
2
+
3
+ A React Native UI component library built for Expo applications.
4
+
5
+ ## Overview
6
+
7
+ This package provides reusable UI components for React Native applications. Components are built on top of React Native primitives and are designed to work seamlessly with Expo.
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ pnpm add @codewithbeto/ui
13
+ ```
14
+
15
+ Or with npm:
16
+
17
+ ```bash
18
+ npm install @codewithbeto/ui
19
+ ```
20
+
21
+ ## Usage
22
+
23
+ ```typescript
24
+ import { Text } from "@codewithbeto/ui";
25
+
26
+ export default function App() {
27
+ return <Text variant="heading">Hello World</Text>;
28
+ }
29
+ ```
30
+
31
+ ## Development
32
+
33
+ ### Local Development Setup
34
+
35
+ This package is part of a pnpm workspace. For local development:
36
+
37
+ 1. Clone the repository and install dependencies:
38
+
39
+ ```bash
40
+ pnpm install
41
+ ```
42
+
43
+ 2. Use the workspace link in `apps/example` to test your changes:
44
+
45
+ ```typescript
46
+ import { Text } from "@codewithbeto/ui";
47
+ ```
48
+
49
+ 3. Changes will hot-reload automatically in Expo.
50
+
51
+ ### Building
52
+
53
+ Before publishing, you must build the package to compile TypeScript to JavaScript:
54
+
55
+ ```bash
56
+ pnpm --filter @codewithbeto/ui build
57
+ ```
58
+
59
+ This command:
60
+
61
+ - Compiles TypeScript files from `src/` to JavaScript in `dist/`
62
+ - Generates TypeScript declaration files (`.d.ts`) for type support
63
+ - Creates source maps for debugging
64
+
65
+ **Why build?** We publish compiled JavaScript to npm, not TypeScript source files. This ensures:
66
+
67
+ - Faster installs (no compilation needed)
68
+ - Smaller package size
69
+ - Better compatibility across different TypeScript versions
70
+
71
+ ### Type Checking
72
+
73
+ Run type checking without building:
74
+
75
+ ```bash
76
+ pnpm --filter @codewithbeto/ui typecheck
77
+ ```
78
+
79
+ ## Publishing
80
+
81
+ Publishing is automated via GitHub Actions. No local `.npmrc` or Personal Access Token is required.
82
+
83
+ ### How It Works
84
+
85
+ The repository includes a [publish workflow](../../.github/workflows/publish.yml) that:
86
+
87
+ - Triggers automatically when a **GitHub Release** is created
88
+ - Publishes as `latest` for stable releases, or `beta` for pre-releases
89
+ - Builds the package and publishes it to npm
90
+ - Uses an `NPM_TOKEN` repository secret for authentication
91
+
92
+ ### Publishing a Stable Release
93
+
94
+ 1. **Bump the version** in `package.json` according to [Semantic Versioning](https://semver.org/):
95
+ - **Patch** (`0.0.1` → `0.0.2`): Bug fixes, small improvements
96
+ - **Minor** (`0.0.1` → `0.1.0`): New features (backward compatible)
97
+ - **Major** (`0.0.1` → `1.0.0`): Breaking changes
98
+
99
+ 2. **Commit the version bump** and push to `main`.
100
+
101
+ 3. **Create a GitHub Release:**
102
+ - Go to the [Releases page](https://github.com/Code-with-Beto/cwb/releases/new)
103
+ - Click "Draft a new release"
104
+ - Create a new tag matching the version (e.g., `v0.0.2`)
105
+ - Add release notes describing the changes
106
+ - Click "Publish release"
107
+
108
+ 4. The workflow will automatically build and publish the package under the `latest` tag.
109
+
110
+ ### Publishing a Beta Release
111
+
112
+ Beta releases let you test new changes without affecting users on the stable version.
113
+
114
+ 1. **Bump the version** with a prerelease identifier, e.g. `0.0.2-beta.1`.
115
+
116
+ 2. **Commit the version bump** and push to your branch.
117
+
118
+ 3. **Create a GitHub Release:**
119
+ - Go to the [Releases page](https://github.com/Code-with-Beto/cwb/releases/new)
120
+ - Create a new tag matching the version (e.g., `v0.0.2-beta.1`)
121
+ - Check the **"Set as a pre-release"** checkbox
122
+ - Click "Publish release"
123
+
124
+ 4. The workflow detects the pre-release flag and publishes under the `beta` dist-tag instead of `latest`.
125
+
126
+ **Installing a beta version:**
127
+
128
+ ```bash
129
+ pnpm add @codewithbeto/ui@beta
130
+ ```
131
+
132
+ Users who run `pnpm add @codewithbeto/ui` (without `@beta`) will continue to get the latest stable version.
133
+
134
+ ### Promoting Beta to Stable
135
+
136
+ Once a beta has been tested and is ready for production:
137
+
138
+ 1. **Update the version** in `package.json` to the stable version (remove the prerelease identifier):
139
+ - `0.0.2-beta.3` → `0.0.2`
140
+
141
+ 2. **Commit the version bump** and push to `main`.
142
+
143
+ 3. **Create a regular GitHub Release** (do **not** check "Set as a pre-release"):
144
+ - Create a new tag matching the stable version (e.g., `v0.0.2`)
145
+ - Click "Publish release"
146
+
147
+ 4. The workflow publishes the package under `latest`. All users will get the stable version on their next install or update.
148
+
149
+ ### Example: Full Release Lifecycle
150
+
151
+ Here's a typical workflow from development to stable release:
152
+
153
+ | Step | Version in `package.json` | Git Tag | Pre-release? | Dist-tag |
154
+ |------|---------------------------|---------|--------------|----------|
155
+ | First beta | `0.0.2-beta.1` | `v0.0.2-beta.1` | Yes | `beta` |
156
+ | Fix a bug in beta | `0.0.2-beta.2` | `v0.0.2-beta.2` | Yes | `beta` |
157
+ | Promote to stable | `0.0.2` | `v0.0.2` | No | `latest` |
158
+
159
+ You can also trigger the workflow manually from the **Actions** tab with a custom dist-tag if needed.
160
+
161
+ ### Package Configuration
162
+
163
+ The package is configured to publish to npm:
164
+
165
+ - **Registry:** `https://registry.npmjs.org`
166
+ - **Scope:** `@codewithbeto`
167
+ - **Access:** Public
168
+ - **Files included:** Only the `dist/` folder (specified in `package.json`)
169
+
170
+ ## Components
171
+
172
+ ### Text
173
+
174
+ A text component with variant support.
175
+
176
+ ```typescript
177
+ import { Text } from "@codewithbeto/ui";
178
+
179
+ <Text variant="heading">Heading Text</Text>
180
+ <Text variant="body">Body Text</Text>
181
+ <Text variant="caption">Caption Text</Text>
182
+ ```
183
+
184
+ **Props:**
185
+
186
+ - `variant?: "body" | "heading" | "caption"` - Text style variant
187
+ - All standard React Native `Text` props are supported
188
+
189
+ ## Adding New Components
190
+
191
+ 1. Create your component file in `src/`:
192
+
193
+ ```typescript
194
+ // src/MyComponent.tsx
195
+ import { View } from "react-native";
196
+
197
+ export interface MyComponentProps {
198
+ // your props
199
+ }
200
+
201
+ export function MyComponent({ ...props }: MyComponentProps) {
202
+ return <View>...</View>;
203
+ }
204
+ ```
205
+
206
+ 2. Export it from `src/index.ts`:
207
+
208
+ ```typescript
209
+ export { MyComponent, type MyComponentProps } from "./MyComponent";
210
+ ```
211
+
212
+ 3. Test it in `apps/example` before publishing.
213
+
214
+ ## License
215
+
216
+ This package is licensed under the [MIT License](../../LICENSE).
package/dist/Text.d.ts ADDED
@@ -0,0 +1,74 @@
1
+ import { type TextProps as RNTextProps } from "react-native";
2
+ import { type ReactNode } from "react";
3
+ /**
4
+ * Text component with automatic color scheme support and multiple size variants.
5
+ *
6
+ * @example
7
+ * ```tsx
8
+ * // Basic usage with default size
9
+ * <Text>Hello World</Text>
10
+ *
11
+ * // Using different size types
12
+ * <Text type="title">Page Title</Text>
13
+ * <Text type="body">Body text content</Text>
14
+ * <Text type="caption">Small caption text</Text>
15
+ *
16
+ * // Using numeric sizes
17
+ * <Text type="xs">Extra small text</Text>
18
+ * <Text type="lg">Large text</Text>
19
+ * <Text type="3xl">Very large heading</Text>
20
+ *
21
+ * // Using secondary prop for description text
22
+ * <Text secondary>This is a description with gray color</Text>
23
+ * <Text type="caption" secondary>Secondary caption text</Text>
24
+ *
25
+ * // Using weight, fontStyle, and color props
26
+ * <Text weight="bold">Bold text</Text>
27
+ * <Text weight={600} fontStyle="italic">Semi-bold italic text</Text>
28
+ * <Text color="#FF0000">Red text</Text>
29
+ * <Text weight="bold" color="#0066CC">Bold blue text</Text>
30
+ *
31
+ * // All standard React Native Text props are supported
32
+ * <Text type="heading" style={{ marginTop: 10 }}>
33
+ * Custom styled text
34
+ * </Text>
35
+ * ```
36
+ */
37
+ export type TextProps = RNTextProps & {
38
+ /** Text content to display */
39
+ children?: ReactNode;
40
+ /**
41
+ * Text size variant
42
+ * @default "default"
43
+ */
44
+ type?: "default" | "base" | "xs" | "sm" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl" | "6xl" | "7xl" | "8xl" | "9xl" | "10xl" | "11xl" | "12xl" | "title" | "subtitle" | "link" | "body" | "caption";
45
+ /**
46
+ * When enabled, uses a secondary gray color suitable for descriptions and less prominent text.
47
+ * Follows Apple's Human Interface Guidelines for secondary label colors.
48
+ * @default false
49
+ */
50
+ secondary?: boolean;
51
+ /**
52
+ * Font weight of the text.
53
+ * Can be a string ("normal", "bold") or a number (100-900).
54
+ * @default "normal"
55
+ */
56
+ weight?: "normal" | "bold" | "100" | "200" | "300" | "400" | "500" | "600" | "700" | "800" | "900" | number;
57
+ /**
58
+ * Font style of the text.
59
+ * @default "normal"
60
+ */
61
+ fontStyle?: "normal" | "italic";
62
+ /**
63
+ * Override the default color. When provided, this takes precedence over the automatic
64
+ * color scheme and secondary prop.
65
+ */
66
+ color?: string;
67
+ };
68
+ /**
69
+ * Text component that automatically adapts to light/dark color scheme.
70
+ * Text color will be black in light mode and white in dark mode.
71
+ * Use the `secondary` prop for description text with a gray color.
72
+ */
73
+ export declare function Text({ style, type, secondary, weight, fontStyle, color: colorOverride, ...rest }: TextProps): import("react").JSX.Element;
74
+ //# sourceMappingURL=Text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Text.d.ts","sourceRoot":"","sources":["../src/Text.tsx"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,SAAS,IAAI,WAAW,EAC9B,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,MAAM,MAAM,SAAS,GAAG,WAAW,GAAG;IACpC,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;OAGG;IACH,IAAI,CAAC,EACD,SAAS,GACT,MAAM,GACN,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,MAAM,GACN,MAAM,GACN,MAAM,GACN,OAAO,GACP,UAAU,GACV,MAAM,GACN,MAAM,GACN,SAAS,CAAC;IACd;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;OAIG;IACH,MAAM,CAAC,EACH,QAAQ,GACR,MAAM,GACN,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,MAAM,CAAC;IACX;;;OAGG;IACH,SAAS,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAChC;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,IAAI,CAAC,EACnB,KAAK,EACL,IAAgB,EAChB,SAAiB,EACjB,MAAM,EACN,SAAS,EACT,KAAK,EAAE,aAAa,EACpB,GAAG,IAAI,EACR,EAAE,SAAS,+BAuCX"}
package/dist/Text.js ADDED
@@ -0,0 +1,63 @@
1
+ import { useMemo } from "react";
2
+ import { Text as RNText, StyleSheet, useColorScheme, } from "react-native";
3
+ import {} from "react";
4
+ /**
5
+ * Text component that automatically adapts to light/dark color scheme.
6
+ * Text color will be black in light mode and white in dark mode.
7
+ * Use the `secondary` prop for description text with a gray color.
8
+ */
9
+ export function Text({ style, type = "default", secondary = false, weight, fontStyle, color: colorOverride, ...rest }) {
10
+ const colorScheme = useColorScheme();
11
+ // Default to light mode if colorScheme is null/undefined
12
+ const color = useMemo(() => {
13
+ // If color override is provided, use it
14
+ if (colorOverride) {
15
+ return colorOverride;
16
+ }
17
+ if (secondary) {
18
+ // Apple's secondary label colors following HIG guidelines
19
+ // Light mode: #6E6E73 (60% opacity equivalent)
20
+ // Dark mode: #8E8E93 (60% opacity equivalent)
21
+ return colorScheme === "dark" ? "#8E8E93" : "#6E6E73";
22
+ }
23
+ return colorScheme === "dark" ? "#ffffff" : "#000000";
24
+ }, [colorScheme, secondary, colorOverride]);
25
+ // Memoize size style lookup
26
+ const sizeStyle = useMemo(() => sizeStyles[type], [type]);
27
+ // Build dynamic styles from props
28
+ const dynamicStyles = useMemo(() => {
29
+ const styles = {};
30
+ if (weight !== undefined) {
31
+ styles.fontWeight = weight;
32
+ }
33
+ if (fontStyle !== undefined) {
34
+ styles.fontStyle = fontStyle;
35
+ }
36
+ return styles;
37
+ }, [weight, fontStyle]);
38
+ return (<RNText style={[{ color }, sizeStyle, dynamicStyles, style]} textBreakStrategy="simple" {...rest}/>);
39
+ }
40
+ const sizeStyles = StyleSheet.create({
41
+ default: { fontSize: 16, lineHeight: 24 },
42
+ base: { fontSize: 16, lineHeight: 24 },
43
+ xs: { fontSize: 12, lineHeight: 16 },
44
+ sm: { fontSize: 14, lineHeight: 20 },
45
+ lg: { fontSize: 18, lineHeight: 28 },
46
+ xl: { fontSize: 20, lineHeight: 28 },
47
+ "2xl": { fontSize: 24, lineHeight: 32 },
48
+ "3xl": { fontSize: 30, lineHeight: 36 },
49
+ "4xl": { fontSize: 36, lineHeight: 44 },
50
+ "5xl": { fontSize: 48, lineHeight: 58 },
51
+ "6xl": { fontSize: 60, lineHeight: 72 },
52
+ "7xl": { fontSize: 72, lineHeight: 86 },
53
+ "8xl": { fontSize: 96, lineHeight: 116 },
54
+ "9xl": { fontSize: 128, lineHeight: 154 },
55
+ "10xl": { fontSize: 160, lineHeight: 192 },
56
+ "11xl": { fontSize: 192, lineHeight: 230 },
57
+ "12xl": { fontSize: 220, lineHeight: 268 },
58
+ title: { fontSize: 32, lineHeight: 32 },
59
+ subtitle: { fontSize: 20, lineHeight: 28 },
60
+ body: { fontSize: 14, lineHeight: 20 },
61
+ caption: { fontSize: 12, lineHeight: 16 },
62
+ link: { lineHeight: 30, fontSize: 16 },
63
+ });
@@ -0,0 +1,2 @@
1
+ export { Text, type TextProps } from "./Text";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,KAAK,SAAS,EAAE,MAAM,QAAQ,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ export { Text } from "./Text";
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@codewithbeto/ui",
3
+ "version": "0.0.2-beta.1",
4
+ "private": false,
5
+ "license": "MIT",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "sideEffects": false,
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "publishConfig": {
13
+ "access": "public"
14
+ },
15
+ "peerDependencies": {
16
+ "react": "*",
17
+ "react-native": "*",
18
+ "expo": "*"
19
+ },
20
+ "devDependencies": {
21
+ "@types/react": "~19.1.1",
22
+ "typescript": "^5.9.2"
23
+ },
24
+ "scripts": {
25
+ "build": "tsc -p tsconfig.json",
26
+ "typecheck": "tsc --noEmit",
27
+ "watch": "tsc -p tsconfig.json --watch"
28
+ }
29
+ }