@gemboss/gem-framework 0.18.13 → 0.18.15
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 +28 -0
- package/dist/SOURCE.json +3 -3
- package/dist/editions.js +2 -0
- package/dist/gem-framework.css +7 -6
- package/dist/gem-runtime.js +655 -1
- package/dist/index.js +692 -11
- package/dist/plugins/reviews.d.ts +9 -0
- package/dist/plugins/reviews.js +670 -0
- package/dist/popup-shell.css +4 -4
- package/dist/primitives.css +1 -1
- package/dist/section-gate.js +681 -8
- package/dist/sections.css +1 -1
- package/dist/tokens.css +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -93,6 +93,34 @@ Từ 0.8.2 mỗi module có `.d.ts` cạnh nó (`mount(root?: ParentNode | null,
|
|
|
93
93
|
|
|
94
94
|
## Nhật ký thay đổi
|
|
95
95
|
|
|
96
|
+
- **0.18.15** (20/10/2026): plugin `reviews`, engine danh sách review (GemFactory gap #44). 8 section product-reviews của
|
|
97
|
+
GemFactory mỗi cái mang một bản riêng của cùng một lõi trong behavior.js (14–27 KB mỗi cái); nay lõi đó là MỘT plugin:
|
|
98
|
+
`gem-runtime.js` (load `idle`) hoặc `import { mount } from "@gemboss/gem-framework/plugins/reviews"`. Section xin engine bằng
|
|
99
|
+
`data-rv-root` trên gốc của nó; section không có dấu đó (vẫn mang lõi riêng) không bị gắn, nên lõi riêng và plugin không chạy
|
|
100
|
+
chồng. Hợp đồng chỉ là thuộc tính `data-rv-*` (đầy đủ ở đầu `reviews-engine.ts`):
|
|
101
|
+
- Lõi: sort (menu hoặc select, 13 khoá), lọc sao / có ảnh / chủ đề / quốc gia / tìm (trễ 180 ms) / xoá lọc, trang số (một hay
|
|
102
|
+
nhiều thanh, cửa sổ cố định hoặc `1 2 3 4 … n`) hoặc xem thêm, đếm, đọc thêm, menu, sheet lọc, hữu ích một lần mỗi review
|
|
103
|
+
(`gem:review:vote` trên hub và trên window), lightbox.
|
|
104
|
+
- Chỗ 8 section khác nhau thành thuộc tính: thu gọn N review đầu (`data-rv-collapsed` + `data-rv-expand`), Show N mỗi trang,
|
|
105
|
+
nhãn trang, sao giữ khi bấm lại (`data-rv-star-keep`), chip bộ lọc đang bật, sheet có Apply / Reset, vùng bật tắt và vùng tự
|
|
106
|
+
bỏ lọc khi đóng, dải trượt, tô chữ tìm thấy, chữ số ít (`data-rv-count-one`, `data-rv-status-one`), số theo locale
|
|
107
|
+
(`data-rv-locale`), lightbox (đầu cuối ẩn / mờ / vòng, tập ảnh theo review / nhóm / danh sách JSON của thẻ, bỏ trùng, ảnh kế
|
|
108
|
+
ló ra, vuốt, nền mờ, bỏ phiếu từ trong lightbox hoặc chỉ xem).
|
|
109
|
+
- Khác bản cũ có chủ đích: chọn một mục trong menu thì focus về nút của menu (bản cũ để focus rơi xuống `<body>`); cửa sổ trang
|
|
110
|
+
cố định không còn vẽ dấu … trước trang đầu cửa sổ.
|
|
111
|
+
- Còn ở behavior của từng section: masonry, carousel vòng vô tận + tự chạy, hộp đọc cả review, dịch, sắp xếp hỏi đáp, thẻ chen
|
|
112
|
+
giữa. Chúng vẽ lại theo `gem:reviews:render` (phát trên hub VÀ trên gốc section), và nhờ engine vẽ lại bằng
|
|
113
|
+
`gem:reviews:refresh` trên gốc.
|
|
114
|
+
Đối chiếu trong Chromium trên markup thật của cả 8 section, cùng một chuỗi thao tác (sort, sao, lọc, trang, xem thêm, đọc thêm,
|
|
115
|
+
hữu ích, lightbox, menu; 1280 và 390), behavior.js gốc so với engine: trạng thái trùng từng bước, trừ khác biệt có chủ đích ở trên
|
|
116
|
+
và phần còn ở section.
|
|
117
|
+
- **0.18.14** (20/10/2026): lớp phủ tối là một token (GemFactory gap #17). Khoá màu TUỲ CHỌN `color.scrim` (phát thành
|
|
118
|
+
`--gem-color-scrim`) là màu lớp phủ ở độ đậm tối đa; nền sau dialog popup (55%), lớp tối trên ảnh nền popup (35% → 60%), nền sau
|
|
119
|
+
cart drawer (36%) và lớp tối trên ảnh của hero mặc định (32%) đọc nó qua `gemScrim(N)` = `color-mix(in srgb,
|
|
120
|
+
var(--gem-color-scrim, #000) N%, transparent)`. Không đặt thì ra ĐÚNG như trước (đo Chromium: 5/5 độ đậm trùng từng giá trị
|
|
121
|
+
pixel với màu viết cứng cũ); preset đặt màu có alpha (`rgb(0 0 0 / .7)`) thì mọi lớp phủ nhạt cùng tỉ lệ. Băng dark / accent
|
|
122
|
+
không đảo khoá này. Cảnh báo `untokenized_visual_value` trên một màu đen có alpha giờ chỉ thẳng cách viết bằng token, giữ đúng
|
|
123
|
+
độ đậm.
|
|
96
124
|
- **0.18.13** (20/10/2026): ô nhập, select, textarea có trạng thái hover và lỗi (§9.2; GemFactory Framework › Controls đo cả
|
|
97
125
|
hai là INERT). Hover dày viền thêm 1px theo màu chữ của ô (vòng theo hộp; ô gạch chân và ô tô nền chỉ dày cạnh đáy), chỉ trên
|
|
98
126
|
máy có chuột (`@media (hover: hover)`), không áp cho ô disabled hay ô lỗi. Lỗi (`aria-invalid="true"`, do form đặt) tô viền
|
package/dist/SOURCE.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"package": "@gemboss/gem-framework",
|
|
3
|
-
"version": "0.18.
|
|
4
|
-
"gemtheme_sha": "
|
|
3
|
+
"version": "0.18.15",
|
|
4
|
+
"gemtheme_sha": "998fe4dc3096e9bc0a8e9d39e23b27081138b2c9",
|
|
5
5
|
"gemtheme_dirty": false,
|
|
6
|
-
"framework_version": "0.18.
|
|
6
|
+
"framework_version": "0.18.15"
|
|
7
7
|
}
|
package/dist/editions.js
CHANGED
|
@@ -83,6 +83,8 @@ var GEM_MOTION_SCALE_DEFAULTS = {
|
|
|
83
83
|
blur: "8px"
|
|
84
84
|
};
|
|
85
85
|
var optionalGemTokenKeys = {
|
|
86
|
+
// Lớp phủ tối (GemFactory gap #17): xem GEM_SCRIM_FALLBACK / gemScrim bên dưới.
|
|
87
|
+
color: ["scrim"],
|
|
86
88
|
typography: [...GEM_TYPE_RAMP_KEYS, ...GEM_LINE_HEIGHT_TOKEN_KEYS, ...GEM_BUTTON_TOKEN_KEYS.typography],
|
|
87
89
|
spacing: [...Object.keys(GEM_DERIVED_SPACE_STEPS), ...GEM_PHONE_TOKEN_TARGETS.spacing.map((k) => `${k}Mobile`)],
|
|
88
90
|
layout: GEM_PHONE_TOKEN_TARGETS.layout.map((k) => `${k}Mobile`),
|
package/dist/gem-framework.css
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
--gem-color-success: #008060;
|
|
10
10
|
--gem-color-warning: #9a661a;
|
|
11
11
|
--gem-color-danger: #d72c0d;
|
|
12
|
+
--gem-color-scrim: #000;
|
|
12
13
|
--gem-font-body: Inter, system-ui, sans-serif;
|
|
13
14
|
--gem-font-heading: Inter, system-ui, sans-serif;
|
|
14
15
|
--gem-font-mono: ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
@@ -1295,7 +1296,7 @@ a {
|
|
|
1295
1296
|
.gem-cart-drawer__overlay {
|
|
1296
1297
|
position: fixed;
|
|
1297
1298
|
inset: 0;
|
|
1298
|
-
background:
|
|
1299
|
+
background: color-mix(in srgb, var(--gem-color-scrim, #000) 36%, transparent);
|
|
1299
1300
|
}
|
|
1300
1301
|
@keyframes gem-cart-drawer-panel-in { from { translate: calc(var(--gem-drawer-offset, 24px) * var(--gem-drawer-dir, 1)) 0; opacity: 0; } }
|
|
1301
1302
|
@keyframes gem-cart-drawer-overlay-in { from { opacity: 0; } }
|
|
@@ -1571,7 +1572,7 @@ a {
|
|
|
1571
1572
|
width: min(880px, 92vw); max-width: none; max-height: min(640px, 92vh); overflow: hidden;
|
|
1572
1573
|
border-radius: var(--gem-radius-lg); box-shadow: var(--gem-shadow-md);
|
|
1573
1574
|
}
|
|
1574
|
-
.gem-popup-shell__dialog::backdrop { background:
|
|
1575
|
+
.gem-popup-shell__dialog::backdrop { background: color-mix(in srgb, var(--gem-color-scrim, #000) 55%, transparent); }
|
|
1575
1576
|
.gem-popup-shell__frame { position: relative; display: grid; grid-template-columns: 1fr 1fr; min-height: 520px; height: 100%; }
|
|
1576
1577
|
.gem-popup-shell__media { position: relative; min-width: 0; overflow: hidden; background: var(--gem-color-surface); }
|
|
1577
1578
|
.gem-popup-shell__image { display: block; width: 100%; height: 100%; object-fit: cover; }
|
|
@@ -1594,7 +1595,7 @@ a {
|
|
|
1594
1595
|
.gem-popup-shell[data-gem-popup-desktop='card-over-image'] .gem-popup-shell__panel {
|
|
1595
1596
|
width: min(420px, 86%); margin: var(--gem-space-xl) 0; background: var(--gem-color-background); border-radius: var(--gem-radius-lg); box-shadow: var(--gem-shadow-sm);
|
|
1596
1597
|
}
|
|
1597
|
-
.gem-popup-shell[data-gem-popup-media='background'] .gem-popup-shell__media::after { content: ''; position: absolute; inset: 0; background: linear-gradient(
|
|
1598
|
+
.gem-popup-shell[data-gem-popup-media='background'] .gem-popup-shell__media::after { content: ''; position: absolute; inset: 0; background: linear-gradient(color-mix(in srgb, var(--gem-color-scrim, #000) 35%, transparent), color-mix(in srgb, var(--gem-color-scrim, #000) 60%, transparent)); }
|
|
1598
1599
|
.gem-popup-shell[data-gem-popup-media='background'] .gem-popup-shell__panel,
|
|
1599
1600
|
.gem-popup-shell[data-gem-popup-media='background'] .gem-popup-shell__close { color: #fff; }
|
|
1600
1601
|
.gem-popup-shell__close {
|
|
@@ -1641,10 +1642,10 @@ a {
|
|
|
1641
1642
|
.gem-popup-shell[data-gem-popup-media='background'] .gem-popup-shell__frame { grid-template-rows: 1fr; }
|
|
1642
1643
|
.gem-popup-shell[data-gem-popup-media='background'] .gem-popup-shell__media { position: absolute; inset: 0; max-height: none; }
|
|
1643
1644
|
}
|
|
1644
|
-
:root:not(:has([data-gem-canvas])) .gem-popup-shell[data-gem-popup-preview='true'] { position: fixed; inset: 0; z-index: 1000; padding: 0; background:
|
|
1645
|
+
:root:not(:has([data-gem-canvas])) .gem-popup-shell[data-gem-popup-preview='true'] { position: fixed; inset: 0; z-index: 1000; padding: 0; background: color-mix(in srgb, var(--gem-color-scrim, #000) 55%, transparent); }
|
|
1645
1646
|
:root:not(:has([data-gem-canvas])) .gem-popup-shell[data-gem-popup-preview='true'] .gem-popup-shell__dialog { position: fixed; inset: 0; display: block; }
|
|
1646
1647
|
:root:has([data-gem-canvas]) .gem-popup-shell[data-gem-popup-preview='true'] .gem-popup-shell__dialog { position: relative; display: block; inset: auto; }
|
|
1647
|
-
:root:has([data-gem-canvas]) .gem-popup-shell[data-gem-popup-preview='true'] { padding: var(--gem-space-xl) var(--gem-layout-gutter); background:
|
|
1648
|
+
:root:has([data-gem-canvas]) .gem-popup-shell[data-gem-popup-preview='true'] { padding: var(--gem-space-xl) var(--gem-layout-gutter); background: color-mix(in srgb, var(--gem-color-scrim, #000) 55%, transparent); }
|
|
1648
1649
|
@media (min-width: 750px) {
|
|
1649
1650
|
:root:has([data-gem-canvas]) .gem-popup-shell[data-gem-popup-preview='true'][data-gem-popup-desktop='fullscreen'] { padding: 0; }
|
|
1650
1651
|
:root:has([data-gem-canvas]) .gem-popup-shell[data-gem-popup-preview='true'][data-gem-popup-desktop='fullscreen'] .gem-popup-shell__dialog { height: 720px; max-height: none; }
|
|
@@ -2474,7 +2475,7 @@ main > .gem-section:first-child { padding-top: 0; }
|
|
|
2474
2475
|
.gem-hero-banner--default { position: relative; overflow: hidden; padding: 0; color: white; place-items: stretch; }
|
|
2475
2476
|
.gem-hero-banner--default .gem-hero-banner__inner { position: static; width: 100%; min-height: 720px; height: 100%; display: grid; align-items: end; justify-items: center; padding-bottom: 0; }
|
|
2476
2477
|
.gem-hero-banner--default .gem-hero-banner__media { position: absolute; inset: 0; z-index: 0; }
|
|
2477
|
-
.gem-hero-banner--default .gem-hero-banner__media::after { content: ''; position: absolute; inset: 0; background:
|
|
2478
|
+
.gem-hero-banner--default .gem-hero-banner__media::after { content: ''; position: absolute; inset: 0; background: color-mix(in srgb, var(--gem-color-scrim, #000) 32%, transparent); }
|
|
2478
2479
|
.gem-hero-banner--default .gem-hero-banner__image, .gem-hero-banner--default .gem-hero-banner__placeholder { width: 100%; height: 100%; object-fit: cover; display: block; }
|
|
2479
2480
|
.gem-hero-banner--default .gem-hero-banner__copy { position: absolute; z-index: 1; left: 50%; bottom: 50px; transform: translateX(-50%); width: min(702px, 100%); margin: 0; padding: 40px 0; text-align: center; display: block; }
|
|
2480
2481
|
.gem-hero-banner--default .gem-section__heading { margin: 0; font-size: 52px; line-height: 67.6px; color: currentColor; }
|