@feugene/granularity 0.47.0 → 0.49.0
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 +3 -3
- package/dist/chunks/{config-2vrOFn2f.js → config-AKpLyIGD.js} +2 -2
- package/dist/chunks/{config-2vrOFn2f.js.map → config-AKpLyIGD.js.map} +1 -1
- package/dist/chunks/config-BBtBQE3s.js +108 -0
- package/dist/chunks/config-BBtBQE3s.js.map +1 -0
- package/dist/chunks/{config-DeyT9dJl.js → config-Bs1HwUcx.js} +47 -4
- package/dist/chunks/{config-DeyT9dJl.js.map → config-Bs1HwUcx.js.map} +1 -1
- package/dist/chunks/{config-B3J0alyY.js → config-CzeZg2LO.js} +49 -4
- package/dist/chunks/config-CzeZg2LO.js.map +1 -0
- package/dist/chunks/{config-DCq4JySZ.js → config-D3HOuHDe.js} +1 -1
- package/dist/chunks/{config-DCq4JySZ.js.map → config-D3HOuHDe.js.map} +1 -1
- package/dist/chunks/{config-BscVxZR3.js → config-DF1ezU6y.js} +1 -1
- package/dist/chunks/{config-BscVxZR3.js.map → config-DF1ezU6y.js.map} +1 -1
- package/dist/chunks/config-MUkhktTP.js +267 -0
- package/dist/chunks/config-MUkhktTP.js.map +1 -0
- package/dist/chunks/{en-DjTnfTqM.js → en-CsQUoBS2.js} +14 -2
- package/dist/chunks/en-CsQUoBS2.js.map +1 -0
- package/dist/chunks/{es-Bc_t3FI8.js → es-9nbkPvdA.js} +14 -2
- package/dist/chunks/es-9nbkPvdA.js.map +1 -0
- package/dist/chunks/{es-DIFzSXSZ.js → es-DrUz5J6I.js} +3 -3
- package/dist/chunks/{es-DIFzSXSZ.js.map → es-DrUz5J6I.js.map} +1 -1
- package/dist/chunks/{generated-CQ4h6Ieq.js → generated-CxvC5O0V.js} +140 -0
- package/dist/chunks/{generated-CQ4h6Ieq.js.map → generated-CxvC5O0V.js.map} +1 -1
- package/dist/chunks/{grBadgeStyles-DV0DrAew.js → grBadgeStyles-D51AXbj5.js} +57 -1
- package/dist/chunks/grBadgeStyles-D51AXbj5.js.map +1 -0
- package/dist/chunks/{grChipStyles-DcDyxAL0.js → grChipStyles-CA9Wj1_E.js} +1 -1
- package/dist/chunks/{grChipStyles-DcDyxAL0.js.map → grChipStyles-CA9Wj1_E.js.map} +1 -1
- package/dist/chunks/{grTableStyles-uuMPSOBR.js → grTableStyles-DkQPMfx9.js} +16 -3
- package/dist/chunks/grTableStyles-DkQPMfx9.js.map +1 -0
- package/dist/chunks/{granular-provider-AKukmYva.js → granular-provider-B6xomapW.js} +8 -6
- package/dist/chunks/granular-provider-B6xomapW.js.map +1 -0
- package/dist/chunks/{ru-Bb-co59W.js → ru-88i1WG0b.js} +14 -2
- package/dist/chunks/ru-88i1WG0b.js.map +1 -0
- package/dist/chunks/{safelist-x8USecK8.js → safelist-CSfynUC1.js} +5 -1
- package/dist/chunks/safelist-CSfynUC1.js.map +1 -0
- package/dist/components/GrAutocomplete/chunks/{GrAutocomplete-C-uovdv8.js → GrAutocomplete-Chhw65pI.js} +2 -2
- package/dist/components/GrAutocomplete/chunks/{GrAutocomplete-C-uovdv8.js.map → GrAutocomplete-Chhw65pI.js.map} +1 -1
- package/dist/components/GrAutocomplete/index.js +1 -1
- package/dist/components/GrAvatar/chunks/{GrAvatar-dWEXiCJG.js → GrAvatar-Do5-C409.js} +12 -1
- package/dist/components/GrAvatar/chunks/GrAvatar-Do5-C409.js.map +1 -0
- package/dist/components/GrAvatar/index.js +2 -2
- package/dist/components/GrAvatar/themes/light.css +35 -0
- package/dist/components/GrBadge/chunks/GrBadge-C42KLyUD.js +71 -0
- package/dist/components/GrBadge/chunks/GrBadge-C42KLyUD.js.map +1 -0
- package/dist/components/GrBadge/index.js +3 -3
- package/dist/components/GrBadge/styles.css +1 -1
- package/dist/components/GrChip/chunks/{GrChip-CKqyzYcv.js → GrChip-DoyS1Dr4.js} +1 -1
- package/dist/components/GrChip/chunks/{GrChip-CKqyzYcv.js.map → GrChip-DoyS1Dr4.js.map} +1 -1
- package/dist/components/GrChip/index.js +2 -2
- package/dist/components/GrDataTable/chunks/{GrDataTable-Dp9Fp_P5.js → GrDataTable-DQxYYgQk.js} +438 -160
- package/dist/components/GrDataTable/chunks/GrDataTable-DQxYYgQk.js.map +1 -0
- package/dist/components/GrDataTable/index.js +2 -2
- package/dist/components/GrDataTable/themes/light.css +10 -0
- package/dist/components/GrInputTag/chunks/{GrInputTag-CO0YU-ok.js → GrInputTag-qnRdAZnn.js} +2 -2
- package/dist/components/GrInputTag/chunks/{GrInputTag-CO0YU-ok.js.map → GrInputTag-qnRdAZnn.js.map} +1 -1
- package/dist/components/GrInputTag/index.js +1 -1
- package/dist/components/GrOtpInput/chunks/GrOtpInput-B_Q-RDLw.js +419 -0
- package/dist/components/GrOtpInput/chunks/GrOtpInput-B_Q-RDLw.js.map +1 -0
- package/dist/components/GrOtpInput/index.js +3 -0
- package/dist/components/GrOtpInput/styles.css +1 -0
- package/dist/components/GrPagination/chunks/{GrPagination-BbaF5eXk.js → GrPagination-CMrLPzvL.js} +1 -1
- package/dist/components/GrPagination/chunks/{GrPagination-BbaF5eXk.js.map → GrPagination-CMrLPzvL.js.map} +1 -1
- package/dist/components/GrPagination/index.js +1 -1
- package/dist/components/GrSelect/chunks/{GrSelect-0iI4wdR_.js → GrSelect-DvSq-nV-.js} +2 -2
- package/dist/components/GrSelect/chunks/{GrSelect-0iI4wdR_.js.map → GrSelect-DvSq-nV-.js.map} +1 -1
- package/dist/components/GrSelect/index.js +1 -1
- package/dist/components/GrSwitch/chunks/{GrSwitch-CriHWT2A.js → GrSwitch-D7X42uIA.js} +61 -7
- package/dist/components/GrSwitch/chunks/GrSwitch-D7X42uIA.js.map +1 -0
- package/dist/components/GrSwitch/index.js +2 -2
- package/dist/components/GrTable/chunks/{GrTable-iwzHvlMC.js → GrTable-CKJ-HrsN.js} +1 -1
- package/dist/components/GrTable/chunks/{GrTable-iwzHvlMC.js.map → GrTable-CKJ-HrsN.js.map} +1 -1
- package/dist/components/GrTable/index.js +2 -2
- package/dist/granular-provider-node.js +1 -1
- package/dist/granular-provider.js +1 -1
- package/dist/i18n/all.js +1 -1
- package/dist/i18n/index.js +1 -1
- package/dist/index.js +20 -19
- package/dist/theme.js +1 -1
- package/dist/tokens.js +1 -1
- package/dist/types/components/GrAvatar/GrAvatar.vue.d.ts +11 -0
- package/dist/types/components/GrAvatar/defaults.d.ts +1 -0
- package/dist/types/components/GrAvatar/grAvatarStyles.d.ts +26 -1
- package/dist/types/components/GrBadge/GrBadge.vue.d.ts +15 -1
- package/dist/types/components/GrBadge/grBadgeStyles.d.ts +57 -0
- package/dist/types/components/GrBadge/index.d.ts +1 -1
- package/dist/types/components/GrDataTable/GrDataTable.vue.d.ts +59 -0
- package/dist/types/components/GrDataTable/composables/useDataTableExpansion.d.ts +46 -0
- package/dist/types/components/GrDataTable/grDataTableStyles.d.ts +23 -0
- package/dist/types/components/GrOtpInput/GrOtpInput.vue.d.ts +164 -0
- package/dist/types/components/GrOtpInput/config.d.ts +1 -0
- package/dist/types/components/GrOtpInput/defaults.d.ts +15 -0
- package/dist/types/components/GrOtpInput/grOtpInputStyles.d.ts +62 -0
- package/dist/types/components/GrOtpInput/index.d.ts +9 -0
- package/dist/types/components/GrOtpInput/otpValue.d.ts +71 -0
- package/dist/types/components/GrOtpInput/safelist.d.ts +7 -0
- package/dist/types/components/GrSwitch/GrSwitch.vue.d.ts +42 -4
- package/dist/types/components/GrSwitch/defaults.d.ts +2 -0
- package/dist/types/components/GrSwitch/grSwitchStyles.d.ts +129 -25
- package/dist/types/components/GrSwitch/index.d.ts +1 -1
- package/dist/types/components/GrSwitch/safelist.d.ts +4 -3
- package/dist/types/components/GrTable/grTableStyles.d.ts +16 -3
- package/dist/types/granular-provider/shared.d.ts +1 -0
- package/dist/types/i18n/messages/en.d.ts +20 -0
- package/dist/types/i18n/messages/es.d.ts +20 -0
- package/dist/types/i18n/messages/ru.d.ts +20 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/web-types.json +329 -8
- package/package.json +5 -1
- package/dist/chunks/config-B3J0alyY.js.map +0 -1
- package/dist/chunks/config-Yy67uWHY.js +0 -140
- package/dist/chunks/config-Yy67uWHY.js.map +0 -1
- package/dist/chunks/en-DjTnfTqM.js.map +0 -1
- package/dist/chunks/es-Bc_t3FI8.js.map +0 -1
- package/dist/chunks/grBadgeStyles-DV0DrAew.js.map +0 -1
- package/dist/chunks/grTableStyles-uuMPSOBR.js.map +0 -1
- package/dist/chunks/granular-provider-AKukmYva.js.map +0 -1
- package/dist/chunks/ru-Bb-co59W.js.map +0 -1
- package/dist/chunks/safelist-x8USecK8.js.map +0 -1
- package/dist/components/GrAvatar/chunks/GrAvatar-dWEXiCJG.js.map +0 -1
- package/dist/components/GrBadge/chunks/GrBadge-DBeQXEir.js +0 -47
- package/dist/components/GrBadge/chunks/GrBadge-DBeQXEir.js.map +0 -1
- package/dist/components/GrDataTable/chunks/GrDataTable-Dp9Fp_P5.js.map +0 -1
- package/dist/components/GrSwitch/chunks/GrSwitch-CriHWT2A.js.map +0 -1
package/README.md
CHANGED
|
@@ -91,10 +91,10 @@ from its own chunk, so a granular import already brings everything it needs.
|
|
|
91
91
|
<!-- entry-sizes:generated:start lang=en -->
|
|
92
92
|
| What you import | gzip | of the barrel |
|
|
93
93
|
| --- | ---: | ---: |
|
|
94
|
-
| the whole package from the root |
|
|
94
|
+
| the whole package from the root | 619.8 kB | 100 % |
|
|
95
95
|
| the lightest component — `GrButtonGroup` | 1.8 kB | < 1 % |
|
|
96
|
-
| the median component — `
|
|
97
|
-
| the 5 heaviest together |
|
|
96
|
+
| the median component — `GrNavbar` | 15.4 kB | 2 % |
|
|
97
|
+
| the 5 heaviest together | 178.4 kB | 29 % |
|
|
98
98
|
|
|
99
99
|
These numbers **do not add up**: shared code is counted again in every row but paid for once, which is why
|
|
100
100
|
the set is shown as a union rather than a sum. They are an upper bound — the gzip of everything a subpath
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { n as splitClassTokens } from "./classTokens-8v2XC74x.js";
|
|
2
|
-
import { a as chipIconSizeClassBySize, c as chipRootClass, i as chipIconClass, l as chipSelectedClass, n as chipCloseClass, o as chipInteractiveClass, r as chipDisabledClass, s as chipLabelClass, t as chipCloseButtonClass, u as chipSizeClassBySize } from "./grChipStyles-
|
|
3
|
-
import { t as grBadgeSafelist } from "./safelist-
|
|
2
|
+
import { a as chipIconSizeClassBySize, c as chipRootClass, i as chipIconClass, l as chipSelectedClass, n as chipCloseClass, o as chipInteractiveClass, r as chipDisabledClass, s as chipLabelClass, t as chipCloseButtonClass, u as chipSizeClassBySize } from "./grChipStyles-CA9Wj1_E.js";
|
|
3
|
+
import { t as grBadgeSafelist } from "./safelist-CSfynUC1.js";
|
|
4
4
|
import { defineGranularComponent } from "@feugene/unocss-preset-granular/contract";
|
|
5
5
|
//#region src/components/GrChip/safelist.ts
|
|
6
6
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-
|
|
1
|
+
{"version":3,"file":"config-AKpLyIGD.js","names":[],"sources":["../../src/components/GrChip/safelist.ts","../../src/components/GrChip/config.ts"],"sourcesContent":["import { grBadgeSafelist } from '../GrBadge/safelist'\nimport { splitClassTokens } from '../shared/classTokens'\n\nimport {\n chipCloseButtonClass,\n chipCloseClass,\n chipDisabledClass,\n chipIconClass,\n chipIconSizeClassBySize,\n chipInteractiveClass,\n chipLabelClass,\n chipRootClass,\n chipSelectedClass,\n chipSizeClassBySize,\n} from './grChipStyles'\n\n/**\n * Тона и радиусы приходят из `grBadgeStyles.ts`, поэтому их safelist берётся\n * ссылкой, а не копией: копия разошлась бы с оригиналом молча. Ребро\n * `GrChip → GrBadge` объявлено в `config.ts` — без него пресет не подмешает\n * стили бейджа при гранулярной селекции, и чип придёт бесцветным.\n */\nexport const grChipSafelist = [...new Set([\n ...grBadgeSafelist,\n ...Object.values(chipSizeClassBySize).flatMap(splitClassTokens),\n ...Object.values(chipIconSizeClassBySize).flatMap(splitClassTokens),\n ...splitClassTokens(chipRootClass),\n ...splitClassTokens(chipLabelClass),\n ...splitClassTokens(chipInteractiveClass),\n ...splitClassTokens(chipDisabledClass),\n ...splitClassTokens(chipSelectedClass),\n ...splitClassTokens(chipCloseClass),\n ...splitClassTokens(chipCloseButtonClass),\n ...splitClassTokens(chipIconClass),\n 'h-full',\n 'w-full',\n])]\n","import { defineGranularComponent } from '@feugene/unocss-preset-granular/contract'\n\nimport { grChipSafelist } from './safelist'\n\nexport const grChipConfig = defineGranularComponent(import.meta.url, {\n name: 'GrChip',\n // `GrBadge` — импорт его класс-мап и safelist; `GrIcon` не рендерится,\n // крестик — прямой `~icons`-компонент, поэтому его в зависимостях нет.\n dependencies: ['GrBadge'],\n safelist: grChipSafelist,\n})\n"],"mappings":";;;;;;;;;;;AAsBA,IAAa,iBAAiB,CAAC,mBAAG,IAAI,IAAI;CACxC,GAAG;CACH,GAAG,OAAO,OAAO,mBAAmB,CAAC,CAAC,QAAQ,gBAAgB;CAC9D,GAAG,OAAO,OAAO,uBAAuB,CAAC,CAAC,QAAQ,gBAAgB;CAClE,GAAG,iBAAiB,aAAa;CACjC,GAAG,iBAAiB,cAAc;CAClC,GAAG,iBAAiB,oBAAoB;CACxC,GAAG,iBAAiB,iBAAiB;CACrC,GAAG,iBAAiB,iBAAiB;CACrC,GAAG,iBAAiB,cAAc;CAClC,GAAG,iBAAiB,oBAAoB;CACxC,GAAG,iBAAiB,aAAa;CACjC;CACA;AACF,CAAC,CAAC;;;AChCF,IAAa,eAAe,wBAAwB,YAAY,KAAK;CACnE,MAAM;CAGN,cAAc,CAAC,SAAS;CACxB,UAAU;AACZ,CAAC"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { n as splitClassTokens } from "./classTokens-8v2XC74x.js";
|
|
2
|
+
import { defineGranularComponent } from "@feugene/unocss-preset-granular/contract";
|
|
3
|
+
//#region src/components/GrOtpInput/grOtpInputStyles.ts
|
|
4
|
+
/**
|
|
5
|
+
* `w-fit` тут не украшение. Гридовый или флексовый родитель **блокифицирует**
|
|
6
|
+
* `inline-flex`, и ряд растягивался на всю колонку: сами ячейки оставались на
|
|
7
|
+
* месте, а невидимое поле поверх них ловило клики далеко справа от кода.
|
|
8
|
+
*/
|
|
9
|
+
var rootBaseClass = "relative inline-flex w-fit items-center";
|
|
10
|
+
var rootGaps = {
|
|
11
|
+
xs: "gap-1",
|
|
12
|
+
sm: "gap-1.5",
|
|
13
|
+
md: "gap-2",
|
|
14
|
+
lg: "gap-2"
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Настоящее поле лежит **поверх** ряда ячеек и невидимо: текст, каретка и
|
|
18
|
+
* подсветка выделения прозрачны, всё видимое рисуют ячейки.
|
|
19
|
+
*
|
|
20
|
+
* Оно остаётся полноценным `<input>`, и потому даром достаются вставка,
|
|
21
|
+
* автозаполнение кода из SMS, отмена, выделение и вся каретка со стрелками —
|
|
22
|
+
* см. `docs/components/GrOtpInput.md`.
|
|
23
|
+
*
|
|
24
|
+
* `z-index` не нужен: поле позиционировано, ячейки — нет, а позиционированный
|
|
25
|
+
* элемент и так красится поверх статичных соседей. Литерал слоя тут был бы
|
|
26
|
+
* лишней записью в шкале `docs/z-index.md`.
|
|
27
|
+
*/
|
|
28
|
+
var fieldClass = "absolute inset-0 w-full cursor-text bg-transparent text-transparent [caret-color:transparent] outline-none selection:bg-transparent disabled:cursor-not-allowed";
|
|
29
|
+
var cellBaseClass = "relative inline-flex shrink-0 items-center justify-center rounded-[var(--gr-radius-control)] border [font-variant-numeric:tabular-nums] transition-colors duration-[var(--gr-duration-fast)]";
|
|
30
|
+
/**
|
|
31
|
+
* Сторона ячейки повторяет высоту `GrInput` на той же ступени: код стоит в
|
|
32
|
+
* форме рядом с полями, и ряд обязан садиться с ними в одну линию.
|
|
33
|
+
*
|
|
34
|
+
* Через хук, а не классом-числом: квадратная ячейка — решение оформления, и
|
|
35
|
+
* макет вправе сделать её шире.
|
|
36
|
+
*/
|
|
37
|
+
var cellSizes = {
|
|
38
|
+
xs: "h-[var(--gr-otp-input-cell-size,1.75rem)] w-[var(--gr-otp-input-cell-size,1.75rem)] text-[length:var(--gr-control-text-xs)] leading-[var(--gr-control-leading-xs)]",
|
|
39
|
+
sm: "h-[var(--gr-otp-input-cell-size,2rem)] w-[var(--gr-otp-input-cell-size,2rem)] text-[length:var(--gr-control-text-sm)] leading-[var(--gr-control-leading-sm)]",
|
|
40
|
+
md: "h-[var(--gr-otp-input-cell-size,2.5rem)] w-[var(--gr-otp-input-cell-size,2.5rem)] text-[length:var(--gr-control-text-md)] leading-[var(--gr-control-leading-md)]",
|
|
41
|
+
lg: "h-[var(--gr-otp-input-cell-size,2.75rem)] w-[var(--gr-otp-input-cell-size,2.75rem)] text-[length:var(--gr-control-text-lg)] leading-[var(--gr-control-leading-lg)]"
|
|
42
|
+
};
|
|
43
|
+
var cellIdleClass = "border-[var(--gr-brd)] bg-[var(--gr-bg)] text-[var(--gr-fg)]";
|
|
44
|
+
/** Активная ячейка — та, в которой стоит каретка, и только пока поле в фокусе. */
|
|
45
|
+
var cellActiveClass = "border-[var(--gr-otp-input-active-brd,var(--gr-primary))] ring-2 ring-[var(--gr-ring)]";
|
|
46
|
+
/**
|
|
47
|
+
* Вердикт валидации красится своей ролью, а не декоративным `danger`: тема
|
|
48
|
+
* вправе развести подсветку по решению разработчика и ошибку формы.
|
|
49
|
+
*/
|
|
50
|
+
var cellInvalidClass = "border-[var(--gr-invalid-brd)] bg-[var(--gr-bg)] text-[var(--gr-fg)]";
|
|
51
|
+
var cellInvalidActiveClass = "ring-2 ring-[var(--gr-invalid-ring)]";
|
|
52
|
+
/**
|
|
53
|
+
* Недоступность гасится фоном, а не `opacity`: прозрачность разбавляет
|
|
54
|
+
* выверенные на AA токены текста и роняет контраст кода.
|
|
55
|
+
*/
|
|
56
|
+
var cellDisabledClass = "border-[var(--gr-disabled-brd)] bg-[var(--gr-disabled-bg)] text-[var(--gr-disabled-fg)]";
|
|
57
|
+
var placeholderClass = "text-[var(--gr-muted-fg)]";
|
|
58
|
+
/**
|
|
59
|
+
* Каретка рисуется своей, потому что настоящая скрыта вместе с текстом.
|
|
60
|
+
* Мигание — CSS-анимация, значит подчиняется глобальному клампу движения
|
|
61
|
+
* пакета (`docs/motion.md`), а не собственному таймеру.
|
|
62
|
+
*/
|
|
63
|
+
var caretClass = "pointer-events-none absolute h-[1em] w-px bg-[var(--gr-otp-input-caret,var(--gr-primary))]";
|
|
64
|
+
var separatorClass = "select-none px-0.5 text-[var(--gr-muted-fg)]";
|
|
65
|
+
function grOtpInputRootClass(size) {
|
|
66
|
+
return [rootBaseClass, rootGaps[size]].join(" ");
|
|
67
|
+
}
|
|
68
|
+
function grOtpInputCellClass(options) {
|
|
69
|
+
const tokens = [cellBaseClass, cellSizes[options.size]];
|
|
70
|
+
if (options.disabled) tokens.push(cellDisabledClass);
|
|
71
|
+
else if (options.invalid) tokens.push(cellInvalidClass, options.active ? cellInvalidActiveClass : "");
|
|
72
|
+
else tokens.push(cellIdleClass, options.active ? cellActiveClass : "");
|
|
73
|
+
return tokens.filter(Boolean).join(" ");
|
|
74
|
+
}
|
|
75
|
+
//#endregion
|
|
76
|
+
//#region src/components/GrOtpInput/safelist.ts
|
|
77
|
+
var grOtpInputClassTokens = {
|
|
78
|
+
root: [...splitClassTokens(rootBaseClass), ...Object.values(rootGaps).flatMap(splitClassTokens)],
|
|
79
|
+
field: splitClassTokens(fieldClass),
|
|
80
|
+
cell: [
|
|
81
|
+
...splitClassTokens(cellBaseClass),
|
|
82
|
+
...Object.values(cellSizes).flatMap(splitClassTokens),
|
|
83
|
+
...splitClassTokens(cellIdleClass),
|
|
84
|
+
...splitClassTokens(cellActiveClass),
|
|
85
|
+
...splitClassTokens(cellInvalidClass),
|
|
86
|
+
...splitClassTokens(cellInvalidActiveClass),
|
|
87
|
+
...splitClassTokens(cellDisabledClass)
|
|
88
|
+
],
|
|
89
|
+
decoration: [
|
|
90
|
+
...splitClassTokens(placeholderClass),
|
|
91
|
+
...splitClassTokens(caretClass),
|
|
92
|
+
...splitClassTokens(separatorClass)
|
|
93
|
+
]
|
|
94
|
+
};
|
|
95
|
+
var grOtpInputSafelist = [.../* @__PURE__ */ new Set([
|
|
96
|
+
...grOtpInputClassTokens.root,
|
|
97
|
+
...grOtpInputClassTokens.field,
|
|
98
|
+
...grOtpInputClassTokens.cell,
|
|
99
|
+
...grOtpInputClassTokens.decoration
|
|
100
|
+
])];
|
|
101
|
+
//#endregion
|
|
102
|
+
//#region src/components/GrOtpInput/config.ts
|
|
103
|
+
var grOtpInputConfig = defineGranularComponent(import.meta.url, {
|
|
104
|
+
name: "GrOtpInput",
|
|
105
|
+
safelist: grOtpInputSafelist
|
|
106
|
+
});
|
|
107
|
+
//#endregion
|
|
108
|
+
export { grOtpInputCellClass as a, separatorClass as c, fieldClass as i, grOtpInputSafelist as n, grOtpInputRootClass as o, caretClass as r, placeholderClass as s, grOtpInputConfig as t };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-BBtBQE3s.js","names":[],"sources":["../../src/components/GrOtpInput/grOtpInputStyles.ts","../../src/components/GrOtpInput/safelist.ts","../../src/components/GrOtpInput/config.ts"],"sourcesContent":["import type { GrComponentSize } from '../shared/sizes'\n\nexport type GrOtpInputSize = GrComponentSize\n\n/**\n * `w-fit` тут не украшение. Гридовый или флексовый родитель **блокифицирует**\n * `inline-flex`, и ряд растягивался на всю колонку: сами ячейки оставались на\n * месте, а невидимое поле поверх них ловило клики далеко справа от кода.\n */\nexport const rootBaseClass = 'relative inline-flex w-fit items-center'\n\nexport const rootGaps: Record<GrOtpInputSize, string> = {\n xs: 'gap-1',\n sm: 'gap-1.5',\n md: 'gap-2',\n lg: 'gap-2',\n}\n\n/**\n * Настоящее поле лежит **поверх** ряда ячеек и невидимо: текст, каретка и\n * подсветка выделения прозрачны, всё видимое рисуют ячейки.\n *\n * Оно остаётся полноценным `<input>`, и потому даром достаются вставка,\n * автозаполнение кода из SMS, отмена, выделение и вся каретка со стрелками —\n * см. `docs/components/GrOtpInput.md`.\n *\n * `z-index` не нужен: поле позиционировано, ячейки — нет, а позиционированный\n * элемент и так красится поверх статичных соседей. Литерал слоя тут был бы\n * лишней записью в шкале `docs/z-index.md`.\n */\nexport const fieldClass = 'absolute inset-0 w-full cursor-text bg-transparent text-transparent [caret-color:transparent] outline-none selection:bg-transparent disabled:cursor-not-allowed'\n\nexport const cellBaseClass = 'relative inline-flex shrink-0 items-center justify-center rounded-[var(--gr-radius-control)] border [font-variant-numeric:tabular-nums] transition-colors duration-[var(--gr-duration-fast)]'\n\n/**\n * Сторона ячейки повторяет высоту `GrInput` на той же ступени: код стоит в\n * форме рядом с полями, и ряд обязан садиться с ними в одну линию.\n *\n * Через хук, а не классом-числом: квадратная ячейка — решение оформления, и\n * макет вправе сделать её шире.\n */\nexport const cellSizes: Record<GrOtpInputSize, string> = {\n xs: 'h-[var(--gr-otp-input-cell-size,1.75rem)] w-[var(--gr-otp-input-cell-size,1.75rem)] text-[length:var(--gr-control-text-xs)] leading-[var(--gr-control-leading-xs)]',\n sm: 'h-[var(--gr-otp-input-cell-size,2rem)] w-[var(--gr-otp-input-cell-size,2rem)] text-[length:var(--gr-control-text-sm)] leading-[var(--gr-control-leading-sm)]',\n md: 'h-[var(--gr-otp-input-cell-size,2.5rem)] w-[var(--gr-otp-input-cell-size,2.5rem)] text-[length:var(--gr-control-text-md)] leading-[var(--gr-control-leading-md)]',\n lg: 'h-[var(--gr-otp-input-cell-size,2.75rem)] w-[var(--gr-otp-input-cell-size,2.75rem)] text-[length:var(--gr-control-text-lg)] leading-[var(--gr-control-leading-lg)]',\n}\n\nexport const cellIdleClass = 'border-[var(--gr-brd)] bg-[var(--gr-bg)] text-[var(--gr-fg)]'\n\n/** Активная ячейка — та, в которой стоит каретка, и только пока поле в фокусе. */\nexport const cellActiveClass = 'border-[var(--gr-otp-input-active-brd,var(--gr-primary))] ring-2 ring-[var(--gr-ring)]'\n\n/**\n * Вердикт валидации красится своей ролью, а не декоративным `danger`: тема\n * вправе развести подсветку по решению разработчика и ошибку формы.\n */\nexport const cellInvalidClass = 'border-[var(--gr-invalid-brd)] bg-[var(--gr-bg)] text-[var(--gr-fg)]'\n\nexport const cellInvalidActiveClass = 'ring-2 ring-[var(--gr-invalid-ring)]'\n\n/**\n * Недоступность гасится фоном, а не `opacity`: прозрачность разбавляет\n * выверенные на AA токены текста и роняет контраст кода.\n */\nexport const cellDisabledClass = 'border-[var(--gr-disabled-brd)] bg-[var(--gr-disabled-bg)] text-[var(--gr-disabled-fg)]'\n\nexport const placeholderClass = 'text-[var(--gr-muted-fg)]'\n\n/**\n * Каретка рисуется своей, потому что настоящая скрыта вместе с текстом.\n * Мигание — CSS-анимация, значит подчиняется глобальному клампу движения\n * пакета (`docs/motion.md`), а не собственному таймеру.\n */\nexport const caretClass = 'pointer-events-none absolute h-[1em] w-px bg-[var(--gr-otp-input-caret,var(--gr-primary))]'\n\nexport const separatorClass = 'select-none px-0.5 text-[var(--gr-muted-fg)]'\n\nexport function grOtpInputRootClass(size: GrOtpInputSize): string {\n return [rootBaseClass, rootGaps[size]].join(' ')\n}\n\ntype GrOtpInputCellClassOptions = {\n size: GrOtpInputSize\n active: boolean\n invalid: boolean\n disabled: boolean\n}\n\nexport function grOtpInputCellClass(options: GrOtpInputCellClassOptions): string {\n const tokens = [cellBaseClass, cellSizes[options.size]]\n\n if (options.disabled)\n tokens.push(cellDisabledClass)\n else if (options.invalid)\n tokens.push(cellInvalidClass, options.active ? cellInvalidActiveClass : '')\n else\n tokens.push(cellIdleClass, options.active ? cellActiveClass : '')\n\n return tokens.filter(Boolean).join(' ')\n}\n","import { splitClassTokens } from '../shared/classTokens'\nimport {\n caretClass,\n cellActiveClass,\n cellBaseClass,\n cellDisabledClass,\n cellIdleClass,\n cellInvalidActiveClass,\n cellInvalidClass,\n cellSizes,\n fieldClass,\n placeholderClass,\n rootBaseClass,\n rootGaps,\n separatorClass,\n} from './grOtpInputStyles'\n\nexport const grOtpInputClassTokens = {\n root: [...splitClassTokens(rootBaseClass), ...Object.values(rootGaps).flatMap(splitClassTokens)],\n field: splitClassTokens(fieldClass),\n cell: [\n ...splitClassTokens(cellBaseClass),\n ...Object.values(cellSizes).flatMap(splitClassTokens),\n ...splitClassTokens(cellIdleClass),\n ...splitClassTokens(cellActiveClass),\n ...splitClassTokens(cellInvalidClass),\n ...splitClassTokens(cellInvalidActiveClass),\n ...splitClassTokens(cellDisabledClass),\n ],\n decoration: [\n ...splitClassTokens(placeholderClass),\n ...splitClassTokens(caretClass),\n ...splitClassTokens(separatorClass),\n ],\n} as const\n\nexport const grOtpInputSafelist = [...new Set([\n ...grOtpInputClassTokens.root,\n ...grOtpInputClassTokens.field,\n ...grOtpInputClassTokens.cell,\n ...grOtpInputClassTokens.decoration,\n])]\n","import { defineGranularComponent } from '@feugene/unocss-preset-granular/contract'\n\nimport { grOtpInputSafelist } from './safelist'\n\nexport const grOtpInputConfig = defineGranularComponent(import.meta.url, {\n name: 'GrOtpInput',\n safelist: grOtpInputSafelist,\n})\n"],"mappings":";;;;;;;;AASA,IAAa,gBAAgB;AAE7B,IAAa,WAA2C;CACtD,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;AACN;;;;;;;;;;;;;AAcA,IAAa,aAAa;AAE1B,IAAa,gBAAgB;;;;;;;;AAS7B,IAAa,YAA4C;CACvD,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;AACN;AAEA,IAAa,gBAAgB;;AAG7B,IAAa,kBAAkB;;;;;AAM/B,IAAa,mBAAmB;AAEhC,IAAa,yBAAyB;;;;;AAMtC,IAAa,oBAAoB;AAEjC,IAAa,mBAAmB;;;;;;AAOhC,IAAa,aAAa;AAE1B,IAAa,iBAAiB;AAE9B,SAAgB,oBAAoB,MAA8B;CAChE,OAAO,CAAC,eAAe,SAAS,KAAK,CAAC,CAAC,KAAK,GAAG;AACjD;AASA,SAAgB,oBAAoB,SAA6C;CAC/E,MAAM,SAAS,CAAC,eAAe,UAAU,QAAQ,KAAK;CAEtD,IAAI,QAAQ,UACV,OAAO,KAAK,iBAAiB;MAC1B,IAAI,QAAQ,SACf,OAAO,KAAK,kBAAkB,QAAQ,SAAS,yBAAyB,EAAE;MAE1E,OAAO,KAAK,eAAe,QAAQ,SAAS,kBAAkB,EAAE;CAElE,OAAO,OAAO,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;AACxC;;;ACnFA,IAAa,wBAAwB;CACnC,MAAM,CAAC,GAAG,iBAAiB,aAAa,GAAG,GAAG,OAAO,OAAO,QAAQ,CAAC,CAAC,QAAQ,gBAAgB,CAAC;CAC/F,OAAO,iBAAiB,UAAU;CAClC,MAAM;EACJ,GAAG,iBAAiB,aAAa;EACjC,GAAG,OAAO,OAAO,SAAS,CAAC,CAAC,QAAQ,gBAAgB;EACpD,GAAG,iBAAiB,aAAa;EACjC,GAAG,iBAAiB,eAAe;EACnC,GAAG,iBAAiB,gBAAgB;EACpC,GAAG,iBAAiB,sBAAsB;EAC1C,GAAG,iBAAiB,iBAAiB;CACvC;CACA,YAAY;EACV,GAAG,iBAAiB,gBAAgB;EACpC,GAAG,iBAAiB,UAAU;EAC9B,GAAG,iBAAiB,cAAc;CACpC;AACF;AAEA,IAAa,qBAAqB,CAAC,mBAAG,IAAI,IAAI;CAC5C,GAAG,sBAAsB;CACzB,GAAG,sBAAsB;CACzB,GAAG,sBAAsB;CACzB,GAAG,sBAAsB;AAC3B,CAAC,CAAC;;;ACrCF,IAAa,mBAAmB,wBAAwB,YAAY,KAAK;CACvE,MAAM;CACN,UAAU;AACZ,CAAC"}
|
|
@@ -117,6 +117,34 @@ var sortIconSizes = {
|
|
|
117
117
|
md: "sm",
|
|
118
118
|
lg: "md"
|
|
119
119
|
};
|
|
120
|
+
/**
|
|
121
|
+
* Второй ярус строки: подробности под ней.
|
|
122
|
+
*
|
|
123
|
+
* Фон мягче строки набора, а не ярче: подробности обязаны читаться как
|
|
124
|
+
* вложенное в строку, а не как следующая строка. Акцентная полоса слева
|
|
125
|
+
* связывает деталь с её строкой, когда между ними уже прокрутили.
|
|
126
|
+
*/
|
|
127
|
+
var detailRowClass = "bg-[var(--gr-datatable-detail-bg,color-mix(in_srgb,var(--gr-muted)_45%,transparent))]";
|
|
128
|
+
var detailCellClass = "border-t border-[var(--gr-brd)] border-l-2 border-l-[var(--gr-datatable-detail-accent,var(--gr-primary))]";
|
|
129
|
+
/** Содержимое липнет к левому краю: иначе при горизонтальной прокрутке его не видно. */
|
|
130
|
+
var detailContentClass = "sticky left-0";
|
|
131
|
+
var detailPaddings = {
|
|
132
|
+
xs: "px-2 py-2",
|
|
133
|
+
sm: "px-3 py-2.5",
|
|
134
|
+
md: "px-4 py-3",
|
|
135
|
+
lg: "px-5 py-4"
|
|
136
|
+
};
|
|
137
|
+
/** Колонка кнопки раскрытия — той же ширины, что колонка выбора: шапка не должна съезжать. */
|
|
138
|
+
var expandColumnWidths = selectColumnWidths;
|
|
139
|
+
var expandButtonClass = "inline-flex items-center justify-center rounded-[var(--gr-radius-sm)] text-[var(--gr-muted-fg)] transition-colors hover:bg-[var(--gr-muted)] hover:text-[var(--gr-fg)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--gr-ring)]";
|
|
140
|
+
/**
|
|
141
|
+
* Поворот шеврона. Своего `motion-reduce:` здесь нет намеренно: движение пакет
|
|
142
|
+
* гасит одним глобальным блоком в `base.css`, а под `presetMini` этот вариант
|
|
143
|
+
* вдобавок не генерирует CSS вовсе (`docs/motion.md`).
|
|
144
|
+
*/
|
|
145
|
+
var expandIconClass = "h-4 w-4 transition-transform duration-[var(--gr-duration-fast)]";
|
|
146
|
+
var expandIconOpenClass = "rotate-90";
|
|
147
|
+
var detailErrorClass = "flex flex-wrap items-center gap-2 text-[var(--gr-invalid-text)]";
|
|
120
148
|
//#endregion
|
|
121
149
|
//#region src/components/GrDataTable/safelist.ts
|
|
122
150
|
var grDataTableSafelist = [.../* @__PURE__ */ new Set([
|
|
@@ -139,7 +167,16 @@ var grDataTableSafelist = [.../* @__PURE__ */ new Set([
|
|
|
139
167
|
...splitClassTokens(columnPinnedLeftEdgeClass),
|
|
140
168
|
...splitClassTokens(columnPinnedRightEdgeClass),
|
|
141
169
|
...splitClassTokens(rowSelectedClass),
|
|
142
|
-
...splitClassTokens(summaryRowClass)
|
|
170
|
+
...splitClassTokens(summaryRowClass),
|
|
171
|
+
...splitClassTokens(detailRowClass),
|
|
172
|
+
...splitClassTokens(detailCellClass),
|
|
173
|
+
...splitClassTokens(detailContentClass),
|
|
174
|
+
...splitClassTokens(detailErrorClass),
|
|
175
|
+
...Object.values(detailPaddings).flatMap(splitClassTokens),
|
|
176
|
+
...splitClassTokens(expandButtonClass),
|
|
177
|
+
...splitClassTokens(expandIconClass),
|
|
178
|
+
...splitClassTokens(expandIconOpenClass),
|
|
179
|
+
...splitClassTokens("h-5 w-5 h-6 w-6")
|
|
143
180
|
])];
|
|
144
181
|
//#endregion
|
|
145
182
|
//#region src/components/GrDataTable/config.ts
|
|
@@ -148,9 +185,15 @@ var grDataTableConfig = defineGranularComponent(import.meta.url, {
|
|
|
148
185
|
dependencies: [
|
|
149
186
|
"GrTable",
|
|
150
187
|
"GrIcon",
|
|
151
|
-
"GrCheckbox"
|
|
188
|
+
"GrCheckbox",
|
|
189
|
+
"GrButton",
|
|
190
|
+
"GrSkeleton"
|
|
152
191
|
],
|
|
153
|
-
safelist: grDataTableSafelist
|
|
192
|
+
safelist: grDataTableSafelist,
|
|
193
|
+
tokenDefinitionsRef: { light: {
|
|
194
|
+
url: "./themes/light.css",
|
|
195
|
+
selector: ":root"
|
|
196
|
+
} }
|
|
154
197
|
});
|
|
155
198
|
//#endregion
|
|
156
|
-
export {
|
|
199
|
+
export { selectCheckboxSizes as A, expandIconClass as C, placeholderPaddings as D, headerTextSizes as E, sortIconSizes as M, spinnerSizes as N, rowHeightEstimates as O, summaryRowClass as P, expandColumnWidths as S, headerGaps as T, detailContentClass as _, columnDropAfterClass as a, detailRowClass as b, columnHandleClass as c, columnPinnedRightEdgeClass as d, columnResizerClass as f, detailCellClass as g, columnResizerLineClass as h, columnDraggingClass as i, selectColumnWidths as j, rowSelectedClass as k, columnPinnedClass as l, columnResizerLineActiveClass as m, grDataTableSafelist as n, columnDropBeforeClass as o, columnResizerHoverClass as p, cellPaddings as r, columnHandleActiveClass as s, grDataTableConfig as t, columnPinnedLeftEdgeClass as u, detailErrorClass as v, expandIconOpenClass as w, expandButtonClass as x, detailPaddings as y };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-DeyT9dJl.js","names":[],"sources":["../../src/components/GrDataTable/grDataTableStyles.ts","../../src/components/GrDataTable/safelist.ts","../../src/components/GrDataTable/config.ts"],"sourcesContent":["import type { GrCheckboxSize } from '../GrCheckbox/grCheckboxStyles'\nimport type { GrComponentSize } from '../shared/sizes'\n\nexport type GrDataTableSize = GrComponentSize\n\n/** Паддинг ячейки — и в шапке, и в теле: колонки обязаны совпадать по сетке. */\nexport const cellPaddings: Record<GrDataTableSize, string> = {\n xs: 'px-2 py-1.5',\n sm: 'px-3 py-2',\n md: 'px-4 py-3',\n lg: 'px-5 py-4',\n}\n\n/**\n * Оценка высоты строки по размеру: два вертикальных отступа ячейки плюс строка\n * текста и рамка. Виртуализация уточняет её замером — точное число здесь знать\n * неоткуда, содержимое ячейки задаёт потребитель.\n */\nexport const rowHeightEstimates: Record<GrDataTableSize, number> = {\n xs: 33,\n sm: 41,\n md: 49,\n lg: 57,\n}\n\n/** Заглушки loading/empty: по горизонтали как ячейка, по вертикали просторнее. */\nexport const placeholderPaddings: Record<GrDataTableSize, string> = {\n xs: 'px-2 py-3',\n sm: 'px-3 py-4',\n md: 'px-4 py-6',\n lg: 'px-5 py-8',\n}\n\n/**\n * Ручка перестановки колонки. Появляется по наведению на заголовок и по\n * фокусу: постоянная сетка ручек в шапке из десяти колонок читается как рябь,\n * а не как управление.\n */\nexport const columnHandleClass = 'inline-flex shrink-0 cursor-grab items-center text-[var(--gr-datatable-drag-handle,var(--gr-muted-fg))] opacity-0 [touch-action:none] transition-opacity duration-[var(--gr-duration-fast)] focus:outline-none focus-visible:opacity-100 focus-visible:ring-2 focus-visible:ring-[var(--gr-ring)] rounded-[var(--gr-radius-sm)] group-hover:opacity-100'\n\nexport const columnHandleActiveClass = 'opacity-100'\n\n/** Переносимая колонка гасится, чтобы было видно, что она «поднята». */\nexport const columnDraggingClass = 'bg-[var(--gr-muted)]'\n\n/**\n * Место вставки — полоса по краю ячейки заголовка. Псевдоэлемент, а не свой\n * узел: `<th>` не терпит посторонних детей в раскладке таблицы.\n */\nexport const columnDropBeforeClass = 'before:absolute before:inset-y-0 before:left-0 before:w-[var(--gr-datatable-drag-indicator-width,2px)] before:bg-[var(--gr-datatable-drag-indicator,var(--gr-primary))] before:content-empty'\n\nexport const columnDropAfterClass = 'after:absolute after:inset-y-0 after:right-0 after:w-[var(--gr-datatable-drag-indicator-width,2px)] after:bg-[var(--gr-datatable-drag-indicator,var(--gr-primary))] after:content-empty'\n\n/**\n * Подсветка выбранной строки. Живёт здесь, потому что закреплённой ячейке её\n * приходится повторять: у ячейки свой непрозрачный фон, и подсветка строки\n * сквозь него не видна.\n */\nexport const rowSelectedClass = 'bg-[color-mix(in_srgb,var(--gr-primary)_8%,transparent)]'\n\n/**\n * Итоговая строка. Отбивка та же, что между строками тела, плюс вес: итог —\n * вывод из набора, а не ещё одна его запись, и читатель должен видеть это до\n * того, как разберёт цифры. Тон оставлен потребителю: «возвраты» и «прибыль» —\n * разные сообщения, и выбирать за него компонент не должен.\n */\nexport const summaryRowClass = 'border-t border-[var(--gr-brd)] font-600'\n\n/**\n * Ручка ширины — полоса у правого края заголовка. Видима она узкой линией, а\n * ловится широкой зоной: попасть в двухпиксельную границу мышью тяжело.\n */\nexport const columnResizerClass = 'absolute inset-y-0 right-0 z-[1] flex w-3 translate-x-1/2 cursor-col-resize items-stretch justify-center [touch-action:none] focus:outline-none'\n\nexport const columnResizerLineClass = 'w-[var(--gr-datatable-resizer-width,2px)] bg-transparent transition-colors duration-[var(--gr-duration-fast)]'\n\n/** Полоса подсвечивается только когда её ведут или на неё встал фокус. */\nexport const columnResizerLineActiveClass = 'bg-[var(--gr-datatable-resizer,var(--gr-primary))]'\n\nexport const columnResizerHoverClass = 'hover:bg-[var(--gr-datatable-resizer,var(--gr-primary))] focus-visible:bg-[var(--gr-datatable-resizer,var(--gr-primary))]'\n\n/**\n * Закреплённая колонка липнет к краю прокрутки. Фон обязателен: без него\n * уезжающие под неё ячейки просвечивают насквозь.\n */\nexport const columnPinnedClass = 'sticky z-[2] bg-[var(--gr-card)]'\n\n/** Граница группы закреплённых колонок — тень, а не рамка: рамка сдвигает сетку. */\nexport const columnPinnedLeftEdgeClass = 'shadow-[var(--gr-datatable-pinned-shadow,4px_0_6px_-4px_rgba(0,0,0,0.25))]'\n\nexport const columnPinnedRightEdgeClass = 'shadow-[var(--gr-datatable-pinned-shadow-end,-4px_0_6px_-4px_rgba(0,0,0,0.25))]'\n\n/** Подпись колонки набирается мельче тела таблицы — она не данные, а навигация. */\nexport const headerTextSizes: Record<GrDataTableSize, string> = {\n xs: 'text-[length:var(--gr-control-text-3xs)] leading-[var(--gr-control-leading-3xs)]',\n sm: 'text-[length:var(--gr-control-text-2xs)] leading-[var(--gr-control-leading-2xs)]',\n md: 'text-[length:var(--gr-control-text-xs)] leading-[var(--gr-leading-xs)]',\n lg: 'text-[length:var(--gr-control-text-md)] leading-[var(--gr-leading-sm)]',\n}\n\n/**\n * Размер `GrCheckbox` в колонке выбора. Здесь не классы, а ступень шкалы:\n * коробку рисует сам чекбокс — он же держит `indeterminate`, disabled без\n * `opacity` и фокус-кольцо.\n */\nexport const selectCheckboxSizes: Record<GrDataTableSize, GrCheckboxSize> = {\n xs: 'xs',\n sm: 'sm',\n md: 'md',\n lg: 'lg',\n}\n\n/** Ширина колонки выбора: коробка чекбокса плюс горизонтальный паддинг ячейки. */\nexport const selectColumnWidths: Record<GrDataTableSize, string> = {\n xs: 'w-7',\n sm: 'w-8',\n md: 'w-10',\n lg: 'w-12',\n}\n\n/** Зазор между подписью колонки и стрелкой сортировки. */\nexport const headerGaps: Record<GrDataTableSize, string> = {\n xs: 'gap-1',\n sm: 'gap-1.5',\n md: 'gap-2',\n lg: 'gap-2',\n}\n\n/** Спиннер в строке загрузки — тем же кеглем, что иконка сортировки рядом. */\nexport const spinnerSizes: Record<GrDataTableSize, string> = {\n xs: 'h-3 w-3',\n sm: 'h-3.5 w-3.5',\n md: 'h-4 w-4',\n lg: 'h-5 w-5',\n}\n\n/** Стрелка сортировки берёт размер из шкалы `GrIcon` (`xs…lg` → `14…20px`). */\nexport const sortIconSizes: Record<GrDataTableSize, GrComponentSize> = {\n xs: 'xs',\n sm: 'xs',\n md: 'sm',\n lg: 'md',\n}\n","import { splitClassTokens } from '../shared/classTokens'\nimport {\n cellPaddings,\n columnDraggingClass,\n columnDropAfterClass,\n columnDropBeforeClass,\n columnHandleActiveClass,\n columnHandleClass,\n columnPinnedClass,\n columnPinnedLeftEdgeClass,\n columnPinnedRightEdgeClass,\n columnResizerClass,\n columnResizerHoverClass,\n columnResizerLineActiveClass,\n columnResizerLineClass,\n headerGaps,\n headerTextSizes,\n placeholderPaddings,\n rowSelectedClass,\n selectColumnWidths,\n spinnerSizes,\n summaryRowClass,\n} from './grDataTableStyles'\n\nexport const grDataTableSafelist = [...new Set([\n ...Object.values(cellPaddings).flatMap(splitClassTokens),\n ...Object.values(placeholderPaddings).flatMap(splitClassTokens),\n ...Object.values(headerTextSizes).flatMap(splitClassTokens),\n ...Object.values(selectColumnWidths).flatMap(splitClassTokens),\n ...Object.values(headerGaps).flatMap(splitClassTokens),\n ...Object.values(spinnerSizes).flatMap(splitClassTokens),\n ...splitClassTokens(columnHandleClass),\n ...splitClassTokens(columnHandleActiveClass),\n ...splitClassTokens(columnDraggingClass),\n ...splitClassTokens(columnDropBeforeClass),\n ...splitClassTokens(columnDropAfterClass),\n ...splitClassTokens(columnResizerClass),\n ...splitClassTokens(columnResizerLineClass),\n ...splitClassTokens(columnResizerLineActiveClass),\n ...splitClassTokens(columnResizerHoverClass),\n ...splitClassTokens(columnPinnedClass),\n ...splitClassTokens(columnPinnedLeftEdgeClass),\n ...splitClassTokens(columnPinnedRightEdgeClass),\n ...splitClassTokens(rowSelectedClass),\n ...splitClassTokens(summaryRowClass),\n])]\n","import { defineGranularComponent } from '@feugene/unocss-preset-granular/contract'\n\nimport { grDataTableSafelist } from './safelist'\n\nexport const grDataTableConfig = defineGranularComponent(import.meta.url, {\n name: 'GrDataTable',\n dependencies: ['GrTable', 'GrIcon', 'GrCheckbox'],\n safelist: grDataTableSafelist,\n})\n"],"mappings":";;;;AAMA,IAAa,eAAgD;CAC3D,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;AACN;;;;;;AAOA,IAAa,qBAAsD;CACjE,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;AACN;;AAGA,IAAa,sBAAuD;CAClE,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;AACN;;;;;;AAOA,IAAa,oBAAoB;AAEjC,IAAa,0BAA0B;;AAGvC,IAAa,sBAAsB;;;;;AAMnC,IAAa,wBAAwB;AAErC,IAAa,uBAAuB;;;;;;AAOpC,IAAa,mBAAmB;;;;;;;AAQhC,IAAa,kBAAkB;;;;;AAM/B,IAAa,qBAAqB;AAElC,IAAa,yBAAyB;;AAGtC,IAAa,+BAA+B;AAE5C,IAAa,0BAA0B;;;;;AAMvC,IAAa,oBAAoB;;AAGjC,IAAa,4BAA4B;AAEzC,IAAa,6BAA6B;;AAG1C,IAAa,kBAAmD;CAC9D,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;AACN;;;;;;AAOA,IAAa,sBAA+D;CAC1E,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;AACN;;AAGA,IAAa,qBAAsD;CACjE,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;AACN;;AAGA,IAAa,aAA8C;CACzD,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;AACN;;AAGA,IAAa,eAAgD;CAC3D,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;AACN;;AAGA,IAAa,gBAA0D;CACrE,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;AACN;;;ACtHA,IAAa,sBAAsB,CAAC,mBAAG,IAAI,IAAI;CAC7C,GAAG,OAAO,OAAO,YAAY,CAAC,CAAC,QAAQ,gBAAgB;CACvD,GAAG,OAAO,OAAO,mBAAmB,CAAC,CAAC,QAAQ,gBAAgB;CAC9D,GAAG,OAAO,OAAO,eAAe,CAAC,CAAC,QAAQ,gBAAgB;CAC1D,GAAG,OAAO,OAAO,kBAAkB,CAAC,CAAC,QAAQ,gBAAgB;CAC7D,GAAG,OAAO,OAAO,UAAU,CAAC,CAAC,QAAQ,gBAAgB;CACrD,GAAG,OAAO,OAAO,YAAY,CAAC,CAAC,QAAQ,gBAAgB;CACvD,GAAG,iBAAiB,iBAAiB;CACrC,GAAG,iBAAiB,uBAAuB;CAC3C,GAAG,iBAAiB,mBAAmB;CACvC,GAAG,iBAAiB,qBAAqB;CACzC,GAAG,iBAAiB,oBAAoB;CACxC,GAAG,iBAAiB,kBAAkB;CACtC,GAAG,iBAAiB,sBAAsB;CAC1C,GAAG,iBAAiB,4BAA4B;CAChD,GAAG,iBAAiB,uBAAuB;CAC3C,GAAG,iBAAiB,iBAAiB;CACrC,GAAG,iBAAiB,yBAAyB;CAC7C,GAAG,iBAAiB,0BAA0B;CAC9C,GAAG,iBAAiB,gBAAgB;CACpC,GAAG,iBAAiB,eAAe;AACrC,CAAC,CAAC;;;ACzCF,IAAa,oBAAoB,wBAAwB,YAAY,KAAK;CACxE,MAAM;CACN,cAAc;EAAC;EAAW;EAAU;CAAY;CAChD,UAAU;AACZ,CAAC"}
|
|
1
|
+
{"version":3,"file":"config-Bs1HwUcx.js","names":[],"sources":["../../src/components/GrDataTable/grDataTableStyles.ts","../../src/components/GrDataTable/safelist.ts","../../src/components/GrDataTable/config.ts"],"sourcesContent":["import type { GrCheckboxSize } from '../GrCheckbox/grCheckboxStyles'\nimport type { GrComponentSize } from '../shared/sizes'\n\nexport type GrDataTableSize = GrComponentSize\n\n/** Паддинг ячейки — и в шапке, и в теле: колонки обязаны совпадать по сетке. */\nexport const cellPaddings: Record<GrDataTableSize, string> = {\n xs: 'px-2 py-1.5',\n sm: 'px-3 py-2',\n md: 'px-4 py-3',\n lg: 'px-5 py-4',\n}\n\n/**\n * Оценка высоты строки по размеру: два вертикальных отступа ячейки плюс строка\n * текста и рамка. Виртуализация уточняет её замером — точное число здесь знать\n * неоткуда, содержимое ячейки задаёт потребитель.\n */\nexport const rowHeightEstimates: Record<GrDataTableSize, number> = {\n xs: 33,\n sm: 41,\n md: 49,\n lg: 57,\n}\n\n/** Заглушки loading/empty: по горизонтали как ячейка, по вертикали просторнее. */\nexport const placeholderPaddings: Record<GrDataTableSize, string> = {\n xs: 'px-2 py-3',\n sm: 'px-3 py-4',\n md: 'px-4 py-6',\n lg: 'px-5 py-8',\n}\n\n/**\n * Ручка перестановки колонки. Появляется по наведению на заголовок и по\n * фокусу: постоянная сетка ручек в шапке из десяти колонок читается как рябь,\n * а не как управление.\n */\nexport const columnHandleClass = 'inline-flex shrink-0 cursor-grab items-center text-[var(--gr-datatable-drag-handle,var(--gr-muted-fg))] opacity-0 [touch-action:none] transition-opacity duration-[var(--gr-duration-fast)] focus:outline-none focus-visible:opacity-100 focus-visible:ring-2 focus-visible:ring-[var(--gr-ring)] rounded-[var(--gr-radius-sm)] group-hover:opacity-100'\n\nexport const columnHandleActiveClass = 'opacity-100'\n\n/** Переносимая колонка гасится, чтобы было видно, что она «поднята». */\nexport const columnDraggingClass = 'bg-[var(--gr-muted)]'\n\n/**\n * Место вставки — полоса по краю ячейки заголовка. Псевдоэлемент, а не свой\n * узел: `<th>` не терпит посторонних детей в раскладке таблицы.\n */\nexport const columnDropBeforeClass = 'before:absolute before:inset-y-0 before:left-0 before:w-[var(--gr-datatable-drag-indicator-width,2px)] before:bg-[var(--gr-datatable-drag-indicator,var(--gr-primary))] before:content-empty'\n\nexport const columnDropAfterClass = 'after:absolute after:inset-y-0 after:right-0 after:w-[var(--gr-datatable-drag-indicator-width,2px)] after:bg-[var(--gr-datatable-drag-indicator,var(--gr-primary))] after:content-empty'\n\n/**\n * Подсветка выбранной строки. Живёт здесь, потому что закреплённой ячейке её\n * приходится повторять: у ячейки свой непрозрачный фон, и подсветка строки\n * сквозь него не видна.\n */\nexport const rowSelectedClass = 'bg-[color-mix(in_srgb,var(--gr-primary)_8%,transparent)]'\n\n/**\n * Итоговая строка. Отбивка та же, что между строками тела, плюс вес: итог —\n * вывод из набора, а не ещё одна его запись, и читатель должен видеть это до\n * того, как разберёт цифры. Тон оставлен потребителю: «возвраты» и «прибыль» —\n * разные сообщения, и выбирать за него компонент не должен.\n */\nexport const summaryRowClass = 'border-t border-[var(--gr-brd)] font-600'\n\n/**\n * Ручка ширины — полоса у правого края заголовка. Видима она узкой линией, а\n * ловится широкой зоной: попасть в двухпиксельную границу мышью тяжело.\n */\nexport const columnResizerClass = 'absolute inset-y-0 right-0 z-[1] flex w-3 translate-x-1/2 cursor-col-resize items-stretch justify-center [touch-action:none] focus:outline-none'\n\nexport const columnResizerLineClass = 'w-[var(--gr-datatable-resizer-width,2px)] bg-transparent transition-colors duration-[var(--gr-duration-fast)]'\n\n/** Полоса подсвечивается только когда её ведут или на неё встал фокус. */\nexport const columnResizerLineActiveClass = 'bg-[var(--gr-datatable-resizer,var(--gr-primary))]'\n\nexport const columnResizerHoverClass = 'hover:bg-[var(--gr-datatable-resizer,var(--gr-primary))] focus-visible:bg-[var(--gr-datatable-resizer,var(--gr-primary))]'\n\n/**\n * Закреплённая колонка липнет к краю прокрутки. Фон обязателен: без него\n * уезжающие под неё ячейки просвечивают насквозь.\n */\nexport const columnPinnedClass = 'sticky z-[2] bg-[var(--gr-card)]'\n\n/** Граница группы закреплённых колонок — тень, а не рамка: рамка сдвигает сетку. */\nexport const columnPinnedLeftEdgeClass = 'shadow-[var(--gr-datatable-pinned-shadow,4px_0_6px_-4px_rgba(0,0,0,0.25))]'\n\nexport const columnPinnedRightEdgeClass = 'shadow-[var(--gr-datatable-pinned-shadow-end,-4px_0_6px_-4px_rgba(0,0,0,0.25))]'\n\n/** Подпись колонки набирается мельче тела таблицы — она не данные, а навигация. */\nexport const headerTextSizes: Record<GrDataTableSize, string> = {\n xs: 'text-[length:var(--gr-control-text-3xs)] leading-[var(--gr-control-leading-3xs)]',\n sm: 'text-[length:var(--gr-control-text-2xs)] leading-[var(--gr-control-leading-2xs)]',\n md: 'text-[length:var(--gr-control-text-xs)] leading-[var(--gr-leading-xs)]',\n lg: 'text-[length:var(--gr-control-text-md)] leading-[var(--gr-leading-sm)]',\n}\n\n/**\n * Размер `GrCheckbox` в колонке выбора. Здесь не классы, а ступень шкалы:\n * коробку рисует сам чекбокс — он же держит `indeterminate`, disabled без\n * `opacity` и фокус-кольцо.\n */\nexport const selectCheckboxSizes: Record<GrDataTableSize, GrCheckboxSize> = {\n xs: 'xs',\n sm: 'sm',\n md: 'md',\n lg: 'lg',\n}\n\n/** Ширина колонки выбора: коробка чекбокса плюс горизонтальный паддинг ячейки. */\nexport const selectColumnWidths: Record<GrDataTableSize, string> = {\n xs: 'w-7',\n sm: 'w-8',\n md: 'w-10',\n lg: 'w-12',\n}\n\n/** Зазор между подписью колонки и стрелкой сортировки. */\nexport const headerGaps: Record<GrDataTableSize, string> = {\n xs: 'gap-1',\n sm: 'gap-1.5',\n md: 'gap-2',\n lg: 'gap-2',\n}\n\n/** Спиннер в строке загрузки — тем же кеглем, что иконка сортировки рядом. */\nexport const spinnerSizes: Record<GrDataTableSize, string> = {\n xs: 'h-3 w-3',\n sm: 'h-3.5 w-3.5',\n md: 'h-4 w-4',\n lg: 'h-5 w-5',\n}\n\n/** Стрелка сортировки берёт размер из шкалы `GrIcon` (`xs…lg` → `14…20px`). */\nexport const sortIconSizes: Record<GrDataTableSize, GrComponentSize> = {\n xs: 'xs',\n sm: 'xs',\n md: 'sm',\n lg: 'md',\n}\n\n/**\n * Второй ярус строки: подробности под ней.\n *\n * Фон мягче строки набора, а не ярче: подробности обязаны читаться как\n * вложенное в строку, а не как следующая строка. Акцентная полоса слева\n * связывает деталь с её строкой, когда между ними уже прокрутили.\n */\nexport const detailRowClass = 'bg-[var(--gr-datatable-detail-bg,color-mix(in_srgb,var(--gr-muted)_45%,transparent))]'\n\nexport const detailCellClass = 'border-t border-[var(--gr-brd)] border-l-2 border-l-[var(--gr-datatable-detail-accent,var(--gr-primary))]'\n\n/** Содержимое липнет к левому краю: иначе при горизонтальной прокрутке его не видно. */\nexport const detailContentClass = 'sticky left-0'\n\nexport const detailPaddings: Record<GrDataTableSize, string> = {\n xs: 'px-2 py-2',\n sm: 'px-3 py-2.5',\n md: 'px-4 py-3',\n lg: 'px-5 py-4',\n}\n\n/** Колонка кнопки раскрытия — той же ширины, что колонка выбора: шапка не должна съезжать. */\nexport const expandColumnWidths = selectColumnWidths\n\nexport const expandButtonClass = 'inline-flex items-center justify-center rounded-[var(--gr-radius-sm)] text-[var(--gr-muted-fg)] transition-colors hover:bg-[var(--gr-muted)] hover:text-[var(--gr-fg)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--gr-ring)]'\n\n/**\n * Поворот шеврона. Своего `motion-reduce:` здесь нет намеренно: движение пакет\n * гасит одним глобальным блоком в `base.css`, а под `presetMini` этот вариант\n * вдобавок не генерирует CSS вовсе (`docs/motion.md`).\n */\nexport const expandIconClass = 'h-4 w-4 transition-transform duration-[var(--gr-duration-fast)]'\n\nexport const expandIconOpenClass = 'rotate-90'\n\nexport const detailErrorClass = 'flex flex-wrap items-center gap-2 text-[var(--gr-invalid-text)]'\n","import { splitClassTokens } from '../shared/classTokens'\nimport {\n cellPaddings,\n columnDraggingClass,\n detailCellClass,\n detailContentClass,\n detailErrorClass,\n detailPaddings,\n detailRowClass,\n expandButtonClass,\n expandIconClass,\n expandIconOpenClass,\n columnDropAfterClass,\n columnDropBeforeClass,\n columnHandleActiveClass,\n columnHandleClass,\n columnPinnedClass,\n columnPinnedLeftEdgeClass,\n columnPinnedRightEdgeClass,\n columnResizerClass,\n columnResizerHoverClass,\n columnResizerLineActiveClass,\n columnResizerLineClass,\n headerGaps,\n headerTextSizes,\n placeholderPaddings,\n rowSelectedClass,\n selectColumnWidths,\n spinnerSizes,\n summaryRowClass,\n} from './grDataTableStyles'\n\nexport const grDataTableSafelist = [...new Set([\n ...Object.values(cellPaddings).flatMap(splitClassTokens),\n ...Object.values(placeholderPaddings).flatMap(splitClassTokens),\n ...Object.values(headerTextSizes).flatMap(splitClassTokens),\n ...Object.values(selectColumnWidths).flatMap(splitClassTokens),\n ...Object.values(headerGaps).flatMap(splitClassTokens),\n ...Object.values(spinnerSizes).flatMap(splitClassTokens),\n ...splitClassTokens(columnHandleClass),\n ...splitClassTokens(columnHandleActiveClass),\n ...splitClassTokens(columnDraggingClass),\n ...splitClassTokens(columnDropBeforeClass),\n ...splitClassTokens(columnDropAfterClass),\n ...splitClassTokens(columnResizerClass),\n ...splitClassTokens(columnResizerLineClass),\n ...splitClassTokens(columnResizerLineActiveClass),\n ...splitClassTokens(columnResizerHoverClass),\n ...splitClassTokens(columnPinnedClass),\n ...splitClassTokens(columnPinnedLeftEdgeClass),\n ...splitClassTokens(columnPinnedRightEdgeClass),\n ...splitClassTokens(rowSelectedClass),\n ...splitClassTokens(summaryRowClass),\n // Второй ярус строки: классы приходят из `.ts`-хелпера, а такие литералы\n // пресет не видит.\n ...splitClassTokens(detailRowClass),\n ...splitClassTokens(detailCellClass),\n ...splitClassTokens(detailContentClass),\n ...splitClassTokens(detailErrorClass),\n ...Object.values(detailPaddings).flatMap(splitClassTokens),\n ...splitClassTokens(expandButtonClass),\n ...splitClassTokens(expandIconClass),\n ...splitClassTokens(expandIconOpenClass),\n ...splitClassTokens('h-5 w-5 h-6 w-6'),\n])]\n","import { defineGranularComponent } from '@feugene/unocss-preset-granular/contract'\n\nimport { grDataTableSafelist } from './safelist'\n\nexport const grDataTableConfig = defineGranularComponent(import.meta.url, {\n name: 'GrDataTable',\n dependencies: ['GrTable', 'GrIcon', 'GrCheckbox', 'GrButton', 'GrSkeleton'],\n safelist: grDataTableSafelist,\n // Только светлая: обе роли ссылаются на токены, которые сами меняются с темой.\n tokenDefinitionsRef: {\n light: { url: './themes/light.css', selector: ':root' },\n },\n})\n"],"mappings":";;;;AAMA,IAAa,eAAgD;CAC3D,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;AACN;;;;;;AAOA,IAAa,qBAAsD;CACjE,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;AACN;;AAGA,IAAa,sBAAuD;CAClE,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;AACN;;;;;;AAOA,IAAa,oBAAoB;AAEjC,IAAa,0BAA0B;;AAGvC,IAAa,sBAAsB;;;;;AAMnC,IAAa,wBAAwB;AAErC,IAAa,uBAAuB;;;;;;AAOpC,IAAa,mBAAmB;;;;;;;AAQhC,IAAa,kBAAkB;;;;;AAM/B,IAAa,qBAAqB;AAElC,IAAa,yBAAyB;;AAGtC,IAAa,+BAA+B;AAE5C,IAAa,0BAA0B;;;;;AAMvC,IAAa,oBAAoB;;AAGjC,IAAa,4BAA4B;AAEzC,IAAa,6BAA6B;;AAG1C,IAAa,kBAAmD;CAC9D,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;AACN;;;;;;AAOA,IAAa,sBAA+D;CAC1E,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;AACN;;AAGA,IAAa,qBAAsD;CACjE,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;AACN;;AAGA,IAAa,aAA8C;CACzD,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;AACN;;AAGA,IAAa,eAAgD;CAC3D,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;AACN;;AAGA,IAAa,gBAA0D;CACrE,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;AACN;;;;;;;;AASA,IAAa,iBAAiB;AAE9B,IAAa,kBAAkB;;AAG/B,IAAa,qBAAqB;AAElC,IAAa,iBAAkD;CAC7D,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;AACN;;AAGA,IAAa,qBAAqB;AAElC,IAAa,oBAAoB;;;;;;AAOjC,IAAa,kBAAkB;AAE/B,IAAa,sBAAsB;AAEnC,IAAa,mBAAmB;;;ACnJhC,IAAa,sBAAsB,CAAC,mBAAG,IAAI,IAAI;CAC7C,GAAG,OAAO,OAAO,YAAY,CAAC,CAAC,QAAQ,gBAAgB;CACvD,GAAG,OAAO,OAAO,mBAAmB,CAAC,CAAC,QAAQ,gBAAgB;CAC9D,GAAG,OAAO,OAAO,eAAe,CAAC,CAAC,QAAQ,gBAAgB;CAC1D,GAAG,OAAO,OAAO,kBAAkB,CAAC,CAAC,QAAQ,gBAAgB;CAC7D,GAAG,OAAO,OAAO,UAAU,CAAC,CAAC,QAAQ,gBAAgB;CACrD,GAAG,OAAO,OAAO,YAAY,CAAC,CAAC,QAAQ,gBAAgB;CACvD,GAAG,iBAAiB,iBAAiB;CACrC,GAAG,iBAAiB,uBAAuB;CAC3C,GAAG,iBAAiB,mBAAmB;CACvC,GAAG,iBAAiB,qBAAqB;CACzC,GAAG,iBAAiB,oBAAoB;CACxC,GAAG,iBAAiB,kBAAkB;CACtC,GAAG,iBAAiB,sBAAsB;CAC1C,GAAG,iBAAiB,4BAA4B;CAChD,GAAG,iBAAiB,uBAAuB;CAC3C,GAAG,iBAAiB,iBAAiB;CACrC,GAAG,iBAAiB,yBAAyB;CAC7C,GAAG,iBAAiB,0BAA0B;CAC9C,GAAG,iBAAiB,gBAAgB;CACpC,GAAG,iBAAiB,eAAe;CAGnC,GAAG,iBAAiB,cAAc;CAClC,GAAG,iBAAiB,eAAe;CACnC,GAAG,iBAAiB,kBAAkB;CACtC,GAAG,iBAAiB,gBAAgB;CACpC,GAAG,OAAO,OAAO,cAAc,CAAC,CAAC,QAAQ,gBAAgB;CACzD,GAAG,iBAAiB,iBAAiB;CACrC,GAAG,iBAAiB,eAAe;CACnC,GAAG,iBAAiB,mBAAmB;CACvC,GAAG,iBAAiB,iBAAiB;AACvC,CAAC,CAAC;;;AC5DF,IAAa,oBAAoB,wBAAwB,YAAY,KAAK;CACxE,MAAM;CACN,cAAc;EAAC;EAAW;EAAU;EAAc;EAAY;CAAY;CAC1E,UAAU;CAEV,qBAAqB,EACnB,OAAO;EAAE,KAAK;EAAsB,UAAU;CAAQ,EACxD;AACF,CAAC"}
|
|
@@ -5,7 +5,43 @@ var shapes = {
|
|
|
5
5
|
circle: "rounded-[var(--gr-radius-full)]",
|
|
6
6
|
square: "rounded-[var(--gr-avatar-square-radius,10px)]"
|
|
7
7
|
};
|
|
8
|
-
var rootBaseClass = "relative inline-flex shrink-0 items-center justify-center overflow-hidden border border-[var(--gr-brd)]
|
|
8
|
+
var rootBaseClass = "relative inline-flex shrink-0 items-center justify-center overflow-hidden border border-[var(--gr-brd)] font-700";
|
|
9
|
+
/** Цвет по умолчанию. Отделён от базы, иначе он спорил бы с автоцветом порядком правил. */
|
|
10
|
+
var rootNeutralClass = "bg-[var(--gr-muted)] text-[var(--gr-muted-fg)]";
|
|
11
|
+
/**
|
|
12
|
+
* Палитра автоцвета: подложка и инициалы одним классом на слот.
|
|
13
|
+
*
|
|
14
|
+
* Цвета сюда не попадают — только имена слотов. Что стоит за слотом, решает
|
|
15
|
+
* тема (`--gr-avatar-N-bg`/`-fg` ссылаются на пары `-light`/`-text` тонов), и
|
|
16
|
+
* приложение вправе переопределить любой, не трогая компонент.
|
|
17
|
+
*
|
|
18
|
+
* Классы статические: UnoCSS сканирует литералы, и собранный в рантайме
|
|
19
|
+
* `bg-[var(--gr-avatar-${n}-bg)]` в CSS не превратился бы.
|
|
20
|
+
*/
|
|
21
|
+
var avatarToneClasses = [
|
|
22
|
+
"bg-[var(--gr-avatar-1-bg)] text-[var(--gr-avatar-1-fg)]",
|
|
23
|
+
"bg-[var(--gr-avatar-2-bg)] text-[var(--gr-avatar-2-fg)]",
|
|
24
|
+
"bg-[var(--gr-avatar-3-bg)] text-[var(--gr-avatar-3-fg)]",
|
|
25
|
+
"bg-[var(--gr-avatar-4-bg)] text-[var(--gr-avatar-4-fg)]",
|
|
26
|
+
"bg-[var(--gr-avatar-5-bg)] text-[var(--gr-avatar-5-fg)]",
|
|
27
|
+
"bg-[var(--gr-avatar-6-bg)] text-[var(--gr-avatar-6-fg)]"
|
|
28
|
+
];
|
|
29
|
+
/**
|
|
30
|
+
* Слот палитры по имени: тот же человек — тот же цвет.
|
|
31
|
+
*
|
|
32
|
+
* Стабильность здесь и есть смысл функции: цвет не должен меняться ни между
|
|
33
|
+
* сессиями, ни между сервером и клиентом, иначе аватар мигает на гидрации, а
|
|
34
|
+
* узнаваемость — то, ради чего автоцвет и заводят, — теряется. Отсюда обычный
|
|
35
|
+
* детерминированный перебор кодов, а не хеш из окружения.
|
|
36
|
+
*
|
|
37
|
+
* `>>> 0` обязателен: без него сумма уходит в отрицательные на длинных именах,
|
|
38
|
+
* и остаток от деления даёт отрицательный индекс.
|
|
39
|
+
*/
|
|
40
|
+
function avatarToneIndex(name) {
|
|
41
|
+
let hash = 0;
|
|
42
|
+
for (const char of name.trim()) hash = hash * 31 + (char.codePointAt(0) ?? 0) >>> 0;
|
|
43
|
+
return hash % avatarToneClasses.length;
|
|
44
|
+
}
|
|
9
45
|
/** Индикатор статуса: кольцо цветом фона отделяет точку от самого аватара. */
|
|
10
46
|
var statusDotClass = "absolute bottom-0 right-0 block h-1/4 w-1/4 min-h-2 min-w-2 rounded-[var(--gr-radius-full)] ring-2 ring-[var(--gr-bg)]";
|
|
11
47
|
var statusToneClass = {
|
|
@@ -58,7 +94,12 @@ function initialsFrom(name) {
|
|
|
58
94
|
//#region src/components/GrAvatar/safelist.ts
|
|
59
95
|
var grAvatarClassTokens = {
|
|
60
96
|
shapes: Object.values(shapes).flatMap(splitClassTokens),
|
|
61
|
-
root: [
|
|
97
|
+
root: [
|
|
98
|
+
...splitClassTokens(rootBaseClass),
|
|
99
|
+
...splitClassTokens(rootNeutralClass),
|
|
100
|
+
...splitClassTokens(rootStatusClass),
|
|
101
|
+
...avatarToneClasses.flatMap(splitClassTokens)
|
|
102
|
+
],
|
|
62
103
|
media: [...splitClassTokens(mediaClass), ...splitClassTokens(mediaClipClass)],
|
|
63
104
|
status: [...splitClassTokens(statusDotClass), ...Object.values(statusToneClass).flatMap(splitClassTokens)],
|
|
64
105
|
group: [
|
|
@@ -79,7 +120,11 @@ var grAvatarSafelist = [.../* @__PURE__ */ new Set([
|
|
|
79
120
|
var grAvatarConfig = defineGranularComponent(import.meta.url, {
|
|
80
121
|
name: "GrAvatar",
|
|
81
122
|
dependencies: ["GrSkeleton"],
|
|
82
|
-
safelist: grAvatarSafelist
|
|
123
|
+
safelist: grAvatarSafelist,
|
|
124
|
+
tokenDefinitionsRef: { light: {
|
|
125
|
+
url: "./themes/light.css",
|
|
126
|
+
selector: ":root"
|
|
127
|
+
} }
|
|
83
128
|
});
|
|
84
129
|
//#endregion
|
|
85
|
-
export {
|
|
130
|
+
export { statusToneClass as _, avatarToneIndex as a, groupItemClass as c, mediaClass as d, mediaClipClass as f, statusDotClass as g, rootStatusClass as h, avatarToneClasses as i, groupOverflowClass as l, rootNeutralClass as m, grAvatarSafelist as n, grAvatarClass as o, rootBaseClass as p, avatarFontSizePx as r, groupBaseClass as s, grAvatarConfig as t, initialsFrom as u };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-CzeZg2LO.js","names":[],"sources":["../../src/components/GrAvatar/grAvatarStyles.ts","../../src/components/GrAvatar/safelist.ts","../../src/components/GrAvatar/config.ts"],"sourcesContent":["export type GrAvatarShape = 'circle' | 'square'\n\n/** Статус участника. Точка декоративна — смысл несёт скрытая подпись. */\nexport const GR_AVATAR_STATUSES = ['online', 'offline', 'busy', 'away'] as const\nexport type GrAvatarStatus = typeof GR_AVATAR_STATUSES[number]\n\nexport const shapes: Record<GrAvatarShape, string> = {\n circle: 'rounded-[var(--gr-radius-full)]',\n square: 'rounded-[var(--gr-avatar-square-radius,10px)]',\n}\n\nexport const rootBaseClass = 'relative inline-flex shrink-0 items-center justify-center overflow-hidden border border-[var(--gr-brd)] font-700'\n\n/** Цвет по умолчанию. Отделён от базы, иначе он спорил бы с автоцветом порядком правил. */\nexport const rootNeutralClass = 'bg-[var(--gr-muted)] text-[var(--gr-muted-fg)]'\n\n/**\n * Палитра автоцвета: подложка и инициалы одним классом на слот.\n *\n * Цвета сюда не попадают — только имена слотов. Что стоит за слотом, решает\n * тема (`--gr-avatar-N-bg`/`-fg` ссылаются на пары `-light`/`-text` тонов), и\n * приложение вправе переопределить любой, не трогая компонент.\n *\n * Классы статические: UnoCSS сканирует литералы, и собранный в рантайме\n * `bg-[var(--gr-avatar-${n}-bg)]` в CSS не превратился бы.\n */\nexport const avatarToneClasses: string[] = [\n 'bg-[var(--gr-avatar-1-bg)] text-[var(--gr-avatar-1-fg)]',\n 'bg-[var(--gr-avatar-2-bg)] text-[var(--gr-avatar-2-fg)]',\n 'bg-[var(--gr-avatar-3-bg)] text-[var(--gr-avatar-3-fg)]',\n 'bg-[var(--gr-avatar-4-bg)] text-[var(--gr-avatar-4-fg)]',\n 'bg-[var(--gr-avatar-5-bg)] text-[var(--gr-avatar-5-fg)]',\n 'bg-[var(--gr-avatar-6-bg)] text-[var(--gr-avatar-6-fg)]',\n]\n\n/**\n * Слот палитры по имени: тот же человек — тот же цвет.\n *\n * Стабильность здесь и есть смысл функции: цвет не должен меняться ни между\n * сессиями, ни между сервером и клиентом, иначе аватар мигает на гидрации, а\n * узнаваемость — то, ради чего автоцвет и заводят, — теряется. Отсюда обычный\n * детерминированный перебор кодов, а не хеш из окружения.\n *\n * `>>> 0` обязателен: без него сумма уходит в отрицательные на длинных именах,\n * и остаток от деления даёт отрицательный индекс.\n */\nexport function avatarToneIndex(name: string): number {\n let hash = 0\n for (const char of name.trim())\n hash = (hash * 31 + (char.codePointAt(0) ?? 0)) >>> 0\n\n return hash % avatarToneClasses.length\n}\n\n/** Индикатор статуса: кольцо цветом фона отделяет точку от самого аватара. */\nexport const statusDotClass = 'absolute bottom-0 right-0 block h-1/4 w-1/4 min-h-2 min-w-2 rounded-[var(--gr-radius-full)] ring-2 ring-[var(--gr-bg)]'\n\nexport const statusToneClass: Record<GrAvatarStatus, string> = {\n online: 'bg-[var(--gr-success)]',\n offline: 'bg-[var(--gr-muted-fg)]',\n busy: 'bg-[var(--gr-danger)]',\n away: 'bg-[var(--gr-warning)]',\n}\n\n/**\n * Статус рисуется поверх картинки, поэтому у корня со статусом не может быть\n * `overflow-hidden` — точка обрезалась бы кругом. Скругление вместо этого\n * держит внутренняя обёртка изображения.\n */\nexport const rootStatusClass = 'overflow-visible'\n\n/**\n * Обёртка растянута на весь аватар, поэтому корневой `justify-center`\n * центрирует её саму, а не содержимое: центрирование обязано быть здесь.\n */\nexport const mediaClass = 'flex h-full w-full items-center justify-center'\n\n/**\n * Со статусом корень уходит в `overflow-visible`, чтобы не срезать точку, и\n * резать по форме становится некому — тогда это берёт на себя обёртка.\n */\nexport const mediaClipClass = 'overflow-hidden'\n\n/**\n * Размер бывает произвольным числом пикселей, поэтому кегль считается, а не\n * берётся картой по ступеням. Пол в 10px: у аватара 24px пропорциональные 8px\n * не читаются.\n */\nexport function avatarFontSizePx(sizePx: number): number {\n return Math.max(10, Math.round(sizePx / 3))\n}\n\nexport const groupBaseClass = 'inline-flex items-center'\n\n/** Перекрытие соседей: кольцо цветом фона отделяет аватары друг от друга. */\nexport const groupItemClass = '-ml-2 first:ml-0 ring-2 ring-[var(--gr-bg)]'\n\nexport const groupOverflowClass = 'inline-flex items-center justify-center bg-[var(--gr-muted)] text-[var(--gr-muted-fg)] font-700'\n\nexport function grAvatarClass(shape: GrAvatarShape): string {\n return [shapes[shape]].join(' ')\n}\n\n/**\n * Инициалы из имени: первые буквы двух первых слов. Вынесено чистой функцией —\n * тестируется без монтирования.\n */\nexport function initialsFrom(name: string): string {\n const words = name.trim().split(/\\s+/).filter(Boolean)\n if (words.length === 0)\n return ''\n\n return words\n .slice(0, 2)\n .map(word => [...word][0]?.toUpperCase() ?? '')\n .join('')\n}\n","import { splitClassTokens } from '../shared/classTokens'\nimport {\n avatarToneClasses,\n groupBaseClass,\n groupItemClass,\n groupOverflowClass,\n mediaClass,\n mediaClipClass,\n rootBaseClass,\n rootNeutralClass,\n rootStatusClass,\n shapes,\n statusDotClass,\n statusToneClass,\n} from './grAvatarStyles'\n\nexport const grAvatarClassTokens = {\n shapes: Object.values(shapes).flatMap(splitClassTokens),\n root: [\n ...splitClassTokens(rootBaseClass),\n ...splitClassTokens(rootNeutralClass),\n ...splitClassTokens(rootStatusClass),\n // Палитра автоцвета живёт в `.ts`-хелпере: её литералы пресет не видит.\n ...avatarToneClasses.flatMap(splitClassTokens),\n ],\n media: [...splitClassTokens(mediaClass), ...splitClassTokens(mediaClipClass)],\n status: [\n ...splitClassTokens(statusDotClass),\n ...Object.values(statusToneClass).flatMap(splitClassTokens),\n ],\n group: [\n ...splitClassTokens(groupBaseClass),\n ...splitClassTokens(groupItemClass),\n ...splitClassTokens(groupOverflowClass),\n ],\n} as const\n\nexport const grAvatarSafelist = [...new Set([\n ...grAvatarClassTokens.shapes,\n ...grAvatarClassTokens.root,\n ...grAvatarClassTokens.media,\n ...grAvatarClassTokens.status,\n ...grAvatarClassTokens.group,\n])]\n","import { defineGranularComponent } from '@feugene/unocss-preset-granular/contract'\n\nimport { grAvatarSafelist } from './safelist'\n\nexport const grAvatarConfig = defineGranularComponent(import.meta.url, {\n name: 'GrAvatar',\n dependencies: ['GrSkeleton'],\n safelist: grAvatarSafelist,\n // Только светлая: слоты палитры ссылаются на `-light`/`-text`, а те\n // переключаются вместе с темой сами — см. комментарий в самом файле.\n tokenDefinitionsRef: {\n light: { url: './themes/light.css', selector: ':root' },\n },\n})\n"],"mappings":";;;AAMA,IAAa,SAAwC;CACnD,QAAQ;CACR,QAAQ;AACV;AAEA,IAAa,gBAAgB;;AAG7B,IAAa,mBAAmB;;;;;;;;;;;AAYhC,IAAa,oBAA8B;CACzC;CACA;CACA;CACA;CACA;CACA;AACF;;;;;;;;;;;;AAaA,SAAgB,gBAAgB,MAAsB;CACpD,IAAI,OAAO;CACX,KAAK,MAAM,QAAQ,KAAK,KAAK,GAC3B,OAAQ,OAAO,MAAM,KAAK,YAAY,CAAC,KAAK,OAAQ;CAEtD,OAAO,OAAO,kBAAkB;AAClC;;AAGA,IAAa,iBAAiB;AAE9B,IAAa,kBAAkD;CAC7D,QAAQ;CACR,SAAS;CACT,MAAM;CACN,MAAM;AACR;;;;;;AAOA,IAAa,kBAAkB;;;;;AAM/B,IAAa,aAAa;;;;;AAM1B,IAAa,iBAAiB;;;;;;AAO9B,SAAgB,iBAAiB,QAAwB;CACvD,OAAO,KAAK,IAAI,IAAI,KAAK,MAAM,SAAS,CAAC,CAAC;AAC5C;AAEA,IAAa,iBAAiB;;AAG9B,IAAa,iBAAiB;AAE9B,IAAa,qBAAqB;AAElC,SAAgB,cAAc,OAA8B;CAC1D,OAAO,CAAC,OAAO,MAAM,CAAC,CAAC,KAAK,GAAG;AACjC;;;;;AAMA,SAAgB,aAAa,MAAsB;CACjD,MAAM,QAAQ,KAAK,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,OAAO,OAAO;CACrD,IAAI,MAAM,WAAW,GACnB,OAAO;CAET,OAAO,MACJ,MAAM,GAAG,CAAC,CAAC,CACX,KAAI,SAAQ,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,EAAE,YAAY,KAAK,EAAE,CAAC,CAC9C,KAAK,EAAE;AACZ;;;ACpGA,IAAa,sBAAsB;CACjC,QAAQ,OAAO,OAAO,MAAM,CAAC,CAAC,QAAQ,gBAAgB;CACtD,MAAM;EACJ,GAAG,iBAAiB,aAAa;EACjC,GAAG,iBAAiB,gBAAgB;EACpC,GAAG,iBAAiB,eAAe;EAEnC,GAAG,kBAAkB,QAAQ,gBAAgB;CAC/C;CACA,OAAO,CAAC,GAAG,iBAAiB,UAAU,GAAG,GAAG,iBAAiB,cAAc,CAAC;CAC5E,QAAQ,CACN,GAAG,iBAAiB,cAAc,GAClC,GAAG,OAAO,OAAO,eAAe,CAAC,CAAC,QAAQ,gBAAgB,CAC5D;CACA,OAAO;EACL,GAAG,iBAAiB,cAAc;EAClC,GAAG,iBAAiB,cAAc;EAClC,GAAG,iBAAiB,kBAAkB;CACxC;AACF;AAEA,IAAa,mBAAmB,CAAC,mBAAG,IAAI,IAAI;CAC1C,GAAG,oBAAoB;CACvB,GAAG,oBAAoB;CACvB,GAAG,oBAAoB;CACvB,GAAG,oBAAoB;CACvB,GAAG,oBAAoB;AACzB,CAAC,CAAC;;;ACvCF,IAAa,iBAAiB,wBAAwB,YAAY,KAAK;CACrE,MAAM;CACN,cAAc,CAAC,YAAY;CAC3B,UAAU;CAGV,qBAAqB,EACnB,OAAO;EAAE,KAAK;EAAsB,UAAU;CAAQ,EACxD;AACF,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as splitClassTokens } from "./classTokens-8v2XC74x.js";
|
|
2
|
-
import { a as tableSizes, i as stripedClass, n as hoverableClass, r as loadingRowCellClass, t as emptyCellClass } from "./grTableStyles-
|
|
2
|
+
import { a as tableSizes, i as stripedClass, n as hoverableClass, r as loadingRowCellClass, t as emptyCellClass } from "./grTableStyles-DkQPMfx9.js";
|
|
3
3
|
import { defineGranularComponent } from "@feugene/unocss-preset-granular/contract";
|
|
4
4
|
//#region src/components/GrTable/safelist.ts
|
|
5
5
|
var grTableSafelist = [.../* @__PURE__ */ new Set([
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-
|
|
1
|
+
{"version":3,"file":"config-D3HOuHDe.js","names":[],"sources":["../../src/components/GrTable/safelist.ts","../../src/components/GrTable/config.ts"],"sourcesContent":["import { splitClassTokens } from '../shared/classTokens'\nimport {\n emptyCellClass,\n hoverableClass,\n loadingRowCellClass,\n stripedClass,\n tableSizes,\n} from './grTableStyles'\n\nexport const grTableSafelist = [...new Set([\n ...Object.values(tableSizes).flatMap(splitClassTokens),\n ...splitClassTokens(stripedClass),\n ...splitClassTokens(hoverableClass),\n ...splitClassTokens(emptyCellClass),\n ...splitClassTokens(loadingRowCellClass),\n])]\n","import { defineGranularComponent } from '@feugene/unocss-preset-granular/contract'\n\nimport { grTableSafelist } from './safelist'\n\nexport const grTableConfig = defineGranularComponent(import.meta.url, {\n name: 'GrTable',\n dependencies: ['GrSkeleton'],\n safelist: grTableSafelist,\n})\n"],"mappings":";;;;AASA,IAAa,kBAAkB,CAAC,mBAAG,IAAI,IAAI;CACzC,GAAG,OAAO,OAAO,UAAU,CAAC,CAAC,QAAQ,gBAAgB;CACrD,GAAG,iBAAiB,YAAY;CAChC,GAAG,iBAAiB,cAAc;CAClC,GAAG,iBAAiB,cAAc;CAClC,GAAG,iBAAiB,mBAAmB;AACzC,CAAC,CAAC;;;ACXF,IAAa,gBAAgB,wBAAwB,YAAY,KAAK;CACpE,MAAM;CACN,cAAc,CAAC,YAAY;CAC3B,UAAU;AACZ,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as grBadgeSafelist } from "./safelist-
|
|
1
|
+
import { t as grBadgeSafelist } from "./safelist-CSfynUC1.js";
|
|
2
2
|
import { defineGranularComponent } from "@feugene/unocss-preset-granular/contract";
|
|
3
3
|
//#region src/components/GrBadge/config.ts
|
|
4
4
|
var grBadgeConfig = defineGranularComponent(import.meta.url, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-
|
|
1
|
+
{"version":3,"file":"config-DF1ezU6y.js","names":[],"sources":["../../src/components/GrBadge/config.ts"],"sourcesContent":["import { defineGranularComponent } from '@feugene/unocss-preset-granular/contract'\n\nimport { grBadgeSafelist } from './safelist'\n\nexport const grBadgeConfig = defineGranularComponent(import.meta.url, {\n name: 'GrBadge',\n safelist: grBadgeSafelist,\n tokenDefinitionsRef: {\n light: { url: './themes/light.css', selector: ':root' },\n dark: { url: './themes/dark.css', as: '.dark, [data-theme=\"dark\"]' },\n },\n})\n"],"mappings":";;;AAIA,IAAa,gBAAgB,wBAAwB,YAAY,KAAK;CACpE,MAAM;CACN,UAAU;CACV,qBAAqB;EACnB,OAAO;GAAE,KAAK;GAAsB,UAAU;EAAQ;EACtD,MAAM;GAAE,KAAK;GAAqB,IAAI;EAA6B;CACrE;AACF,CAAC"}
|