@onexapis/cli 1.1.32 → 1.1.36
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/dist/cli.js +18 -2
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +18 -2
- package/dist/cli.mjs.map +1 -1
- package/dist/index.js +18 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +18 -2
- package/dist/index.mjs.map +1 -1
- package/dist/preview/preview-app.tsx +8 -2
- package/package.json +2 -2
- package/templates/default/CLAUDE.md +116 -67
|
@@ -24,7 +24,11 @@ import { initializeOnex } from "@onexapis/core";
|
|
|
24
24
|
import * as coreHooksAll from "@onexapis/core/hooks";
|
|
25
25
|
import * as coreInternal from "@onexapis/core/internal";
|
|
26
26
|
import * as coreTypes from "@onexapis/core/types";
|
|
27
|
-
import {
|
|
27
|
+
import {
|
|
28
|
+
CartProvider,
|
|
29
|
+
FlyToCartProvider,
|
|
30
|
+
PageDataProvider,
|
|
31
|
+
} from "@onexapis/core/contexts";
|
|
28
32
|
import { LocaleProvider } from "@onexapis/core/contexts";
|
|
29
33
|
|
|
30
34
|
// @onexapis/core/hooks is the single source of truth — no manual composition.
|
|
@@ -744,7 +748,9 @@ root.render(
|
|
|
744
748
|
<LocaleProvider locale={_rootLocale as any}>
|
|
745
749
|
<CartProvider>
|
|
746
750
|
<FlyToCartProvider>
|
|
747
|
-
<
|
|
751
|
+
<PageDataProvider data={{}}>
|
|
752
|
+
<PreviewApp />
|
|
753
|
+
</PageDataProvider>
|
|
748
754
|
</FlyToCartProvider>
|
|
749
755
|
</CartProvider>
|
|
750
756
|
</LocaleProvider>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onexapis/cli",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.36",
|
|
4
4
|
"description": "CLI tool for OneX theme development - scaffolds themes using @onexapis/core",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
52
|
"@aws-sdk/client-s3": "^3.470.0",
|
|
53
|
-
"@onexapis/core": "^1.0.
|
|
53
|
+
"@onexapis/core": "^1.0.6",
|
|
54
54
|
"@tanstack/react-query": "^5.90.16",
|
|
55
55
|
"adm-zip": "^0.5.16",
|
|
56
56
|
"archiver": "^7.0.1",
|
|
@@ -348,69 +348,64 @@ export const mySchema: SectionSchema = {
|
|
|
348
348
|
| `url` | URL input | Link href |
|
|
349
349
|
| `array` / `repeater` | List of repeating items | Feature list, social links |
|
|
350
350
|
|
|
351
|
-
## Available Hooks
|
|
351
|
+
## Available Hooks (44 hooks)
|
|
352
352
|
|
|
353
|
-
|
|
353
|
+
All hooks import from `@onexapis/core/hooks`. Use `onexthm_list_hooks` MCP tool for full API details.
|
|
354
354
|
|
|
355
355
|
```tsx
|
|
356
356
|
import {
|
|
357
357
|
useProducts,
|
|
358
358
|
useCart,
|
|
359
|
-
|
|
359
|
+
useCheckout,
|
|
360
360
|
useDesignSystem,
|
|
361
361
|
} from "@onexapis/core/hooks";
|
|
362
362
|
```
|
|
363
363
|
|
|
364
|
-
###
|
|
364
|
+
### Quick Reference
|
|
365
|
+
|
|
366
|
+
| Category | Hooks |
|
|
367
|
+
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
368
|
+
| **Commerce** (11) | `useProducts`, `useProductBySlug`, `useProductById`, `useProductCategories`, `useBlogs`, `useBlogBySlug`, `useBlogById`, `useBlogCategories`, `useSettings`, `useProductListing`, `useBlogListing` |
|
|
369
|
+
| **State** (3) | `useCart`, `useAuth`, `useOrders` |
|
|
370
|
+
| **Checkout** (8) | `useCheckout`, `usePayment`, `useOrderLookup`, `useOrderStatus`, `useOrderSuccess`, `useOrderSummary`, `useFinance`, `saveBuyNowItem` |
|
|
371
|
+
| **Products** (3) | `useSearchProducts`, `useAddToCart`, `useProductDetail` |
|
|
372
|
+
| **Theme** (8) | `useDesignSystem`, `useCommerceData`, `useThemeMode`, `useLocale`, `useViewport`, `usePageData`, `useWebsiteSettings`, `useMotion` |
|
|
373
|
+
| **Utilities** (7) | `useDebounce`, `useMediaQuery`, `useIsMobile`, `useIsTablet`, `useIsDesktop`, `useContactForm`, `useCopyToClipboard`, `useFormatPrice`, `formatVndPrice` |
|
|
374
|
+
| **Animation** (1) | `useFlyToCart` |
|
|
375
|
+
| **Server** (4) | `fetchProducts`, `fetchBlogs`, `fetchSettings`, `prefetchSectionData` |
|
|
376
|
+
|
|
377
|
+
### Most Used Patterns
|
|
365
378
|
|
|
366
379
|
```tsx
|
|
367
|
-
//
|
|
368
|
-
const { data, isLoading } = useProducts({ limit: 8
|
|
380
|
+
// Fetch products
|
|
381
|
+
const { data, isLoading } = useProducts({ limit: 8 });
|
|
369
382
|
const products = data?.data ?? [];
|
|
370
383
|
|
|
371
|
-
//
|
|
372
|
-
const {
|
|
384
|
+
// Cart
|
|
385
|
+
const { items, addItem, itemCount, subtotal } = useCart();
|
|
373
386
|
|
|
374
|
-
//
|
|
375
|
-
const {
|
|
376
|
-
const blogs = data?.data ?? [];
|
|
387
|
+
// Auth
|
|
388
|
+
const { user, isAuthenticated, login, logout } = useAuth();
|
|
377
389
|
|
|
378
|
-
//
|
|
379
|
-
const {
|
|
380
|
-
|
|
390
|
+
// Checkout (full form)
|
|
391
|
+
const checkout = useCheckout({ paymentRedirectUrl: "/payment" });
|
|
392
|
+
// checkout.fullName, checkout.handleCheckout, checkout.errors
|
|
381
393
|
|
|
382
|
-
|
|
394
|
+
// Product detail with buy now
|
|
395
|
+
const detail = useProductDetail({ slug: routeParams.slug });
|
|
396
|
+
// detail.product, detail.handleAddToCart, detail.handleBuyNow
|
|
383
397
|
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
// Authentication
|
|
389
|
-
const auth = useAuth();
|
|
390
|
-
await auth.login(email, password);
|
|
391
|
-
await auth.signup({ username, email, password, name });
|
|
392
|
-
auth.logout();
|
|
393
|
-
await auth.forgotPassword(email);
|
|
394
|
-
|
|
395
|
-
// Orders
|
|
396
|
-
const { createOrder, getOrders } = useOrders();
|
|
397
|
-
```
|
|
398
|
+
// Search with debounce
|
|
399
|
+
const search = useSearchProducts({ debounceMs: 300 });
|
|
400
|
+
// search.query, search.setQuery, search.results
|
|
398
401
|
|
|
399
|
-
|
|
402
|
+
// Responsive
|
|
403
|
+
const isMobile = useIsMobile();
|
|
404
|
+
const isDesktop = useIsDesktop();
|
|
400
405
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
// colors.primary, colors.secondary, colors.background, etc.
|
|
405
|
-
|
|
406
|
-
// Server-side data from SectionComponentProps.data
|
|
407
|
-
const { products, blogs, settings, company } = useCommerceData(data);
|
|
408
|
-
|
|
409
|
-
// Other contexts
|
|
410
|
-
const { mode, isDark } = useThemeMode();
|
|
411
|
-
const { locale, setLocale } = useLocale();
|
|
412
|
-
const { isMobile, isDesktop } = useViewport();
|
|
413
|
-
const motionTokens = useMotion();
|
|
406
|
+
// Price formatting
|
|
407
|
+
const { formatPrice } = useFormatPrice();
|
|
408
|
+
formatPrice(1250000); // "1.250.000đ"
|
|
414
409
|
```
|
|
415
410
|
|
|
416
411
|
## Color System
|
|
@@ -469,44 +464,36 @@ Without these, the editor cannot select sections/blocks for editing.
|
|
|
469
464
|
|
|
470
465
|
34 built-in components from `@onexapis/core` that render inside sections via `ComponentRenderer`:
|
|
471
466
|
|
|
472
|
-
| Component
|
|
473
|
-
|
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
| `progress` | Progress bar | value (0-100), label, color |
|
|
485
|
-
| `rating` | Star rating | value (1-5), readOnly, size |
|
|
486
|
-
| `social-links` | Social media links | Reads from WebsiteSettings context |
|
|
487
|
-
| `hotline-contacts` | Contact info | Reads from WebsiteSettings context |
|
|
488
|
-
| `company-info` | Company details | Reads from WebsiteSettings context |
|
|
489
|
-
| `product-card` | Product display | product (Product), showQuickAdd |
|
|
490
|
-
| `blog-card` | Blog post card | blog (Blog) |
|
|
467
|
+
| Component | Description | Key Settings |
|
|
468
|
+
| --------- | ----------- | ------------ |
|
|
469
|
+
|
|
470
|
+
**Text:** `heading` (H1-H6), `paragraph`, `quote`
|
|
471
|
+
**Interactive:** `button` (default/outline/ghost/link), `link`, `input`, `textarea`, `checkbox`, `select`
|
|
472
|
+
**Media:** `image`, `video` (youtube/vimeo/hosted), `icon` (Lucide icons), `gallery`
|
|
473
|
+
**Layout:** `divider`, `spacer`, `container`, `grid`, `columns`, `card`
|
|
474
|
+
**Display:** `badge`, `alert`, `progress`, `rating`, `timer`, `list`, `table`, `accordion`, `tabs`, `code`, `map`
|
|
475
|
+
**Special:** `product-card`, `blog-card`, `social-links`, `hotline-contacts`, `company-info`
|
|
476
|
+
**Decorative:** `torn-separator`
|
|
477
|
+
|
|
478
|
+
Use `onexthm://components` MCP resource for full details (content/style fields, slots, examples).
|
|
491
479
|
|
|
492
480
|
Components are rendered via `ComponentRenderer` — you don't import them directly.
|
|
493
481
|
|
|
494
482
|
## Component Slots
|
|
495
483
|
|
|
496
|
-
Components use `slot` to
|
|
484
|
+
Components use `slot` to identify their role:
|
|
497
485
|
|
|
498
486
|
```tsx
|
|
499
|
-
// In section component
|
|
500
487
|
const titleComp = components.find((c) => c.slot === "section-title");
|
|
501
488
|
const ctaButton = components.find((c) => c.slot === "cta-button");
|
|
502
|
-
const subtitle = components.find((c) => c.slot === "description");
|
|
503
489
|
```
|
|
504
490
|
|
|
505
|
-
Common
|
|
491
|
+
Common slots: `section-title`, `section-subtitle`, `description`, `cta-button`, `secondary-cta`, `badge`, `icon`, `image`, `block-title`, `block-description`, `feature-icon`
|
|
506
492
|
|
|
507
493
|
## Block System
|
|
508
494
|
|
|
509
|
-
Blocks are nested containers inside sections. They
|
|
495
|
+
Blocks are nested containers inside sections. They hold components and can nest other blocks.
|
|
496
|
+
Use `onexthm://blocks` MCP resource for full block patterns (features, testimonials, pricing, FAQ, team).
|
|
510
497
|
|
|
511
498
|
```tsx
|
|
512
499
|
// Section → Blocks → Components
|
|
@@ -526,6 +513,68 @@ Blocks are nested containers inside sections. They can contain components AND ot
|
|
|
526
513
|
|
|
527
514
|
Use `BlockRenderer` to render blocks — it handles recursive nesting automatically.
|
|
528
515
|
|
|
516
|
+
### Defining Blocks in Schema
|
|
517
|
+
|
|
518
|
+
```tsx
|
|
519
|
+
// In your-section.schema.ts
|
|
520
|
+
export const mySchema: SectionSchema = {
|
|
521
|
+
type: "features",
|
|
522
|
+
// ...settings, defaults...
|
|
523
|
+
blocks: [
|
|
524
|
+
{
|
|
525
|
+
type: "feature-item",
|
|
526
|
+
name: "Feature Item",
|
|
527
|
+
limit: 6, // Max 6 blocks of this type
|
|
528
|
+
settings: [
|
|
529
|
+
{
|
|
530
|
+
id: "backgroundColor",
|
|
531
|
+
type: "color",
|
|
532
|
+
label: "Background",
|
|
533
|
+
default: "#FFFFFF",
|
|
534
|
+
},
|
|
535
|
+
],
|
|
536
|
+
components: [
|
|
537
|
+
{ type: "icon", slot: "feature-icon", label: "Icon" },
|
|
538
|
+
{ type: "heading", slot: "block-title", label: "Title" },
|
|
539
|
+
{ type: "paragraph", slot: "block-description", label: "Description" },
|
|
540
|
+
],
|
|
541
|
+
},
|
|
542
|
+
],
|
|
543
|
+
};
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
### Rendering Blocks
|
|
547
|
+
|
|
548
|
+
```tsx
|
|
549
|
+
const blocks = (section.blocks || []).filter((b) => b.enabled !== false);
|
|
550
|
+
|
|
551
|
+
{
|
|
552
|
+
blocks.map((block) => (
|
|
553
|
+
<div
|
|
554
|
+
key={block.id}
|
|
555
|
+
data-section-id={section.id} // REQUIRED
|
|
556
|
+
data-block-id={block.id} // REQUIRED
|
|
557
|
+
data-block-type={block.type} // REQUIRED
|
|
558
|
+
className="p-6 rounded-xl border"
|
|
559
|
+
>
|
|
560
|
+
<BlockRenderer
|
|
561
|
+
block={block}
|
|
562
|
+
sectionId={section.id}
|
|
563
|
+
isEditing={isEditing}
|
|
564
|
+
/>
|
|
565
|
+
</div>
|
|
566
|
+
));
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
{
|
|
570
|
+
blocks.length === 0 && isEditing && (
|
|
571
|
+
<div className="text-center py-12 border-2 border-dashed border-gray-300 rounded-lg">
|
|
572
|
+
<p className="text-gray-500">Add blocks to populate this section</p>
|
|
573
|
+
</div>
|
|
574
|
+
);
|
|
575
|
+
}
|
|
576
|
+
```
|
|
577
|
+
|
|
529
578
|
## Animation System
|
|
530
579
|
|
|
531
580
|
Sections, blocks, and components support animations via framer-motion:
|