@ecohouse/ui 0.1.0 → 0.1.2

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 (99) hide show
  1. package/README.md +239 -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 +5 -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/fonts.css +1 -0
  95. package/src/web/styles/typography.css +14 -92
  96. package/src/components/Button.stories.tsx +0 -135
  97. package/src/icons/arrowUpRightPath.ts +0 -1
  98. package/src/theme/tokens.test.ts +0 -10
  99. package/src/theme/tokens.ts +0 -286
package/README.md CHANGED
@@ -1,58 +1,261 @@
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 (import fonts first):
101
+
102
+ ```ts
103
+ import "@ecohouse/ui/web/fonts.css";
104
+ import "@ecohouse/ui/web/typography.css";
105
+ ```
106
+
107
+ ## Usage
108
+
109
+ ```tsx
110
+ import { Button, Input, Icon, UserIcon, ShowIcon, colors } from "@ecohouse/ui";
111
+
112
+ export function Example() {
113
+ return (
114
+ <>
115
+ <Button title="Continue" variant="primary" size="lg" showIcon onPress={() => {}} />
116
+
117
+ <Input
118
+ label="Password"
119
+ placeholder="••••••••"
120
+ hint="Use at least 8 characters"
121
+ secureTextEntry
122
+ leftIcon={<UserIcon size={20} />}
123
+ rightIcon={<ShowIcon size={20} />}
124
+ onRightIconPress={() => {}}
125
+ onChangeText={() => {}}
126
+ />
127
+
128
+ <Icon name="home" size={20} color={colors.white} />
129
+ </>
130
+ );
131
+ }
132
+ ```
133
+
134
+ Same API on web and mobile.
135
+
136
+ ## API
137
+
138
+ ### `Button`
139
+
140
+ Pill CTA — sizes `lg` (44px) / `sm` (32px). Secondary fill uses `colors.grey500`.
19
141
 
20
- ## Stack (Architecture v1.4 §§4.4, 5)
142
+ | Prop | Type | Default | Description |
143
+ | ---------- | -------------------------- | ----------- | ----------------- |
144
+ | `title` | `string` | — | Label text |
145
+ | `onPress` | `(event) => void` | required | Press handler |
146
+ | `variant` | `"primary" \| "secondary"` | `"primary"` | Fill style |
147
+ | `size` | `"lg" \| "sm"` | `"lg"` | Height / padding |
148
+ | `showIcon` | `boolean` | `false` | Right arrow badge |
149
+ | `icon` | `ReactNode` | — | Custom badge icon |
150
+ | `disabled` | `boolean` | `false` | 60% opacity |
21
151
 
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) |
152
+ ```tsx
153
+ <Button title="Continue" variant="primary" size="lg" showIcon onPress={() => {}} />
154
+ <Button title="Cancel" variant="secondary" size="sm" onPress={() => {}} />
155
+ ```
156
+
157
+ ### `Input`
158
+
159
+ Extends React Native `TextInput` props. Default size `lg` (44px pill, radius 60).
160
+
161
+ | Prop | Type | Default | Description |
162
+ | ------------------------ | ------------------------------------------------------------ | ------------------ | -------------------------- |
163
+ | `label` / `showLabel` | `string` / `boolean` | `"Label"` / `true` | Top label |
164
+ | `hint` / `showHint` | `string` / `boolean` | `"Hint"` / `true` | Bottom helper |
165
+ | `placeholder` | `string` | `"placeholder"` | Field placeholder |
166
+ | `size` | `"lg" \| "sm"` | `"lg"` | Field height |
167
+ | `state` | `"default" \| "filled" \| "active" \| "error" \| "disabled"` | derived | Override auto state |
168
+ | `disabled` / `error` | `boolean` | `false` | Disabled / error chrome |
169
+ | `showLeftIcon` | `boolean` | `false` | Defaults to `UserIcon` |
170
+ | `showRightIcon` | `boolean` | `false` | Defaults to `ShowIcon` |
171
+ | `leftIcon` / `rightIcon` | `ReactNode` | — | Custom icons |
172
+ | `onRightIconPress` | `() => void` | — | Makes right icon pressable |
173
+
174
+ | State | Behavior |
175
+ | ---------- | -------------------------------------------------------------------- |
176
+ | `default` | Grey field (`grey700`), white label, grey hint |
177
+ | `filled` | Same chrome when value is present |
178
+ | `active` | On focus — border `primaryMuted`, left icon `primary` |
179
+ | `error` | Border `redMuted`; label, text, placeholder, hint, left icon = `red` |
180
+ | `disabled` | Not editable, muted icons/text |
181
+
182
+ ### `Icon`
183
+
184
+ | Prop | Type | Default | Description |
185
+ | ------- | ---------- | ---------------- | ------------------- |
186
+ | `name` | `IconName` | — | Registry key |
187
+ | `size` | `number` | `20` or `24` | Matches SVG viewBox |
188
+ | `color` | `string` | `colors.primary` | Stroke / fill |
189
+
190
+ ```tsx
191
+ import { Icon, iconNames, iconGroups } from "@ecohouse/ui";
192
+
193
+ <Icon name="user" size={20} color="#fff" />;
194
+ ```
195
+
196
+ More: [`docs/icons.md`](./docs/icons.md), [`docs/components.md`](./docs/components.md).
197
+
198
+ ## Design tokens
199
+
200
+ ```tsx
201
+ import { colors, grey, fonts, buttonTypography, inputTypography } from "@ecohouse/ui";
202
+ ```
30
203
 
