@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.
- package/README.md +238 -36
- package/dist/index.cjs +649 -314
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +181 -258
- package/dist/index.d.ts +181 -258
- package/dist/index.js +626 -304
- package/dist/index.js.map +1 -1
- package/package.json +4 -7
- package/src/components/Button/Button.stories.tsx +98 -0
- package/src/components/{Button.tsx → Button/Button.tsx} +39 -71
- package/src/components/Button/index.ts +2 -0
- package/src/components/Input/Input.stories.tsx +118 -0
- package/src/components/Input/Input.tsx +327 -0
- package/src/components/Input/index.ts +2 -0
- package/src/components/index.ts +5 -0
- package/src/icons/{ArrowUpRightIcon.tsx → ArrowRight/ArrowRightIcon.tsx} +8 -7
- package/src/icons/{ArrowUpRightIcon.web.tsx → ArrowRight/ArrowRightIcon.web.tsx} +8 -7
- package/src/icons/ArrowRight/arrowRightPath.ts +2 -0
- package/src/icons/ArrowRight/index.ts +1 -0
- package/src/icons/Bag/BagIcon.tsx +20 -0
- package/src/icons/Bag/BagIcon.web.tsx +26 -0
- package/src/icons/Bag/bagPath.ts +2 -0
- package/src/icons/Bag/index.ts +1 -0
- package/src/icons/Bell/BellIcon.tsx +20 -0
- package/src/icons/Bell/BellIcon.web.tsx +26 -0
- package/src/icons/Bell/bellPath.ts +2 -0
- package/src/icons/Bell/index.ts +1 -0
- package/src/icons/Building/BuildingIcon.tsx +20 -0
- package/src/icons/Building/BuildingIcon.web.tsx +26 -0
- package/src/icons/Building/buildingPath.ts +2 -0
- package/src/icons/Building/index.ts +1 -0
- package/src/icons/Camera/CameraIcon.tsx +20 -0
- package/src/icons/Camera/CameraIcon.web.tsx +26 -0
- package/src/icons/Camera/cameraPath.ts +2 -0
- package/src/icons/Camera/index.ts +1 -0
- package/src/icons/CheckBadge/CheckBadgeIcon.tsx +20 -0
- package/src/icons/CheckBadge/CheckBadgeIcon.web.tsx +26 -0
- package/src/icons/CheckBadge/checkBadgePath.ts +2 -0
- package/src/icons/CheckBadge/index.ts +1 -0
- package/src/icons/Clock/ClockIcon.tsx +20 -0
- package/src/icons/Clock/ClockIcon.web.tsx +26 -0
- package/src/icons/Clock/clockPath.ts +2 -0
- package/src/icons/Clock/index.ts +1 -0
- package/src/icons/Facebook/FacebookIcon.tsx +14 -0
- package/src/icons/Facebook/FacebookIcon.web.tsx +20 -0
- package/src/icons/Facebook/facebookPath.ts +2 -0
- package/src/icons/Facebook/index.ts +1 -0
- package/src/icons/Home/HomeIcon.tsx +20 -0
- package/src/icons/Home/HomeIcon.web.tsx +26 -0
- package/src/icons/Home/homePath.ts +2 -0
- package/src/icons/Home/index.ts +1 -0
- package/src/icons/Icon.tsx +11 -0
- package/src/icons/Icons.stories.tsx +174 -0
- package/src/icons/Instagram/InstagramIcon.tsx +14 -0
- package/src/icons/Instagram/InstagramIcon.web.tsx +20 -0
- package/src/icons/Instagram/index.ts +1 -0
- package/src/icons/Instagram/instagramPath.ts +2 -0
- package/src/icons/Key/KeyIcon.tsx +20 -0
- package/src/icons/Key/KeyIcon.web.tsx +26 -0
- package/src/icons/Key/index.ts +1 -0
- package/src/icons/Key/keyPath.ts +2 -0
- package/src/icons/LinkedIn/LinkedInIcon.tsx +14 -0
- package/src/icons/LinkedIn/LinkedInIcon.web.tsx +20 -0
- package/src/icons/LinkedIn/index.ts +1 -0
- package/src/icons/LinkedIn/linkedinPath.ts +2 -0
- package/src/icons/Mail/MailIcon.tsx +20 -0
- package/src/icons/Mail/MailIcon.web.tsx +26 -0
- package/src/icons/Mail/index.ts +1 -0
- package/src/icons/Mail/mailPath.ts +2 -0
- package/src/icons/Navigate/NavigateIcon.tsx +20 -0
- package/src/icons/Navigate/NavigateIcon.web.tsx +26 -0
- package/src/icons/Navigate/index.ts +1 -0
- package/src/icons/Navigate/navigatePath.ts +2 -0
- package/src/icons/Phone/PhoneIcon.tsx +20 -0
- package/src/icons/Phone/PhoneIcon.web.tsx +26 -0
- package/src/icons/Phone/index.ts +1 -0
- package/src/icons/Phone/phonePath.ts +2 -0
- package/src/icons/Show/ShowIcon.tsx +33 -0
- package/src/icons/Show/ShowIcon.web.tsx +39 -0
- package/src/icons/Show/index.ts +1 -0
- package/src/icons/Show/showPath.ts +6 -0
- package/src/icons/User/UserIcon.tsx +26 -0
- package/src/icons/User/UserIcon.web.tsx +32 -0
- package/src/icons/User/index.ts +1 -0
- package/src/icons/User/userPath.ts +3 -0
- package/src/icons/index.ts +24 -0
- package/src/icons/registry.ts +58 -0
- package/src/icons/types.ts +9 -0
- package/src/index.ts +37 -21
- package/src/theme/colors.test.ts +12 -0
- package/src/theme/colors.ts +46 -0
- package/src/theme/index.ts +4 -0
- package/src/theme/typography.ts +46 -0
- package/src/web/styles/typography.css +8 -90
- package/src/components/Button.stories.tsx +0 -135
- package/src/icons/arrowUpRightPath.ts +0 -1
- package/src/theme/tokens.test.ts +0 -10
- package/src/theme/tokens.ts +0 -286
package/README.md
CHANGED
|
@@ -1,58 +1,260 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @ecohouse/ui
|
|
2
2
|
|
|
3
|
-
|
|
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
|
-
##
|
|
5
|
+
## Components
|
|
6
6
|
|
|
7
|
-
|
|
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
|
-
|
|
13
|
+
Named icon exports (`UserIcon`, `HomeIcon`, …) are also available. Full icon list: [`docs/icons.md`](./docs/icons.md).
|
|
10
14
|
|
|
11
|
-
|
|
15
|
+
## Installation
|
|
12
16
|
|
|
13
|
-
|
|
14
|
-
- No application secrets
|
|
15
|
-
- No provider SDKs
|
|
16
|
-
- No EcoHouse booking / domain business logic
|
|
17
|
+
### React Native (Expo)
|
|
17
18
|
|
|
18
|
-
|
|
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
|
-
|
|
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
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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
|
-
|
|
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
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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
|
-
##
|
|
220
|
+
## Development
|
|
40
221
|
|
|
41
222
|
```bash
|
|
42
|
-
npm
|
|
43
|
-
npm run lint
|
|
44
|
-
npm run format:check
|
|
223
|
+
npm install
|
|
45
224
|
npm run typecheck
|
|
46
|
-
npm
|
|
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
|
-
|
|
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
|
-
|
|
250
|
+
Consumers:
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
npm install @ecohouse/ui@^0.1.0
|
|
254
|
+
```
|
|
55
255
|
|
|
56
|
-
##
|
|
256
|
+
## Package rules
|
|
57
257
|
|
|
58
|
-
|
|
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
|