@ecohouse/ui 0.1.0 → 0.1.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 (98) hide show
  1. package/README.md +238 -36
  2. package/dist/index.cjs +649 -314
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +181 -258
  5. package/dist/index.d.ts +181 -258
  6. package/dist/index.js +626 -304
  7. package/dist/index.js.map +1 -1
  8. package/package.json +4 -7
  9. package/src/components/Button/Button.stories.tsx +98 -0
  10. package/src/components/{Button.tsx → Button/Button.tsx} +39 -71
  11. package/src/components/Button/index.ts +2 -0
  12. package/src/components/Input/Input.stories.tsx +118 -0
  13. package/src/components/Input/Input.tsx +327 -0
  14. package/src/components/Input/index.ts +2 -0
  15. package/src/components/index.ts +5 -0
  16. package/src/icons/{ArrowUpRightIcon.tsx → ArrowRight/ArrowRightIcon.tsx} +8 -7
  17. package/src/icons/{ArrowUpRightIcon.web.tsx → ArrowRight/ArrowRightIcon.web.tsx} +8 -7
  18. package/src/icons/ArrowRight/arrowRightPath.ts +2 -0
  19. package/src/icons/ArrowRight/index.ts +1 -0
  20. package/src/icons/Bag/BagIcon.tsx +20 -0
  21. package/src/icons/Bag/BagIcon.web.tsx +26 -0
  22. package/src/icons/Bag/bagPath.ts +2 -0
  23. package/src/icons/Bag/index.ts +1 -0
  24. package/src/icons/Bell/BellIcon.tsx +20 -0
  25. package/src/icons/Bell/BellIcon.web.tsx +26 -0
  26. package/src/icons/Bell/bellPath.ts +2 -0
  27. package/src/icons/Bell/index.ts +1 -0
  28. package/src/icons/Building/BuildingIcon.tsx +20 -0
  29. package/src/icons/Building/BuildingIcon.web.tsx +26 -0
  30. package/src/icons/Building/buildingPath.ts +2 -0
  31. package/src/icons/Building/index.ts +1 -0
  32. package/src/icons/Camera/CameraIcon.tsx +20 -0
  33. package/src/icons/Camera/CameraIcon.web.tsx +26 -0
  34. package/src/icons/Camera/cameraPath.ts +2 -0
  35. package/src/icons/Camera/index.ts +1 -0
  36. package/src/icons/CheckBadge/CheckBadgeIcon.tsx +20 -0
  37. package/src/icons/CheckBadge/CheckBadgeIcon.web.tsx +26 -0
  38. package/src/icons/CheckBadge/checkBadgePath.ts +2 -0
  39. package/src/icons/CheckBadge/index.ts +1 -0
  40. package/src/icons/Clock/ClockIcon.tsx +20 -0
  41. package/src/icons/Clock/ClockIcon.web.tsx +26 -0
  42. package/src/icons/Clock/clockPath.ts +2 -0
  43. package/src/icons/Clock/index.ts +1 -0
  44. package/src/icons/Facebook/FacebookIcon.tsx +14 -0
  45. package/src/icons/Facebook/FacebookIcon.web.tsx +20 -0
  46. package/src/icons/Facebook/facebookPath.ts +2 -0
  47. package/src/icons/Facebook/index.ts +1 -0
  48. package/src/icons/Home/HomeIcon.tsx +20 -0
  49. package/src/icons/Home/HomeIcon.web.tsx +26 -0
  50. package/src/icons/Home/homePath.ts +2 -0
  51. package/src/icons/Home/index.ts +1 -0
  52. package/src/icons/Icon.tsx +11 -0
  53. package/src/icons/Icons.stories.tsx +174 -0
  54. package/src/icons/Instagram/InstagramIcon.tsx +14 -0
  55. package/src/icons/Instagram/InstagramIcon.web.tsx +20 -0
  56. package/src/icons/Instagram/index.ts +1 -0
  57. package/src/icons/Instagram/instagramPath.ts +2 -0
  58. package/src/icons/Key/KeyIcon.tsx +20 -0
  59. package/src/icons/Key/KeyIcon.web.tsx +26 -0
  60. package/src/icons/Key/index.ts +1 -0
  61. package/src/icons/Key/keyPath.ts +2 -0
  62. package/src/icons/LinkedIn/LinkedInIcon.tsx +14 -0
  63. package/src/icons/LinkedIn/LinkedInIcon.web.tsx +20 -0
  64. package/src/icons/LinkedIn/index.ts +1 -0
  65. package/src/icons/LinkedIn/linkedinPath.ts +2 -0
  66. package/src/icons/Mail/MailIcon.tsx +20 -0
  67. package/src/icons/Mail/MailIcon.web.tsx +26 -0
  68. package/src/icons/Mail/index.ts +1 -0
  69. package/src/icons/Mail/mailPath.ts +2 -0
  70. package/src/icons/Navigate/NavigateIcon.tsx +20 -0
  71. package/src/icons/Navigate/NavigateIcon.web.tsx +26 -0
  72. package/src/icons/Navigate/index.ts +1 -0
  73. package/src/icons/Navigate/navigatePath.ts +2 -0
  74. package/src/icons/Phone/PhoneIcon.tsx +20 -0
  75. package/src/icons/Phone/PhoneIcon.web.tsx +26 -0
  76. package/src/icons/Phone/index.ts +1 -0
  77. package/src/icons/Phone/phonePath.ts +2 -0
  78. package/src/icons/Show/ShowIcon.tsx +33 -0
  79. package/src/icons/Show/ShowIcon.web.tsx +39 -0
  80. package/src/icons/Show/index.ts +1 -0
  81. package/src/icons/Show/showPath.ts +6 -0
  82. package/src/icons/User/UserIcon.tsx +26 -0
  83. package/src/icons/User/UserIcon.web.tsx +32 -0
  84. package/src/icons/User/index.ts +1 -0
  85. package/src/icons/User/userPath.ts +3 -0
  86. package/src/icons/index.ts +24 -0
  87. package/src/icons/registry.ts +58 -0
  88. package/src/icons/types.ts +9 -0
  89. package/src/index.ts +37 -21
  90. package/src/theme/colors.test.ts +12 -0
  91. package/src/theme/colors.ts +46 -0
  92. package/src/theme/index.ts +4 -0
  93. package/src/theme/typography.ts +46 -0
  94. package/src/web/styles/typography.css +8 -90
  95. package/src/components/Button.stories.tsx +0 -135
  96. package/src/icons/arrowUpRightPath.ts +0 -1
  97. package/src/theme/tokens.test.ts +0 -10
  98. package/src/theme/tokens.ts +0 -286
