@usetrip/react-ui 0.2.0 → 0.2.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 (2) hide show
  1. package/README.md +347 -0
  2. package/package.json +1 -1
package/README.md ADDED
@@ -0,0 +1,347 @@
1
+ # @usetrip/react-ui
2
+
3
+ > Shared React component library for the UseTrip platform — built with TypeScript, Tailwind CSS v4, and Radix UI.
4
+
5
+ Used across `use-trip-web` and future UseTrip projects to keep the design system consistent and maintainable in a single place.
6
+
7
+ ---
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ npm install @usetrip/react-ui
13
+ ```
14
+
15
+ Then import the library's CSS in your app's entry stylesheet (required for `CustomEditor` toolbar styles):
16
+
17
+ ```css
18
+ @import "@usetrip/react-ui/dist/react-ui.css";
19
+ ```
20
+
21
+ And add the Tailwind `@source` directive so the library's class names are included in your CSS bundle:
22
+
23
+ ```css
24
+ @source "../node_modules/@usetrip/react-ui/dist";
25
+ ```
26
+
27
+ ---
28
+
29
+ ## Usage
30
+
31
+ ### Per-component imports (recommended — best tree shaking)
32
+
33
+ ```tsx
34
+ import Button from '@usetrip/react-ui/Button'
35
+ import Typography from '@usetrip/react-ui/Typography'
36
+ import TextField from '@usetrip/react-ui/TextField'
37
+ ```
38
+
39
+ ### Barrel import (convenient for multiple components)
40
+
41
+ ```tsx
42
+ import { Button, Typography, TextField } from '@usetrip/react-ui'
43
+ ```
44
+
45
+ Both styles are fully supported. The library ships with `"sideEffects": false` so unused components are always tree-shaken by your bundler.
46
+
47
+ ---
48
+
49
+ ## Components
50
+
51
+ ### `Button`
52
+
53
+ A versatile button component with multiple variants, sizes, loading state, and icon support.
54
+
55
+ ```tsx
56
+ import Button from '@usetrip/react-ui/Button'
57
+
58
+ <Button variant="primary" size="md">Save Trip</Button>
59
+ <Button variant="destructive" isLoading>Deleting...</Button>
60
+ <Button variant="outline" startIcon={<Plus />}>Add Location</Button>
61
+ ```
62
+
63
+ | Prop | Type | Default | Description |
64
+ |------|------|---------|-------------|
65
+ | `variant` | `primary` \| `secondary` \| `destructive` \| `outline` \| `ghost` \| `link` | `primary` | Visual style |
66
+ | `size` | `sm` \| `md` \| `lg` \| `full` \| `icon` | `md` | Button size |
67
+ | `rounded` | `default` \| `full` \| `none` | `default` | Border radius |
68
+ | `isLoading` | `boolean` | `false` | Shows spinner, disables interaction |
69
+ | `startIcon` | `ReactNode` | — | Icon before label |
70
+ | `endIcon` | `ReactNode` | — | Icon after label |
71
+ | `asChild` | `boolean` | `false` | Renders as child element (Radix Slot) |
72
+
73
+ ---
74
+
75
+ ### `ButtonLink`
76
+
77
+ Same variants as `Button`, but renders a `react-router-dom` `<Link>` for client-side navigation.
78
+
79
+ ```tsx
80
+ import ButtonLink from '@usetrip/react-ui/ButtonLink'
81
+
82
+ <ButtonLink to="/trips" variant="outline">View All Trips</ButtonLink>
83
+ ```
84
+
85
+ | Prop | Type | Description |
86
+ |------|------|-------------|
87
+ | `to` | `To` (react-router-dom) | Navigation target |
88
+ | `variant` / `size` / `rounded` | same as Button | Visual props |
89
+
90
+ ---
91
+
92
+ ### `TextField`
93
+
94
+ Controlled text input with label, hint text, validation states, and password toggle.
95
+
96
+ ```tsx
97
+ import TextField from '@usetrip/react-ui/TextField'
98
+
99
+ <TextField
100
+ label="Email"
101
+ type="email"
102
+ placeholder="you@example.com"
103
+ value={email}
104
+ onChange={setEmail}
105
+ />
106
+
107
+ <TextField
108
+ label="Password"
109
+ type="password"
110
+ state="error"
111
+ hintText="Password must be at least 8 characters"
112
+ value={password}
113
+ onChange={setPassword}
114
+ />
115
+ ```
116
+
117
+ | Prop | Type | Default | Description |
118
+ |------|------|---------|-------------|
119
+ | `label` | `string` | — | Input label |
120
+ | `type` | `text` \| `password` \| `email` \| `number` \| `date` | `text` | Input type |
121
+ | `state` | `default` \| `warning` \| `error` | `default` | Validation state |
122
+ | `hintText` | `string` | — | Helper or error message below input |
123
+ | `value` | `string` | — | Controlled value |
124
+ | `onChange` | `(value: string) => void` | — | Change handler |
125
+ | `disabled` | `boolean` | `false` | Disables the input |
126
+
127
+ ---
128
+
129
+ ### `Typography`
130
+
131
+ Semantic text component with consistent sizing, weight, and line-height tokens.
132
+
133
+ ```tsx
134
+ import Typography from '@usetrip/react-ui/Typography'
135
+
136
+ <Typography variant="h1">Plan your trip</Typography>
137
+ <Typography variant="body2" className="text-gray-500">10 days in Japan</Typography>
138
+ <Typography as="span" variant="caption">Last updated today</Typography>
139
+ ```
140
+
141
+ | Prop | Type | Default | Description |
142
+ |------|------|---------|-------------|
143
+ | `variant` | `h1` \| `h2` \| `h3` \| `h4` \| `h5` \| `body1` \| `body2` \| `caption` \| `label` \| `button` | `body1` | Typography style |
144
+ | `as` | `ElementType` | inferred from variant | HTML element to render |
145
+ | `className` | `string` | — | Additional classes |
146
+
147
+ ---
148
+
149
+ ### `AlertBox`
150
+
151
+ Inline feedback banners for success, error, warning, info, or default states.
152
+
153
+ ```tsx
154
+ import AlertBox from '@usetrip/react-ui/AlertBox'
155
+
156
+ <AlertBox type="success" message="Trip saved successfully!" />
157
+ <AlertBox type="error" message="Something went wrong. Please try again." />
158
+ ```
159
+
160
+ | Prop | Type | Description |
161
+ |------|------|-------------|
162
+ | `type` | `default` \| `info` \| `warning` \| `error` \| `success` | Alert style |
163
+ | `message` | `string` | Message text |
164
+
165
+ ---
166
+
167
+ ### `SearchInput`
168
+
169
+ Search field with a built-in search icon, available in multiple sizes and variants.
170
+
171
+ ```tsx
172
+ import SearchInput from '@usetrip/react-ui/SearchInput'
173
+
174
+ <SearchInput
175
+ size="md"
176
+ placeholder="Search destinations..."
177
+ value={query}
178
+ onChange={(e) => setQuery(e.target.value)}
179
+ />
180
+ ```
181
+
182
+ | Prop | Type | Default | Description |
183
+ |------|------|---------|-------------|
184
+ | `size` | `sm` \| `md` \| `lg` \| `full` | `md` | Controls width and height |
185
+ | `variant` | `default` \| `compact` | `default` | Border radius style |
186
+ | `placeholder` | `string` | `"Digite..."` | Placeholder text |
187
+
188
+ ---
189
+
190
+ ### `CalendarInput`
191
+
192
+ Read-only date display field that triggers a calendar picker when clicked.
193
+
194
+ ```tsx
195
+ import CalendarInput from '@usetrip/react-ui/CalendarInput'
196
+
197
+ <CalendarInput
198
+ label="Check-in"
199
+ value={date ? format(date, 'dd/MM/yyyy') : ''}
200
+ onClick={() => setPickerOpen(true)}
201
+ state="error"
202
+ hintText="Required field"
203
+ />
204
+ ```
205
+
206
+ | Prop | Type | Default | Description |
207
+ |------|------|---------|-------------|
208
+ | `label` | `string` | — | Input label |
209
+ | `value` | `string` | — | Formatted date string to display |
210
+ | `placeholder` | `string` | `"Selecione uma data"` | Shown when no value |
211
+ | `state` | `default` \| `warning` \| `error` | `default` | Validation state |
212
+ | `hintText` | `string` | — | Helper or error message |
213
+ | `compact` | `boolean` | `false` | Reduces spacing for dense layouts |
214
+ | `onClick` | `() => void` | — | Opens the date picker |
215
+
216
+ ---
217
+
218
+ ### `InputCounter`
219
+
220
+ Increment/decrement counter with label, hint text, and minimum value enforcement.
221
+
222
+ ```tsx
223
+ import InputCounter from '@usetrip/react-ui/InputCounter'
224
+
225
+ <InputCounter
226
+ label="Adults"
227
+ value={adults}
228
+ onIncrement={() => setAdults(adults + 1)}
229
+ onDecrement={() => setAdults(adults - 1)}
230
+ minValue={1}
231
+ hintText="Ages 18+"
232
+ />
233
+ ```
234
+
235
+ | Prop | Type | Default | Description |
236
+ |------|------|---------|-------------|
237
+ | `label` | `string` | — | Counter label |
238
+ | `value` | `number` | — | Current count |
239
+ | `onIncrement` | `() => void` | — | Called when + is pressed |
240
+ | `onDecrement` | `() => void` | — | Called when − is pressed |
241
+ | `minValue` | `number` | `0` | Disables decrement at this value |
242
+ | `hintText` | `string` | — | Helper text below counter |
243
+ | `compact` | `boolean` | `false` | Reduces padding for dense layouts |
244
+
245
+ ---
246
+
247
+ ### `RangeDatePicker`
248
+
249
+ Modal date range picker with dual-month calendar, navigation, and confirm/cancel/reset actions.
250
+
251
+ ```tsx
252
+ import RangeDatePicker from '@usetrip/react-ui/RangeDatePicker'
253
+ import type { DateRange } from 'react-day-picker'
254
+
255
+ const [range, setRange] = useState<DateRange | undefined>()
256
+
257
+ <RangeDatePicker
258
+ isOpen={isOpen}
259
+ onClose={() => setIsOpen(false)}
260
+ onSelect={(range) => { setRange(range); setIsOpen(false) }}
261
+ initialRange={range}
262
+ minDate={new Date()}
263
+ />
264
+ ```
265
+
266
+ | Prop | Type | Description |
267
+ |------|------|-------------|
268
+ | `isOpen` | `boolean` | Controls dialog visibility |
269
+ | `onClose` | `() => void` | Called when dialog is closed |
270
+ | `onSelect` | `(range: DateRange \| undefined) => void` | Called when selection is confirmed |
271
+ | `initialRange` | `DateRange` | Pre-selected range |
272
+ | `minDate` | `Date` | Disables dates before this date |
273
+
274
+ ---
275
+
276
+ ### `CustomEditor`
277
+
278
+ WYSIWYG rich text editor with a fixed toolbar (bold, italic, underline, strikethrough, ordered list, bullet list). Value is stored as an HTML string.
279
+
280
+ ```tsx
281
+ import CustomEditor from '@usetrip/react-ui/CustomEditor'
282
+ import type { ContentEditableEvent } from 'react-simple-wysiwyg'
283
+
284
+ <CustomEditor
285
+ value={content}
286
+ onChange={(e: ContentEditableEvent) => setContent(e.target.value)}
287
+ placeholder="Describe your trip..."
288
+ />
289
+ ```
290
+
291
+ | Prop | Type | Description |
292
+ |------|------|-------------|
293
+ | `value` | `string` | HTML string content |
294
+ | `onChange` | `(e: ContentEditableEvent) => void` | Change handler |
295
+ | `placeholder` | `string` | Placeholder when empty |
296
+ | `containerProps` | `ComponentProps<"div">` | Props for the outer container |
297
+
298
+ > **Security:** Always sanitize the HTML string with [DOMPurify](https://github.com/cure53/DOMPurify) before rendering it with `dangerouslySetInnerHTML`.
299
+
300
+ ---
301
+
302
+ ## Peer Dependencies
303
+
304
+ The library does not bundle these — your project must have them installed:
305
+
306
+ ```bash
307
+ npm install react react-dom react-router-dom
308
+ npm install @radix-ui/react-dialog @radix-ui/react-label @radix-ui/react-popover @radix-ui/react-slot
309
+ npm install tailwindcss class-variance-authority clsx tailwind-merge
310
+ npm install lucide-react react-icons
311
+ npm install date-fns react-day-picker
312
+ npm install react-simple-wysiwyg
313
+ ```
314
+
315
+ ---
316
+
317
+ ## Development
318
+
319
+ Clone the repo and start the playground to develop and test components interactively:
320
+
321
+ ```bash
322
+ git clone https://github.com/UseTrip/use-trip-web-ui.git
323
+ cd use-trip-web-ui
324
+ npm install
325
+ npm run dev # starts playground at localhost:5173
326
+ npm run build # bundles library to dist/
327
+ ```
328
+
329
+ The playground (`src/playground/`) has a dedicated page for each component with live examples. Changes to component source are hot-reloaded instantly.
330
+
331
+ ---
332
+
333
+ ## Publishing
334
+
335
+ ```bash
336
+ npm run build
337
+ npm publish --access public
338
+ ```
339
+
340
+ Bump the version in `package.json` before publishing (`0.x.0` for new features, `0.0.x` for patches).
341
+
342
+ ---
343
+
344
+ ## Repository
345
+
346
+ - **npm**: [@usetrip/react-ui](https://www.npmjs.com/package/@usetrip/react-ui)
347
+ - **GitHub**: [UseTrip/use-trip-web-ui](https://github.com/UseTrip/use-trip-web-ui)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usetrip/react-ui",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "main": "dist/index.cjs",