@scripso-homepad/ui 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,14 +8,48 @@ Cross-platform UI component library for Homepad. Components use React Native pri
8
8
  npm install @scripso-homepad/ui react react-native
9
9
  ```
10
10
 
11
- ### React Web (Next.js)
11
+ ### React Web
12
12
 
13
- Also install `react-native-web` and alias `react-native` → `react-native-web` in your bundler:
13
+ Also install `react-native-web`:
14
14
 
15
15
  ```bash
16
16
  npm install react-native-web
17
17
  ```
18
18
 
19
+ Alias `react-native` → `react-native-web` in your bundler.
20
+
21
+ #### Vite (React)
22
+
23
+ ```ts
24
+ // vite.config.ts
25
+ import { defineConfig } from "vite";
26
+ import react from "@vitejs/plugin-react";
27
+
28
+ export default defineConfig({
29
+ plugins: [react()],
30
+ resolve: {
31
+ alias: {
32
+ "react-native": "react-native-web",
33
+ },
34
+ extensions: [
35
+ ".web.tsx",
36
+ ".web.ts",
37
+ ".web.jsx",
38
+ ".web.js",
39
+ ".tsx",
40
+ ".ts",
41
+ ".jsx",
42
+ ".js",
43
+ ],
44
+ },
45
+ optimizeDeps: {
46
+ include: ["react-native-web", "@scripso-homepad/ui"],
47
+ },
48
+ });
49
+ ```
50
+
51
+ #### Next.js
52
+
19
53
  ```js
20
54
  // next.config.js
