@7onic-ui/react 0.2.1 → 0.2.3

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/llms.txt CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## What is 7onic?
4
4
 
5
- Token-driven React design system with 38 components on Radix UI.
5
+ Token-driven React design system with 42 components on Radix UI.
6
6
  Single source of truth — design tokens to code. Use this to build any React service.
7
7
 
8
8
  - Documentation: https://7onic.design
@@ -56,12 +56,12 @@ npm install @7onic-ui/react @7onic-ui/tokens lucide-react
56
56
  **Existing project with Tailwind v3** (detect from tailwind.config.js):
57
57
  ```css
58
58
  /* globals.css */
59
- @tailwind base;
60
- @tailwind components;
61
- @tailwind utilities;
62
59
  @import '@7onic-ui/tokens/css/variables.css';
63
60
  @import '@7onic-ui/tokens/css/themes/light.css';
64
61
  @import '@7onic-ui/tokens/css/themes/dark.css'; /* omit ONLY if dark mode = no */
62
+ @tailwind base;
63
+ @tailwind components;
64
+ @tailwind utilities;
65
65
  ```
66
66
  ```js
67
67
  // tailwind.config.js — add preset
@@ -177,6 +177,12 @@ Design freely based on user's project description. Always use 7onic components +
177
177
  - Do NOT use `opacity-*` utility as a workaround — it affects the entire element including children
178
178
  - `bg-primary/10` ✅ (only background is transparent) / `bg-primary opacity-10` ❌ (children also become transparent)
179
179
 
180
+ 9. **Token-first rule** — Before adding any Tailwind utility, check if the property is already included in a design token. Typography tokens (`text-sm`, `text-md`, etc.) include both font-size AND line-height as a pair. Do NOT override with Tailwind line-height utilities:
181
+ - `text-sm` ✅ (token provides font-size + line-height)
182
+ - `text-sm leading-relaxed` ❌ (overrides token line-height)
183
+ - `text-sm leading-none` ❌ (overrides token line-height)
184
+ - `text-sm leading-[18px]` ❌ (hardcodes line-height)
185
+
180
186
  **Everything not in this list is FORBIDDEN.**
181
187
 
182
188
  ⚠️ **Gradient/visual utilities must use token colors only:** `from-primary to-secondary` ✅ / `from-blue-500 to-purple-600` ❌
@@ -193,7 +199,7 @@ Step 2: Is this a layout/structural element? (flex container, grid, section wrap
193
199
  → YES: Use div/section + token classes only.
194
200
  → NO: Step 3
195
201
 
196
- Step 3: Re-check the 38 components. Most UI can be built with component combinations.
202
+ Step 3: Re-check the 42 components. Most UI can be built with component combinations.
197
203
  → Still no match: Use div + token classes only.
198
204
  ```
199
205
 
@@ -343,7 +349,7 @@ Strategy: `dark` class on `<html>` element.
343
349
  - Border: `border`, `border-subtle`, `border-strong`
344
350
  - State: `disabled`, `disabled-text`, `focus-ring`, `focus-ring-error`
345
351
 
346
- **Spacing:** 0, 0.5(2px), 1(4px), 1.5(6px), 2(8px), 2.5(10px), 3(12px), 4(16px), 5(20px), 6(24px), 7(28px), 8(32px), 10(40px), 12(48px), 14(56px), 16(64px), 20(80px), 24(96px)
352
+ **Spacing:** 0, 0.5(2px), 1(4px), 1.5(6px), 2(8px), 2.5(10px), 3(12px), 3.5(14px), 4(16px), 5(20px), 6(24px), 7(28px), 8(32px), 10(40px), 12(48px), 14(56px), 16(64px), 20(80px), 24(96px)
347
353
 
348
354
  **Font:** `font-sans` (user-defined), `font-mono` (user-defined)
349
355
  **Font Sizes:** text-2xs(11px), text-xs(12px), text-sm(13px), text-md(14px), text-base(16px), text-lg(18px), text-xl(20px), text-2xl(24px), text-3xl(30px), text-4xl(36px), text-5xl(48px)
@@ -401,17 +407,17 @@ import { Card } from '@7onic-ui/react'
401
407
  import { Card, CardHeader, CardTitle, CardContent } from '@7onic-ui/react'
