@kawaiininja/layouts 1.0.3 → 1.0.4

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 CHANGED
@@ -2,14 +2,36 @@
2
2
 
3
3
  High-performance, premium mobile-first layouts for the Onyx Framework. Designed with a focus on fluid gestures, modularity, and state-of-the-art aesthetics.
4
4
 
5
+ [**📖 Read the Full Developer Guide**](./GUIDE.md) | [**🎨 Explore Examples**](./examples/)
6
+
7
+ ---
8
+
5
9
  ## ✨ Features
6
10
 
7
- - **Gesture-Driven Navigation**: Horizontal tab swiping and vertical pull-to-refresh logic.
8
- - **Radial Quick Actions**: Long-press navigation keys to trigger a radial menu for rapid access to actions.
9
- - **Dynamic Headers**: Auto-updating header titles based on navigation state, with support for custom actions.
10
- - **Modular Drawers**: Easily integrate side menus and custom bottom sheets/panels.
11
- - **Integrated Theme Support**: Built-in dark/light mode toggle with persistence and system-wide CSS variable injection.
12
- - **Hardware Back Button Support**: Sophisticated history management for closing overlays and panels seamlessly on mobile devices.
11
+ ### 🖐️ Gesture-Driven Navigation (Fluid Flow)
12
+
13
+ - **Horizontal Tab Swiping**: Seamlessly transition between sub-tabs with natural swipe gestures. Built on a custom gesture engine for zero-lag response.
14
+ - **Vertical Pull-to-Refresh**: Per-tab or global refresh logic with integrated spring physics and haptic feedback support.
15
+ - **Smart History management**: Integrated hardware back-button handling. Pressing "Back" on Android or using back gestures will close drawers and panels before navigating away from the page.
16
+
17
+ ### 🔘 Radial Quick Actions (Long-Press)
18
+
19
+ - **Zero-Friction Access**: Long-press any navigation rail item to reveal a radial selection menu.
20
+ - **Directional Selection**: Swipe towards an action item to select and execute it instantly without lifting your finger.
21
+ - **Programmable Logic**: Quick actions can trigger internal state changes, external redirects, or open custom layout drawers.
22
+
23
+ ### 🖼️ Modular Layout Engine
24
+
25
+ - **Dynamic Headers**: Auto-syncing header titles with current navigation state. Supports custom right-aligned actions (buttons, icons, etc.).
26
+ - **Flexible Side Drawer**: Fully configurable drawer menu with support for deep-linking (target specific tabs/sub-tabs) and custom action links.
27
+ - **Panel System**: Register any number of custom drawers (Bottom Sheets) that can be triggered from anywhere in the app.
28
+
29
+ ### 🎨 Design System & Theme
30
+
31
+ - **Premium Glassmorphism**: High-quality backdrop blurs and subtle gradients for a modern, high-end feel.
32
+ - **Integrated Theme Support**: Robust dark/light mode toggle with local storage persistence and system-aware defaults.
33
+
34
+ ---
13
35
 
14
36
  ## 🚀 Installation
15
37
 
@@ -19,91 +41,148 @@ npm install @onyx/layouts
19
41
 
20
42
  Note: This package requires `framer-motion`, `lucide-react`, and `react` >= 18.0.0.
21
43
 
44
+ ---
45
+
22
46
  ## 📦 Usage
23
47
 
48
+ ### Basic Example
49
+
24
50
  ```jsx
25
51
  import { OnyxMobileLayout } from "@onyx/layouts";
26
- import { Home, Settings, PenTool, RefreshCw } from "lucide-react";
52
+ import { Home, Search, Bell, User, PenTool, Grid } from "lucide-react";
27
53
 
28
- const MyLayout = () => {
54
+ const MyApp = () => {
29
55
  const tabs = [
30
56
  {
31
57
  id: "home",
32
- icon: Home,
33
58
  label: "Home",
34
- navTitle: "My Feed",
35
- subTabs: [{ label: "Overview", icon: Grid, view: MyViewComponent }],
59
+ icon: Home,
60
+ navTitle: "Activity Feed",
61
+ subTabs: [
62
+ { label: "Inbox", icon: Grid, view: () => <div>Your Messages</div> },
63
+ ],
36
64
  quickActions: [
37
65
  {
66
+ label: "New Post",
38
67
  icon: PenTool,
39
- label: "Create",
40
- onClick: ({ openDrawer }) => openDrawer("editor"),
68
+ onClick: ({ openDrawer }) => openDrawer("post_editor"),
41
69
  },
42
70
  ],
43
- onRefresh: () => fetchData(),
44
- isRefreshing: loadingState,
45
71
  },
46
72
  ];
47
73
 
48
74
  return (
49
75
  <OnyxMobileLayout
50
76
  tabs={tabs}
51
- user={{ name: "Alex", handle: "@alex", avatar: "url" }}
77
+ user={{
78
+ name: "Alex Designer",
79
+ handle: "@alex_ui",
80
+ avatar: "https://example.com/avatar.png",
81
+ }}
52
82
  drawers={{
53
- editor: MyEditorPanel,
83
+ post_editor: PostEditorPanel,
54
84
  }}
55
85
  />
56
86
  );
57
87
  };
58
88
  ```
