@scripso-homepad/ui 0.3.0 → 0.3.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/README.md CHANGED
@@ -115,6 +115,8 @@ export function Example() {
115
115
 
116
116
  #### Tailwind classes (React web)
117
117
 
118
+ On web, `className` is applied to real DOM elements (`<button>` / `<span>`), so Tailwind utilities work with Vite or Next.js:
119
+
118
120
  ```tsx
119
121
  <Button
120
122
  title="Save"
@@ -124,7 +126,7 @@ export function Example() {
124
126
  />
125
127
  ```
126
128
 
127
- Default package styles are merged with your `style` / `className` values.
129
+ > **Note:** `react-native-web` does not forward `className` to the DOM by default. This package renders native HTML elements on web so Tailwind classes appear in the DOM. On React Native, use `style` or [NativeWind](https://www.nativewind.dev/) with `cssInterop`.
128
130
 
129
131
  ## Development
130
132
 
@@ -153,7 +155,7 @@ npm run build-storybook
153
155
 
154
156
  ## Publishing
155
157
 
156
- See [PUBLISHING.md](./PUBLISHING.md) for release workflow details.
158
+ Push to `main` — CI auto-bumps the patch version and publishes to npm. See [PUBLISHING.md](./PUBLISHING.md).
157
159
 
158
160
  ## Architecture
159
161
 
package/dist/index.cjs CHANGED
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
 
3
+ var react = require('react');
3
4
  var reactNative = require('react-native');
4
5
  var jsxRuntime = require('react/jsx-runtime');
5
6
 
@@ -13,26 +14,41 @@ function Button({
13
14
  className,
14
15
  textClassName
15
16
  }) {
16
- const containerWebProps = className != null ? { className } : {};
17
- const textWebProps = textClassName != null ? { className: textClassName } : {};
17
+ const containerStyle = [styles.button, disabled && styles.buttonDisabled, style];
18
+ const labelStyle = [styles.text, disabled && styles.textDisabled, textStyle];
19
+ if (reactNative.Platform.OS === "web") {
20
+ return react.createElement(
21
+ "button",
22
+ {
23
+ type: "button",
24
+ className,
25
+ style: reactNative.StyleSheet.flatten(containerStyle),
26
+ disabled,
27
+ onClick: (event) => {
28
+ onPress(event);
29
+ },
30
+ "aria-disabled": disabled
31
+ },
32
+ react.createElement(
33
+ "span",
34
+ {
35
+ className: textClassName,
36
+ style: reactNative.StyleSheet.flatten(labelStyle)
37
+ },
38
+ title
39
+ )
40
+ );
41
+ }
18
42
  return /* @__PURE__ */ jsxRuntime.jsx(
19
43
  reactNative.TouchableOpacity,
20
44
  {
21
- style: [styles.button, disabled && styles.buttonDisabled, style],
45
+ style: containerStyle,
22
46
  onPress,
23
47
  disabled,
24
48
  activeOpacity: 0.7,
25
49
  accessibilityRole: "button",
26
50
  accessibilityState: { disabled },
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
- )
51
+ children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: labelStyle, children: title })
36
52
  }
37
53
  );
38
54
  }