21
55
  module.exports = {
@@ -58,11 +92,39 @@ export function Example() {
58
92
 
59
93
  ### `Button`
60
94
 
61
- | Prop | Type | Required | Default | Description |
62
- | ---------- | ------------ | -------- | ------- | -------------------- |
63
- | `title` | `string` | Yes | — | Button label text |
64
- | `onPress` | `() => void` | Yes | — | Press handler |
65
- | `disabled` | `boolean` | No | `false` | Disables interaction |
95
+ | Prop | Type | Required | Default | Description |
96
+ | --------------- | ---------------------- | -------- | ------- | -------------------------------------------------------- |
97
+ | `title` | `string` | Yes | — | Button label text |
98
+ | `onPress` | `() => void` | Yes | — | Press handler |
99
+ | `disabled` | `boolean` | No | `false` | Disables interaction |
100
+ | `style` | `StyleProp<ViewStyle>` | No | — | Extra container styles (web + native) |
101
+ | `textStyle` | `StyleProp<TextStyle>` | No | — | Extra label styles (web + native) |
102
+ | `className` | `string` | No | — | CSS/Tailwind classes for container (web / NativeWind) |
103
+ | `textClassName` | `string` | No | — | CSS/Tailwind classes for label (web / NativeWind) |
104
+
105
+ #### Custom styles (React Native `style`)
106
+
107
+ ```tsx
108
+ <Button
109
+ title="Save"
110
+ onPress={handleSave}
111
+ style={{ backgroundColor: "#dc2626", borderRadius: 999 }}
112
+ textStyle={{ fontSize: 14, textTransform: "uppercase" }}
113
+ />
114
+ ```
115
+
116
+ #### Tailwind classes (React web)
117
+
118
+ ```tsx
119
+ <Button
120
+ title="Save"
121
+ onPress={handleSave}
122
+ className="rounded-full bg-violet-600 px-8 shadow-lg"
123
+ textClassName="text-sm font-bold uppercase"
124
+ />
125
+ ```
126
+
127
+ Default package styles are merged with your `style` / `className` values.
66
128
 
67
129
  ## Development
68
130
 
package/dist/index.cjs CHANGED
@@ -4,17 +4,35 @@ var reactNative = require('react-native');
4
4
  var jsxRuntime = require('react/jsx-runtime');
5
5
 
6
6
  // src/components/Button.tsx
7
- function Button({ title, onPress, disabled = false }) {
7
+ function Button({
8
+ title,
9
+ onPress,
10
+ disabled = false,
11
+ style,
12
+ textStyle,
13
+ className,
14
+ textClassName
15
+ }) {
16
+ const containerWebProps = className != null ? { className } : {};
17
+ const textWebProps = textClassName != null ? { className: textClassName } : {};
8
18
  return /* @__PURE__ */ jsxRuntime.jsx(
9
19
  reactNative.TouchableOpacity,
10
20
  {
11
- style: [styles.button, disabled && styles.buttonDisabled],
21
+ style: [styles.button, disabled && styles.buttonDisabled, style],
12
22
  onPress,
13
23
  disabled,
14
24
  activeOpacity: 0.7,
15
25
  accessibilityRole: "button",
16
26
  accessibilityState: { disabled },
17
- children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles.text, disabled && styles.textDisabled], children: title })
27
+ ...containerWebProps,
28
+ children: /* @__PURE__ */ jsxRuntime.jsx(
29
+ reactNative.Text,
30
+ {
31
+ style: [styles.text, disabled && styles.textDisabled, textStyle],
32
+ ...textWebProps,
33
+ children: title
34
+ }
35
+ )
18
36
  }
19
37
  );
20
38
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/Button.tsx"],"names":["jsx","TouchableOpacity","Text","StyleSheet"],"mappings":";;;;;;AAaO,SAAS,OAAO,EAAE,KAAA,EAAO,OAAA,EAAS,QAAA,GAAW,OAAM,EAAgB;AACxE,EAAA,uBACEA,cAAA;AAAA,IAACC,4BAAA;AAAA,IAAA;AAAA,MACC,OAAO,CAAC,MAAA,CAAO,MAAA,EAAQ,QAAA,IAAY,OAAO,cAAc,CAAA;AAAA,MACxD,OAAA;AAAA,MACA,QAAA;AAAA,MACA,aAAA,EAAe,GAAA;AAAA,MACf,iBAAA,EAAkB,QAAA;AAAA,MAClB,kBAAA,EAAoB,EAAE,QAAA,EAAS;AAAA,MAE/B,QAAA,kBAAAD,cAAA,CAACE,gBAAA,EAAA,EAAK,KAAA,EAAO,CAAC,MAAA,CAAO,MAAM,QAAA,IAAY,MAAA,CAAO,YAAY,CAAA,EAAI,QAAA,EAAA,KAAA,EAAM;AAAA;AAAA,GACtE;AAEJ;AAEA,IAAM,MAAA,GAASC,uBAAW,MAAA,CAAO;AAAA,EAC/B,MAAA,EAAQ;AAAA,IACN,eAAA,EAAiB,SAAA;AAAA,IACjB,eAAA,EAAiB,EAAA;AAAA,IACjB,iBAAA,EAAmB,EAAA;AAAA,IACnB,YAAA,EAAc,CAAA;AAAA,IACd,UAAA,EAAY,QAAA;AAAA,IACZ,cAAA,EAAgB,QAAA;AAAA,IAChB,QAAA,EAAU;AAAA,GACZ;AAAA,EACA,cAAA,EAAgB;AAAA,IACd,eAAA,EAAiB,SAAA;AAAA,IACjB,OAAA,EAAS;AAAA,GACX;AAAA,EACA,IAAA,EAAM;AAAA,IACJ,KAAA,EAAO,SAAA;AAAA,IACP,QAAA,EAAU,EAAA;AAAA,IACV,UAAA,EAAY;AAAA,GACd;AAAA,EACA,YAAA,EAAc;AAAA,IACZ,KAAA,EAAO;AAAA;AAEX,CAAC,CAAA","file":"index.cjs","sourcesContent":["import {\n StyleSheet,\n Text,\n TouchableOpacity,\n type GestureResponderEvent,\n} from \"react-native\";\n\nexport interface ButtonProps {\n title: string;\n onPress: (event: GestureResponderEvent) => void;\n disabled?: boolean;\n}\n\nexport function Button({ title, onPress, disabled = false }: ButtonProps) {\n return (\n <TouchableOpacity\n style={[styles.button, disabled && styles.buttonDisabled]}\n onPress={onPress}\n disabled={disabled}\n activeOpacity={0.7}\n accessibilityRole=\"button\"\n accessibilityState={{ disabled }}\n >\n <Text style={[styles.text, disabled && styles.textDisabled]}>{title}</Text>\n </TouchableOpacity>\n );\n}\n\nconst styles = StyleSheet.create({\n button: {\n backgroundColor: \"#2563eb\",\n paddingVertical: 12,\n paddingHorizontal: 24,\n borderRadius: 8,\n alignItems: \"center\",\n justifyContent: \"center\",\n minWidth: 120,\n },\n buttonDisabled: {\n backgroundColor: \"#93c5fd\",\n opacity: 0.7,\n },\n text: {\n color: \"#ffffff\",\n fontSize: 16,\n fontWeight: \"600\",\n },\n textDisabled: {\n color: \"#e5e7eb\",\n },\n});\n"]}
1
+ {"version":3,"sources":["../src/components/Button.tsx"],"names":["jsx","TouchableOpacity","Text","StyleSheet"],"mappings":";;;;;;AA2BO,SAAS,MAAA,CAAO;AAAA,EACrB,KAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA,GAAW,KAAA;AAAA,EACX,KAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EACA;AACF,CAAA,EAAgB;AACd,EAAA,MAAM,oBACJ,SAAA,IAAa,IAAA,GAAQ,EAAE,SAAA,KAA0C,EAAC;AACpE,EAAA,MAAM,eACJ,aAAA,IAAiB,IAAA,GAAQ,EAAE,SAAA,EAAW,aAAA,KAA8C,EAAC;AAEvF,EAAA,uBACEA,cAAA;AAAA,IAACC,4BAAA;AAAA,IAAA;AAAA,MACC,OAAO,CAAC,MAAA,CAAO,QAAQ,QAAA,IAAY,MAAA,CAAO,gBAAgB,KAAK,CAAA;AAAA,MAC/D,OAAA;AAAA,MACA,QAAA;AAAA,MACA,aAAA,EAAe,GAAA;AAAA,MACf,iBAAA,EAAkB,QAAA;AAAA,MAClB,kBAAA,EAAoB,EAAE,QAAA,EAAS;AAAA,MAC9B,GAAG,iBAAA;AAAA,MAEJ,QAAA,kBAAAD,cAAA;AAAA,QAACE,gBAAA;AAAA,QAAA;AAAA,UACC,OAAO,CAAC,MAAA,CAAO,MAAM,QAAA,IAAY,MAAA,CAAO,cAAc,SAAS,CAAA;AAAA,UAC9D,GAAG,YAAA;AAAA,UAEH,QAAA,EAAA;AAAA;AAAA;AACH;AAAA,GACF;AAEJ;AAEA,IAAM,MAAA,GAASC,uBAAW,MAAA,CAAO;AAAA,EAC/B,MAAA,EAAQ;AAAA,IACN,eAAA,EAAiB,SAAA;AAAA,IACjB,eAAA,EAAiB,EAAA;AAAA,IACjB,iBAAA,EAAmB,EAAA;AAAA,IACnB,YAAA,EAAc,CAAA;AAAA,IACd,UAAA,EAAY,QAAA;AAAA,IACZ,cAAA,EAAgB,QAAA;AAAA,IAChB,QAAA,EAAU;AAAA,GACZ;AAAA,EACA,cAAA,EAAgB;AAAA,IACd,eAAA,EAAiB,SAAA;AAAA,IACjB,OAAA,EAAS;AAAA,GACX;AAAA,EACA,IAAA,EAAM;AAAA,IACJ,KAAA,EAAO,SAAA;AAAA,IACP,QAAA,EAAU,EAAA;AAAA,IACV,UAAA,EAAY;AAAA,GACd;AAAA,EACA,YAAA,EAAc;AAAA,IACZ,KAAA,EAAO;AAAA;AAEX,CAAC,CAAA","file":"index.cjs","sourcesContent":["import {\n StyleSheet,\n Text,\n TouchableOpacity,\n type GestureResponderEvent,\n type StyleProp,\n type TextStyle,\n type ViewStyle,\n} from \"react-native\";\n\nexport interface ButtonProps {\n title: string;\n onPress: (event: GestureResponderEvent) => void;\n disabled?: boolean;\n /** Additional container styles (works on web and native). */\n style?: StyleProp<ViewStyle>;\n /** Additional label styles (works on web and native). */\n textStyle?: StyleProp<TextStyle>;\n /**\n * CSS class names for the container (web via react-native-web, or native with NativeWind).\n * Merged with default styles — use Tailwind utilities in React web apps.\n */\n className?: string;\n /** CSS class names for the label (web via react-native-web, or native with NativeWind). */\n textClassName?: string;\n}\n\nexport function Button({\n title,\n onPress,\n disabled = false,\n style,\n textStyle,\n className,\n textClassName,\n}: ButtonProps) {\n const containerWebProps =\n className != null ? ({ className } as Record<string, unknown>) : {};\n const textWebProps =\n textClassName != null ? ({ className: textClassName } as Record<string, unknown>) : {};\n\n return (\n <TouchableOpacity\n style={[styles.button, disabled && styles.buttonDisabled, style]}\n onPress={onPress}\n disabled={disabled}\n activeOpacity={0.7}\n accessibilityRole=\"button\"\n accessibilityState={{ disabled }}\n {...containerWebProps}\n >\n <Text\n style={[styles.text, disabled && styles.textDisabled, textStyle]}\n {...textWebProps}\n >\n {title}\n </Text>\n </TouchableOpacity>\n );\n}\n\nconst styles = StyleSheet.create({\n button: {\n backgroundColor: \"#2563eb\",\n paddingVertical: 12,\n paddingHorizontal: 24,\n borderRadius: 8,\n alignItems: \"center\",\n justifyContent: \"center\",\n minWidth: 120,\n },\n buttonDisabled: {\n backgroundColor: \"#93c5fd\",\n opacity: 0.7,\n },\n text: {\n color: \"#ffffff\",\n fontSize: 16,\n fontWeight: \"600\",\n },\n textDisabled: {\n color: \"#e5e7eb\",\n },\n});\n"]}
package/dist/index.d.cts CHANGED
@@ -1,11 +1,22 @@
1
1
  import * as react from 'react';