59
89
 
90
+ ---
91
+
60
92
  ## 🛠️ Configuration API
61
93
 
62
- ### OnyxMobileLayoutProps
63
-
64
- | Prop | Type | Description |
65
- | :------------- | :-------------------------- | :------------------------------------------------------ |
66
- | `tabs` | `TabConfig[]` | Array of main navigation tabs (right rail). |
67
- | `user` | `UserConfig` | User profile data for the side drawer. |
68
- | `drawers` | `Record<string, Component>` | Dictionary of custom panels/bottom sheets. |
69
- | `drawerItems` | `DrawerItemConfig[]` | Custom links for the main side drawer. |
70
- | `onSignOut` | `() => void` | Callback triggered when the sign-out button is clicked. |
71
- | `onRefresh` | `() => void` | (Global) Callback for pull-to-refresh. |
72
- | `isRefreshing` | `boolean` | (Global) Refreshing state. |
73
- | `initialTab` | `string` | ID of the tab to show on mount (default: 'home'). |
74
-
75
- ### TabConfig
76
-
77
- | Field | Type | Description |
78
- | :------------- | :-------------------- | :------------------------------------------------ |
79
- | `id` | `string` | Unique identifier for navigation. |
80
- | `icon` | `LucideIcon` | Icon for the navigation rail. |
81
- | `label` | `string` | Label for the navigation rail. |
82
- | `navTitle` | `string` | (Optional) Title shown in the header when active. |
83
- | `subTabs` | `SubTabConfig[]` | Array of nested horizontal tabs. |
84
- | `quickActions` | `QuickActionConfig[]` | Actions triggered by long-press on the nav key. |
85
- | `onRefresh` | `() => void` | Tab-specific refresh callback. |
86
- | `isRefreshing` | `boolean` | Tab-specific refresh state. |
87
-
88
- ### QuickActionConfig / DrawerItemConfig
89
-
90
- Quick actions and Drawer items support an `onClick` callback that receives a context object:
91
-
92
- ```typescript
93
- onClick: ({ openDrawer: (id: string) => void }) => void
94
- ```
94
+ ### `OnyxMobileLayoutProps`
95
+
96
+ | Prop | Type | Description |
97
+ | :------------- | :-------------------------- | :---------------------------------------------------------------------------- |
98
+ | `tabs` | `TabConfig[]` | **Required**. The main navigation stack (Rails on the right). |
99
+ | `user` | `UserConfig` | **Required**. Data for the side drawer's profile section. |
100
+ | `drawers` | `Record<string, Component>` | Dictionary of custom panel components. Keys are used as IDs for `openDrawer`. |
101
+ | `drawerItems` | `DrawerItemConfig[]` | Custom links for the side menu. If empty, defaults to first tab's subtabs. |
102
+ | `onSignOut` | `() => void` | Triggered when the "Sign Out" button in the drawer is clicked. |
103
+ | `onRefresh` | `() => void` | Global pull-to-refresh handler. Overridden if a tab has its own `onRefresh`. |
104
+ | `isRefreshing` | `boolean` | Global refresh state. |
105
+ | `initialTab` | `string` | The ID of the tab to show initially. Default: `home`. |
106
+ | `rightAction` | `ReactNode` | Global action element shown in the header (e.g., Settings icon). |
107
+
108
+ ### `TabConfig`
95
109
 
96
- ## 🎨 Theme Variables
110
+ | Field | Type | Description |
111
+ | :------------- | :-------------------- | :-------------------------------------------------------------------------- |
112
+ | `id` | `string` | Unique identifier used for internal routing. |
113
+ | `label` | `string` | Text label shown in the Rail. |
114
+ | `icon` | `LucideIcon` | Icon shown in the Rail. |
115
+ | `navTitle` | `string` | Optional. Text shown in the top header when this tab is active. |
116
+ | `subTabs` | `SubTabConfig[]` | Horizontal navigation nested under this tab. |
117
+ | `quickActions` | `QuickActionConfig[]` | Radial menu items triggered by long-press. |
118
+ | `onRefresh` | `() => void` | Tab-specific refresh handler. If provided, disables the global `onRefresh`. |
119
+ | `isRefreshing` | `boolean` | Tab-specific loading state. |
120
+ | `rightAction` | `ReactNode` | Tab-specific header action. |
97
121
 