package/README.md CHANGED
@@ -1,58 +1,260 @@
1
- # eco-cottage-ui (`@ecohouse/ui`)
1
+ # @ecohouse/ui
2
2
 
3
- Presentation-only universal UI package for EcoHouse customer web and mobile.
3
+ Cross-platform UI component library for EcoHouse. Built with React Native primitives — works in **Expo / React Native** and **React web** (via [react-native-web](https://necolas.github.io/react-native-web/)).
4
4
 
5
- ## Purpose
5
+ ## Components
6
6
 
7
- Reusable design tokens and cross-platform components built with **React Native primitives** + **React Native Web**, documented in Storybook.
7
+ | Component | Description |
8
+ | --------- | --------------------------------------------------------------------------- |
9
+ | `Button` | Pill CTA — `primary` / `secondary`, sizes `lg` / `sm`, optional arrow badge |
10
+ | `Input` | Text field with label, hint, left/right icons, error & disabled states |
11
+ | `Icon` | Dynamic icon by name from the registry (`<Icon name="user" />`) |
8
12
 
9
- ## Package rules (MUST)
13
+ Named icon exports (`UserIcon`, `HomeIcon`, …) are also available. Full icon list: [`docs/icons.md`](./docs/icons.md).
10
14
 
11
- This package is **presentation-only**:
15
+ ## Installation
12
16
 
13
- - No backend API clients
14
- - No application secrets
15
- - No provider SDKs
16
- - No EcoHouse booking / domain business logic
17
+ ### React Native (Expo)
17
18
 
18
- Application routes, API calls, and booking logic stay in `eco-cottage-web` and `eco-cottage-mobile`. Consumers install published npm versions only (exact pin in `package-lock.json`).
19
+ ```bash
20
+ npm install @ecohouse/ui react-native-svg
21
+ ```
22
+
23
+ Expo resolves the package from TypeScript source (`react-native` export). Icons use `react-native-svg` on native.
24
+
25
+ ### React web
26
+
27
+ ```bash
28
+ npm install @ecohouse/ui react-native react-native-web react-native-svg
29
+ ```
30
+
31
+ Configure your bundler to alias `react-native` → `react-native-web` and prefer `.web.tsx` icon files.
32
+
33
+ #### Vite
34
+
35
+ ```ts
36
+ // vite.config.ts
37
+ import path from "node:path";
38
+ import { defineConfig } from "vite";
39
+ import react from "@vitejs/plugin-react";
40
+
41
+ export default defineConfig({
42
+ plugins: [
43
+ react({
44
+ include: [/\.[tj]sx?$/, /node_modules\/(@ecohouse\/ui|react-native|react-native-web)/],
45
+ }),
46
+ ],
47
+ resolve: {
48
+ dedupe: ["react", "react-dom", "react-native", "react-native-web"],
49
+ alias: {
50
+ "react-native": "react-native-web",
51
+ react: path.resolve(__dirname, "node_modules/react"),
52
+ "react-dom": path.resolve(__dirname, "node_modules/react-dom"),
53
+ "react/jsx-runtime": path.resolve(__dirname, "node_modules/react/jsx-runtime"),
54
+ "react/jsx-dev-runtime": path.resolve(__dirname, "node_modules/react/jsx-dev-runtime"),
55
+ },
56
+ extensions: [".web.tsx", ".web.ts", ".web.jsx", ".web.js", ".tsx", ".ts", ".jsx", ".js"],
57
+ },
58
+ optimizeDeps: {
59
+ include: ["react", "react-dom", "react/jsx-runtime", "react-native-web"],
60
+ exclude: ["react-native-svg", "@ecohouse/ui"],
61
+ esbuildOptions: {
62
+ resolveExtensions: [
63
+ ".web.js",
64
+ ".web.jsx",
65
+ ".web.ts",
66
+ ".web.tsx",
67
+ ".js",
68
+ ".jsx",
69
+ ".ts",
70
+ ".tsx",
71
+ ],
72
+ },
73
+ },
74
+ });
75
+ ```
76
+
77
+ #### Next.js
78
+
79
+ ```js
80
+ // next.config.js / next.config.ts
81
+ module.exports = {
82
+ transpilePackages: ["@ecohouse/ui", "react-native-web", "react-native-svg"],
83
+ webpack: (config) => {
84
+ config.resolve.alias = {
85
+ ...config.resolve.alias,
86
+ "react-native$": "react-native-web",
87
+ };
88
+ config.resolve.extensions = [
89
+ ".web.js",
90
+ ".web.jsx",
91
+ ".web.ts",
92
+ ".web.tsx",
93
+ ...config.resolve.extensions,
94
+ ];
95
+ return config;
96
+ },
97
+ };
98
+ ```
99
+
100
+ Optional web typography helpers:
101
+
102
+ ```ts
103
+ import "@ecohouse/ui/web/typography.css";
104
+ ```
105
+
106
+ ## Usage
107
+
108
+ ```tsx
109
+ import { Button, Input, Icon, UserIcon, ShowIcon, colors } from "@ecohouse/ui";
110
+
111
+ export function Example() {
112
+ return (
113
+ <>
114
+ <Button title="Continue" variant="primary" size="lg" showIcon onPress={() => {}} />
115
+
116
+ <Input
117
+ label="Password"
118
+ placeholder="••••••••"
119
+ hint="Use at least 8 characters"
120
+ secureTextEntry
121
+ leftIcon={<UserIcon size={20} />}
122
+ rightIcon={<ShowIcon size={20} />}
123
+ onRightIconPress={() => {}}
124
+ onChangeText={() => {}}
125
+ />
126
+
127
+ <Icon name="home" size={20} color={colors.white} />
128
+ </>
129
+ );
130
+ }
131
+ ```
132
+
133
+ Same API on web and mobile.
134
+
135
+ ## API
136
+
137
+ ### `Button`
138
+
139
+ Pill CTA — sizes `lg` (44px) / `sm` (32px). Secondary fill uses `colors.grey500`.
19
140
 
20
- ## Stack (Architecture v1.4 §§4.4, 5)
141
+ | Prop | Type | Default | Description |
142
+ | ---------- | -------------------------- | ----------- | ----------------- |
143
+ | `title` | `string` | — | Label text |
144
+ | `onPress` | `(event) => void` | required | Press handler |
145
+ | `variant` | `"primary" \| "secondary"` | `"primary"` | Fill style |
146
+ | `size` | `"lg" \| "sm"` | `"lg"` | Height / padding |
147
+ | `showIcon` | `boolean` | `false` | Right arrow badge |
148
+ | `icon` | `ReactNode` | — | Custom badge icon |
149
+ | `disabled` | `boolean` | `false` | 60% opacity |
21
150
 
22
- | Area | Technology |
23
- | ------------- | ----------------------------------------- |
24
- | Package | TypeScript, tsup |
25
- | UI | React Native primitives, React Native Web |
26
- | Docs | Storybook |
27
- | Lint / format | ESLint, Prettier |
28
- | Tests | Vitest |
29
- | Commits | Conventional Commits (commitlint + husky) |
151
+ ```tsx
152
+ <Button title="Continue" variant="primary" size="lg" showIcon onPress={() => {}} />
153
+ <Button title="Cancel" variant="secondary" size="sm" onPress={() => {}} />
154
+ ```
155
+
156
+ ### `Input`
157
+
158
+ Extends React Native `TextInput` props. Default size `lg` (44px pill, radius 60).
159
+
160
+ | Prop | Type | Default | Description |
161
+ | ------------------------ | ------------------------------------------------------------ | ------------------ | -------------------------- |
162
+ | `label` / `showLabel` | `string` / `boolean` | `"Label"` / `true` | Top label |
163
+ | `hint` / `showHint` | `string` / `boolean` | `"Hint"` / `true` | Bottom helper |
164
+ | `placeholder` | `string` | `"placeholder"` | Field placeholder |
165
+ | `size` | `"lg" \| "sm"` | `"lg"` | Field height |
166
+ | `state` | `"default" \| "filled" \| "active" \| "error" \| "disabled"` | derived | Override auto state |
167
+ | `disabled` / `error` | `boolean` | `false` | Disabled / error chrome |
168
+ | `showLeftIcon` | `boolean` | `false` | Defaults to `UserIcon` |
169
+ | `showRightIcon` | `boolean` | `false` | Defaults to `ShowIcon` |
170
+ | `leftIcon` / `rightIcon` | `ReactNode` | — | Custom icons |
171
+ | `onRightIconPress` | `() => void` | — | Makes right icon pressable |
172
+
173
+ | State | Behavior |
174
+ | ---------- | -------------------------------------------------------------------- |
175
+ | `default` | Grey field (`grey700`), white label, grey hint |
176
+ | `filled` | Same chrome when value is present |
177
+ | `active` | On focus — border `primaryMuted`, left icon `primary` |
178
+ | `error` | Border `redMuted`; label, text, placeholder, hint, left icon = `red` |
179
+ | `disabled` | Not editable, muted icons/text |
180
+
181
+ ### `Icon`
182
+
183
+ | Prop | Type | Default | Description |
184
+ | ------- | ---------- | ---------------- | ------------------- |
185
+ | `name` | `IconName` | — | Registry key |
186
+ | `size` | `number` | `20` or `24` | Matches SVG viewBox |
187
+ | `color` | `string` | `colors.primary` | Stroke / fill |
188
+
189
+ ```tsx
190
+ import { Icon, iconNames, iconGroups } from "@ecohouse/ui";
191
+
192
+ <Icon name="user" size={20} color="#fff" />;
193
+ ```
194
+
195
+ More: [`docs/icons.md`](./docs/icons.md), [`docs/components.md`](./docs/components.md).
196
+
197
+ ## Design tokens
198
+
199
+ ```tsx
200
+ import { colors, grey, fonts, buttonTypography, inputTypography } from "@ecohouse/ui";
201
+ ```
30
202
 
31
- ## Current exports
203
+ | Token | Value | Use |
204
+ | ------------------- | --------------- | -------------------------- |
205
+ | `primary` | `#B46436` | Brand / active left icon |
206
+ | `primaryMuted` | `#B464360F` | Input active border |
207
+ | `red` | `#A63E3E` | Error text / icons |
208
+ | `redMuted` | `#A63E3E0F` | Input error border |
209
+ | `black` / `white` | `#000` / `#fff` | Surfaces / labels |
210
+ | `grey0` … `grey950` | Grey scale | e.g. `grey700` = `#171717` |
32
211
 
33
- | Export | Description |
34
- | ------------------ | --------------------------------------------------------- |
35
- | `Button` | Primary actions with variants, sizes, optional icon badge |
36
- | Design tokens | `colors`, typography, spacing, radii, shadows |
37
- | `ArrowUpRightIcon` | Default button badge icon |
212
+ ```tsx
213
+ colors.primary;
214
+ colors.grey700;
215
+ grey["5"]; // same as colors.grey500
216
+ ```
217
+
218
+ Full token reference: [`docs/tokens.md`](./docs/tokens.md).
38
219
 
39
- ## Scripts
220
+ ## Development
40
221
 
41
222
  ```bash
42
- npm ci
43
- npm run lint
44
- npm run format:check
223
+ npm install
45
224
  npm run typecheck
46
- npm test
225
+ npm run lint
226
+ npm run test
47
227
  npm run build
48
- npm run storybook
228
+ npm run storybook # http://localhost:6006
49
229
  npm run build-storybook
50
230
  ```
51
231
 
52
- ## Branch model
232
+ Clear Storybook cache if needed:
233
+
234
+ ```bash
235
+ rm -rf node_modules/.cache/storybook node_modules/.vite
236
+ ```
237
+
238
+ ## Architecture
239
+
240
+ - **Shared implementation** — React Native primitives throughout (one API for web + mobile)
241
+ - **Web icons** — `.web.tsx` uses plain SVG (no `react-native-svg` on web)
242
+ - **Native icons** — `react-native-svg` (peer dependency)
243
+ - **Source resolution** — package `react-native` / `import` exports point at `src/index.ts` for correct `.web.tsx` resolution
244
+ - **Presentation only** — no API clients, secrets, or booking domain logic
245
+
246
+ ## Publishing
247
+
248
+ Push to `main` after CI `verify` passes. The **Release** job publishes `@ecohouse/ui` to npm (bumps patch if the current version already exists). Requires the `NPM_TOKEN` repository secret.
53
249
 
54
- `feature/*` (or ticket branches such as `E0-1-ui/bootstrap-repo`) → `development` → `staging` → `main`
250
+ Consumers:
251
+
252
+ ```bash
253
+ npm install @ecohouse/ui@^0.1.0
254
+ ```
55
255
 
56
- ## Out of scope for E0-1
256
+ ## Package rules
57
257
 
58
- npm publishing / semantic-release / consumer update PRs (E0-3-ui), full component set, consumer app integration.
258
+ - No backend API clients, secrets, provider SDKs, or domain business logic
259
+ - App routes and booking logic stay in `eco-cottage-web` / `eco-cottage-mobile`
260
+ - Prefer published npm versions in consumers