2
- import { GestureResponderEvent } from 'react-native';
2
+ import { GestureResponderEvent, StyleProp, ViewStyle, TextStyle } from 'react-native';
3
3
 
4
4
  interface ButtonProps {
5
5
  title: string;
6
6
  onPress: (event: GestureResponderEvent) => void;
7
7
  disabled?: boolean;
8
+ /** Additional container styles (works on web and native). */
9
+ style?: StyleProp<ViewStyle>;
10
+ /** Additional label styles (works on web and native). */
11
+ textStyle?: StyleProp<TextStyle>;
12
+ /**
13
+ * CSS class names for the container (web via react-native-web, or native with NativeWind).
14
+ * Merged with default styles — use Tailwind utilities in React web apps.
15
+ */
16
+ className?: string;
17
+ /** CSS class names for the label (web via react-native-web, or native with NativeWind). */
18
+ textClassName?: string;
8
19
  }
9
- declare function Button({ title, onPress, disabled }: ButtonProps): react.JSX.Element;
20
+ declare function Button({ title, onPress, disabled, style, textStyle, className, textClassName, }: ButtonProps): react.JSX.Element;
10
21
 
11
22
  export { Button, type ButtonProps };
package/dist/index.d.ts CHANGED
@@ -1,11 +1,22 @@
1
1
  import * as react from 'react';