402
408
  ```
403
409
 
404
- ### Compound Components List (21)
410
+ ### Compound Components List (24)
405
411
 
406
- Accordion, Alert, Avatar, Breadcrumb, Card, Chart, Drawer, DropdownMenu, Field, MetricCard, Modal, NavigationMenu, Pagination, Popover, RadioGroup, Segmented, Select, Table, Tabs, ToggleGroup, Tooltip
412
+ Accordion, Alert, Avatar, Breadcrumb, Card, ChatInput, ChatMessage, Chart, Drawer, DropdownMenu, Field, MetricCard, Modal, NavigationMenu, Pagination, Popover, QuickReply, RadioGroup, Segmented, Select, Table, Tabs, ToggleGroup, Tooltip
407
413
 
408
- ### Standalone Components (15)
414
+ ### Standalone Components (16)
409
415
 
410
- Badge, Button, ButtonGroup, Checkbox, Divider, IconButton, Input, Progress, Skeleton, Slider, Spinner, Switch, Textarea, Toast, Toggle
416
+ Badge, Button, ButtonGroup, Checkbox, Divider, IconButton, Input, Progress, Skeleton, Slider, Spinner, Switch, Textarea, Toast, Toggle, TypingIndicator
411
417
 
412
418
  ---
413
419
 
414
- # ═══ SECTION 3: ALL COMPONENTS (38) ═══
420
+ # ═══ SECTION 3: ALL COMPONENTS (42) ═══
415
421
 
416
422
  ---
417
423
 
@@ -1940,6 +1946,266 @@ But if YOUR code uses React hooks (`useState`, `useEffect`) or event handlers (`
1940
1946
  | NavigationMenu | Compound | — | sm/md/default/lg | — | horizontal/vertical, collapsed |
1941
1947
  | Chart | Compound | — | — | chart colors | Bar/Line/Area/Pie |
1942
1948
  | MetricCard | Compound | default/elevated/ghost | sm/default/lg | — | animated value, trend |