98
- The layout relies on the following CSS variables for its design system:
122
+ ### `SubTabConfig`
123
+
124
+ | Field | Type | Description |
125
+ | :------ | :----------- | :--------------------------------------------------- |
126
+ | `label` | `string` | Text shown in the horizontal pill. |
127
+ | `icon` | `LucideIcon` | Icon next to the label. |
128
+ | `view` | `Component` | The component to render when this sub-tab is active. |
129
+
130
+ ### `QuickActionConfig` & `DrawerItemConfig`
131
+
132
+ Both configurations share an `onClick` context provider:
133
+
134
+ | Prop | Type | Description |
135
+ | :------------- | :-------------- | :------------------------------------------------------------------------ |
136
+ | `label` | `string` | Item text. |
137
+ | `icon` | `LucideIcon` | Item icon. |
138
+ | `targetTab` | `string` | (Drawer only) Target Tab ID for navigation. |
139
+ | `targetSubTab` | `string` | (Drawer only) Target Sub-tab Label for deep-linking. |
140
+ | `onClick` | `(ctx) => void` | Custom callback. Context contains `{ openDrawer: (id: string) => void }`. |
141
+
142
+ ---
143
+
144
+ ## 🌊 Gesture Interactions Guide
145
+
146
+ ### Pull-to-Refresh
147
+
148
+ To enable the refresh indicator, simply provide an `onRefresh` callback. The indicator will appear when the user pulls down from the top of the scroll container.
149
+
150
+ - **Threshold**: 60px pull triggers the refresh.
151
+ - **State Control**: Use `isRefreshing` to let the layout know when the operation is complete.
152
+
153
+ ### Quick Action Menu (Radial Selection)
154
+
155
+ 1. **Trigger**: Press and hold any item in the right navigation rail for 400ms.
156
+ 2. **Selection**: While holding, move your finger up or down. The selection indicator will follow.
157
+ 3. **Execution**: Release your finger to execute the highlighted action.
158
+
159
+ ---
160
+
161
+ ## 🎨 Design System (CSS Tokens)
162
+
163
+ The layout is highly skinable using CSS variables. Override these in your root CSS:
164
+
165
+ ```css
166
+ :root {
167
+ /* Backgrounds */
168
+ --bg-main: 0, 0, 0; /* Pure black */
169
+ --bg-surface: 18, 18, 18; /* Elevate surface */
170
+ --bg-elevated: 28, 28, 28; /* Drawer/Menus */
171
+
172
+ /* Brand */
173
+ --color-accent: 99, 102, 241; /* Primary brand color (Indigo) */
174
+ --color-secondary: 236, 72, 153;
175
+
176
+ /* Text */
177
+ --text-primary: 255, 255, 255;
178
+ --text-muted: 156, 163, 175;
179
+
180
+ /* Borders */
181
+ --color-border-subtle: 255, 255, 255, 0.1;
182
+ }
183
+ ```
99
184
 
100
- - `--bg-main`: Page background
101
- - `--bg-surface`: Header/Tab background
102
- - `--bg-elevated`: Drawer/Overlay background
103
- - `--color-accent`: Highlight/Active color
104
- - `--text-primary`: Main text
105
- - `--text-muted`: Secondary text
106
- - `--color-border-subtle`: Borders and dividers
185
+ ---
107
186
 
108
187
  ## ⚖️ License
109
188
 
package/dist/types.d.ts CHANGED
@@ -7,7 +7,9 @@ export interface SubTabConfig {
7
7
  export interface QuickActionConfig {
8
8
  label: string;
9
9
  icon: ComponentType<any>;
10
- onClick?: () => void;
10
+ onClick?: (ctx: {
11
+ openDrawer: (id: string) => void;
12
+ }) => void;
11
13
  }
12
14
  export interface TabConfig {
13
15
  id: string;
@@ -25,7 +27,9 @@ export interface DrawerItemConfig {
25
27
  icon: any;
26
28
  targetTab?: string;
27
29
  targetSubTab?: string;
28
- onClick?: () => void;
30
+ onClick?: (ctx: {
31
+ openDrawer: (id: string) => void;
32
+ }) => void;
29
33
  }
30
34
  export interface UserConfig {
31
35
  name: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kawaiininja/layouts",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "High-performance, premium mobile-first layouts for the Onyx Framework, featuring gesture-driven navigation, radial quick actions, and integrated theme support.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",