2
- import { GestureResponderEvent } from 'react-native';
2
+ import { GestureResponderEvent, StyleProp, ViewStyle, TextStyle } from 'react-native';
3
3
 
4
4
  interface ButtonProps {
5
5
  title: string;
6
6
  onPress: (event: GestureResponderEvent) => void;
7
7
  disabled?: boolean;
8
+ /** Additional container styles (works on web and native). */
9
+ style?: StyleProp<ViewStyle>;
10
+ /** Additional label styles (works on web and native). */
11
+ textStyle?: StyleProp<TextStyle>;
12
+ /**
13
+ * CSS class names for the container (web via react-native-web, or native with NativeWind).
14
+ * Merged with default styles — use Tailwind utilities in React web apps.
15
+ */
16
+ className?: string;
17
+ /** CSS class names for the label (web via react-native-web, or native with NativeWind). */
18
+ textClassName?: string;
8
19
  }
9
- declare function Button({ title, onPress, disabled }: ButtonProps): react.JSX.Element;
20
+ declare function Button({ title, onPress, disabled, style, textStyle, className, textClassName, }: ButtonProps): react.JSX.Element;
10
21
 
11
22
  export { Button, type ButtonProps };
package/dist/index.js CHANGED
@@ -2,17 +2,35 @@ import { StyleSheet, TouchableOpacity, Text } from 'react-native';
2
2
  import { jsx } from 'react/jsx-runtime';