1949
+ | TypingIndicator | Standalone | dots/cursor | sm/default/lg | default/primary/muted | speed (dots only), animate-typing-cursor, showLabel |
1950
+ | QuickReply | Compound | outline/filled/ghost | sm/default/lg | default/primary | layout (scroll/wrap), radius (md/lg/full), gap, icon, asChild |
1951
+ | ChatInput | Compound | outline/filled | sm/default/lg | default/primary | layout (default/inline), radius (sm/md/lg/xl/2xl/full), buttonRadius, auto-resize, showCount, loading, onStop |
1952
+ | ChatMessage | Compound | bubble/flat | sm/default/lg | default/muted/primary/dark | role (assistant/user), tail, avatarSize, radius (md/lg/xl/2xl), typing, actions, Avatar/Content/Footer sub-components |
1953
+ ---
1954
+
1955
+ ### TypingIndicator
1956
+
1957
+ ```tsx
1958
+ import { TypingIndicator } from '@7onic-ui/react'
1959
+
1960
+ {/* Default — dots, muted, default size */}
1961
+ <TypingIndicator />
1962
+
1963
+ {/* Cursor variant */}
1964
+ <TypingIndicator variant="cursor" />
1965
+
1966
+ {/* Chat bubble */}
1967
+ <TypingIndicator variant="dots" color="muted" />
1968
+
1969
+ {/* AI response — fast with label */}
1970
+ <TypingIndicator
1971
+ variant="dots"
1972
+ color="primary"
1973
+ speed="fast"
1974
+ showLabel
1975
+ label="AI is typing..."
1976
+ />
1977
+
1978
+ {/* Large cursor, primary color */}
1979
+ <TypingIndicator variant="cursor" size="lg" color="primary" />
1980
+ ```
1981
+
1982
+ | Prop | Type | Default | Description |
1983
+ |---|---|---|---|
1984
+ | variant | `'dots' \| 'cursor'` | `'dots'` | Animation style |
1985
+ | size | `'sm' \| 'default' \| 'lg'` | `'default'` | Size |
1986
+ | color | `'default' \| 'primary' \| 'muted'` | `'muted'` | Color |
1987
+ | speed | `'slow' \| 'default' \| 'fast'` | `'default'` | Speed (dots only) |
1988
+ | label | `string` | `'Typing'` | aria-label and showLabel text |
1989
+ | showLabel | `boolean` | `false` | Show text label alongside indicator |
1990
+
1991
+ ---
1992
+
1993
+ ### QuickReply
1994
+
1995
+ ```tsx
1996
+ import { QuickReply } from '@7onic-ui/react'
1997
+
1998
+ {/* Basic suggested replies */}
1999
+ <QuickReply aria-label="Suggested replies">
2000
+ <QuickReply.Item>About payment</QuickReply.Item>
2001
+ <QuickReply.Item>Shipping info</QuickReply.Item>
2002
+ <QuickReply.Item>Return policy</QuickReply.Item>
2003
+ </QuickReply>
2004
+
2005
+ {/* Primary color, filled variant */}
2006
+ <QuickReply color="primary" variant="filled" aria-label="Quick replies">
2007
+ <QuickReply.Item>Payment</QuickReply.Item>
2008
+ <QuickReply.Item>Shipping</QuickReply.Item>
2009
+ </QuickReply>
2010
+
2011
+ {/* Wrap layout for FAQ */}
2012
+ <QuickReply layout="wrap" aria-label="FAQ topics">
2013
+ <QuickReply.Item>Payments</QuickReply.Item>
2014
+ <QuickReply.Item>Shipping</QuickReply.Item>
2015
+ <QuickReply.Item>Returns</QuickReply.Item>
2016
+ <QuickReply.Item>Account</QuickReply.Item>
2017
+ </QuickReply>
2018
+
2019
+ {/* With icon */}
2020
+ <QuickReply aria-label="Actions">
2021
+ <QuickReply.Item icon={<MessageCircle />}>Contact us</QuickReply.Item>
2022
+ <QuickReply.Item icon={<Package />}>Track order</QuickReply.Item>
2023
+ </QuickReply>
2024
+ ```
2025
+
2026
+ | Prop (QuickReply) | Type | Default | Description |
2027
+ |---|---|---|---|
2028
+ | layout | `'scroll' \| 'wrap'` | `'scroll'` | Chip layout mode |
2029
+ | variant | `'outline' \| 'filled' \| 'ghost'` | `'outline'` | Visual style |
2030
+ | color | `'default' \| 'primary'` | `'default'` | Color theme |
2031
+ | size | `'sm' \| 'default' \| 'lg'` | `'default'` | Chip size |
2032
+ | radius | `'md' \| 'lg' \| 'full'` | `'full'` | Border radius |
2033
+ | gap | `'sm' \| 'default' \| 'lg'` | `'default'` | Gap between chips |
2034
+
2035
+ | Prop (QuickReply.Item) | Type | Default | Description |
2036
+ |---|---|---|---|
2037
+ | icon | `ReactNode` | — | Leading icon |
2038
+ | asChild | `boolean` | `false` | Compose with custom element (Radix Slot) |
2039
+ | disabled | `boolean` | `false` | Disable the chip |
2040
+ | onClick | `() => void` | — | Click callback |
2041
+
2042
+ ---
2043
+
2044
+ ### ChatInput
2045
+
2046
+ ```tsx
2047
+ import { ChatInput } from '@7onic-ui/react'
2048
+
2049
+ {/* Basic uncontrolled */}
2050
+ <ChatInput onSubmit={(value) => console.log(value)}>
2051
+ <ChatInput.Field placeholder="Ask me anything..." />
2052
+ <ChatInput.Submit />
2053
+ </ChatInput>
2054
+
2055
+ {/* Controlled mode */}
2056
+ const [value, setValue] = useState('')
2057
+ <ChatInput onSubmit={(v) => { handleSend(v); setValue('') }}>
2058
+ <ChatInput.Field
2059
+ value={value}
2060
+ onChange={(e) => setValue(e.target.value)}
2061
+ placeholder="Ask me anything..."
2062
+ />
2063
+ <ChatInput.Submit />
2064
+ </ChatInput>
2065
+
2066
+ {/* With loading state + stop */}
2067
+ <ChatInput onSubmit={handleSubmit}>
2068
+ <ChatInput.Field placeholder="Ask me anything..." />
2069
+ <ChatInput.Submit
2070
+ loading={isLoading}
2071
+ onStop={() => abortController.abort()}
2072
+ />
2073
+ </ChatInput>
2074
+
2075
+ {/* Character count */}
2076
+ <ChatInput onSubmit={(value) => console.log(value)}>
2077
+ <ChatInput.Field placeholder="Ask me anything..." showCount maxLength={500} />
2078
+ <ChatInput.Submit />
2079
+ </ChatInput>
2080
+
2081
+ {/* Filled variant, large, custom radius */}
2082
+ <ChatInput variant="filled" size="lg" radius="2xl" onSubmit={(v) => console.log(v)}>
2083
+ <ChatInput.Field placeholder="Ask me anything..." maxRows={6} />
2084
+ <ChatInput.Submit />
2085
+ </ChatInput>
2086
+
2087
+ {/* Inline layout (single-line field + button side by side) */}
2088
+ <ChatInput layout="inline" radius="full" onSubmit={(value) => console.log(value)}>
2089
+ <ChatInput.Field placeholder="Message..." />
2090
+ <ChatInput.Submit />
2091
+ </ChatInput>
2092
+
2093
+ {/* Inline with custom button radius */}
2094
+ <ChatInput layout="inline" radius="xl" onSubmit={handleSubmit}>
2095
+ <ChatInput.Field placeholder="Message..." />
2096
+ <ChatInput.Submit buttonRadius="full" loading={isLoading} onStop={handleStop} />
2097
+ </ChatInput>
2098
+ ```
2099
+
2100
+ | Prop (ChatInput) | Type | Default | Description |
2101
+ |---|---|---|---|
2102
+ | variant | `'outline' \| 'filled'` | `'outline'` | Visual style |
2103
+ | size | `'sm' \| 'default' \| 'lg'` | `'default'` | Size scale |
2104
+ | radius | `'sm' \| 'md' \| 'lg' \| 'xl' \| '2xl' \| 'full'` | `'xl'` | Corner radius (`'full'` available in inline layout) |
2105
+ | color | `'default' \| 'primary'` | `'default'` | Submit button color |
2106
+ | layout | `'default' \| 'inline'` | `'default'` | `'inline'` renders field and button side by side |
2107
+ | disabled | `boolean` | `false` | Disable input and submit |
2108
+ | onSubmit | `(value: string) => void` | — | Submit callback |
2109
+
2110
+ | Prop (ChatInput.Field) | Type | Default | Description |
2111
+ |---|---|---|---|
2112
+ | maxRows | `number` | `8` | Max rows before scrolling |
2113
+ | showCount | `boolean` | `false` | Show character counter (default layout only) |
2114
+ | maxLength | `number` | — | Max characters |
2115
+ | placeholder | `string` | — | Placeholder text |
2116
+
2117
+ | Prop (ChatInput.Submit) | Type | Default | Description |
2118
+ |---|---|---|---|
2119
+ | loading | `boolean` | `false` | Switch to stop icon — button stays enabled |
2120
+ | onStop | `() => void` | — | Called on click when loading |
2121
+ | buttonRadius | `'sm' \| 'md' \| 'lg' \| 'xl' \| '2xl' \| 'full'` | — | Override button radius (default: auto from container radius) |
2122
+ | children | `ReactNode` | — | Custom icon (default: send arrow) |
2123
+
2124
+ ### ChatMessage
2125
+
2126
+ ```tsx
2127
+ import { ChatMessage } from '@7onic-ui/react'
2128
+
2129
+ {/* Assistant message */}
2130
+ <ChatMessage role="assistant">
2131
+ <ChatMessage.Avatar />
2132
+ <div className="flex flex-col gap-1">
2133
+ <ChatMessage.Content>How can I help you today?</ChatMessage.Content>
2134
+ <ChatMessage.Footer timestamp="12:34" />
2135
+ </div>
2136
+ </ChatMessage>
2137
+
2138
+ {/* User message with status */}
2139
+ <ChatMessage role="user">
2140
+ <div className="flex flex-col gap-1 items-end">
2141
+ <ChatMessage.Content>Thank you for your help!</ChatMessage.Content>
2142
+ <ChatMessage.Footer timestamp="12:34" status="read" />
2143
+ </div>
2144
+ </ChatMessage>
2145
+
2146
+ {/* Typing animation */}
2147
+ <ChatMessage role="assistant" typing>
2148
+ <ChatMessage.Avatar />
2149
+ <ChatMessage.Content />
2150
+ </ChatMessage>
2151
+
2152
+ {/* Custom avatar + hover actions */}
2153
+ <ChatMessage
2154
+ role="assistant"
2155
+ actions={<button aria-label="Copy">...</button>}
2156
+ >
2157
+ <ChatMessage.Avatar initials="AI" />
2158
+ <div className="flex flex-col gap-1">
2159
+ <ChatMessage.Content>Response text here.</ChatMessage.Content>
2160
+ <ChatMessage.Footer timestamp="12:34" />
2161
+ </div>
2162
+ </ChatMessage>
2163
+
2164
+ {/* User bubble with muted color (common pattern) */}
2165
+ <ChatMessage role="user" color="muted">
2166
+ <div className="flex flex-col gap-1 items-end">
2167
+ <ChatMessage.Content>Message text</ChatMessage.Content>
2168
+ <ChatMessage.Footer timestamp="12:34" status="read" />
2169
+ </div>
2170
+ </ChatMessage>
2171
+
2172
+ {/* History (flat) layout — full-width, no footer */}
2173
+ <div className="flex flex-col gap-3">
2174
+ <ChatMessage role="assistant" variant="flat">
2175
+ <ChatMessage.Avatar />
2176
+ <ChatMessage.Content className="w-full">Here is the answer.</ChatMessage.Content>
2177
+ </ChatMessage>
2178
+ <ChatMessage role="user" variant="flat" color="muted">
2179
+ <ChatMessage.Content className="w-full">Thanks!</ChatMessage.Content>
2180
+ </ChatMessage>
2181
+ </div>
2182
+ ```
2183
+
2184
+ | Prop (ChatMessage) | Type | Default | Description |
2185
+ |---|---|---|---|
2186
+ | role | `'assistant' \| 'user'` | `'assistant'` | Aligns left (assistant) or right (user) |
2187
+ | variant | `'bubble' \| 'flat'` | `'bubble'` | Bubble style with background/border, or flat with no fill |
2188
+ | color | `'default' \| 'muted' \| 'primary' \| 'dark'` | `'default'` | Bubble background color |
2189
+ | size | `'sm' \| 'default' \| 'lg'` | `'default'` | Size scale affecting padding and font |
2190
+ | radius | `'md' \| 'lg' \| 'xl' \| '2xl'` | `'2xl'` | Bubble corner radius |
2191
+ | tail | `boolean` | `true` | Asymmetric tail corner (sharp on avatar side) — bubble only |
2192
+ | avatarSize | `'sm' \| 'md' \| 'lg'` | — | Avatar size — also adjusts gap between avatar and bubble |
2193
+ | typing | `boolean` | `false` | Show animated typing dots inside Content |
2194
+ | actions | `ReactNode` | — | Hover-reveal action buttons (copy, react, etc.) |
2195
+
2196
+ | Prop (ChatMessage.Avatar) | Type | Default | Description |
2197
+ |---|---|---|---|
2198
+ | size | `'sm' \| 'md' \| 'lg'` | `'md'` | Avatar size: 24/28/32px |
2199
+ | src | `string` | — | Avatar image URL |
2200
+ | alt | `string` | `'Avatar'` | Alt text |
2201
+ | initials | `string` | — | 1–2 character initials (fallback) |
2202
+ | icon | `ReactNode` | — | Custom icon (fallback) |
2203
+
2204
+ | Prop (ChatMessage.Footer) | Type | Default | Description |
2205
+ |---|---|---|---|
2206
+ | timestamp | `string` | — | Pre-formatted time string |
2207
+ | status | `'sending' \| 'sent' \| 'read' \| 'error' \| ReactNode` | — | Delivery status (built-in presets or custom node) |
2208
+ | size | `'sm' \| 'default' \| 'lg'` | — | Size override (defaults to context value from root) |
1943
2209
 