@@ -44,7 +60,8 @@ var styles = reactNative.StyleSheet.create({
44
60
  borderRadius: 8,
45
61
  alignItems: "center",
46
62
  justifyContent: "center",
47
- minWidth: 120
63
+ minWidth: 120,
64
+ borderWidth: 0
48
65
  },
49
66
  buttonDisabled: {
50
67
  backgroundColor: "#93c5fd",
@@ -1 +1 @@
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"]}
1
+ {"version":3,"sources":["../src/components/Button.tsx"],"names":["Platform","createElement","StyleSheet","jsx","TouchableOpacity","Text"],"mappings":";;;;;;;AAkCO,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,iBAAiB,CAAC,MAAA,CAAO,QAAQ,QAAA,IAAY,MAAA,CAAO,gBAAgB,KAAK,CAAA;AAC/E,EAAA,MAAM,aAAa,CAAC,MAAA,CAAO,MAAM,QAAA,IAAY,MAAA,CAAO,cAAc,SAAS,CAAA;AAE3E,EAAA,IAAIA,oBAAA,CAAS,OAAO,KAAA,EAAO;AACzB,IAAA,OAAOC,mBAAA;AAAA,MACL,QAAA;AAAA,MACA;AAAA,QACE,IAAA,EAAM,QAAA;AAAA,QACN,SAAA;AAAA,QACA,KAAA,EAAOC,sBAAA,CAAW,OAAA,CAAQ,cAAc,CAAA;AAAA,QACxC,QAAA;AAAA,QACA,OAAA,EAAS,CAAC,KAAA,KAA+C;AACvD,UAAA,OAAA,CAAQ,KAAyC,CAAA;AAAA,QACnD,CAAA;AAAA,QACA,eAAA,EAAiB;AAAA,OACnB;AAAA,MACAD,mBAAA;AAAA,QACE,MAAA;AAAA,QACA;AAAA,UACE,SAAA,EAAW,aAAA;AAAA,UACX,KAAA,EAAOC,sBAAA,CAAW,OAAA,CAAQ,UAAU;AAAA,SACtC;AAAA,QACA;AAAA;AACF,KACF;AAAA,EACF;AAEA,EAAA,uBACEC,cAAA;AAAA,IAACC,4BAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,cAAA;AAAA,MACP,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,UAAA,EAAa,QAAA,EAAA,KAAA,EAAM;AAAA;AAAA,GAClC;AAEJ;AAEA,IAAM,MAAA,GAASH,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,GAAA;AAAA,IACV,WAAA,EAAa;AAAA,GACf;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 React, { createElement } from \"react\";\nimport {\n Platform,\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.\n * On web: applied to the underlying `<button>` element (Tailwind works).\n * On native: ignored unless using NativeWind with cssInterop.\n */\n className?: string;\n /**\n * CSS class names for the label.\n * On web: applied to the underlying `<span>` element (Tailwind works).\n * On native: ignored unless using NativeWind with cssInterop.\n */\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 containerStyle = [styles.button, disabled && styles.buttonDisabled, style];\n const labelStyle = [styles.text, disabled && styles.textDisabled, textStyle];\n\n if (Platform.OS === \"web\") {\n return createElement(\n \"button\",\n {\n type: \"button\",\n className,\n style: StyleSheet.flatten(containerStyle),\n disabled,\n onClick: (event: React.MouseEvent<HTMLButtonElement>) => {\n onPress(event as unknown as GestureResponderEvent);\n },\n \"aria-disabled\": disabled,\n },\n createElement(\n \"span\",\n {\n className: textClassName,\n style: StyleSheet.flatten(labelStyle),\n },\n title,\n ),\n );\n }\n\n return (\n <TouchableOpacity\n style={containerStyle}\n onPress={onPress}\n disabled={disabled}\n activeOpacity={0.7}\n accessibilityRole=\"button\"\n accessibilityState={{ disabled }}\n >\n <Text style={labelStyle}>{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 borderWidth: 0,\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,4 +1,4 @@
1
- import * as react from 'react';
1
+ import React from 'react';
2
2
  import { GestureResponderEvent, StyleProp, ViewStyle, TextStyle } from 'react-native';
3
3
 
4
4
  interface ButtonProps {
@@ -10,13 +10,18 @@ interface ButtonProps {
10
10
  /** Additional label styles (works on web and native). */
11
11
  textStyle?: StyleProp<TextStyle>;
12
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.
13
+ * CSS class names for the container.
14
+ * On web: applied to the underlying `<button>` element (Tailwind works).
15
+ * On native: ignored unless using NativeWind with cssInterop.
15
16
  */
16
17
  className?: string;
17
- /** CSS class names for the label (web via react-native-web, or native with NativeWind). */
18
+ /**
19
+ * CSS class names for the label.
20
+ * On web: applied to the underlying `<span>` element (Tailwind works).
21
+ * On native: ignored unless using NativeWind with cssInterop.
22
+ */
18
23
  textClassName?: string;
19
24
  }
20
- declare function Button({ title, onPress, disabled, style, textStyle, className, textClassName, }: ButtonProps): react.JSX.Element;
25
+ declare function Button({ title, onPress, disabled, style, textStyle, className, textClassName, }: ButtonProps): React.JSX.Element;
21
26
 
22
27
  export { Button, type ButtonProps };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import * as react from 'react';
1
+ import React from 'react';
2
2
  import { GestureResponderEvent, StyleProp, ViewStyle, TextStyle } from 'react-native';
3
3
 
4
4
  interface ButtonProps {
@@ -10,13 +10,18 @@ interface ButtonProps {
10
10
  /** Additional label styles (works on web and native). */
11
11
  textStyle?: StyleProp<TextStyle>;
12
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.
13
+ * CSS class names for the container.
14
+ * On web: applied to the underlying `<button>` element (Tailwind works).
15
+ * On native: ignored unless using NativeWind with cssInterop.
15
16
  */
16
17
  className?: string;
17
- /** CSS class names for the label (web via react-native-web, or native with NativeWind). */
18
+ /**
19
+ * CSS class names for the label.
20
+ * On web: applied to the underlying `<span>` element (Tailwind works).
21
+ * On native: ignored unless using NativeWind with cssInterop.
22
+ */
18
23
  textClassName?: string;
19
24
  }
20
- declare function Button({ title, onPress, disabled, style, textStyle, className, textClassName, }: ButtonProps): react.JSX.Element;
25
+ declare function Button({ title, onPress, disabled, style, textStyle, className, textClassName, }: ButtonProps): React.JSX.Element;
21
26
 
22
27
  export { Button, type ButtonProps };
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
- import { StyleSheet, TouchableOpacity, Text } from 'react-native';
1
+ import { createElement } from 'react';
2
+ import { StyleSheet, Platform, TouchableOpacity, Text } from 'react-native';
2
3
  import { jsx } from 'react/jsx-runtime';
3
4
 
4
5
  // src/components/Button.tsx
@@ -11,26 +12,41 @@ function Button({
11
12
  className,
12
13
  textClassName
13
14
  }) {
14
- const containerWebProps = className != null ? { className } : {};
15
- const textWebProps = textClassName != null ? { className: textClassName } : {};
15
+ const containerStyle = [styles.button, disabled && styles.buttonDisabled, style];
16
+ const labelStyle = [styles.text, disabled && styles.textDisabled, textStyle];
17
+ if (Platform.OS === "web") {
18
+ return createElement(
19
+ "button",
20
+ {
21
+ type: "button",
22
+ className,
23
+ style: StyleSheet.flatten(containerStyle),
24
+ disabled,
25
+ onClick: (event) => {
26
+ onPress(event);
27
+ },
28
+ "aria-disabled": disabled
29
+ },
30
+ createElement(
31
+ "span",
32
+ {
33
+ className: textClassName,
34
+ style: StyleSheet.flatten(labelStyle)
35
+ },
36
+ title
37
+ )
38
+ );
39
+ }
16
40
  return /* @__PURE__ */ jsx(
17
41
  TouchableOpacity,
18
42
  {
19
- style: [styles.button, disabled && styles.buttonDisabled, style],
43
+ style: containerStyle,
20
44
  onPress,
21
45
  disabled,
22
46
  activeOpacity: 0.7,
23
47
  accessibilityRole: "button",
24
48
  accessibilityState: { disabled },
25
- ...containerWebProps,
26
- children: /* @__PURE__ */ jsx(
27
- Text,
28
- {
29
- style: [styles.text, disabled && styles.textDisabled, textStyle],
30
- ...textWebProps,
31
- children: title
32
- }
33
- )
49
+ children: /* @__PURE__ */ jsx(Text, { style: labelStyle, children: title })
34
50
  }
35
51
  );
36
52
  }
@@ -42,7 +58,8 @@ var styles = StyleSheet.create({
42
58
  borderRadius: 8,
43
59
  alignItems: "center",
44
60
  justifyContent: "center",
45
- minWidth: 120
61
+ minWidth: 120,
62
+ borderWidth: 0
46
63
  },
47
64
  buttonDisabled: {
48
65
  backgroundColor: "#93c5fd",
package/dist/index.js.map CHANGED
@@ -1 +1 @@
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"]}
1
+ {"version":3,"sources":["../src/components/Button.tsx"],"names":[],"mappings":";;;;;AAkCO,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,iBAAiB,CAAC,MAAA,CAAO,QAAQ,QAAA,IAAY,MAAA,CAAO,gBAAgB,KAAK,CAAA;AAC/E,EAAA,MAAM,aAAa,CAAC,MAAA,CAAO,MAAM,QAAA,IAAY,MAAA,CAAO,cAAc,SAAS,CAAA;AAE3E,EAAA,IAAI,QAAA,CAAS,OAAO,KAAA,EAAO;AACzB,IAAA,OAAO,aAAA;AAAA,MACL,QAAA;AAAA,MACA;AAAA,QACE,IAAA,EAAM,QAAA;AAAA,QACN,SAAA;AAAA,QACA,KAAA,EAAO,UAAA,CAAW,OAAA,CAAQ,cAAc,CAAA;AAAA,QACxC,QAAA;AAAA,QACA,OAAA,EAAS,CAAC,KAAA,KAA+C;AACvD,UAAA,OAAA,CAAQ,KAAyC,CAAA;AAAA,QACnD,CAAA;AAAA,QACA,eAAA,EAAiB;AAAA,OACnB;AAAA,MACA,aAAA;AAAA,QACE,MAAA;AAAA,QACA;AAAA,UACE,SAAA,EAAW,aAAA;AAAA,UACX,KAAA,EAAO,UAAA,CAAW,OAAA,CAAQ,UAAU;AAAA,SACtC;AAAA,QACA;AAAA;AACF,KACF;AAAA,EACF;AAEA,EAAA,uBACE,GAAA;AAAA,IAAC,gBAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,cAAA;AAAA,MACP,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,UAAA,EAAa,QAAA,EAAA,KAAA,EAAM;AAAA;AAAA,GAClC;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,GAAA;AAAA,IACV,WAAA,EAAa;AAAA,GACf;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 React, { createElement } from \"react\";\nimport {\n Platform,\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.\n * On web: applied to the underlying `<button>` element (Tailwind works).\n * On native: ignored unless using NativeWind with cssInterop.\n */\n className?: string;\n /**\n * CSS class names for the label.\n * On web: applied to the underlying `<span>` element (Tailwind works).\n * On native: ignored unless using NativeWind with cssInterop.\n */\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 containerStyle = [styles.button, disabled && styles.buttonDisabled, style];\n const labelStyle = [styles.text, disabled && styles.textDisabled, textStyle];\n\n if (Platform.OS === \"web\") {\n return createElement(\n \"button\",\n {\n type: \"button\",\n className,\n style: StyleSheet.flatten(containerStyle),\n disabled,\n onClick: (event: React.MouseEvent<HTMLButtonElement>) => {\n onPress(event as unknown as GestureResponderEvent);\n },\n \"aria-disabled\": disabled,\n },\n createElement(\n \"span\",\n {\n className: textClassName,\n style: StyleSheet.flatten(labelStyle),\n },\n title,\n ),\n );\n }\n\n return (\n <TouchableOpacity\n style={containerStyle}\n onPress={onPress}\n disabled={disabled}\n activeOpacity={0.7}\n accessibilityRole=\"button\"\n accessibilityState={{ disabled }}\n >\n <Text style={labelStyle}>{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 borderWidth: 0,\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,6 +1,6 @@
1
1
  {
2
2
  "name": "@scripso-homepad/ui",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "type": "module",
5
5
  "description": "Cross-platform UI components for Homepad (React Web + React Native)",
6
6
  "license": "MIT",
@@ -35,18 +35,13 @@
35
35
  "clean": "rm -rf dist",
36
36
  "storybook": "storybook dev -p 6006",
37
37
  "build-storybook": "storybook build",
38
- "prepublishOnly": "npm run build",
39
- "changeset": "changeset",
40
- "version-packages": "changeset version",
41
- "release": "npm run build && changeset publish"
38
+ "prepublishOnly": "npm run build"
42
39
  },
43
40
  "peerDependencies": {
44
41
  "react": ">=18",
45
42
  "react-native": ">=0.74"
46
43
  },
47
44
  "devDependencies": {
48
- "@changesets/changelog-github": "^0.5.0",
49
- "@changesets/cli": "^2.27.10",
50
45
  "@eslint/js": "^9.17.0",
51
46
  "@storybook/addon-essentials": "^8.4.7",
52
47
  "@storybook/addon-interactions": "^8.4.7",
@@ -1,4 +1,6 @@
1
+ import React, { createElement } from "react";
1
2
  import {
3
+ Platform,
2
4
  StyleSheet,
3
5
  Text,
4
6
  TouchableOpacity,
@@ -17,11 +19,16 @@ export interface ButtonProps {
17
19
  /** Additional label styles (works on web and native). */
18
20
  textStyle?: StyleProp<TextStyle>;
19
21
  /**
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
+ * CSS class names for the container.
23
+ * On web: applied to the underlying `<button>` element (Tailwind works).
24
+ * On native: ignored unless using NativeWind with cssInterop.
22
25
  */
23
26
  className?: string;
24
- /** CSS class names for the label (web via react-native-web, or native with NativeWind). */
27
+ /**
28
+ * CSS class names for the label.
29
+ * On web: applied to the underlying `<span>` element (Tailwind works).
30
+ * On native: ignored unless using NativeWind with cssInterop.
31
+ */
25
32
  textClassName?: string;
26
33
  }
27
34
 
@@ -34,27 +41,43 @@ export function Button({
34
41
  className,
35
42
  textClassName,
36
43
  }: ButtonProps) {
37
- const containerWebProps =
38
- className != null ? ({ className } as Record<string, unknown>) : {};
39
- const textWebProps =
40
- textClassName != null ? ({ className: textClassName } as Record<string, unknown>) : {};
44
+ const containerStyle = [styles.button, disabled && styles.buttonDisabled, style];
45
+ const labelStyle = [styles.text, disabled && styles.textDisabled, textStyle];
46
+
47
+ if (Platform.OS === "web") {
48
+ return createElement(
49
+ "button",
50
+ {
51
+ type: "button",
52
+ className,
53
+ style: StyleSheet.flatten(containerStyle),
54
+ disabled,
55
+ onClick: (event: React.MouseEvent<HTMLButtonElement>) => {
56
+ onPress(event as unknown as GestureResponderEvent);
57
+ },
58
+ "aria-disabled": disabled,
59
+ },
60
+ createElement(
61
+ "span",
62
+ {
63
+ className: textClassName,
64
+ style: StyleSheet.flatten(labelStyle),
65
+ },
66
+ title,
67
+ ),
68
+ );
69
+ }
41
70
 
42
71
  return (
43
72
  <TouchableOpacity
44
- style={[styles.button, disabled && styles.buttonDisabled, style]}
73
+ style={containerStyle}
45
74
  onPress={onPress}
46
75
  disabled={disabled}
47
76
  activeOpacity={0.7}
48
77
  accessibilityRole="button"
49
78
  accessibilityState={{ disabled }}
50
- {...containerWebProps}
51
79
  >
52
- <Text
53
- style={[styles.text, disabled && styles.textDisabled, textStyle]}
54
- {...textWebProps}
55
- >
56
- {title}
57
- </Text>
80
+ <Text style={labelStyle}>{title}</Text>
58
81
  </TouchableOpacity>
59
82
  );
60
83
  }
@@ -68,6 +91,7 @@ const styles = StyleSheet.create({
68
91
  alignItems: "center",
69
92
  justifyContent: "center",
70
93
  minWidth: 120,
94
+ borderWidth: 0,
71
95
  },
72
96
  buttonDisabled: {
73
97
  backgroundColor: "#93c5fd",