3
3
 
4
4
  // src/components/Button.tsx
5
- function Button({ title, onPress, disabled = false }) {
5
+ function Button({
6
+ title,
7
+ onPress,
8
+ disabled = false,
9
+ style,
10
+ textStyle,
11
+ className,
12
+ textClassName
13
+ }) {
14
+ const containerWebProps = className != null ? { className } : {};
15
+ const textWebProps = textClassName != null ? { className: textClassName } : {};
6
16
  return /* @__PURE__ */ jsx(
7
17
  TouchableOpacity,
8
18
  {
9
- style: [styles.button, disabled && styles.buttonDisabled],
19
+ style: [styles.button, disabled && styles.buttonDisabled, style],
10
20
  onPress,
11
21
  disabled,
12
22
  activeOpacity: 0.7,
13
23
  accessibilityRole: "button",
14
24
  accessibilityState: { disabled },
15
- children: /* @__PURE__ */ jsx(Text, { style: [styles.text, disabled && styles.textDisabled], children: title })
25
+ ...containerWebProps,
26
+ children: /* @__PURE__ */ jsx(
27
+ Text,
28
+ {
29
+ style: [styles.text, disabled && styles.textDisabled, textStyle],
30
+ ...textWebProps,
31
+ children: title
32
+ }
33
+ )
16
34
  }
17
35
  );
18
36
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/Button.tsx"],"names":[],"mappings":";;;;AAaO,SAAS,OAAO,EAAE,KAAA,EAAO,OAAA,EAAS,QAAA,GAAW,OAAM,EAAgB;AACxE,EAAA,uBACE,GAAA;AAAA,IAAC,gBAAA;AAAA,IAAA;AAAA,MACC,OAAO,CAAC,MAAA,CAAO,MAAA,EAAQ,QAAA,IAAY,OAAO,cAAc,CAAA;AAAA,MACxD,OAAA;AAAA,MACA,QAAA;AAAA,MACA,aAAA,EAAe,GAAA;AAAA,MACf,iBAAA,EAAkB,QAAA;AAAA,MAClB,kBAAA,EAAoB,EAAE,QAAA,EAAS;AAAA,MAE/B,QAAA,kBAAA,GAAA,CAAC,IAAA,EAAA,EAAK,KAAA,EAAO,CAAC,MAAA,CAAO,MAAM,QAAA,IAAY,MAAA,CAAO,YAAY,CAAA,EAAI,QAAA,EAAA,KAAA,EAAM;AAAA;AAAA,GACtE;AAEJ;AAEA,IAAM,MAAA,GAAS,WAAW,MAAA,CAAO;AAAA,EAC/B,MAAA,EAAQ;AAAA,IACN,eAAA,EAAiB,SAAA;AAAA,IACjB,eAAA,EAAiB,EAAA;AAAA,IACjB,iBAAA,EAAmB,EAAA;AAAA,IACnB,YAAA,EAAc,CAAA;AAAA,IACd,UAAA,EAAY,QAAA;AAAA,IACZ,cAAA,EAAgB,QAAA;AAAA,IAChB,QAAA,EAAU;AAAA,GACZ;AAAA,EACA,cAAA,EAAgB;AAAA,IACd,eAAA,EAAiB,SAAA;AAAA,IACjB,OAAA,EAAS;AAAA,GACX;AAAA,EACA,IAAA,EAAM;AAAA,IACJ,KAAA,EAAO,SAAA;AAAA,IACP,QAAA,EAAU,EAAA;AAAA,IACV,UAAA,EAAY;AAAA,GACd;AAAA,EACA,YAAA,EAAc;AAAA,IACZ,KAAA,EAAO;AAAA;AAEX,CAAC,CAAA","file":"index.js","sourcesContent":["import {\n StyleSheet,\n Text,\n TouchableOpacity,\n type GestureResponderEvent,\n} from \"react-native\";\n\nexport interface ButtonProps {\n title: string;\n onPress: (event: GestureResponderEvent) => void;\n disabled?: boolean;\n}\n\nexport function Button({ title, onPress, disabled = false }: ButtonProps) {\n return (\n <TouchableOpacity\n style={[styles.button, disabled && styles.buttonDisabled]}\n onPress={onPress}\n disabled={disabled}\n activeOpacity={0.7}\n accessibilityRole=\"button\"\n accessibilityState={{ disabled }}\n >\n <Text style={[styles.text, disabled && styles.textDisabled]}>{title}</Text>\n </TouchableOpacity>\n );\n}\n\nconst styles = StyleSheet.create({\n button: {\n backgroundColor: \"#2563eb\",\n paddingVertical: 12,\n paddingHorizontal: 24,\n borderRadius: 8,\n alignItems: \"center\",\n justifyContent: \"center\",\n minWidth: 120,\n },\n buttonDisabled: {\n backgroundColor: \"#93c5fd\",\n opacity: 0.7,\n },\n text: {\n color: \"#ffffff\",\n fontSize: 16,\n fontWeight: \"600\",\n },\n textDisabled: {\n color: \"#e5e7eb\",\n },\n});\n"]}
1
+ {"version":3,"sources":["../src/components/Button.tsx"],"names":[],"mappings":";;;;AA2BO,SAAS,MAAA,CAAO;AAAA,EACrB,KAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA,GAAW,KAAA;AAAA,EACX,KAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EACA;AACF,CAAA,EAAgB;AACd,EAAA,MAAM,oBACJ,SAAA,IAAa,IAAA,GAAQ,EAAE,SAAA,KAA0C,EAAC;AACpE,EAAA,MAAM,eACJ,aAAA,IAAiB,IAAA,GAAQ,EAAE,SAAA,EAAW,aAAA,KAA8C,EAAC;AAEvF,EAAA,uBACE,GAAA;AAAA,IAAC,gBAAA;AAAA,IAAA;AAAA,MACC,OAAO,CAAC,MAAA,CAAO,QAAQ,QAAA,IAAY,MAAA,CAAO,gBAAgB,KAAK,CAAA;AAAA,MAC/D,OAAA;AAAA,MACA,QAAA;AAAA,MACA,aAAA,EAAe,GAAA;AAAA,MACf,iBAAA,EAAkB,QAAA;AAAA,MAClB,kBAAA,EAAoB,EAAE,QAAA,EAAS;AAAA,MAC9B,GAAG,iBAAA;AAAA,MAEJ,QAAA,kBAAA,GAAA;AAAA,QAAC,IAAA;AAAA,QAAA;AAAA,UACC,OAAO,CAAC,MAAA,CAAO,MAAM,QAAA,IAAY,MAAA,CAAO,cAAc,SAAS,CAAA;AAAA,UAC9D,GAAG,YAAA;AAAA,UAEH,QAAA,EAAA;AAAA;AAAA;AACH;AAAA,GACF;AAEJ;AAEA,IAAM,MAAA,GAAS,WAAW,MAAA,CAAO;AAAA,EAC/B,MAAA,EAAQ;AAAA,IACN,eAAA,EAAiB,SAAA;AAAA,IACjB,eAAA,EAAiB,EAAA;AAAA,IACjB,iBAAA,EAAmB,EAAA;AAAA,IACnB,YAAA,EAAc,CAAA;AAAA,IACd,UAAA,EAAY,QAAA;AAAA,IACZ,cAAA,EAAgB,QAAA;AAAA,IAChB,QAAA,EAAU;AAAA,GACZ;AAAA,EACA,cAAA,EAAgB;AAAA,IACd,eAAA,EAAiB,SAAA;AAAA,IACjB,OAAA,EAAS;AAAA,GACX;AAAA,EACA,IAAA,EAAM;AAAA,IACJ,KAAA,EAAO,SAAA;AAAA,IACP,QAAA,EAAU,EAAA;AAAA,IACV,UAAA,EAAY;AAAA,GACd;AAAA,EACA,YAAA,EAAc;AAAA,IACZ,KAAA,EAAO;AAAA;AAEX,CAAC,CAAA","file":"index.js","sourcesContent":["import {\n StyleSheet,\n Text,\n TouchableOpacity,\n type GestureResponderEvent,\n type StyleProp,\n type TextStyle,\n type ViewStyle,\n} from \"react-native\";\n\nexport interface ButtonProps {\n title: string;\n onPress: (event: GestureResponderEvent) => void;\n disabled?: boolean;\n /** Additional container styles (works on web and native). */\n style?: StyleProp<ViewStyle>;\n /** Additional label styles (works on web and native). */\n textStyle?: StyleProp<TextStyle>;\n /**\n * CSS class names for the container (web via react-native-web, or native with NativeWind).\n * Merged with default styles — use Tailwind utilities in React web apps.\n */\n className?: string;\n /** CSS class names for the label (web via react-native-web, or native with NativeWind). */\n textClassName?: string;\n}\n\nexport function Button({\n title,\n onPress,\n disabled = false,\n style,\n textStyle,\n className,\n textClassName,\n}: ButtonProps) {\n const containerWebProps =\n className != null ? ({ className } as Record<string, unknown>) : {};\n const textWebProps =\n textClassName != null ? ({ className: textClassName } as Record<string, unknown>) : {};\n\n return (\n <TouchableOpacity\n style={[styles.button, disabled && styles.buttonDisabled, style]}\n onPress={onPress}\n disabled={disabled}\n activeOpacity={0.7}\n accessibilityRole=\"button\"\n accessibilityState={{ disabled }}\n {...containerWebProps}\n >\n <Text\n style={[styles.text, disabled && styles.textDisabled, textStyle]}\n {...textWebProps}\n >\n {title}\n </Text>\n </TouchableOpacity>\n );\n}\n\nconst styles = StyleSheet.create({\n button: {\n backgroundColor: \"#2563eb\",\n paddingVertical: 12,\n paddingHorizontal: 24,\n borderRadius: 8,\n alignItems: \"center\",\n justifyContent: \"center\",\n minWidth: 120,\n },\n buttonDisabled: {\n backgroundColor: \"#93c5fd\",\n opacity: 0.7,\n },\n text: {\n color: \"#ffffff\",\n fontSize: 16,\n fontWeight: \"600\",\n },\n textDisabled: {\n color: \"#e5e7eb\",\n },\n});\n"]}
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@scripso-homepad/ui",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "type": "module",
5
5
  "description": "Cross-platform UI components for Homepad (React Web + React Native)",