31
- ## Current exports
204
+ | Token | Value | Use |
205
+ | ------------------- | --------------- | -------------------------- |
206
+ | `primary` | `#B46436` | Brand / active left icon |
207
+ | `primaryMuted` | `#B464360F` | Input active border |
208
+ | `red` | `#A63E3E` | Error text / icons |
209
+ | `redMuted` | `#A63E3E0F` | Input error border |
210
+ | `black` / `white` | `#000` / `#fff` | Surfaces / labels |
211
+ | `grey0` … `grey950` | Grey scale | e.g. `grey700` = `#171717` |
32
212
 
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 |
213
+ ```tsx
214
+ colors.primary;
215
+ colors.grey700;
216
+ grey["5"]; // same as colors.grey500
217
+ ```
218
+
219
+ Full token reference: [`docs/tokens.md`](./docs/tokens.md).
38
220
 
39
- ## Scripts
221
+ ## Development
40
222
 
41
223
  ```bash
42
- npm ci
43
- npm run lint
44
- npm run format:check
224
+ npm install
45
225
  npm run typecheck
46
- npm test
226
+ npm run lint
227
+ npm run test
47
228
  npm run build
48
- npm run storybook
229
+ npm run storybook # http://localhost:6006
49
230
  npm run build-storybook
50
231
  ```
51
232
 
52
- ## Branch model
233
+ Clear Storybook cache if needed:
234
+
235
+ ```bash
236
+ rm -rf node_modules/.cache/storybook node_modules/.vite
237
+ ```
238
+
239
+ ## Architecture
240
+
241
+ - **Shared implementation** — React Native primitives throughout (one API for web + mobile)
242
+ - **Web icons** — `.web.tsx` uses plain SVG (no `react-native-svg` on web)
243
+ - **Native icons** — `react-native-svg` (peer dependency)
244
+ - **Source resolution** — package `react-native` / `import` exports point at `src/index.ts` for correct `.web.tsx` resolution
245
+ - **Presentation only** — no API clients, secrets, or booking domain logic
246
+
247
+ ## Publishing
248
+
249
+ 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
250
 
54
- `feature/*` (or ticket branches such as `E0-1-ui/bootstrap-repo`) → `development` → `staging` → `main`
251
+ Consumers:
252
+
253
+ ```bash
254
+ npm install @ecohouse/ui@^0.1.0
255
+ ```
55
256
 
56
- ## Out of scope for E0-1
257
+ ## Package rules
57
258
 
58
- npm publishing / semantic-release / consumer update PRs (E0-3-ui), full component set, consumer app integration.
259
+ - No backend API clients, secrets, provider SDKs, or domain business logic
260
+ - App routes and booking logic stay in `eco-cottage-web` / `eco-cottage-mobile`
261
+ - Prefer published npm versions in consumers