@enyxs/wikex-components
Reusable Material UI blocks with CMS metadata and inline-edit support.
Included blocks
hero-bannerfeature-gridimage-textcall-to-actionannouncement-barmetrics-striptestimonial-gridfaq-sectionpricing-planslogo-cloudsite-header(Minimal UI)centered-header(Minimal UI)utility-header(Minimal UI)site-footer(Minimal UI)compact-footer(Minimal UI)newsletter-footer(Minimal UI)social-footer(Minimal UI)download-section(Wikex)- Bộ section Wikex Commodity cho landing, giới thiệu, chính sách, khiếu nại, thông tin, thông báo MXV, sản phẩm, biểu phí và coming-soon
Các block Wikex Commodity thuộc category wikex, cho phép admin hiển thị riêng
thư viện component của website hàng hóa.
Package cũng export wikexCommodityPageTemplates và wikexCommodityRoutes từ
entry @enyxs/wikex-components/page-templates. Đây là nguồn route/template dùng
chung giữa frontend và CMS, không kéo Material UI vào code chỉ cần metadata route.
Wikex download assets are stored in src/wikex/assets/download-section/. Replace the placeholder
files there, then update src/wikex/download-assets.ts if the filenames or formats change.
Install
Before publishing to an npm registry, consume the versioned GitLab package:
npm install git+ssh://[email protected]/tamenyxs/wikex-components.git#v0.8.1
Use with a CMS registry
import { wikexCmsBlocks } from "@enyxs/wikex-components";
export const cmsCodeBlocks = [...wikexCmsBlocks];
The package has React, Material UI and Emotion as peer dependencies, so the host app owns their versions.
Release
0.11.50
Audit fixes. Partner art ships as WebP at 2× display size (npm tarball 32 MB → 1.6 MB). Each breakpoint downloads only its own variant, and below-the-fold art loads lazily. Saved /partner-assets/*.png overrides are mapped to the new .webp files. Every CMS-controlled href now goes through the safeCmsTextHref link policy. # links and disabled header items are never marked as the current page. Package blocks render <div> roots instead of <main>. The legacy commodity-partner-registration block submits kind: partner with a region. The complaints support form is disabled with a contact note, because no backend accepts it yet. The dead Lenis/Swiper code is removed. i18next, lucide, morphicons and radix-ui are now peer dependencies (UI peers are optional for model-only consumers), and next is bounded to >=16 <17. Exports use nested types conditions and add ./package.json and ./chrome/model/styles.css. Frontend and backend must pin the same published version.
0.11.49
Desktop header submenus open smoothly when moving straight from one submenu to another: the menu that just opened no longer closes itself because focus returned to the previous trigger. Escape and clicking outside still return focus to the trigger. Submenus fade and slide in (180 ms) and fade out (120 ms), with no motion when reduced motion is requested. No CMS schema or manifest changes. Frontend and backend must pin the same published version.
0.11.48
Header submenu links now match the query string as well as the pathname. Siblings that share a path, such as /thong-bao/?source=wikex and /thong-bao/?source=mxv, are no longer highlighted together; only the most specific matching link is active, in both the desktop dropdown and the mobile drawer. A parent item stays active on any page under its children's paths. No CMS schema or manifest changes. Frontend and backend must pin the same published version.
0.11.47
Adds per-device CMS layout profiles and independent editable images for the three landing hero metrics. The partner hero includes the broker application form, shared validation, date and address inputs, and localized text. Runtime exports, types, embedded artwork, and the generated CMS manifest ship together. Frontend and backend must pin the same published version.
npm run check
npm run build
git tag v0.8.1
git push origin main --tags
Editable fees and margin table
commodity-fees supports editing every data cell and column title in CMS preview,
adding/removing rows and columns with confirmation dialogs, and selecting multiple tags per row with MUI Select.
Search ignores Vietnamese accents and searches commodity names/codes. Tag and
search filters are combined before pagination (25 rows per page by default; selectable 5/10/25/50/100/all). Adding a row
clears filters and opens its page. Deleting all rows keeps the table empty.
CMS stores the table as JSON strings in vi.feesTable and en.feesTable, so the
existing page save/publish flow persists it without separate database tables.
Old pages retain their original sample table until edited. Visitors only get
search, tag filters and pagination, with no editing controls.
For another app, import FeesTable and FeesTableData from
@enyxs/wikex-components. Pass controlled value, onChange, and editable.
The component supplies its table theme; provide the package's existing icon
assets for pagination, as with other Wikex components. Run npm run test:fees
for data/search/pagination regression checks.
Create tags from the toolbar dialog; unassigned tags persist in the table catalog. Editor textareas automatically fit their text. Header actions share an aligned row.
In Căn lề theo cột, choose from the table's current columns, then select left,
center or right. This aligns the column header and every value in that column,
including filtered rows, other pages and newly added rows. Mặc định resets
only that column. Settings persist in columns[].textAlign, follow the column's
key across reordering, and apply on desktop/mobile. Choosing column alignment
also removes legacy per-cell overrides in that column so values stay consistent.
Other columns keep their settings. setFeesColumnAlignment is exported from
fees/model; the old per-cell helper remains only for compatibility.
The Định dạng chữ panel retains table-wide font size and weight controls.
Server-side consumers must use the updated fees/model validator to retain
column alignment when saving and reading table data.
Public tables display commodity names in locale-aware A–Z order before pagination.
The editor keeps manual row positions while typing; Sắp xếp tên A–Z sorts all
rows (including filtered-out rows) and returns to page one. Save the table to
persist this order. sortFeesRowsByName is also exported from fees/model.
Product UI and shared controls
Import product UI from @enyxs/wikex-components/products and standalone
ProductCard, Pagination, Breadcrumb (with their prop types) from
@enyxs/wikex-components/ui. These are client entries; the product UI supplies
its own styled-components theme. Standalone controls use the host's Wikex theme.
Icons and the default product placeholder are bundled into the package.
import { ProductListing, ProductDetailView, ProductListingSkeleton } from '@enyxs/wikex-components/products';
<ProductListing products={items} />
<ProductDetailView product={detail} related={items} listingHref="/san-pham/" />
<ProductListingSkeleton language="vi" />
Each list item supplies href; the host owns the API, categories, publication
rules, SEO and route generation. The detail view accepts introduction, contract
specifications, quality tables (including per-table columns, units, conditions
and source notes). Pass language="en", homeHref, or placeholderImage to
customize navigation, labels and fallback imagery. Product listing renders and
paginates the supplied public list; category selection belongs to the host menu; no API is called by this UI.
Existing CMS demo blocks remain available through the root entry.
Run npm run check, npm run build, and npm run test:products before packaging.
ESM and CommonJS builds preserve client directives and matching styled-components
IDs for server rendering and hydration.
Fees management UI and shared validation
Import FeesManager and its prop types from @enyxs/wikex-components/fees.
This controlled screen includes the table selector, language selector, save
button, notices, row/column counts and the responsive management layout. Supply
entries, selectedId, language, table, dirtyKeys (id:language),
canWrite, saving and the selection/change/save callbacks. The host owns API
calls, authentication, draft state and navigation warnings. The host may pass
statusChipVariant if its MUI theme supports additional Chip variants.
Import pure types, validateFeesTable, defaultFeesTable, parseFeesTable,
filtering, pagination and ordering helpers from
@enyxs/wikex-components/fees/model. This entry has no React or CMS dependency
and can run on a backend. Strict validation throws for invalid table data;
parseFeesTable retains public rendering's legacy fallback behavior.
Consultation forms and management
The original landing registration renderer accepts onConsultationSubmit, an
async callback receiving ConsultationSubmission exported from the root entry.
It preserves the existing form style, uses MUI selects and shows accessible
success/error notices. While sending, fields are disabled; failures retain the
values and submission ID for idempotent retries. Success clears all fields.
Editable CMS previews do not submit live requests. The host owns the endpoint,
validation, authentication and storage. The separate partnership form is unchanged.
Use ConsultationManager from @enyxs/wikex-components/consultations for the
controlled admin table, filters, pagination, detail/status/notes dialog and delete
confirmation. Supply data, permissions and API callbacks. Pure models and labels
are exported from @enyxs/wikex-components/consultations/model.
Editable Wikex header and footer lists
commodity-header defines vi.header.menuItems and en.header.menuItems.
Each item has label, href, and a children list with its own label/href items.
commodity-footer defines these lists in both languages:
footer.aboutLinks, footer.productLinks, footer.guideLinks,
footer.supportLinks, footer.contacts, footer.socials, and footer.downloads.
Contact, social, and download items include an icon; downloads also have prefix.
Lists and nested lists use JSON strings, following the existing CMS field contract.
An explicit [] removes a list's items.
Hosts can import migrateWikexChromeContent from
@enyxs/wikex-components/chrome/model before merging defaults or saving content.
It migrates legacy labels, links, text formatting, and removed items into the lists;
renderers also apply this migration for older saved pages.
Liên kết hai nút Header
commodity-header hỗ trợ vi.header.loginHref, vi.header.loginLinkType,
vi.header.registerHref, vi.header.registerLinkType và các khóa tương ứng en.*.
internal nhận /duong-dan/ hoặc #muc, mở trong tab hiện tại; external nhận
URL HTTP(S), mở tab mới với noopener noreferrer. URL trống sẽ tắt liên kết.
Mặc định “Mở Tài khoản” trỏ tới /#register; “Đăng nhập” chưa có liên kết.
Host CMS có thể đặt CmsButtonLinkControl trong thanh công cụ element, truyền
field, content và onChange(changes) để cập nhật các khóa trong cùng một
transaction undo/autosave. Hai nút vẫn chọn và sửa được trong chế độ editor.
Liên kết nút tải ứng dụng
CmsButtonLinkControl cũng hỗ trợ App Store, Google Play và Web Trading/Desktop
trong download-section và commodity-footer. Trong Select element, bấm vào
nút, chọn biểu tượng liên kết, chọn Internal/External, nhập đường dẫn và Áp dụng.
Khối tải lưu {vi|en}.landing.download.{appStore|googlePlay|web}Href và
LinkType; các field chọn trên canvas là ...appStorePrefix, ...googlePlayPrefix
và ...webPrefix. Footer giữ href và linkType trong item của danh sách
{vi|en}.footer.downloads; chọn label hoặc prefix đều sửa link của cả nút.
Các URL footer cũ tự nhận loại liên kết theo URL khi chưa có linkType.
Chạy node scripts/check-download-button-links.cjs sau build để kiểm tra liên kết
hai ngôn ngữ, HTML editor, lưu danh sách, bỏ liên kết và URL không hợp lệ.
Trang đối tác môi giới IB
wikexPartnerBlocks (cũng có trong wikexCommodityBlocks / wikexCmsBlocks)
chứa 7 block độc lập: commodity-partner-hero, commodity-partner-challenges,
commodity-partner-benefits, commodity-partner-commission,
commodity-partner-process, commodity-partner-faq, commodity-partner-registration.
Template commodity-partner đăng ký route /doi-tac-moi-gioi với header/footer chung.
Mỗi block nhận CmsRendererProps sẵn có. Trường vi.partner.* là nội dung tiếng Việt, en.partner.* là tiếng Anh:
chọn chữ trong preview để dùng select element / toolbar hiện tại; sửa inline gọi
onChange(field, value), chọn chữ gọi onSelectText. ID của từng card/FAQ độc lập,
không phụ thuộc nội dung. Nhãn và placeholder form cũng có trường riêng; dữ liệu
khách nhập không trở thành nội dung CMS. FAQ mở sẵn khi chỉnh sửa để chọn câu trả lời.
Trường partnerImage.* có type: image, chia riêng desktop/mobile. Nhấn “Thay ảnh”
trên ảnh chính hoặc chọn trực tiếp từng lớp hình/icon để gọi onImageRequest.
Các mask, gradient, đường kẻ, bóng và khung là trang trí cố định. Thay ảnh vẫn giữ
mask và bố cục gốc. Trường màu, TextLayout và __cmsElements dùng cơ chế chung,
bao gồm ẩn/xóa text/ảnh và thêm element. Các block có nội dung mặc định VI và EN; CMS ghi đè riêng theo từng ngôn ngữ.
Ảnh gốc được phân phối dưới dạng file tĩnh, không nhúng vào JavaScript. Ứng dụng host cần chép assets vào public (frontend nguồn đã có các file này):
mkdir -p public/partner-assets
cp -R node_modules/@enyxs/wikex-components/assets/partner-assets/. public/partner-assets/
Form gọi onConsultationSubmit với kind: broker, dùng chung validate, cooldown và toast MUI với form tư vấn/đối tác. Host chịu trách nhiệm gửi API; trong editor không gửi đăng ký. Chạy node scripts/check-partner-blocks.cjs
sau npm run build để kiểm tra schema, render, override text/ảnh và template.
Native IB page
The IB blocks render the original HTML and styled-components from frontend
commit 13f09404 (fix UI IB). Their public and editor hosts use no MUI
components. Import the isolated client entry when embedding the page:
import { PartnerPage, wikexPartnerBlocks } from '@enyxs/wikex-components/partner';
import '@enyxs/wikex-components/partner/styles.css';
<PartnerPage />
PartnerPage is the seven-section page body. The host supplies its shared site
header/footer. All existing block types, vi.partner.* text fields,
partnerImage.* slots and CMS callbacks remain compatible. The source native
Button and InputCommon are kept under src/wikex/partner/primitives.
Native editing also supports hidden/added elements, typography, rich text,
read-only fields and text lists without MUI. Masks and decorative layers retain
the original dimensions; scoped baseline rules protect them from host styles
such as img { max-width: 100% } and inherited body line height.
The partner page hosts remain native HTML. Registration notifications reuse the existing MUI Alert/Portal/Snackbar shared with consultation and partner forms.
The shared footer also retains the source page’s mobile overrides on /doi-tac-moi-gioi.
Original artwork is still copied to public/partner-assets as described above.
Pass onConsultationSubmit to connect broker registration; the form keeps input on failure, shares validation and toast behavior, and supports browser autofill on its dark inputs.
IB content languages and persistence
IB defaults live in src/wikex/partner/fields.ts (VI) and english.ts (EN).
Each of the 70 text fields has an independent VI/EN key. content.__cmsLanguage
selects the active language (vi by default); e.g.
<PartnerPage content={{ __cmsLanguage: 'en' }} />.
Placeholders, image descriptions and accessible labels follow that language too.
CMS edits use the existing save flow. A component can store both
vi.partner.hero.title and en.partner.hero.title in its content JSON.
The host merges package defaults with saved overrides; saved values win, including
intentional empty text. Defaults equal to the source are compacted out of DB
content, so adding EN defaults requires no data migration or database writes.
Existing VI keys/overrides remain intact. Shared images retain their existing keys.
Both frontend and backend registries must use the same local package/manifest.
Run npm run test:partner:language for locale selection and independent override checks.
Release 0.11.39
Includes broker registration with shared validation/toasts and dark autofill styling; API fees tables with full columns, field selection for new/existing columns, column visibility, read-only API rows and a separate manual-table snapshot. API column mappings and raw field values survive strict validation, autosave, publication and history.
Run npm run build before packaging. The build regenerates dist/manifest.json from the same block definitions exported by dist/index.js; both the runtime and manifest are included in the npm tarball. Frontend and backend should pin the same package version and regenerate host assets after installation.