6
6
  "license": "MIT",
7
7
  "author": "Homepad",
8
8
  "repository": {
9
9
  "type": "git",
10
- "url": "https://github.com/Home-Pad/homepad-ui.git"
10
+ "url": "git+https://github.com/Home-Pad/homepad-ui.git"
11
11
  },
12
12
  "publishConfig": {
13
13
  "access": "public"
@@ -32,3 +32,35 @@ export const LongLabel: Story = {
32
32
  title: "Continue to next step",
33
33
  },
34
34
  };
35
+
36
+ export const CustomStyle: Story = {
37
+ args: {
38
+ title: "Custom styles",
39
+ style: {
40
+ backgroundColor: "#dc2626",
41
+ borderRadius: 999,
42
+ paddingHorizontal: 32,
43
+ },
44
+ textStyle: {
45
+ fontSize: 14,
46
+ letterSpacing: 1,
47
+ textTransform: "uppercase",
48
+ },
49
+ },
50
+ };
51
+
52
+ export const WithClassName: Story = {
53
+ args: {
54
+ title: "Tailwind classes",
55
+ className: "rounded-full bg-violet-600 px-8 shadow-lg",
56
+ textClassName: "text-sm font-bold uppercase tracking-wide",
57
+ },
58
+ parameters: {
59
+ docs: {
60
+ description: {
61
+ story:
62
+ "Pass Tailwind utility classes via className. Requires Tailwind in your web app (or NativeWind on native).",
63
+ },
64
+ },
65
+ },
66
+ };
@@ -3,25 +3,58 @@ import {
3
3
  Text,
4
4
  TouchableOpacity,
5
5
  type GestureResponderEvent,
6
+ type StyleProp,
7
+ type TextStyle,
8
+ type ViewStyle,
6
9
  } from "react-native";