1944
2210
  ---
1945
2211
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@7onic-ui/react",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "private": false,
5
5
  "sideEffects": [
6
6
  "*.css"
@@ -48,7 +48,6 @@
48
48
  "build:7onic": "node scripts/build-7onic-cli.js",
49
49
  "generate:registry": "tsx scripts/generate-registry.ts",
50
50
  "verify:registry": "tsx scripts/generate-registry.ts && git diff --exit-code cli/src/registry/index.ts",
51
- "verify:docs": "tsx scripts/verify-docs.ts",
52
51
  "verify:i18n": "tsx scripts/verify-i18n.ts",
53
52
  "verify:i18n:html": "tsx scripts/verify-i18n-html.ts",
54
53
  "verify:components": "tsx scripts/verify-components.ts",
@@ -83,7 +82,7 @@
83
82
  "tailwind-merge": "^2.3.0"
84
83
  },
85
84
  "peerDependencies": {
86
- "@7onic-ui/tokens": "^0.1.0",
85
+ "@7onic-ui/tokens": ">=0.1.0 <1.0.0",
87
86
  "react": "^18.2.0 || ^19.0.0",
88
87
  "react-dom": "^18.2.0 || ^19.0.0",
89
88
  "recharts": "^2.15.0 || ^3.0.0"