wenay-react2 1.0.42 → 1.0.44
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/doc/changes/v1.0.43.md +10 -0
- package/doc/changes/v1.0.44.md +14 -0
- package/doc/progress/column-state-present-gate.md +28 -0
- package/doc/target/my.md +34 -2
- package/doc/wenay-react2.md +3 -1
- package/lib/common/src/grid/columnState/ColumnDots.js +34 -17
- package/lib/common/src/grid/columnState/columnState.js +5 -1
- package/lib/common/src/styles/tokens.d.ts +3 -0
- package/lib/common/src/styles/tokens.js +3 -0
- package/lib/style/style.css +693 -679
- package/lib/style/tokens.css +11 -8
- package/package.json +1 -1
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# v1.0.43
|
|
2
|
+
|
|
3
|
+
Date: 2026-07-10
|
|
4
|
+
|
|
5
|
+
Status: released.
|
|
6
|
+
|
|
7
|
+
- Changed: `ColumnDots` drag is LIVE (user request from the stand, card 32: "отображать и выключать надо по мере движения — я так буду искать нужный мне столбик"): every EMPTY mark the dot crosses swaps the shown column immediately - the grid/cards follow the finger during the drag; the drop no longer commits a swap (it only settles selection and the tear-off). Occupied marks are passed over; a fixed dot still never swaps; the vertical tear-off flick hides the CURRENTLY shown column of the gesture.
|
|
8
|
+
- Added: a small label above the dragged dot (`.wenayColDotsDragLabel`, tokens `--cols-dots-drag-label-bg/color/font-size` + TS mirror) naming the currently shown column - sized for a finger on a phone.
|
|
9
|
+
- Changed: QA cards 29 and 32 do/expect texts updated to the live semantics.
|
|
10
|
+
- Verification: `npx tsc -p tsconfig.qa-check.json --noEmit`; `npm run testjest -- --runInBand` (62/62, incl. the two-way tokens sync test); stand 3010 card 32 - dragging the NOTE dot left across QTY to PRICE leaves the table showing NAME+PRICE with the dot settled on the PRICE mark (the drop path commits nothing, so the end state proves the live path), zero console errors.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# v1.0.44
|
|
2
|
+
|
|
3
|
+
Date: 2026-07-10
|
|
4
|
+
|
|
5
|
+
Status: ready for publish.
|
|
6
|
+
|
|
7
|
+
- Fixed: `createColumnState` no longer persists `visible=false` for a column
|
|
8
|
+
hidden solely by runtime `presentGate` when another grid interaction is read
|
|
9
|
+
back. Opening the gate restores the user's saved visibility as intended.
|
|
10
|
+
- Added: regression coverage for gated-column readback and normal user
|
|
11
|
+
visibility changes while the gate is open.
|
|
12
|
+
- Verification: repro first failed on v1.0.43 (`visible.b` became `false` after
|
|
13
|
+
an unrelated resize); targeted Jest 3/3; full Jest 64/64; `tsc -p
|
|
14
|
+
tsconfig.qa-check.json --noEmit`; `pnpm run build`.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# ColumnState present-gate — progress
|
|
2
|
+
|
|
3
|
+
## Scope
|
|
4
|
+
|
|
5
|
+
Fix the v1.0.43 regression reported by a consumer: a grid event must not persist
|
|
6
|
+
`visible=false` for a column that is hidden only by the runtime `presentGate`.
|
|
7
|
+
|
|
8
|
+
## Contract
|
|
9
|
+
|
|
10
|
+
`presentGate` is application-owned runtime presence. `visible` is user-owned,
|
|
11
|
+
persisted configuration. A grid readback may update visibility only when the
|
|
12
|
+
column passes the gate; order, width, sort and filter continue to read back for
|
|
13
|
+
all known columns.
|
|
14
|
+
|
|
15
|
+
## Plan
|
|
16
|
+
|
|
17
|
+
1. Reproduce against current source with a fake grid. **Confirmed:** an unrelated
|
|
18
|
+
resize changed gated `b` from persisted `visible=true` to `false`.
|
|
19
|
+
2. Guard the visibility fold in `readFromGrid` with `passesPresentGate`. **Done.**
|
|
20
|
+
3. Add regression coverage for closed and open gates. **Done:** fake GridApi
|
|
21
|
+
covers both the protected gated column and a normal open-gate visibility edit.
|
|
22
|
+
4. Run TypeScript, Jest and package build; record release notes. **Done:**
|
|
23
|
+
targeted Jest 3/3, full Jest 64/64, qa-check TypeScript and build passed.
|
|
24
|
+
|
|
25
|
+
## Result
|
|
26
|
+
|
|
27
|
+
Version v1.0.44 is prepared for publication; durable details are in
|
|
28
|
+
`doc/changes/v1.0.44.md`.
|
package/doc/target/my.md
CHANGED
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
## In Progress
|
|
6
6
|
|
|
7
|
-
_Пусто._
|
|
7
|
+
_Пусто._
|
|
8
|
+
|
|
9
|
+
«Hook extraction — do-now кандидаты (3)» выполнен 2026-07-09: `useCacheMapPersistence` (cache.ts), `useResizeObserver`/`useElementSize` (MyResizeObserver.tsx), `useLogsPageTable` (logs.tsx); старые имена — compatibility wrappers, card 25 не тронута. Проверено: tsc qa-check, jest 45/45, build, стенд 3010 (карточки 21 F5-persistence / 19 resize / 9 logs). Durable-запись: `doc/changes/v1.0.41.md`; parked/отклонённые кандидаты остаются в `doc/progress/hook-extraction-audit.md`.
|
|
8
10
|
|
|
9
11
|
(Предыдущий проход «Нормализация внутренних слоёв библиотеки» проверен multi-agent-верификацией и отгружен в v1.0.40/v1.0.41; durable-запись: `doc/progress/public-surface-normalization.md`, `doc/progress/hook-controller-opportunities.md`, `doc/changes/v1.0.38–v1.0.41.md`.)
|
|
10
12
|
|
|
@@ -42,10 +44,36 @@ _Пусто._ «Hook extraction — do-now кандидаты (3)» выполн
|
|
|
42
44
|
- **A10 remaining (breaking only)**: raw `ListenApi` (emit/close) exposed from columnState/Toolbar onChange (narrowing is breaking); removal of deprecated `onCLickClose`/`keySave` — breaking pass only.
|
|
43
45
|
- Rule: each fix is its own focused pass with verify (tsc+jest+build+stand); breaking removals only in a deliberate breaking version.
|
|
44
46
|
|
|
47
|
+
- **Architecture follow-up: ownership and lifecycle boundaries (overlay / grid / columnState)** (code review 2026-07-10).
|
|
48
|
+
- **Overlay stack (high)**: `Overlay` instances independently subscribe to `document`. A `SettingsDialog` above a `ModalProvider` lets the lower modal handle the same Escape/outside interaction; this breaks SettingsDialog's two-stage Escape contract. Introduce an internal stack/arbiter so only the topmost dismissible layer receives Escape and outside-click; verify nested ModalProvider + SettingsDialog (search clear on first Escape, dialog close on second, parent remains open).
|
|
49
|
+
- **ag-grid row identity (high)**: `AgGridTable` currently lets a caller supply `getRowId` alongside `controller`, while the controller buffer owns another `getId`. Make the ownership unambiguous (reject/ignore override or explicitly derive the core identity); verify update/remove/reconnect with a controller and a conflicting callback.
|
|
50
|
+
- **ColumnGrid attachment ownership (high)**: one controller keeps one mutable `gridApi`, but its `Table` surface permits multiple mounts; an old table's destroy can detach the newer one. Either enforce one table per controller with a clear error or scope attachment state to a Table instance; verify two mounts plus either unmount order.
|
|
51
|
+
- **ColumnState contract consistency (medium)**: `groups` affects `visibleKeys()`/cards but is ignored when applying state to desktop ag-grid; `ColumnGrid.View` also forwards index `0` to a supplied `getId`. Align the shared config on both views and pass the actual row index. Add integration coverage.
|
|
52
|
+
- **Dispose lifecycle (medium)**: `createColumnGrid.dispose()` releases local listeners but not its attached grid listeners. Define dispose as a full release and make it detach the active grid; verify no grid events mutate state after dispose.
|
|
53
|
+
- Приоритет: отдельные focused passes; не смешивать с feature-задачами ColumnDots. Проверка каждого: tsc qa-check, jest, build и соответствующий lifecycle/integration test.
|
|
54
|
+
|
|
55
|
+
- **QA-стенд: расширить интеграционное покрытие и сделать его картой публичных примитивов**.
|
|
56
|
+
- Проблема: стенд уже содержит полезные локальные карточки (modal 13, Settings 20, columnState 28–32, replay 23–26), но не покрывает опасные межслойные сценарии: вложенные overlay, ownership `GridApi`, `dispose`, повторный mount и смену entrypoint/платформенного слоя. Зелёный Jest не заменяет эти проверки.
|
|
57
|
+
- Задача: 1) составить компактную матрицу «публичный primitive → unit → QA card → ручной сценарий» и пометить пробелы; 2) добавить active QA-карточки только для interaction/lifecycle сценариев, которые нельзя надёжно доказать unit-тестом: overlay stack (Modal + Settings), ColumnGrid mount/unmount/ownership, persistence reload/reset, replay reconnect/route switch; 3) дать каждой карточке действия, ожидаемый результат, reset/изоляцию ключей и номер без дублей; 4) завести правило: новая визуальная либо lifecycle-поверхность не считается готовой без unit/integration проверки и обновлённой или намеренно неприменимой QA-карточки.
|
|
58
|
+
- Не превращать стенд в копию всех компонентов: чистые функции и детерминированные controller-ветки остаются в Jest; стенд — для пользовательского взаимодействия, DOM, аг-grid, browser lifecycle и визуальной приёмки.
|
|
59
|
+
- Acceptance: карточки запускаются на чистой странице без console errors; ключевые сценарии воспроизводимы вручную; карта покрытия хранится в `doc/`; команды tsc qa-check, jest и build проходят.
|
|
60
|
+
- Приоритет: после исправления overlay/grid ownership — новые карточки должны проверять именно исправленные контракты.
|
|
61
|
+
|
|
45
62
|
- **Hook extraction — parked кандидаты** (do-now 1-3 выполнены и отгружены, см. In Progress выше / `doc/changes/v1.0.41.md`). Остались условные: `useChartCanvas` (ждёт ChartDemo в карточке/тесте), `useContextMenuGesture` (ждёт оживления menuR или live touch-consumer), `columnState.api.reorderPreview` (ждёт общего reorder-контракта), `useResizeableFit` (маленький shared bind callback-ref, отдельный микро-pass). Полные причины/условия возврата: [../progress/hook-extraction-audit.md](../progress/hook-extraction-audit.md).
|
|
46
63
|
|
|
47
64
|
## Inbox
|
|
48
65
|
|
|
66
|
+
- **ColumnDots: фильтр-ползунок по значениям + мультисорт-опция + именованные пресеты** (надиктовка 2026-07-10, дословно в конце файла; контекст — мобильный ползунок таблицы, карточки 29/32).
|
|
67
|
+
- **1. Сорт-кнопка**: сейчас одна (asc→desc→off) — оставить одиночной по умолчанию, но добавить ОПЦИЮ множественной сортировки (multi-sort) настройкой.
|
|
68
|
+
- **2. Второй ползунок — фильтр по значениям** (открывается по кнопке при необходимости, кнопок вызова две — уточнить у пользователя что вторая): такой же трек с ячейками/метками, на котором пользователь СТАВИТ ТОЧКИ:
|
|
69
|
+
- числовые значения: значения раскладываются по треку; две точки = диапазон (считаем всегда по КРАЙНИМ точкам — лишние точки внутри не меняют диапазон); крайняя правая + середина = правый диапазон;
|
|
70
|
+
- категориальные значения (например, 9 типов): те же точки по меткам типов; выбор = диапазон ЛИБО конкретные точки;
|
|
71
|
+
- **режим фильтра** переключается кнопкой (как сорт-кнопка): «левее точек / между точками / только по точкам / …» — т.е. lt/range/in-set и т.п.;
|
|
72
|
+
- главный сценарий — мобила, всё пальцем (продолжение live-драга точек из v1.0.43).
|
|
73
|
+
- **3. Именованные пресеты**: кнопки «Сохранить» (с именем) и «Сбросить»; загрузка = выбор из сохранённых по имени. ОТКРЫТЫЙ ВОПРОС (пользователь сам не решил): куда поместить кнопки на телефоне — места на треке не хватает; кандидаты — в шапку дотс-панели / в меню по long-press / отдельная строка-«шторка». Персист — обычный путь memoryGetOrCreate→memoryCache (пресеты = отдельный ключ со словарём имя→конфиг фильтра+сорта).
|
|
74
|
+
- Смежное: фильтр должен лечь в columnState-конфиг (`filter` там уже есть — формат согласовать с ag-grid setFilterModel), чтобы desktop-грид получал тот же фильтр через grid.attach.
|
|
75
|
+
- Статус: надиктовка записана, скоупинг и уточнения (вторая кнопка вызова; полный список режимов) — перед взятием в работу.
|
|
76
|
+
|
|
49
77
|
- **React Native / мобильная версия функционала** (надиктовка 2026-07-10, дословно в конце файла).
|
|
50
78
|
- Суть: библиотеку планируют использовать и в мобильном (React Native), где DOM недоступен (нет `document`/`window`/`createPortal`/CSS-классов).
|
|
51
79
|
- Первичная оценка: слоистость уже движется в нужную сторону — headless/controller-слой (updateBy/renderBy, columnState config, createToolbar config+Settings-модель, callbackHub, observableMap/memoryCache, replay-хуки) в основном DOM-free и потенциально переносим; DOM живёт во view-слое (FloatingWindow/Rnd, порталы/скримы, CSS-токены, ag-grid). Направление: (1) аудит `document`/`window`/`createPortal`/CSS-зависимостей по модулям; (2) выделить/закрепить platform-neutral core (возможно отдельный entrypoint без DOM-импортов); (3) RN-view-адаптеры — отдельный пакет/подпапка, не в этом проходе. ag-grid в RN не живёт — мобильные представления уже есть (ColumnDots/CardList) как модель. Персист: storage-слой абстрагировать (localStorage → AsyncStorage).
|
|
@@ -53,7 +81,9 @@ _Пусто._ «Hook extraction — do-now кандидаты (3)» выполн
|
|
|
53
81
|
|
|
54
82
|
## Verify
|
|
55
83
|
|
|
56
|
-
|
|
84
|
+
- **ColumnState present-gate не должен перезаписывать пользовательскую visibility** — реализация и release v1.0.44 готовы; [progress](../progress/column-state-present-gate.md), [changelog](../changes/v1.0.44.md). Проверить публикацию пакета и потребительский repro: gated `b` остаётся `visible:true` после resize другой колонки и становится видимой при открытии gate.
|
|
85
|
+
|
|
86
|
+
«Система стилей и CSS variables» проверена: `doneInCode=fully`, `.wenayColsMenu*`/`--cols-menu-*` и `--cols-dots-*`/`--cols-card-*` в коде, changelog v1.0.38/v1.0.39/v1.0.41, отгружено в релизах. Удалено; durable-запись — `doc/progress/style-system-normalization.md`.
|
|
57
87
|
|
|
58
88
|
## Blocked — уровень приложения (не эта React-библиотека)
|
|
59
89
|
|
|
@@ -79,3 +109,5 @@ _Пусто._ «Система стилей и CSS variables» проверен
|
|
|
79
109
|
> да мы еще планиурем использовать библиотеку и для мобильного использования , а там дум обьекты вроде не потдерживаются.... ну ты сам знаешь что надо для реакт нативу - может сделать мобильную версию этого функционала
|
|
80
110
|
|
|
81
111
|
> вопрос насоклько этот код вобще лакнчиный и юзабельный?ты бы сам ег остал использовать [оценка 2026-07-10: вызовы лаконичны, изучение — нет; задача «API-витрина» в Ready] да оформи задачу в my.md но текущий релиз запуш
|
|
112
|
+
|
|
113
|
+
> Запиши такую задачу. Значит, надо М-м-м, где менюшка? Ст-- для таблицы есть, особенно вот этот ползунок. Надо его улучшить. А именно: там вот есть фильтр по возрастанию, по убыванию, кнопочка одна. Во-первых, он должен быть множественный. Либо не множественный. Пока что пусть он будет нормальный. С-- но опционально такая настройка должна быть. А-а-а, второй момент важен. Есть ли помимооо фильтра у нас открывается второй ползунок? Если нужно. Там получается две кнопки вызвать ползунок второй. Второй ползунок, оннн так же, как и первый, состоит из каких-то ячеек иии ползунков . Ну, вот этих вот. То есть, допустим, мы там можем задать Кремль, край? Естественно, если мы выбрали «Больше» и выбираем тут-- там на ползунке есть эти цифры, то они, цифры, расположены, ну, вся эта куча, чтобы человек мог выбрать Там в левую часть либо в правую часть. То есть технический человек ставит сразу две точки? А-а-а, ты поставил крайние, я посередине. Это означает, что, ну, был этот диапазон. Крайний правый посередине означает, что был правый диапазон. Если он добавляет еще точки, мы их всё равно считаем по крайним точкам. Нам неважно, если этооо Если этооо, к-к-какой-нибудь, например, тверд-- ну, либо какой-нибудь другой вариант еще рассматриваем. Вот. А если этооо, к примеру Там название чего-то, и этих названий определенное количество. Допустим Девять типов чего-то. То мыыы-- э-э-э, вот у нас есть девять типов. Мы точно так же точки расставляем. Человек может выбрать несколько точек: либо диапазон, автооо, типа, либо конкретно. И режим выбирается, к примеру, вот этой кнопкой: фильтровать вверх, вниз. То есть мы выбираем левее, точки, между точками, только по точкам, там меньше точек. Ну, чё-то типа такого. Вот, я думаю, это будет очень удобно. Особенно на мобиле. Иии нужна настройка ещёёё Сохранить этот настрой. Ну, типа, вот, н-- допустим, так сделали . Понятно, кнопка «Сбросить» их вот, и кнопка «Сохранить». Только пока не очень понимаю, куда это поставить. Особенно на мобиле, на телефоне там места не хватает, ну, точнее, не хватает. Типа ты, допустим, настроил настройку . Кнопку нажал, их там запримел. Иии, соответственно, точно так же, еслиии тыыы Как загружать правильно? Загружать на опять же, смотреть, чё ты сохраняешься. Сохраняешься с именем?
|
package/doc/wenay-react2.md
CHANGED
|
@@ -341,7 +341,9 @@ keep `ColumnsMenu` for compact button strips or custom presentation-only menus.
|
|
|
341
341
|
Mobile (no ag-grid): dots selector + card rows over the same config:
|
|
342
342
|
```
|
|
343
343
|
<ColumnDots state={cs} max?=8 /> // track of marks; dots = shown columns; tap empty=add,
|
|
344
|
-
// drag=replace
|
|
344
|
+
// drag=LIVE replace (every empty mark crossed swaps the shown
|
|
345
|
+
// column immediately + small label names it - column search
|
|
346
|
+
// by finger), swipe up=remove, tap dot=select, sort cycles
|
|
345
347
|
<CardList<Row> state={cs} data={rows} getId? renderValue? /> // visible cols -> card fields; cardRole:'title'/'accent'
|
|
346
348
|
```
|
|
347
349
|
|
|
@@ -3,8 +3,11 @@ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
|
3
3
|
// with dots on the columns that are currently shown. Placing a dot IS showing
|
|
4
4
|
// the column; the card view (CardList) rebuilds from the same config live.
|
|
5
5
|
// Gestures (pointer events, mouse + touch):
|
|
6
|
-
// drag a dot along the track ->
|
|
7
|
-
// column
|
|
6
|
+
// drag a dot along the track -> LIVE: every empty mark the dot crosses swaps
|
|
7
|
+
// the shown column immediately (the grid/cards
|
|
8
|
+
// follow the finger - that is how you SEARCH for
|
|
9
|
+
// a column on a phone); a small label above the
|
|
10
|
+
// finger names the currently shown column
|
|
8
11
|
// swipe a dot UP (flick off) -> the dot tears off the track: column hidden
|
|
9
12
|
// tap an empty mark -> a dot appears there: column shown
|
|
10
13
|
// tap a dot (no move) -> select the field (highlight); the sort
|
|
@@ -38,7 +41,7 @@ export function ColumnDots(p) {
|
|
|
38
41
|
function downDot(key, e) {
|
|
39
42
|
e.preventDefault();
|
|
40
43
|
e.currentTarget.setPointerCapture(e.pointerId);
|
|
41
|
-
gestureRef.current = { key, startX: e.clientX, startY: e.clientY, moved: false };
|
|
44
|
+
gestureRef.current = { key, startX: e.clientX, startY: e.clientY, moved: false, shown: key, fixed: !!byKey.get(key)?.fixed };
|
|
42
45
|
}
|
|
43
46
|
function moveDot(e) {
|
|
44
47
|
const g = gestureRef.current;
|
|
@@ -56,7 +59,17 @@ export function ColumnDots(p) {
|
|
|
56
59
|
const from = order.indexOf(g.key);
|
|
57
60
|
const off = -dy > REMOVE_DY && -dy > Math.abs(dx);
|
|
58
61
|
const to = Math.max(0, Math.min(n - 1, Math.round(from + dx / step)));
|
|
59
|
-
|
|
62
|
+
// LIVE swap: crossing an EMPTY mark shows that column immediately (the grid
|
|
63
|
+
// follows the finger - column search by dragging). Occupied marks are passed
|
|
64
|
+
// over; a fixed dot never swaps (same rule the old on-drop commit had).
|
|
65
|
+
if (!off && !g.fixed) {
|
|
66
|
+
const target = order[to];
|
|
67
|
+
if (target && target != g.shown && cfg.visible[target] == false) {
|
|
68
|
+
p.state.api.setConfig({ ...cfg, visible: { ...cfg.visible, [g.shown]: false, [target]: true } });
|
|
69
|
+
g.shown = target;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
setDrag({ key: g.key, dx, dy, to, off, shown: g.shown });
|
|
60
73
|
}
|
|
61
74
|
function upDot() {
|
|
62
75
|
const g = gestureRef.current;
|
|
@@ -71,21 +84,19 @@ export function ColumnDots(p) {
|
|
|
71
84
|
}
|
|
72
85
|
if (!st)
|
|
73
86
|
return;
|
|
74
|
-
|
|
87
|
+
// swaps already happened live during the move; the drop only settles
|
|
88
|
+
// selection and handles the tear-off of the CURRENTLY shown column
|
|
75
89
|
if (st.off) {
|
|
90
|
+
const meta = byKey.get(g.shown);
|
|
76
91
|
if (!meta?.fixed && visibleKeys.length > 1) {
|
|
77
|
-
p.state.api.show(g.
|
|
78
|
-
if (selected == g.key)
|
|
92
|
+
p.state.api.show(g.shown, false);
|
|
93
|
+
if (selected == g.key || selected == g.shown)
|
|
79
94
|
setSelected(null);
|
|
80
95
|
}
|
|
81
96
|
return;
|
|
82
97
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
p.state.api.setConfig({ ...cfg, visible: { ...cfg.visible, [g.key]: false, [target]: true } });
|
|
86
|
-
if (selected == g.key)
|
|
87
|
-
setSelected(target);
|
|
88
|
-
}
|
|
98
|
+
if (g.shown != g.key && selected == g.key)
|
|
99
|
+
setSelected(g.shown);
|
|
89
100
|
}
|
|
90
101
|
function tapMark(key) {
|
|
91
102
|
if (cfg.visible[key] != false)
|
|
@@ -101,11 +112,17 @@ export function ColumnDots(p) {
|
|
|
101
112
|
const isSorted = cfg.sort?.key == k;
|
|
102
113
|
return _jsxs("div", { onPointerUp: () => tapMark(k), className: cx(['wenayColDotsMark', vis ? 'wenayColDotsMark_on' : 'wenayColDotsMark_off']), style: { left: `${pct(i)}%`, cursor: !vis && visibleKeys.length < max ? 'pointer' : 'default' }, children: [isSorted && _jsx("div", { className: 'wenayColDotsSortMark', children: cfg.sort.dir == 'asc' ? '↑' : '↓' }), _jsx("div", { className: 'wenayColDotsMarkPin' }), _jsx("div", { className: 'wenayColDotsMarkLabel', children: short(k) })] }, 'm' + k);
|
|
103
114
|
}), order.map((k, i) => {
|
|
104
|
-
|
|
115
|
+
const d = drag?.key == k ? drag : null;
|
|
116
|
+
// the dragged dot stays mounted through live swaps (its column may be
|
|
117
|
+
// hidden mid-gesture; unmounting would kill the pointer capture)...
|
|
118
|
+
if (cfg.visible[k] == false && !d)
|
|
119
|
+
return null;
|
|
120
|
+
// ...and the live-shown column's resting dot is suppressed: its
|
|
121
|
+
// representation IS the dot under the finger
|
|
122
|
+
if (drag && !d && k == drag.shown && drag.shown != drag.key)
|
|
105
123
|
return null;
|
|
106
124
|
const meta = byKey.get(k);
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
return _jsx("div", { onPointerDown: e => downDot(k, e), onPointerMove: moveDot, onPointerUp: upDot, onPointerCancel: upDot, className: cx(['wenayColDotsDotWrap', d && 'wenayColDotsDotWrap_dragging', removing && 'wenayColDotsDotWrap_removing']), style: { left: `${pct(i)}%`, transform: d ? `translate(${d.dx}px, ${removing ? d.dy : 0}px)` : undefined }, children: _jsx("div", { className: cx(['wenayColDotsDot', selected == k && 'wenayColDotsDot_selected', meta?.fixed && 'wenayColDotsDot_fixed']) }) }, 'd' + k);
|
|
125
|
+
const removing = !!d?.off && !byKey.get(d.shown)?.fixed && visibleKeys.length > 1;
|
|
126
|
+
return _jsxs("div", { onPointerDown: e => downDot(k, e), onPointerMove: moveDot, onPointerUp: upDot, onPointerCancel: upDot, className: cx(['wenayColDotsDotWrap', d && 'wenayColDotsDotWrap_dragging', removing && 'wenayColDotsDotWrap_removing']), style: { left: `${pct(i)}%`, transform: d ? `translate(${d.dx}px, ${removing ? d.dy : 0}px)` : undefined }, children: [d && !d.off && _jsx("div", { className: 'wenayColDotsDragLabel', children: short(d.shown) }), _jsx("div", { className: cx(['wenayColDotsDot', selected == k && 'wenayColDotsDot_selected', meta?.fixed && 'wenayColDotsDot_fixed']) })] }, 'd' + k);
|
|
110
127
|
})] })] });
|
|
111
128
|
}
|
|
@@ -229,7 +229,11 @@ export function createColumnState(opts) {
|
|
|
229
229
|
if (!known.has(s.colId))
|
|
230
230
|
continue;
|
|
231
231
|
order.push(s.colId);
|
|
232
|
-
|
|
232
|
+
// `hide` for a gated-out column was written by applyToGrid(), not by
|
|
233
|
+
// the user. Folding it back would turn runtime presence into persisted
|
|
234
|
+
// visibility and keep the column hidden when the gate opens again.
|
|
235
|
+
if (passesPresentGate(s.colId))
|
|
236
|
+
visible[s.colId] = !s.hide;
|
|
233
237
|
if (typeof s.width == 'number' && s.width > 0)
|
|
234
238
|
width[s.colId] = s.width;
|
|
235
239
|
if (s.sort == 'asc' || s.sort == 'desc')
|
|
@@ -133,6 +133,9 @@ export declare const tokens: {
|
|
|
133
133
|
readonly selectedBg: "#0969da";
|
|
134
134
|
readonly selectedBorder: "#b6d4fe";
|
|
135
135
|
readonly fixedBorder: "#afb8c1";
|
|
136
|
+
readonly dragLabelBg: "#24292f";
|
|
137
|
+
readonly dragLabelColor: "#fff";
|
|
138
|
+
readonly dragLabelFontSize: "10px";
|
|
136
139
|
};
|
|
137
140
|
/** CardList chrome (--cols-card-*). Defaults preserve restored card-29 look. */
|
|
138
141
|
readonly colsCard: {
|
|
@@ -137,6 +137,9 @@ export const tokens = {
|
|
|
137
137
|
selectedBg: '#0969da',
|
|
138
138
|
selectedBorder: '#b6d4fe',
|
|
139
139
|
fixedBorder: '#afb8c1',
|
|
140
|
+
dragLabelBg: '#24292f',
|
|
141
|
+
dragLabelColor: '#fff',
|
|
142
|
+
dragLabelFontSize: '10px',
|
|
140
143
|
},
|
|
141
144
|
/** CardList chrome (--cols-card-*). Defaults preserve restored card-29 look. */
|
|
142
145
|
colsCard: {
|