7
10
 
8
11
  export interface ButtonProps {
9
12
  title: string;
10
13
  onPress: (event: GestureResponderEvent) => void;
11
14
  disabled?: boolean;
15
+ /** Additional container styles (works on web and native). */
16
+ style?: StyleProp<ViewStyle>;
17
+ /** Additional label styles (works on web and native). */
18
+ textStyle?: StyleProp<TextStyle>;
19
+ /**
20
+ * CSS class names for the container (web via react-native-web, or native with NativeWind).
21
+ * Merged with default styles — use Tailwind utilities in React web apps.
22
+ */
23
+ className?: string;
24
+ /** CSS class names for the label (web via react-native-web, or native with NativeWind). */
25
+ textClassName?: string;
12
26
  }
13
27
 
14
- export function Button({ title, onPress, disabled = false }: ButtonProps) {
28
+ export function Button({
29
+ title,
30
+ onPress,
31
+ disabled = false,
32
+ style,
33
+ textStyle,
34
+ className,
35
+ textClassName,
36
+ }: ButtonProps) {
37
+ const containerWebProps =
38
+ className != null ? ({ className } as Record<string, unknown>) : {};
39
+ const textWebProps =
40
+ textClassName != null ? ({ className: textClassName } as Record<string, unknown>) : {};
41
+
15
42
  return (
16
43
  <TouchableOpacity
17
- style={[styles.button, disabled && styles.buttonDisabled]}
44
+ style={[styles.button, disabled && styles.buttonDisabled, style]}
18
45
  onPress={onPress}
19
46
  disabled={disabled}
20
47
  activeOpacity={0.7}
21
48
  accessibilityRole="button"
22
49
  accessibilityState={{ disabled }}
50
+ {...containerWebProps}
23
51
  >
24
- <Text style={[styles.text, disabled && styles.textDisabled]}>{title}</Text>
52
+ <Text
53
+ style={[styles.text, disabled && styles.textDisabled, textStyle]}
54
+ {...textWebProps}
55
+ >
56
+ {title}
57
+ </Text>
25
58
  </TouchableOpacity>
26
59
  );
27
60
  }