@feugene/granularity 0.32.0 → 0.33.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/dist/chunks/{config-Dv_r92GL.js → config-2vrOFn2f.js} +2 -2
- package/dist/chunks/{config-Dv_r92GL.js.map → config-2vrOFn2f.js.map} +1 -1
- package/dist/chunks/{config-g8-JGZ_Y.js → config-BscVxZR3.js} +1 -1
- package/dist/chunks/{config-g8-JGZ_Y.js.map → config-BscVxZR3.js.map} +1 -1
- package/dist/chunks/{grBadgeStyles-D8Mz73B5.js → grBadgeStyles-DV0DrAew.js} +17 -1
- package/dist/chunks/grBadgeStyles-DV0DrAew.js.map +1 -0
- package/dist/chunks/{grChipStyles-3JZApw03.js → grChipStyles-DcDyxAL0.js} +1 -1
- package/dist/chunks/{grChipStyles-3JZApw03.js.map → grChipStyles-DcDyxAL0.js.map} +1 -1
- package/dist/chunks/{granular-provider-Da2CJO6j.js → granular-provider-CrQua8PT.js} +2 -2
- package/dist/chunks/{granular-provider-Da2CJO6j.js.map → granular-provider-CrQua8PT.js.map} +1 -1
- package/dist/chunks/{safelist-CtiHPgrj.js → safelist-x8USecK8.js} +3 -1
- package/dist/chunks/safelist-x8USecK8.js.map +1 -0
- package/dist/components/GrAutocomplete/chunks/{GrAutocomplete-rYEY15UI.js → GrAutocomplete-CoQjEF8h.js} +2 -2
- package/dist/components/GrAutocomplete/chunks/{GrAutocomplete-rYEY15UI.js.map → GrAutocomplete-CoQjEF8h.js.map} +1 -1
- package/dist/components/GrAutocomplete/index.js +1 -1
- package/dist/components/GrBadge/chunks/{GrBadge-D2MfThPz.js → GrBadge-DpUDXKbq.js} +9 -4
- package/dist/components/GrBadge/chunks/GrBadge-DpUDXKbq.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-C0vU69tf.js → GrChip-BTivtwff.js} +1 -1
- package/dist/components/GrChip/chunks/{GrChip-C0vU69tf.js.map → GrChip-BTivtwff.js.map} +1 -1
- package/dist/components/GrChip/index.js +2 -2
- package/dist/components/GrDataTable/chunks/{GrDataTable-CAGgRk27.js → GrDataTable-4JAgOQ-7.js} +1 -1
- package/dist/components/GrDataTable/chunks/{GrDataTable-CAGgRk27.js.map → GrDataTable-4JAgOQ-7.js.map} +1 -1
- package/dist/components/GrDataTable/index.js +1 -1
- package/dist/components/GrInputTag/chunks/{GrInputTag-Cj4A9Xgs.js → GrInputTag-ByD9NugQ.js} +2 -2
- package/dist/components/GrInputTag/chunks/{GrInputTag-Cj4A9Xgs.js.map → GrInputTag-ByD9NugQ.js.map} +1 -1
- package/dist/components/GrInputTag/index.js +1 -1
- package/dist/components/GrPagination/chunks/{GrPagination-B_kAhoAV.js → GrPagination-FiiXzVyv.js} +1 -1
- package/dist/components/GrPagination/chunks/{GrPagination-B_kAhoAV.js.map → GrPagination-FiiXzVyv.js.map} +1 -1
- package/dist/components/GrPagination/index.js +1 -1
- package/dist/components/GrSelect/chunks/{GrSelect-gCeRFgQo.js → GrSelect-Dt8iqruc.js} +2 -2
- package/dist/components/GrSelect/chunks/{GrSelect-gCeRFgQo.js.map → GrSelect-Dt8iqruc.js.map} +1 -1
- package/dist/components/GrSelect/index.js +1 -1
- package/dist/components/GrTable/chunks/{GrTable-Zcdz2St_.js → GrTable-jhUTczjv.js} +12 -1
- package/dist/components/GrTable/chunks/GrTable-jhUTczjv.js.map +1 -0
- package/dist/components/GrTable/index.js +1 -1
- package/dist/granular-provider-node.js +1 -1
- package/dist/granular-provider.js +1 -1
- package/dist/index.js +11 -11
- package/dist/types/components/GrBadge/GrBadge.vue.d.ts +11 -0
- package/dist/types/components/GrBadge/grBadgeStyles.d.ts +11 -0
- package/dist/web-types.json +5 -1
- package/package.json +3 -3
- package/dist/chunks/grBadgeStyles-D8Mz73B5.js.map +0 -1
- package/dist/chunks/safelist-CtiHPgrj.js.map +0 -1
- package/dist/components/GrBadge/chunks/GrBadge-D2MfThPz.js.map +0 -1
- package/dist/components/GrTable/chunks/GrTable-Zcdz2St_.js.map +0 -1
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { t as GrSelect_default } from "./chunks/GrSelect-
|
|
1
|
+
import { t as GrSelect_default } from "./chunks/GrSelect-Dt8iqruc.js";
|
|
2
2
|
import { n as grSelectSafelist, t as grSelectConfig } from "../../chunks/config-DnF472Ox.js";
|
|
3
3
|
export { GrSelect_default as GrSelect, GrSelect_default as default, grSelectConfig, grSelectSafelist };
|
|
@@ -127,6 +127,17 @@ var GrTable_default = /* @__PURE__ */ defineComponent({
|
|
|
127
127
|
/** Прокрутить к строке содержимого по её индексу в разметке. `false` — строки нет в DOM. */
|
|
128
128
|
scrollToRow
|
|
129
129
|
});
|
|
130
|
+
/**
|
|
131
|
+
* `relative` на скроллере — не для потомков с координатами, а чтобы он стал
|
|
132
|
+
* containing block. Без него абсолютные потомки (`sr-only`-подсказка у кнопки
|
|
133
|
+
* сортировки — единственный такой в самой таблице, но разметка ячеек чужая)
|
|
134
|
+
* считают позицию от документа и выпадают из прокрутки наружу: на узком экране
|
|
135
|
+
* широкая таблица начинает тащить вбок всю страницу, а не только себя.
|
|
136
|
+
*
|
|
137
|
+
* Живёт здесь, а не над `<div>`: комментарий в корне `<template>` делает
|
|
138
|
+
* компонент фрагментом, и `$el` у потребителя становится Comment-нодой —
|
|
139
|
+
* `GrDataTable` падает на `root.matches` ещё до первого рендера.
|
|
140
|
+
*/
|
|
130
141
|
return (_ctx, _cache) => {
|
|
131
142
|
return openBlock(), createElementBlock("div", {
|
|
132
143
|
ref_key: "scrollEl",
|
|
@@ -136,7 +147,7 @@ var GrTable_default = /* @__PURE__ */ defineComponent({
|
|
|
136
147
|
"aria-label": __props.regionLabel,
|
|
137
148
|
"aria-busy": __props.loading ? "true" : void 0,
|
|
138
149
|
tabindex: "0",
|
|
139
|
-
class: "overflow-x-auto rounded-[var(--gr-radius-lg)] border border-[var(--gr-brd)] bg-[var(--gr-card)] focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--gr-ring)]",
|
|
150
|
+
class: "relative overflow-x-auto rounded-[var(--gr-radius-lg)] border border-[var(--gr-brd)] bg-[var(--gr-card)] focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--gr-ring)]",
|
|
140
151
|
style: normalizeStyle(scrollStyle.value)
|
|
141
152
|
}, [createElementVNode("table", {
|
|
142
153
|
"data-gr-table": "",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GrTable-jhUTczjv.js","names":[],"sources":["../../../../src/components/GrTable/GrTable.vue","../../../../src/components/GrTable/GrTable.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, useSlots } from 'vue'\n\nimport { useGrComponentSize } from '../GrConfigProvider/context'\nimport GrSkeleton from '../GrSkeleton/GrSkeleton.vue'\nimport { hasMeaningfulSlotContent } from '../shared/slotNodes'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport {\n emptyCellClass,\n hoverableClass,\n loadingRowCellClass,\n stripedClass,\n tableSizes,\n type GrTableSize,\n} from './grTableStyles'\n\nexport interface GrTableProps {\n /**\n * Размер таблицы — базовый кегль текста. Паддинги ячеек оставлены за\n * консьюмером (GrTable — «тонкий» контейнер).\n */\n size?: GrTableSize\n /**\n * Текст caption для screen reader'ов. Рендерится как `<caption class=\"sr-only\">`,\n * если не передан слот `#caption`.\n */\n caption?: string\n /** Прямой ARIA-label для `<table>`. Игнорируется, если задан `ariaLabelledby`. */\n ariaLabel?: string\n /** ID элемента-заголовка, связанного с `<table>` через `aria-labelledby`. */\n ariaLabelledby?: string\n /**\n * ARIA-label для скролл-контейнера. Включает `role=\"region\"`; сам скролл\n * достижим с клавиатуры всегда, независимо от метки.\n */\n regionLabel?: string\n /** Идёт загрузка: вместо строк — скелетоны, контейнер помечен `aria-busy`. */\n loading?: boolean\n /** Сколько строк-заглушек показать при `loading`. */\n loadingRows?: number\n /** Сколько колонок занимает служебная строка (пустое состояние и скелетоны). */\n columnCount?: number\n /** Текст пустого состояния. Слот `#empty` сильнее. */\n emptyText?: string\n /** Таблица пуста. По умолчанию определяется по содержимому слота. */\n empty?: boolean\n /** Чередование строк. */\n striped?: boolean\n /** Подсветка строки под курсором. */\n hoverable?: boolean\n /**\n * Прилипающий заголовок: `<thead>` остаётся видимым при вертикальном скролле.\n * Осмысленно вместе с `maxHeight` (иначе таблица не скроллится вертикально).\n */\n stickyHeader?: boolean\n /**\n * Полное число строк набора, включая строки заголовка (`aria-rowcount`).\n *\n * Нужен, когда в DOM не весь набор — например, при виртуализации: диктор\n * считает строки по разметке и объявил бы «5 из 20» на таблице в десять\n * тысяч. Строки при этом обязаны нести `aria-rowindex`.\n */\n rowCount?: number\n /**\n * Фиксированная раскладка (`table-layout: fixed`): ширины колонок берутся из\n * первой строки, а не из содержимого всех.\n *\n * Обязателен, если в DOM не весь набор: иначе ширины считаются по\n * отрисованному окну и прыгают на каждой прокрутке.\n *\n * Класс — arbitrary-значение, а не `table-fixed`: такого правила в\n * `presetMini` нет, и класс молча не превратился бы в CSS.\n */\n fixedLayout?: boolean\n /**\n * Минимальная ширина самой таблицы (число — пиксели).\n *\n * Нужна при `fixedLayout`: с фиксированной раскладкой и шириной `auto`\n * браузер вписывает таблицу в контейнер и делит место между колонками\n * пропорционально — то есть заданные ширины молча ужимаются, а\n * горизонтальной прокрутки, на которой держатся закреплённые колонки, не\n * возникает вовсе.\n */\n tableMinWidth?: string | number\n /**\n * Максимальная высота скролл-контейнера (включает вертикальный скролл).\n * Число трактуется как пиксели. Нужен для работы `stickyHeader`.\n */\n maxHeight?: string | number\n}\n\n/**\n * `GrTable` — «тонкий» GR-контейнер для табличных данных.\n *\n * Рендерит `<table>` внутри скролл-обёртки и даёт слоты `#caption`, `#header`,\n * default (tbody) и `#footer`. Стили ячеек (`<th>`/`<td>` паддинги, выравнивание)\n * оставлены на консьюмере.\n *\n * ВАЖНО: `min-w-full` сам по себе не даст горизонтального скролла. Для него\n * консьюмеру нужны `white-space: nowrap` на ячейках или явные ширины колонок.\n */\nconst props = withDefaults(defineProps<GrTableProps>(), {\n size: undefined,\n caption: undefined,\n ariaLabel: undefined,\n ariaLabelledby: undefined,\n regionLabel: undefined,\n loading: false,\n loadingRows: 3,\n columnCount: 1,\n emptyText: undefined,\n empty: undefined,\n striped: false,\n hoverable: false,\n stickyHeader: false,\n maxHeight: undefined,\n rowCount: undefined,\n fixedLayout: false,\n tableMinWidth: undefined,\n})\n\nconst slots = useSlots()\n\nconst resolvedSize = useGrComponentSize(() => props.size, { component: 'GrTable' })\nconst tableTextClass = computed(() => tableSizes[resolvedSize.value])\nconst hasCaption = computed(() => Boolean(slots.caption) || Boolean(props.caption))\n\nconst { t } = useGranularityTranslations()\nconst resolvedEmptyText = computed(() => props.emptyText ?? t('gr.table.empty', 'Nothing here yet'))\n\n// Пустоту видно по слоту: `v-for` по пустому массиву оставляет фрагмент без\n// узлов, `v-if` — комментарий, и ни то ни другое строкой не является.\nconst isEmpty = computed(() => {\n if (props.empty !== undefined)\n return props.empty\n\n return !hasMeaningfulSlotContent(slots.default?.() ?? [])\n})\n\nconst showRows = computed(() => !props.loading && !isEmpty.value)\nconst loadingRowCount = computed(() => Math.max(1, Math.trunc(props.loadingRows)))\nconst serviceColSpan = computed(() => Math.max(1, Math.trunc(props.columnCount)))\n\nconst tbodyClass = computed(() => [\n 'text-[var(--gr-fg)]',\n props.striped && showRows.value ? stripedClass : '',\n props.hoverable && showRows.value ? hoverableClass : '',\n].filter(Boolean).join(' '))\n\nconst scrollStyle = computed(() => {\n // Неполный набор в DOM (`rowCount`) означает виртуализацию, а с ней обязан\n // быть выключен браузерный scroll anchoring: он подправляет `scrollTop`,\n // когда меняется высота содержимого выше видимого узла, — а окно меняет её\n // на каждом кадре прокрутки, и список уезжает.\n const anchor = props.rowCount === undefined ? undefined : { overflowAnchor: 'none' as const }\n\n if (props.maxHeight === undefined)\n return anchor\n\n const value = typeof props.maxHeight === 'number' ? `${props.maxHeight}px` : props.maxHeight\n return { ...anchor, maxHeight: value, overflowY: 'auto' as const }\n})\n\n// Прилипающий заголовок: `<thead>` на `position: sticky`; фон обязателен, иначе\n// сквозь него будут просвечивать строки при скролле.\nconst theadClass = computed(() => [\n 'bg-[var(--gr-muted)] text-[var(--gr-muted-fg)]',\n props.stickyHeader ? 'sticky top-0 z-[1]' : '',\n].filter(Boolean).join(' '))\n\nconst tableStyle = computed(() => {\n if (props.tableMinWidth === undefined)\n return undefined\n\n const value = typeof props.tableMinWidth === 'number' ? `${props.tableMinWidth}px` : props.tableMinWidth\n\n return { minWidth: value }\n})\n\nconst scrollEl = ref<HTMLElement | null>(null)\n\nfunction scrollTo(options: ScrollToOptions): void {\n scrollEl.value?.scrollTo(options)\n}\n\n// Только верхний уровень собственного tbody: вложенная таблица в ячейке не\n// должна сдвигать индексацию строк.\nfunction contentRows(): HTMLElement[] {\n if (!showRows.value)\n return []\n const el = scrollEl.value\n if (!el)\n return []\n return Array.from(el.querySelectorAll<HTMLElement>(':scope > table > tbody > tr'))\n}\n\nfunction scrollToRow(index: number, options?: ScrollIntoViewOptions): boolean {\n const row = contentRows()[index]\n if (!row)\n return false\n row.scrollIntoView(options ?? { block: 'nearest' })\n return true\n}\n\ndefineExpose({\n /** Прокрутить скролл-контейнер таблицы — тот же контракт, что у `GrDataTable`. */\n scrollTo,\n /** Прокрутить к строке содержимого по её индексу в разметке. `false` — строки нет в DOM. */\n scrollToRow,\n})\n\ndefineSlots<{\n /** Строки таблицы, когда разметка пишется руками вместо `data`. */\n default?: () => any\n /** Подпись таблицы — `<caption>`, читается диктором первой. */\n caption?: () => any\n /** Шапка вместо построенной по `columns`. */\n header?: () => any\n /** Содержимое, пока едут данные, — вместо строк-заглушек. */\n loading?: () => any\n /** Пустое состояние вместо текста по умолчанию. */\n empty?: () => any\n /** Итоговая строка под таблицей. */\n footer?: () => any\n}>()\n\n/**\n * `relative` на скроллере — не для потомков с координатами, а чтобы он стал\n * containing block. Без него абсолютные потомки (`sr-only`-подсказка у кнопки\n * сортировки — единственный такой в самой таблице, но разметка ячеек чужая)\n * считают позицию от документа и выпадают из прокрутки наружу: на узком экране\n * широкая таблица начинает тащить вбок всю страницу, а не только себя.\n *\n * Живёт здесь, а не над `<div>`: комментарий в корне `<template>` делает\n * компонент фрагментом, и `$el` у потребителя становится Comment-нодой —\n * `GrDataTable` падает на `root.matches` ещё до первого рендера.\n */\n</script>\n\n<template>\n <div\n ref=\"scrollEl\"\n data-gr-table-scroll\n :role=\"regionLabel ? 'region' : undefined\"\n :aria-label=\"regionLabel\"\n :aria-busy=\"loading ? 'true' : undefined\"\n tabindex=\"0\"\n class=\"relative overflow-x-auto rounded-[var(--gr-radius-lg)] border border-[var(--gr-brd)] bg-[var(--gr-card)] focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--gr-ring)]\"\n :style=\"scrollStyle\"\n >\n <table\n data-gr-table\n class=\"min-w-full\" :class=\"[tableTextClass, fixedLayout ? '[table-layout:fixed]' : '']\"\n :style=\"tableStyle\"\n :aria-label=\"ariaLabelledby ? undefined : ariaLabel\"\n :aria-labelledby=\"ariaLabelledby\"\n :aria-rowcount=\"rowCount\"\n >\n <caption v-if=\"hasCaption\" class=\"sr-only\">\n <slot name=\"caption\">\n{{ caption }}\n</slot>\n </caption>\n <thead :class=\"theadClass\">\n <slot name=\"header\" />\n </thead>\n <tbody :class=\"tbodyClass\">\n <template v-if=\"loading\">\n <slot name=\"loading\">\n <tr v-for=\"row in loadingRowCount\" :key=\"row\" data-gr-table-loading-row>\n <td :colspan=\"serviceColSpan\" :class=\"loadingRowCellClass\">\n <GrSkeleton />\n </td>\n </tr>\n </slot>\n </template>\n\n <tr v-else-if=\"isEmpty\" data-gr-table-empty>\n <td :colspan=\"serviceColSpan\" :class=\"emptyCellClass\">\n <slot name=\"empty\">\n {{ resolvedEmptyText }}\n </slot>\n </td>\n </tr>\n\n <slot v-else />\n </tbody>\n <tfoot v-if=\"slots.footer\" class=\"text-[var(--gr-fg)]\">\n <slot name=\"footer\" />\n </tfoot>\n </table>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, ref, useSlots } from 'vue'\n\nimport { useGrComponentSize } from '../GrConfigProvider/context'\nimport GrSkeleton from '../GrSkeleton/GrSkeleton.vue'\nimport { hasMeaningfulSlotContent } from '../shared/slotNodes'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport {\n emptyCellClass,\n hoverableClass,\n loadingRowCellClass,\n stripedClass,\n tableSizes,\n type GrTableSize,\n} from './grTableStyles'\n\nexport interface GrTableProps {\n /**\n * Размер таблицы — базовый кегль текста. Паддинги ячеек оставлены за\n * консьюмером (GrTable — «тонкий» контейнер).\n */\n size?: GrTableSize\n /**\n * Текст caption для screen reader'ов. Рендерится как `<caption class=\"sr-only\">`,\n * если не передан слот `#caption`.\n */\n caption?: string\n /** Прямой ARIA-label для `<table>`. Игнорируется, если задан `ariaLabelledby`. */\n ariaLabel?: string\n /** ID элемента-заголовка, связанного с `<table>` через `aria-labelledby`. */\n ariaLabelledby?: string\n /**\n * ARIA-label для скролл-контейнера. Включает `role=\"region\"`; сам скролл\n * достижим с клавиатуры всегда, независимо от метки.\n */\n regionLabel?: string\n /** Идёт загрузка: вместо строк — скелетоны, контейнер помечен `aria-busy`. */\n loading?: boolean\n /** Сколько строк-заглушек показать при `loading`. */\n loadingRows?: number\n /** Сколько колонок занимает служебная строка (пустое состояние и скелетоны). */\n columnCount?: number\n /** Текст пустого состояния. Слот `#empty` сильнее. */\n emptyText?: string\n /** Таблица пуста. По умолчанию определяется по содержимому слота. */\n empty?: boolean\n /** Чередование строк. */\n striped?: boolean\n /** Подсветка строки под курсором. */\n hoverable?: boolean\n /**\n * Прилипающий заголовок: `<thead>` остаётся видимым при вертикальном скролле.\n * Осмысленно вместе с `maxHeight` (иначе таблица не скроллится вертикально).\n */\n stickyHeader?: boolean\n /**\n * Полное число строк набора, включая строки заголовка (`aria-rowcount`).\n *\n * Нужен, когда в DOM не весь набор — например, при виртуализации: диктор\n * считает строки по разметке и объявил бы «5 из 20» на таблице в десять\n * тысяч. Строки при этом обязаны нести `aria-rowindex`.\n */\n rowCount?: number\n /**\n * Фиксированная раскладка (`table-layout: fixed`): ширины колонок берутся из\n * первой строки, а не из содержимого всех.\n *\n * Обязателен, если в DOM не весь набор: иначе ширины считаются по\n * отрисованному окну и прыгают на каждой прокрутке.\n *\n * Класс — arbitrary-значение, а не `table-fixed`: такого правила в\n * `presetMini` нет, и класс молча не превратился бы в CSS.\n */\n fixedLayout?: boolean\n /**\n * Минимальная ширина самой таблицы (число — пиксели).\n *\n * Нужна при `fixedLayout`: с фиксированной раскладкой и шириной `auto`\n * браузер вписывает таблицу в контейнер и делит место между колонками\n * пропорционально — то есть заданные ширины молча ужимаются, а\n * горизонтальной прокрутки, на которой держатся закреплённые колонки, не\n * возникает вовсе.\n */\n tableMinWidth?: string | number\n /**\n * Максимальная высота скролл-контейнера (включает вертикальный скролл).\n * Число трактуется как пиксели. Нужен для работы `stickyHeader`.\n */\n maxHeight?: string | number\n}\n\n/**\n * `GrTable` — «тонкий» GR-контейнер для табличных данных.\n *\n * Рендерит `<table>` внутри скролл-обёртки и даёт слоты `#caption`, `#header`,\n * default (tbody) и `#footer`. Стили ячеек (`<th>`/`<td>` паддинги, выравнивание)\n * оставлены на консьюмере.\n *\n * ВАЖНО: `min-w-full` сам по себе не даст горизонтального скролла. Для него\n * консьюмеру нужны `white-space: nowrap` на ячейках или явные ширины колонок.\n */\nconst props = withDefaults(defineProps<GrTableProps>(), {\n size: undefined,\n caption: undefined,\n ariaLabel: undefined,\n ariaLabelledby: undefined,\n regionLabel: undefined,\n loading: false,\n loadingRows: 3,\n columnCount: 1,\n emptyText: undefined,\n empty: undefined,\n striped: false,\n hoverable: false,\n stickyHeader: false,\n maxHeight: undefined,\n rowCount: undefined,\n fixedLayout: false,\n tableMinWidth: undefined,\n})\n\nconst slots = useSlots()\n\nconst resolvedSize = useGrComponentSize(() => props.size, { component: 'GrTable' })\nconst tableTextClass = computed(() => tableSizes[resolvedSize.value])\nconst hasCaption = computed(() => Boolean(slots.caption) || Boolean(props.caption))\n\nconst { t } = useGranularityTranslations()\nconst resolvedEmptyText = computed(() => props.emptyText ?? t('gr.table.empty', 'Nothing here yet'))\n\n// Пустоту видно по слоту: `v-for` по пустому массиву оставляет фрагмент без\n// узлов, `v-if` — комментарий, и ни то ни другое строкой не является.\nconst isEmpty = computed(() => {\n if (props.empty !== undefined)\n return props.empty\n\n return !hasMeaningfulSlotContent(slots.default?.() ?? [])\n})\n\nconst showRows = computed(() => !props.loading && !isEmpty.value)\nconst loadingRowCount = computed(() => Math.max(1, Math.trunc(props.loadingRows)))\nconst serviceColSpan = computed(() => Math.max(1, Math.trunc(props.columnCount)))\n\nconst tbodyClass = computed(() => [\n 'text-[var(--gr-fg)]',\n props.striped && showRows.value ? stripedClass : '',\n props.hoverable && showRows.value ? hoverableClass : '',\n].filter(Boolean).join(' '))\n\nconst scrollStyle = computed(() => {\n // Неполный набор в DOM (`rowCount`) означает виртуализацию, а с ней обязан\n // быть выключен браузерный scroll anchoring: он подправляет `scrollTop`,\n // когда меняется высота содержимого выше видимого узла, — а окно меняет её\n // на каждом кадре прокрутки, и список уезжает.\n const anchor = props.rowCount === undefined ? undefined : { overflowAnchor: 'none' as const }\n\n if (props.maxHeight === undefined)\n return anchor\n\n const value = typeof props.maxHeight === 'number' ? `${props.maxHeight}px` : props.maxHeight\n return { ...anchor, maxHeight: value, overflowY: 'auto' as const }\n})\n\n// Прилипающий заголовок: `<thead>` на `position: sticky`; фон обязателен, иначе\n// сквозь него будут просвечивать строки при скролле.\nconst theadClass = computed(() => [\n 'bg-[var(--gr-muted)] text-[var(--gr-muted-fg)]',\n props.stickyHeader ? 'sticky top-0 z-[1]' : '',\n].filter(Boolean).join(' '))\n\nconst tableStyle = computed(() => {\n if (props.tableMinWidth === undefined)\n return undefined\n\n const value = typeof props.tableMinWidth === 'number' ? `${props.tableMinWidth}px` : props.tableMinWidth\n\n return { minWidth: value }\n})\n\nconst scrollEl = ref<HTMLElement | null>(null)\n\nfunction scrollTo(options: ScrollToOptions): void {\n scrollEl.value?.scrollTo(options)\n}\n\n// Только верхний уровень собственного tbody: вложенная таблица в ячейке не\n// должна сдвигать индексацию строк.\nfunction contentRows(): HTMLElement[] {\n if (!showRows.value)\n return []\n const el = scrollEl.value\n if (!el)\n return []\n return Array.from(el.querySelectorAll<HTMLElement>(':scope > table > tbody > tr'))\n}\n\nfunction scrollToRow(index: number, options?: ScrollIntoViewOptions): boolean {\n const row = contentRows()[index]\n if (!row)\n return false\n row.scrollIntoView(options ?? { block: 'nearest' })\n return true\n}\n\ndefineExpose({\n /** Прокрутить скролл-контейнер таблицы — тот же контракт, что у `GrDataTable`. */\n scrollTo,\n /** Прокрутить к строке содержимого по её индексу в разметке. `false` — строки нет в DOM. */\n scrollToRow,\n})\n\ndefineSlots<{\n /** Строки таблицы, когда разметка пишется руками вместо `data`. */\n default?: () => any\n /** Подпись таблицы — `<caption>`, читается диктором первой. */\n caption?: () => any\n /** Шапка вместо построенной по `columns`. */\n header?: () => any\n /** Содержимое, пока едут данные, — вместо строк-заглушек. */\n loading?: () => any\n /** Пустое состояние вместо текста по умолчанию. */\n empty?: () => any\n /** Итоговая строка под таблицей. */\n footer?: () => any\n}>()\n\n/**\n * `relative` на скроллере — не для потомков с координатами, а чтобы он стал\n * containing block. Без него абсолютные потомки (`sr-only`-подсказка у кнопки\n * сортировки — единственный такой в самой таблице, но разметка ячеек чужая)\n * считают позицию от документа и выпадают из прокрутки наружу: на узком экране\n * широкая таблица начинает тащить вбок всю страницу, а не только себя.\n *\n * Живёт здесь, а не над `<div>`: комментарий в корне `<template>` делает\n * компонент фрагментом, и `$el` у потребителя становится Comment-нодой —\n * `GrDataTable` падает на `root.matches` ещё до первого рендера.\n */\n</script>\n\n<template>\n <div\n ref=\"scrollEl\"\n data-gr-table-scroll\n :role=\"regionLabel ? 'region' : undefined\"\n :aria-label=\"regionLabel\"\n :aria-busy=\"loading ? 'true' : undefined\"\n tabindex=\"0\"\n class=\"relative overflow-x-auto rounded-[var(--gr-radius-lg)] border border-[var(--gr-brd)] bg-[var(--gr-card)] focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--gr-ring)]\"\n :style=\"scrollStyle\"\n >\n <table\n data-gr-table\n class=\"min-w-full\" :class=\"[tableTextClass, fixedLayout ? '[table-layout:fixed]' : '']\"\n :style=\"tableStyle\"\n :aria-label=\"ariaLabelledby ? undefined : ariaLabel\"\n :aria-labelledby=\"ariaLabelledby\"\n :aria-rowcount=\"rowCount\"\n >\n <caption v-if=\"hasCaption\" class=\"sr-only\">\n <slot name=\"caption\">\n{{ caption }}\n</slot>\n </caption>\n <thead :class=\"theadClass\">\n <slot name=\"header\" />\n </thead>\n <tbody :class=\"tbodyClass\">\n <template v-if=\"loading\">\n <slot name=\"loading\">\n <tr v-for=\"row in loadingRowCount\" :key=\"row\" data-gr-table-loading-row>\n <td :colspan=\"serviceColSpan\" :class=\"loadingRowCellClass\">\n <GrSkeleton />\n </td>\n </tr>\n </slot>\n </template>\n\n <tr v-else-if=\"isEmpty\" data-gr-table-empty>\n <td :colspan=\"serviceColSpan\" :class=\"emptyCellClass\">\n <slot name=\"empty\">\n {{ resolvedEmptyText }}\n </slot>\n </td>\n </tr>\n\n <slot v-else />\n </tbody>\n <tfoot v-if=\"slots.footer\" class=\"text-[var(--gr-fg)]\">\n <slot name=\"footer\" />\n </tfoot>\n </table>\n </div>\n</template>\n"],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { t as GrTable_default } from "./chunks/GrTable-
|
|
1
|
+
import { t as GrTable_default } from "./chunks/GrTable-jhUTczjv.js";
|
|
2
2
|
import { n as grTableSafelist, t as grTableConfig } from "../../chunks/config-DCq4JySZ.js";
|
|
3
3
|
export { GrTable_default as GrTable, GrTable_default as default, grTableConfig, grTableSafelist };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as granularityDefaultThemes, i as granularityComponentConfigs, n as GRANULARITY_PROVIDER_ID, o as granularityThemeNames, r as createGranularityProvider, t as granularityProvider } from "./chunks/granular-provider-
|
|
1
|
+
import { a as granularityDefaultThemes, i as granularityComponentConfigs, n as GRANULARITY_PROVIDER_ID, o as granularityThemeNames, r as createGranularityProvider, t as granularityProvider } from "./chunks/granular-provider-CrQua8PT.js";
|
|
2
2
|
export { GRANULARITY_PROVIDER_ID, createGranularityProvider, granularityProvider as default, granularityProvider, granularityComponentConfigs, granularityDefaultThemes, granularityThemeNames };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as granularityDefaultThemes, i as granularityComponentConfigs, n as GRANULARITY_PROVIDER_ID, o as granularityThemeNames, r as createGranularityProvider, t as granularityProvider } from "./chunks/granular-provider-
|
|
1
|
+
import { a as granularityDefaultThemes, i as granularityComponentConfigs, n as GRANULARITY_PROVIDER_ID, o as granularityThemeNames, r as createGranularityProvider, t as granularityProvider } from "./chunks/granular-provider-CrQua8PT.js";
|
|
2
2
|
export { GRANULARITY_PROVIDER_ID, createGranularityProvider, granularityProvider as default, granularityProvider, granularityComponentConfigs, granularityDefaultThemes, granularityThemeNames };
|
package/dist/index.js
CHANGED
|
@@ -21,15 +21,15 @@ import { n as useGrFormFieldContext } from "./chunks/context-DdNIxa1w.js";
|
|
|
21
21
|
import { useGrFormControl } from "./composables/useGrFormControl.js";
|
|
22
22
|
import { useComboboxNavigation } from "./composables/useComboboxNavigation.js";
|
|
23
23
|
import { useRovingFocus } from "./composables/useRovingFocus.js";
|
|
24
|
-
import { t as GrChip_default } from "./components/GrChip/chunks/GrChip-
|
|
24
|
+
import { t as GrChip_default } from "./components/GrChip/chunks/GrChip-BTivtwff.js";
|
|
25
25
|
import { n as grAutocompleteSafelist, t as grAutocompleteConfig } from "./chunks/config-vYMJ3Cr1.js";
|
|
26
|
-
import { t as GrAutocomplete_default } from "./components/GrAutocomplete/chunks/GrAutocomplete-
|
|
26
|
+
import { t as GrAutocomplete_default } from "./components/GrAutocomplete/chunks/GrAutocomplete-CoQjEF8h.js";
|
|
27
27
|
import { t as GrSkeleton_default } from "./components/GrSkeleton/chunks/GrSkeleton-CgfXxPQ2.js";
|
|
28
28
|
import { n as GrAvatar_default, t as GrAvatarGroup_default } from "./components/GrAvatar/chunks/GrAvatar-CNmLmgcr.js";
|
|
29
29
|
import { c as initialsFrom, n as grAvatarSafelist, t as grAvatarConfig } from "./chunks/config-B3J0alyY.js";
|
|
30
|
-
import { t as GrBadge_default } from "./components/GrBadge/chunks/GrBadge-
|
|
31
|
-
import { t as grBadgeSafelist } from "./chunks/safelist-
|
|
32
|
-
import { t as grBadgeConfig } from "./chunks/config-
|
|
30
|
+
import { t as GrBadge_default } from "./components/GrBadge/chunks/GrBadge-DpUDXKbq.js";
|
|
31
|
+
import { t as grBadgeSafelist } from "./chunks/safelist-x8USecK8.js";
|
|
32
|
+
import { t as grBadgeConfig } from "./chunks/config-BscVxZR3.js";
|
|
33
33
|
import { n as grBadgeWrapSafelist, o as formatBadgeValue, t as grBadgeWrapConfig } from "./chunks/config-DwABJHEo.js";
|
|
34
34
|
import { t as GrBadgeWrap_default } from "./components/GrBadgeWrap/chunks/GrBadgeWrap-B-A3PRkE.js";
|
|
35
35
|
import { n as grBottomNavSafelist, t as grBottomNavConfig } from "./chunks/config-DM0lsduD.js";
|
|
@@ -51,7 +51,7 @@ import { n as grCheckboxSafelist, t as grCheckboxConfig } from "./chunks/config-
|
|
|
51
51
|
import "./components/GrCheckbox/index.js";
|
|
52
52
|
import { t as GrCheckboxGroup_default } from "./components/GrCheckboxGroup/chunks/GrCheckboxGroup-BOwrVcFr.js";
|
|
53
53
|
import { t as grCheckboxGroupConfig } from "./chunks/config-BuGlNPE9.js";
|
|
54
|
-
import { n as grChipSafelist, t as grChipConfig } from "./chunks/config-
|
|
54
|
+
import { n as grChipSafelist, t as grChipConfig } from "./chunks/config-2vrOFn2f.js";
|
|
55
55
|
import "./components/GrChip/index.js";
|
|
56
56
|
import { n as grChipGroupSafelist, t as grChipGroupConfig } from "./chunks/config-CZPDPJlg.js";
|
|
57
57
|
import { t as GrChipGroup_default } from "./components/GrChipGroup/chunks/GrChipGroup-C78Vcwos.js";
|
|
@@ -82,9 +82,9 @@ import "./components/GrConfirmDialog/index.js";
|
|
|
82
82
|
import { a as GrDropdownMenuItem_default, c as GrDropdownMenuDivider_default, o as GrDropdownMenuGroup_default, s as GrDropdownMenuHeader_default, t as GrDropdownMenuList_default } from "./components/GrDropdownMenu/chunks/GrDropdownMenuList-B33ZzwfB.js";
|
|
83
83
|
import { t as GrContextMenu_default } from "./components/GrContextMenu/chunks/GrContextMenu-ClkVjdcP.js";
|
|
84
84
|
import { t as grContextMenuConfig } from "./chunks/config-CPSxM7XE.js";
|
|
85
|
-
import { t as GrTable_default } from "./components/GrTable/chunks/GrTable-
|
|
85
|
+
import { t as GrTable_default } from "./components/GrTable/chunks/GrTable-jhUTczjv.js";
|
|
86
86
|
import { t as useDragSort } from "./chunks/useDragSort-0l47h4yb.js";
|
|
87
|
-
import { t as GrDataTable_default } from "./components/GrDataTable/chunks/GrDataTable-
|
|
87
|
+
import { t as GrDataTable_default } from "./components/GrDataTable/chunks/GrDataTable-4JAgOQ-7.js";
|
|
88
88
|
import { n as grDataTableSafelist, t as grDataTableConfig } from "./chunks/config-DeyT9dJl.js";
|
|
89
89
|
import { t as GrDelta_default } from "./components/GrDelta/chunks/GrDelta-BZwkgQW-.js";
|
|
90
90
|
import { n as grValueSafelist, t as grValueConfig } from "./chunks/config-Z5LeUXys.js";
|
|
@@ -131,7 +131,7 @@ import { n as grImageViewerSafelist, t as grImageViewerConfig } from "./chunks/c
|
|
|
131
131
|
import { n as grInputSafelist, t as grInputConfig } from "./chunks/config-CIkdsWUk.js";
|
|
132
132
|
import "./components/GrInput/index.js";
|
|
133
133
|
import { n as grInputTagSafelist, t as grInputTagConfig } from "./chunks/config-BqT6PMzO.js";
|
|
134
|
-
import { t as GrInputTag_default } from "./components/GrInputTag/chunks/GrInputTag-
|
|
134
|
+
import { t as GrInputTag_default } from "./components/GrInputTag/chunks/GrInputTag-ByD9NugQ.js";
|
|
135
135
|
import { t as GrTree_default } from "./components/GrTree/chunks/GrTree-Ci6CZfKR.js";
|
|
136
136
|
import { t as GrJsonViewer_default } from "./components/GrJsonViewer/chunks/GrJsonViewer-BCZ7lE2k.js";
|
|
137
137
|
import { n as grJsonViewerSafelist, t as grJsonViewerConfig } from "./chunks/config-DpAYidyY2.js";
|
|
@@ -149,9 +149,9 @@ import { t as GrNavbar_default } from "./components/GrNavbar/chunks/GrNavbar-_rt
|
|
|
149
149
|
import { n as grNavbarSafelist, t as grNavbarConfig } from "./chunks/config-2ZHRsdOc.js";
|
|
150
150
|
import { n as grNumberInputSafelist, t as grNumberInputConfig } from "./chunks/config-MmPym-Z72.js";
|
|
151
151
|
import { t as GrNumberInput_default } from "./components/GrNumberInput/chunks/GrNumberInput-DQ59YICu.js";
|
|
152
|
-
import { t as GrSelect_default } from "./components/GrSelect/chunks/GrSelect-
|
|
152
|
+
import { t as GrSelect_default } from "./components/GrSelect/chunks/GrSelect-Dt8iqruc.js";
|
|
153
153
|
import { n as grPaginationSafelist, t as grPaginationConfig } from "./chunks/config-CjKpUcmy.js";
|
|
154
|
-
import { t as GrPagination_default } from "./components/GrPagination/chunks/GrPagination-
|
|
154
|
+
import { t as GrPagination_default } from "./components/GrPagination/chunks/GrPagination-FiiXzVyv.js";
|
|
155
155
|
import { n as grPopoverSafelist, t as grPopoverConfig } from "./chunks/config-BTwYMQaz2.js";
|
|
156
156
|
import "./components/GrPopover/index.js";
|
|
157
157
|
import { n as grProgressBarSafelist, r as GR_TONES, t as grProgressBarConfig } from "./chunks/config-DWL81-aM.js";
|
|
@@ -9,6 +9,17 @@ export interface GrBadgeProps {
|
|
|
9
9
|
type __VLS_Slots = {
|
|
10
10
|
/** Содержимое метки. */
|
|
11
11
|
default?: () => any;
|
|
12
|
+
/**
|
|
13
|
+
* Иконка перед подписью: статус со спиннером, флаг, значок типа.
|
|
14
|
+
*
|
|
15
|
+
* Размер задаёт обёртка по ступени `size`, поэтому содержимое слота тянется
|
|
16
|
+
* до неё — `class="h-full w-full"`, как у `GrChip`. Вращение спиннера —
|
|
17
|
+
* `animate-spin` на самой иконке.
|
|
18
|
+
*
|
|
19
|
+
* `GrProgressCircle` сюда не кладут: у кругового индикатора шкала виджетная,
|
|
20
|
+
* нижняя ступень — `2rem`, и в строку бейджа он не помещается.
|
|
21
|
+
*/
|
|
22
|
+
icon?: () => any;
|
|
12
23
|
};
|
|
13
24
|
declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToOption<GrBadgeProps>, {
|
|
14
25
|
tone: undefined;
|
|
@@ -4,6 +4,17 @@ export type GrBadgeTone = GrTone;
|
|
|
4
4
|
export type GrBadgeSize = GrComponentSize;
|
|
5
5
|
export type GrBadgeRadius = 'square' | 'semi' | 'round';
|
|
6
6
|
export declare const sizeClassBySize: Record<GrBadgeSize, string>;
|
|
7
|
+
/**
|
|
8
|
+
* Иконка перед подписью растёт медленнее кегля: на нижних ступенях плашка
|
|
9
|
+
* узкая, и иконка «один в один с текстом» разгоняла бы её по высоте.
|
|
10
|
+
*
|
|
11
|
+
* Своя карта, а не заимствованная у `GrChip`: у чипа фиксированная высота
|
|
12
|
+
* плитки и своя шкала кегля, и совпадение значений на средних ступенях —
|
|
13
|
+
* совпадение, а не общий контракт.
|
|
14
|
+
*/
|
|
15
|
+
export declare const badgeIconSizeClassBySize: Record<GrBadgeSize, string>;
|
|
16
|
+
/** Иконка не жмётся: подпись бейджа не переносится, сжиматься должно нечему. */
|
|
17
|
+
export declare const badgeIconClass = "shrink-0";
|
|
7
18
|
export declare const semiRadiusClassBySize: Record<GrBadgeSize, string>;
|
|
8
19
|
export declare const lightToneClassByTone: Record<GrBadgeTone, string>;
|
|
9
20
|
/**
|
package/dist/web-types.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://raw.githubusercontent.com/JetBrains/web-types/master/schema/web-types.json",
|
|
3
3
|
"name": "@feugene/granularity",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.33.0",
|
|
5
5
|
"framework": "vue",
|
|
6
6
|
"js-types-syntax": "typescript",
|
|
7
7
|
"description-markup": "markdown",
|
|
@@ -615,6 +615,10 @@
|
|
|
615
615
|
{
|
|
616
616
|
"name": "default",
|
|
617
617
|
"description": "Содержимое метки."
|
|
618
|
+
},
|
|
619
|
+
{
|
|
620
|
+
"name": "icon",
|
|
621
|
+
"description": "Иконка перед подписью: статус со спиннером, флаг, значок типа. Размер задаёт обёртка по ступени `size`, поэтому содержимое слота тянется до неё — `class=\"h-full w-full\"`, как у `GrChip`. Вращение спиннера — `animate-spin` на самой иконке. `GrProgressCircle` сюда не кладут: у кругового индикатора шкала виджетная, нижняя ступень — `2rem`, и в строку бейджа он не помещается."
|
|
618
622
|
}
|
|
619
623
|
]
|
|
620
624
|
},
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@feugene/granularity",
|
|
3
3
|
"description": "Granularity design system package with Vue 3 components, consumed via the `@feugene/unocss-preset-granular` preset.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.33.0",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Evgeniy Fureev",
|
|
@@ -591,7 +591,7 @@
|
|
|
591
591
|
"./package.json": "./package.json"
|
|
592
592
|
},
|
|
593
593
|
"peerDependencies": {
|
|
594
|
-
"@feugene/fint-i18n": "
|
|
594
|
+
"@feugene/fint-i18n": ">=0.6.0 <1.0.0",
|
|
595
595
|
"@feugene/unocss-preset-granular": "^0.11.0",
|
|
596
596
|
"@floating-ui/dom": "^1.8.0",
|
|
597
597
|
"vue": "^3.5.0"
|
|
@@ -606,7 +606,7 @@
|
|
|
606
606
|
},
|
|
607
607
|
"devDependencies": {
|
|
608
608
|
"@antfu/eslint-config": "^9.1.0",
|
|
609
|
-
"@feugene/fint-i18n": "^0.
|
|
609
|
+
"@feugene/fint-i18n": "^0.7.0",
|
|
610
610
|
"@feugene/granularity-test-kit": "^0.7.0",
|
|
611
611
|
"@feugene/unocss-preset-granular": "^0.11.0",
|
|
612
612
|
"@floating-ui/dom": "^1.8.0",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"grBadgeStyles-D8Mz73B5.js","names":[],"sources":["../../src/components/GrBadge/grBadgeStyles.ts"],"sourcesContent":["import type { GrComponentSize } from '../shared/sizes'\n\nimport type { GrTone } from '../shared/tones'\n\nexport type GrBadgeTone = GrTone\nexport type GrBadgeSize = GrComponentSize\nexport type GrBadgeRadius = 'square' | 'semi' | 'round'\nexport const sizeClassBySize: Record<GrBadgeSize, string> = {\n xs: 'px-2 py-0.4 text-[length:var(--gr-control-text-2xs)] leading-[var(--gr-control-leading-2xs)]',\n sm: 'px-2.5 py-0.5 text-[length:var(--gr-control-text-xs)] leading-[var(--gr-control-leading-xs)]',\n md: 'px-3 py-1 text-[length:var(--gr-control-text-sm)] leading-[var(--gr-control-leading-sm)]',\n lg: 'px-3.5 py-1.5 text-[length:var(--gr-control-text-md)] leading-[var(--gr-control-leading-md)]',\n}\nexport const semiRadiusClassBySize: Record<GrBadgeSize, string> = {\n xs: 'rounded-[var(--gr-badge-semi-radius-xs,3px)]',\n sm: 'rounded-[var(--gr-badge-semi-radius-sm,3px)]',\n md: 'rounded-[var(--gr-badge-semi-radius-md,5px)]',\n lg: 'rounded-[var(--gr-badge-semi-radius-lg,7px)]',\n}\nexport const lightToneClassByTone: Record<GrBadgeTone, string> = {\n neutral: 'bg-[var(--gr-muted)] text-[var(--gr-fg)] border-[var(--gr-brd)]',\n primary:\n 'bg-[var(--gr-accent)] text-[var(--gr-accent-fg)] border-[color-mix(in_srgb,var(--gr-primary)_30%,var(--gr-accent))]',\n // Текст на тонированной подложке — только `-text`, никогда не насыщенный тон:\n // `--gr-success` на `--gr-success-light` даёт 2.24:1, `-text` — 6.78:1.\n // slate/azure ниже уже были сделаны правильно.\n success: 'bg-[var(--gr-success-light)] text-[var(--gr-success-text)] border-[color-mix(in_srgb,var(--gr-success)_30%,var(--gr-success-light))]',\n warning: 'bg-[var(--gr-warning-light)] text-[var(--gr-warning-text)] border-[color-mix(in_srgb,var(--gr-warning)_30%,var(--gr-warning-light))]',\n danger: 'bg-[var(--gr-danger-light)] text-[var(--gr-danger-text)] border-[color-mix(in_srgb,var(--gr-danger)_30%,var(--gr-danger-light))]',\n info: 'bg-[var(--gr-info-light)] text-[var(--gr-info-text)] border-[color-mix(in_srgb,var(--gr-info)_30%,var(--gr-info-light))]',\n slate: 'bg-[var(--gr-slate-light)] text-[var(--gr-slate-text)] border-[color-mix(in_srgb,var(--gr-slate)_30%,var(--gr-slate-light))]',\n azure: 'bg-[var(--gr-azure-light)] text-[var(--gr-azure-text)] border-[color-mix(in_srgb,var(--gr-azure)_30%,var(--gr-azure-light))]',\n}\n/**\n * Заливка filled-бейджа идёт через покомпонентный слой `--gr-badge-{tone}-*`, а\n * не напрямую из роли тона, потому что нужный вес у тем разный.\n *\n * В светлой теме `--gr-{tone}` — это яркая заливка под **тёмный** текст (`-fg`\n * там обязан быть тёмным: белый на `--gr-success` даёт 2.54:1), и filled-бейдж\n * читался как тяжёлая почти чёрная плашка. Слой уводит его на `-solid`/`-solid-fg`\n * — заливку кнопочного веса под светлый текст, ту же, что у solid-кнопок.\n * В тёмной теме пастельная заливка с тёмным текстом — штатная конвенция, и слой\n * оставляет прежние роли. Значения — `themes/{light,dark}.css`.\n */\nexport const darkToneClassByTone: Record<GrBadgeTone, string> = {\n // Нейтральный вес — инверсия страницы, а не тон: `-solid`-роли у него нет.\n neutral: 'bg-[var(--gr-badge-neutral-bg,var(--gr-fg))] text-[var(--gr-badge-neutral-fg,var(--gr-bg))] border-[color-mix(in_srgb,var(--gr-fg)_35%,var(--gr-brd))]',\n primary: 'bg-[var(--gr-badge-primary-bg,var(--gr-primary-solid))] text-[var(--gr-badge-primary-fg,var(--gr-primary-solid-fg))] border-[var(--gr-badge-primary-bg,var(--gr-primary-solid))]',\n success: 'bg-[var(--gr-badge-success-bg,var(--gr-success-solid))] text-[var(--gr-badge-success-fg,var(--gr-success-solid-fg))] border-[var(--gr-badge-success-bg,var(--gr-success-solid))]',\n warning: 'bg-[var(--gr-badge-warning-bg,var(--gr-warning-solid))] text-[var(--gr-badge-warning-fg,var(--gr-warning-solid-fg))] border-[var(--gr-badge-warning-bg,var(--gr-warning-solid))]',\n danger: 'bg-[var(--gr-badge-danger-bg,var(--gr-danger-solid))] text-[var(--gr-badge-danger-fg,var(--gr-danger-solid-fg))] border-[var(--gr-badge-danger-bg,var(--gr-danger-solid))]',\n info: 'bg-[var(--gr-badge-info-bg,var(--gr-info-solid))] text-[var(--gr-badge-info-fg,var(--gr-info-solid-fg))] border-[var(--gr-badge-info-bg,var(--gr-info-solid))]',\n slate: 'bg-[var(--gr-badge-slate-bg,var(--gr-slate-solid))] text-[var(--gr-badge-slate-fg,var(--gr-slate-solid-fg))] border-[var(--gr-badge-slate-bg,var(--gr-slate-solid))]',\n azure: 'bg-[var(--gr-badge-azure-bg,var(--gr-azure-solid))] text-[var(--gr-badge-azure-fg,var(--gr-azure-solid-fg))] border-[var(--gr-badge-azure-bg,var(--gr-azure-solid))]',\n}\n/**\n * Экспортируются ради `GrChip`: у чипа те же три радиуса и та же палитра тонов,\n * и копия этих двух ветвлений разошлась бы с оригиналом молча. Свои у чипа\n * только размеры — он интерактивен, и цель нажатия у него не метки, а контрола.\n */\nexport function radiusClass(radius: GrBadgeRadius, size: GrBadgeSize): string {\n if (radius === 'square')\n return 'rounded-[var(--gr-radius-none)]'\n if (radius === 'semi')\n return semiRadiusClassBySize[size]\n return 'rounded-[var(--gr-radius-full)]'\n}\nexport function toneClass(tone: GrBadgeTone, dark: boolean): string {\n return dark ? darkToneClassByTone[tone] : lightToneClassByTone[tone]\n}\nexport function grBadgeClass(options: { tone: GrBadgeTone, dark: boolean, size: GrBadgeSize, radius: GrBadgeRadius }): string {\n return [\n radiusClass(options.radius, options.size),\n sizeClassBySize[options.size],\n toneClass(options.tone, options.dark),\n ].join(' ')\n}\n"],"mappings":";AAOA,IAAa,kBAA+C;CAC1D,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;AACN;AACA,IAAa,wBAAqD;CAChE,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;AACN;AACA,IAAa,uBAAoD;CAC/D,SAAS;CACT,SACE;CAIF,SAAS;CACT,SAAS;CACT,QAAQ;CACR,MAAM;CACN,OAAO;CACP,OAAO;AACT;;;;;;;;;;;;AAYA,IAAa,sBAAmD;CAE9D,SAAS;CACT,SAAS;CACT,SAAS;CACT,SAAS;CACT,QAAQ;CACR,MAAM;CACN,OAAO;CACP,OAAO;AACT;;;;;;AAMA,SAAgB,YAAY,QAAuB,MAA2B;CAC5E,IAAI,WAAW,UACb,OAAO;CACT,IAAI,WAAW,QACb,OAAO,sBAAsB;CAC/B,OAAO;AACT;AACA,SAAgB,UAAU,MAAmB,MAAuB;CAClE,OAAO,OAAO,oBAAoB,QAAQ,qBAAqB;AACjE;AACA,SAAgB,aAAa,SAAiG;CAC5H,OAAO;EACL,YAAY,QAAQ,QAAQ,QAAQ,IAAI;EACxC,gBAAgB,QAAQ;EACxB,UAAU,QAAQ,MAAM,QAAQ,IAAI;CACtC,CAAC,CAAC,KAAK,GAAG;AACZ"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"safelist-CtiHPgrj.js","names":[],"sources":["../../src/components/GrBadge/safelist.ts"],"sourcesContent":["import { splitClassTokens } from '../shared/classTokens'\nimport {\n darkToneClassByTone,\n lightToneClassByTone,\n semiRadiusClassBySize,\n sizeClassBySize,\n} from './grBadgeStyles'\n\nexport const grBadgeSafelist = [...new Set([\n ...Object.values(sizeClassBySize).flatMap(splitClassTokens),\n ...Object.values(semiRadiusClassBySize).flatMap(splitClassTokens),\n 'rounded-[var(--gr-radius-none)]',\n 'rounded-[var(--gr-radius-full)]',\n ...Object.values(lightToneClassByTone).flatMap(splitClassTokens),\n ...Object.values(darkToneClassByTone).flatMap(splitClassTokens),\n])]\n"],"mappings":";;;AAQA,IAAa,kBAAkB,CAAC,mBAAG,IAAI,IAAI;CACzC,GAAG,OAAO,OAAO,eAAe,CAAC,CAAC,QAAQ,gBAAgB;CAC1D,GAAG,OAAO,OAAO,qBAAqB,CAAC,CAAC,QAAQ,gBAAgB;CAChE;CACA;CACA,GAAG,OAAO,OAAO,oBAAoB,CAAC,CAAC,QAAQ,gBAAgB;CAC/D,GAAG,OAAO,OAAO,mBAAmB,CAAC,CAAC,QAAQ,gBAAgB;AAChE,CAAC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"GrBadge-D2MfThPz.js","names":[],"sources":["../../../../src/components/GrBadge/GrBadge.vue","../../../../src/components/GrBadge/GrBadge.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue'\n\nimport { useGrComponentProp } from '../GrConfigProvider/context'\n\nexport type { GrBadgeRadius, GrBadgeSize, GrBadgeTone } from './grBadgeStyles'\n\nimport { warnRenamedProp } from '../shared/renamedProp'\n\nimport {\n grBadgeClass,\n type GrBadgeRadius,\n type GrBadgeSize,\n type GrBadgeTone,\n} from './grBadgeStyles'\n\nexport interface GrBadgeProps {\n tone?: GrBadgeTone\n dark?: boolean\n size?: GrBadgeSize\n radius?: GrBadgeRadius\n}\n\nconst props = withDefaults(\n defineProps<GrBadgeProps>(),\n {\n // `tone`/`size`/`radius` настраиваются через `GrConfigProvider`, поэтому\n // их дефолты живут в резолверах ниже, а не в `withDefaults`.\n tone: undefined,\n dark: false,\n size: undefined,\n radius: undefined,\n },\n)\n\n// Эффективные значения: локальный проп → `GrConfigProvider` → дефолт компонента.\nconst resolvedTone = useGrComponentProp('GrBadge', 'tone', () => props.tone, 'neutral')\nconst resolvedSize = useGrComponentProp('GrBadge', 'size', () => props.size, 'sm')\nconst resolvedRadius = useGrComponentProp('GrBadge', 'radius', () => props.radius, 'round')\n\n// `variant` переименован в `tone`: незнакомый атрибут Vue сажает на корневой\n// узел, поэтому старое имя не роняет ни типы, ни рантайм — компонент молча\n// рисуется дефолтным тоном.\nwarnRenamedProp('GrBadge', useAttrs(), { variant: 'tone' })\n\nconst className = computed(() => {\n return grBadgeClass({\n tone: resolvedTone.value,\n dark: props.dark,\n size: resolvedSize.value,\n radius: resolvedRadius.value,\n })\n})\n\ndefineSlots<{\n /** Содержимое метки. */\n default?: () => any\n}>()\n</script>\n\n<template>\n <span\n class=\"gr-badge inline-block border whitespace-nowrap leading-none\"\n :class=\"className\"\n >\n <span class=\"gr-badge__label\">\n <span class=\"gr-badge__text\">\n <slot />\n </span>\n </span>\n </span>\n</template>\n\n<style scoped>\n/*\n * Оптически центрируем текст по вертикали независимо от регистра,\n * не уменьшая высоту самого бейджа.\n *\n * Высоту держит обёртка `.gr-badge__label` (`min-height: 1lh` — высота\n * line-box при `leading-none`), а текст (`.gr-badge__text`) обрезается до\n * cap-height и центрируется внутри этой высоты через flex.\n *\n * Обрезка обязана жить на вложенном узле, а не на самом тексте: `text-box-trim`\n * уменьшает line-box, и повесь его прямо на текст — вместе с ним просядет\n * высота контента, а за ней и весь бейдж.\n */\n.gr-badge__label {\n display: flex;\n align-items: center;\n min-height: 1lh;\n}\n\n.gr-badge__text {\n display: block;\n text-box-trim: trim-both;\n text-box-edge: cap alphabetic;\n /* Шорткат для браузеров с поддержкой нового синтаксиса. */\n text-box: trim-both cap alphabetic;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue'\n\nimport { useGrComponentProp } from '../GrConfigProvider/context'\n\nexport type { GrBadgeRadius, GrBadgeSize, GrBadgeTone } from './grBadgeStyles'\n\nimport { warnRenamedProp } from '../shared/renamedProp'\n\nimport {\n grBadgeClass,\n type GrBadgeRadius,\n type GrBadgeSize,\n type GrBadgeTone,\n} from './grBadgeStyles'\n\nexport interface GrBadgeProps {\n tone?: GrBadgeTone\n dark?: boolean\n size?: GrBadgeSize\n radius?: GrBadgeRadius\n}\n\nconst props = withDefaults(\n defineProps<GrBadgeProps>(),\n {\n // `tone`/`size`/`radius` настраиваются через `GrConfigProvider`, поэтому\n // их дефолты живут в резолверах ниже, а не в `withDefaults`.\n tone: undefined,\n dark: false,\n size: undefined,\n radius: undefined,\n },\n)\n\n// Эффективные значения: локальный проп → `GrConfigProvider` → дефолт компонента.\nconst resolvedTone = useGrComponentProp('GrBadge', 'tone', () => props.tone, 'neutral')\nconst resolvedSize = useGrComponentProp('GrBadge', 'size', () => props.size, 'sm')\nconst resolvedRadius = useGrComponentProp('GrBadge', 'radius', () => props.radius, 'round')\n\n// `variant` переименован в `tone`: незнакомый атрибут Vue сажает на корневой\n// узел, поэтому старое имя не роняет ни типы, ни рантайм — компонент молча\n// рисуется дефолтным тоном.\nwarnRenamedProp('GrBadge', useAttrs(), { variant: 'tone' })\n\nconst className = computed(() => {\n return grBadgeClass({\n tone: resolvedTone.value,\n dark: props.dark,\n size: resolvedSize.value,\n radius: resolvedRadius.value,\n })\n})\n\ndefineSlots<{\n /** Содержимое метки. */\n default?: () => any\n}>()\n</script>\n\n<template>\n <span\n class=\"gr-badge inline-block border whitespace-nowrap leading-none\"\n :class=\"className\"\n >\n <span class=\"gr-badge__label\">\n <span class=\"gr-badge__text\">\n <slot />\n </span>\n </span>\n </span>\n</template>\n\n<style scoped>\n/*\n * Оптически центрируем текст по вертикали независимо от регистра,\n * не уменьшая высоту самого бейджа.\n *\n * Высоту держит обёртка `.gr-badge__label` (`min-height: 1lh` — высота\n * line-box при `leading-none`), а текст (`.gr-badge__text`) обрезается до\n * cap-height и центрируется внутри этой высоты через flex.\n *\n * Обрезка обязана жить на вложенном узле, а не на самом тексте: `text-box-trim`\n * уменьшает line-box, и повесь его прямо на текст — вместе с ним просядет\n * высота контента, а за ней и весь бейдж.\n */\n.gr-badge__label {\n display: flex;\n align-items: center;\n min-height: 1lh;\n}\n\n.gr-badge__text {\n display: block;\n text-box-trim: trim-both;\n text-box-edge: cap alphabetic;\n /* Шорткат для браузеров с поддержкой нового синтаксиса. */\n text-box: trim-both cap alphabetic;\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;EAuBA,MAAM,QAAQ;EAad,MAAM,eAAe,mBAAmB,WAAW,cAAc,MAAM,MAAM,SAAS;EACtF,MAAM,eAAe,mBAAmB,WAAW,cAAc,MAAM,MAAM,IAAI;EACjF,MAAM,iBAAiB,mBAAmB,WAAW,gBAAgB,MAAM,QAAQ,OAAO;EAK1F,gBAAgB,WAAW,SAAS,GAAG,EAAE,SAAS,OAAO,CAAC;EAE1D,MAAM,YAAY,eAAe;GAC/B,OAAO,aAAa;IAClB,MAAM,aAAa;IACnB,MAAM,MAAM;IACZ,MAAM,aAAa;IACnB,QAAQ,eAAe;GACzB,CAAC;EACH,CAAC;;uBASC,mBASO,QAAA,EARH,OAAK,eAAA,CAAC,+DACE,UAAA,KAAS,CAAA,EAAA,GAAA,CAEnB,mBAIO,QAJP,YAIO,CAHL,mBAEO,QAFP,YAEO,CADL,WAAQ,KAAA,QAAA,WAAA,CAAA,GAAA,KAAA,GAAA,IAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"GrTable-Zcdz2St_.js","names":[],"sources":["../../../../src/components/GrTable/GrTable.vue","../../../../src/components/GrTable/GrTable.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, useSlots } from 'vue'\n\nimport { useGrComponentSize } from '../GrConfigProvider/context'\nimport GrSkeleton from '../GrSkeleton/GrSkeleton.vue'\nimport { hasMeaningfulSlotContent } from '../shared/slotNodes'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport {\n emptyCellClass,\n hoverableClass,\n loadingRowCellClass,\n stripedClass,\n tableSizes,\n type GrTableSize,\n} from './grTableStyles'\n\nexport interface GrTableProps {\n /**\n * Размер таблицы — базовый кегль текста. Паддинги ячеек оставлены за\n * консьюмером (GrTable — «тонкий» контейнер).\n */\n size?: GrTableSize\n /**\n * Текст caption для screen reader'ов. Рендерится как `<caption class=\"sr-only\">`,\n * если не передан слот `#caption`.\n */\n caption?: string\n /** Прямой ARIA-label для `<table>`. Игнорируется, если задан `ariaLabelledby`. */\n ariaLabel?: string\n /** ID элемента-заголовка, связанного с `<table>` через `aria-labelledby`. */\n ariaLabelledby?: string\n /**\n * ARIA-label для скролл-контейнера. Включает `role=\"region\"`; сам скролл\n * достижим с клавиатуры всегда, независимо от метки.\n */\n regionLabel?: string\n /** Идёт загрузка: вместо строк — скелетоны, контейнер помечен `aria-busy`. */\n loading?: boolean\n /** Сколько строк-заглушек показать при `loading`. */\n loadingRows?: number\n /** Сколько колонок занимает служебная строка (пустое состояние и скелетоны). */\n columnCount?: number\n /** Текст пустого состояния. Слот `#empty` сильнее. */\n emptyText?: string\n /** Таблица пуста. По умолчанию определяется по содержимому слота. */\n empty?: boolean\n /** Чередование строк. */\n striped?: boolean\n /** Подсветка строки под курсором. */\n hoverable?: boolean\n /**\n * Прилипающий заголовок: `<thead>` остаётся видимым при вертикальном скролле.\n * Осмысленно вместе с `maxHeight` (иначе таблица не скроллится вертикально).\n */\n stickyHeader?: boolean\n /**\n * Полное число строк набора, включая строки заголовка (`aria-rowcount`).\n *\n * Нужен, когда в DOM не весь набор — например, при виртуализации: диктор\n * считает строки по разметке и объявил бы «5 из 20» на таблице в десять\n * тысяч. Строки при этом обязаны нести `aria-rowindex`.\n */\n rowCount?: number\n /**\n * Фиксированная раскладка (`table-layout: fixed`): ширины колонок берутся из\n * первой строки, а не из содержимого всех.\n *\n * Обязателен, если в DOM не весь набор: иначе ширины считаются по\n * отрисованному окну и прыгают на каждой прокрутке.\n *\n * Класс — arbitrary-значение, а не `table-fixed`: такого правила в\n * `presetMini` нет, и класс молча не превратился бы в CSS.\n */\n fixedLayout?: boolean\n /**\n * Минимальная ширина самой таблицы (число — пиксели).\n *\n * Нужна при `fixedLayout`: с фиксированной раскладкой и шириной `auto`\n * браузер вписывает таблицу в контейнер и делит место между колонками\n * пропорционально — то есть заданные ширины молча ужимаются, а\n * горизонтальной прокрутки, на которой держатся закреплённые колонки, не\n * возникает вовсе.\n */\n tableMinWidth?: string | number\n /**\n * Максимальная высота скролл-контейнера (включает вертикальный скролл).\n * Число трактуется как пиксели. Нужен для работы `stickyHeader`.\n */\n maxHeight?: string | number\n}\n\n/**\n * `GrTable` — «тонкий» GR-контейнер для табличных данных.\n *\n * Рендерит `<table>` внутри скролл-обёртки и даёт слоты `#caption`, `#header`,\n * default (tbody) и `#footer`. Стили ячеек (`<th>`/`<td>` паддинги, выравнивание)\n * оставлены на консьюмере.\n *\n * ВАЖНО: `min-w-full` сам по себе не даст горизонтального скролла. Для него\n * консьюмеру нужны `white-space: nowrap` на ячейках или явные ширины колонок.\n */\nconst props = withDefaults(defineProps<GrTableProps>(), {\n size: undefined,\n caption: undefined,\n ariaLabel: undefined,\n ariaLabelledby: undefined,\n regionLabel: undefined,\n loading: false,\n loadingRows: 3,\n columnCount: 1,\n emptyText: undefined,\n empty: undefined,\n striped: false,\n hoverable: false,\n stickyHeader: false,\n maxHeight: undefined,\n rowCount: undefined,\n fixedLayout: false,\n tableMinWidth: undefined,\n})\n\nconst slots = useSlots()\n\nconst resolvedSize = useGrComponentSize(() => props.size, { component: 'GrTable' })\nconst tableTextClass = computed(() => tableSizes[resolvedSize.value])\nconst hasCaption = computed(() => Boolean(slots.caption) || Boolean(props.caption))\n\nconst { t } = useGranularityTranslations()\nconst resolvedEmptyText = computed(() => props.emptyText ?? t('gr.table.empty', 'Nothing here yet'))\n\n// Пустоту видно по слоту: `v-for` по пустому массиву оставляет фрагмент без\n// узлов, `v-if` — комментарий, и ни то ни другое строкой не является.\nconst isEmpty = computed(() => {\n if (props.empty !== undefined)\n return props.empty\n\n return !hasMeaningfulSlotContent(slots.default?.() ?? [])\n})\n\nconst showRows = computed(() => !props.loading && !isEmpty.value)\nconst loadingRowCount = computed(() => Math.max(1, Math.trunc(props.loadingRows)))\nconst serviceColSpan = computed(() => Math.max(1, Math.trunc(props.columnCount)))\n\nconst tbodyClass = computed(() => [\n 'text-[var(--gr-fg)]',\n props.striped && showRows.value ? stripedClass : '',\n props.hoverable && showRows.value ? hoverableClass : '',\n].filter(Boolean).join(' '))\n\nconst scrollStyle = computed(() => {\n // Неполный набор в DOM (`rowCount`) означает виртуализацию, а с ней обязан\n // быть выключен браузерный scroll anchoring: он подправляет `scrollTop`,\n // когда меняется высота содержимого выше видимого узла, — а окно меняет её\n // на каждом кадре прокрутки, и список уезжает.\n const anchor = props.rowCount === undefined ? undefined : { overflowAnchor: 'none' as const }\n\n if (props.maxHeight === undefined)\n return anchor\n\n const value = typeof props.maxHeight === 'number' ? `${props.maxHeight}px` : props.maxHeight\n return { ...anchor, maxHeight: value, overflowY: 'auto' as const }\n})\n\n// Прилипающий заголовок: `<thead>` на `position: sticky`; фон обязателен, иначе\n// сквозь него будут просвечивать строки при скролле.\nconst theadClass = computed(() => [\n 'bg-[var(--gr-muted)] text-[var(--gr-muted-fg)]',\n props.stickyHeader ? 'sticky top-0 z-[1]' : '',\n].filter(Boolean).join(' '))\n\nconst tableStyle = computed(() => {\n if (props.tableMinWidth === undefined)\n return undefined\n\n const value = typeof props.tableMinWidth === 'number' ? `${props.tableMinWidth}px` : props.tableMinWidth\n\n return { minWidth: value }\n})\n\nconst scrollEl = ref<HTMLElement | null>(null)\n\nfunction scrollTo(options: ScrollToOptions): void {\n scrollEl.value?.scrollTo(options)\n}\n\n// Только верхний уровень собственного tbody: вложенная таблица в ячейке не\n// должна сдвигать индексацию строк.\nfunction contentRows(): HTMLElement[] {\n if (!showRows.value)\n return []\n const el = scrollEl.value\n if (!el)\n return []\n return Array.from(el.querySelectorAll<HTMLElement>(':scope > table > tbody > tr'))\n}\n\nfunction scrollToRow(index: number, options?: ScrollIntoViewOptions): boolean {\n const row = contentRows()[index]\n if (!row)\n return false\n row.scrollIntoView(options ?? { block: 'nearest' })\n return true\n}\n\ndefineExpose({\n /** Прокрутить скролл-контейнер таблицы — тот же контракт, что у `GrDataTable`. */\n scrollTo,\n /** Прокрутить к строке содержимого по её индексу в разметке. `false` — строки нет в DOM. */\n scrollToRow,\n})\n\ndefineSlots<{\n /** Строки таблицы, когда разметка пишется руками вместо `data`. */\n default?: () => any\n /** Подпись таблицы — `<caption>`, читается диктором первой. */\n caption?: () => any\n /** Шапка вместо построенной по `columns`. */\n header?: () => any\n /** Содержимое, пока едут данные, — вместо строк-заглушек. */\n loading?: () => any\n /** Пустое состояние вместо текста по умолчанию. */\n empty?: () => any\n /** Итоговая строка под таблицей. */\n footer?: () => any\n}>()\n</script>\n\n<template>\n <div\n ref=\"scrollEl\"\n data-gr-table-scroll\n :role=\"regionLabel ? 'region' : undefined\"\n :aria-label=\"regionLabel\"\n :aria-busy=\"loading ? 'true' : undefined\"\n tabindex=\"0\"\n class=\"overflow-x-auto rounded-[var(--gr-radius-lg)] border border-[var(--gr-brd)] bg-[var(--gr-card)] focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--gr-ring)]\"\n :style=\"scrollStyle\"\n >\n <table\n data-gr-table\n class=\"min-w-full\" :class=\"[tableTextClass, fixedLayout ? '[table-layout:fixed]' : '']\"\n :style=\"tableStyle\"\n :aria-label=\"ariaLabelledby ? undefined : ariaLabel\"\n :aria-labelledby=\"ariaLabelledby\"\n :aria-rowcount=\"rowCount\"\n >\n <caption v-if=\"hasCaption\" class=\"sr-only\">\n <slot name=\"caption\">\n{{ caption }}\n</slot>\n </caption>\n <thead :class=\"theadClass\">\n <slot name=\"header\" />\n </thead>\n <tbody :class=\"tbodyClass\">\n <template v-if=\"loading\">\n <slot name=\"loading\">\n <tr v-for=\"row in loadingRowCount\" :key=\"row\" data-gr-table-loading-row>\n <td :colspan=\"serviceColSpan\" :class=\"loadingRowCellClass\">\n <GrSkeleton />\n </td>\n </tr>\n </slot>\n </template>\n\n <tr v-else-if=\"isEmpty\" data-gr-table-empty>\n <td :colspan=\"serviceColSpan\" :class=\"emptyCellClass\">\n <slot name=\"empty\">\n {{ resolvedEmptyText }}\n </slot>\n </td>\n </tr>\n\n <slot v-else />\n </tbody>\n <tfoot v-if=\"slots.footer\" class=\"text-[var(--gr-fg)]\">\n <slot name=\"footer\" />\n </tfoot>\n </table>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, ref, useSlots } from 'vue'\n\nimport { useGrComponentSize } from '../GrConfigProvider/context'\nimport GrSkeleton from '../GrSkeleton/GrSkeleton.vue'\nimport { hasMeaningfulSlotContent } from '../shared/slotNodes'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport {\n emptyCellClass,\n hoverableClass,\n loadingRowCellClass,\n stripedClass,\n tableSizes,\n type GrTableSize,\n} from './grTableStyles'\n\nexport interface GrTableProps {\n /**\n * Размер таблицы — базовый кегль текста. Паддинги ячеек оставлены за\n * консьюмером (GrTable — «тонкий» контейнер).\n */\n size?: GrTableSize\n /**\n * Текст caption для screen reader'ов. Рендерится как `<caption class=\"sr-only\">`,\n * если не передан слот `#caption`.\n */\n caption?: string\n /** Прямой ARIA-label для `<table>`. Игнорируется, если задан `ariaLabelledby`. */\n ariaLabel?: string\n /** ID элемента-заголовка, связанного с `<table>` через `aria-labelledby`. */\n ariaLabelledby?: string\n /**\n * ARIA-label для скролл-контейнера. Включает `role=\"region\"`; сам скролл\n * достижим с клавиатуры всегда, независимо от метки.\n */\n regionLabel?: string\n /** Идёт загрузка: вместо строк — скелетоны, контейнер помечен `aria-busy`. */\n loading?: boolean\n /** Сколько строк-заглушек показать при `loading`. */\n loadingRows?: number\n /** Сколько колонок занимает служебная строка (пустое состояние и скелетоны). */\n columnCount?: number\n /** Текст пустого состояния. Слот `#empty` сильнее. */\n emptyText?: string\n /** Таблица пуста. По умолчанию определяется по содержимому слота. */\n empty?: boolean\n /** Чередование строк. */\n striped?: boolean\n /** Подсветка строки под курсором. */\n hoverable?: boolean\n /**\n * Прилипающий заголовок: `<thead>` остаётся видимым при вертикальном скролле.\n * Осмысленно вместе с `maxHeight` (иначе таблица не скроллится вертикально).\n */\n stickyHeader?: boolean\n /**\n * Полное число строк набора, включая строки заголовка (`aria-rowcount`).\n *\n * Нужен, когда в DOM не весь набор — например, при виртуализации: диктор\n * считает строки по разметке и объявил бы «5 из 20» на таблице в десять\n * тысяч. Строки при этом обязаны нести `aria-rowindex`.\n */\n rowCount?: number\n /**\n * Фиксированная раскладка (`table-layout: fixed`): ширины колонок берутся из\n * первой строки, а не из содержимого всех.\n *\n * Обязателен, если в DOM не весь набор: иначе ширины считаются по\n * отрисованному окну и прыгают на каждой прокрутке.\n *\n * Класс — arbitrary-значение, а не `table-fixed`: такого правила в\n * `presetMini` нет, и класс молча не превратился бы в CSS.\n */\n fixedLayout?: boolean\n /**\n * Минимальная ширина самой таблицы (число — пиксели).\n *\n * Нужна при `fixedLayout`: с фиксированной раскладкой и шириной `auto`\n * браузер вписывает таблицу в контейнер и делит место между колонками\n * пропорционально — то есть заданные ширины молча ужимаются, а\n * горизонтальной прокрутки, на которой держатся закреплённые колонки, не\n * возникает вовсе.\n */\n tableMinWidth?: string | number\n /**\n * Максимальная высота скролл-контейнера (включает вертикальный скролл).\n * Число трактуется как пиксели. Нужен для работы `stickyHeader`.\n */\n maxHeight?: string | number\n}\n\n/**\n * `GrTable` — «тонкий» GR-контейнер для табличных данных.\n *\n * Рендерит `<table>` внутри скролл-обёртки и даёт слоты `#caption`, `#header`,\n * default (tbody) и `#footer`. Стили ячеек (`<th>`/`<td>` паддинги, выравнивание)\n * оставлены на консьюмере.\n *\n * ВАЖНО: `min-w-full` сам по себе не даст горизонтального скролла. Для него\n * консьюмеру нужны `white-space: nowrap` на ячейках или явные ширины колонок.\n */\nconst props = withDefaults(defineProps<GrTableProps>(), {\n size: undefined,\n caption: undefined,\n ariaLabel: undefined,\n ariaLabelledby: undefined,\n regionLabel: undefined,\n loading: false,\n loadingRows: 3,\n columnCount: 1,\n emptyText: undefined,\n empty: undefined,\n striped: false,\n hoverable: false,\n stickyHeader: false,\n maxHeight: undefined,\n rowCount: undefined,\n fixedLayout: false,\n tableMinWidth: undefined,\n})\n\nconst slots = useSlots()\n\nconst resolvedSize = useGrComponentSize(() => props.size, { component: 'GrTable' })\nconst tableTextClass = computed(() => tableSizes[resolvedSize.value])\nconst hasCaption = computed(() => Boolean(slots.caption) || Boolean(props.caption))\n\nconst { t } = useGranularityTranslations()\nconst resolvedEmptyText = computed(() => props.emptyText ?? t('gr.table.empty', 'Nothing here yet'))\n\n// Пустоту видно по слоту: `v-for` по пустому массиву оставляет фрагмент без\n// узлов, `v-if` — комментарий, и ни то ни другое строкой не является.\nconst isEmpty = computed(() => {\n if (props.empty !== undefined)\n return props.empty\n\n return !hasMeaningfulSlotContent(slots.default?.() ?? [])\n})\n\nconst showRows = computed(() => !props.loading && !isEmpty.value)\nconst loadingRowCount = computed(() => Math.max(1, Math.trunc(props.loadingRows)))\nconst serviceColSpan = computed(() => Math.max(1, Math.trunc(props.columnCount)))\n\nconst tbodyClass = computed(() => [\n 'text-[var(--gr-fg)]',\n props.striped && showRows.value ? stripedClass : '',\n props.hoverable && showRows.value ? hoverableClass : '',\n].filter(Boolean).join(' '))\n\nconst scrollStyle = computed(() => {\n // Неполный набор в DOM (`rowCount`) означает виртуализацию, а с ней обязан\n // быть выключен браузерный scroll anchoring: он подправляет `scrollTop`,\n // когда меняется высота содержимого выше видимого узла, — а окно меняет её\n // на каждом кадре прокрутки, и список уезжает.\n const anchor = props.rowCount === undefined ? undefined : { overflowAnchor: 'none' as const }\n\n if (props.maxHeight === undefined)\n return anchor\n\n const value = typeof props.maxHeight === 'number' ? `${props.maxHeight}px` : props.maxHeight\n return { ...anchor, maxHeight: value, overflowY: 'auto' as const }\n})\n\n// Прилипающий заголовок: `<thead>` на `position: sticky`; фон обязателен, иначе\n// сквозь него будут просвечивать строки при скролле.\nconst theadClass = computed(() => [\n 'bg-[var(--gr-muted)] text-[var(--gr-muted-fg)]',\n props.stickyHeader ? 'sticky top-0 z-[1]' : '',\n].filter(Boolean).join(' '))\n\nconst tableStyle = computed(() => {\n if (props.tableMinWidth === undefined)\n return undefined\n\n const value = typeof props.tableMinWidth === 'number' ? `${props.tableMinWidth}px` : props.tableMinWidth\n\n return { minWidth: value }\n})\n\nconst scrollEl = ref<HTMLElement | null>(null)\n\nfunction scrollTo(options: ScrollToOptions): void {\n scrollEl.value?.scrollTo(options)\n}\n\n// Только верхний уровень собственного tbody: вложенная таблица в ячейке не\n// должна сдвигать индексацию строк.\nfunction contentRows(): HTMLElement[] {\n if (!showRows.value)\n return []\n const el = scrollEl.value\n if (!el)\n return []\n return Array.from(el.querySelectorAll<HTMLElement>(':scope > table > tbody > tr'))\n}\n\nfunction scrollToRow(index: number, options?: ScrollIntoViewOptions): boolean {\n const row = contentRows()[index]\n if (!row)\n return false\n row.scrollIntoView(options ?? { block: 'nearest' })\n return true\n}\n\ndefineExpose({\n /** Прокрутить скролл-контейнер таблицы — тот же контракт, что у `GrDataTable`. */\n scrollTo,\n /** Прокрутить к строке содержимого по её индексу в разметке. `false` — строки нет в DOM. */\n scrollToRow,\n})\n\ndefineSlots<{\n /** Строки таблицы, когда разметка пишется руками вместо `data`. */\n default?: () => any\n /** Подпись таблицы — `<caption>`, читается диктором первой. */\n caption?: () => any\n /** Шапка вместо построенной по `columns`. */\n header?: () => any\n /** Содержимое, пока едут данные, — вместо строк-заглушек. */\n loading?: () => any\n /** Пустое состояние вместо текста по умолчанию. */\n empty?: () => any\n /** Итоговая строка под таблицей. */\n footer?: () => any\n}>()\n</script>\n\n<template>\n <div\n ref=\"scrollEl\"\n data-gr-table-scroll\n :role=\"regionLabel ? 'region' : undefined\"\n :aria-label=\"regionLabel\"\n :aria-busy=\"loading ? 'true' : undefined\"\n tabindex=\"0\"\n class=\"overflow-x-auto rounded-[var(--gr-radius-lg)] border border-[var(--gr-brd)] bg-[var(--gr-card)] focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--gr-ring)]\"\n :style=\"scrollStyle\"\n >\n <table\n data-gr-table\n class=\"min-w-full\" :class=\"[tableTextClass, fixedLayout ? '[table-layout:fixed]' : '']\"\n :style=\"tableStyle\"\n :aria-label=\"ariaLabelledby ? undefined : ariaLabel\"\n :aria-labelledby=\"ariaLabelledby\"\n :aria-rowcount=\"rowCount\"\n >\n <caption v-if=\"hasCaption\" class=\"sr-only\">\n <slot name=\"caption\">\n{{ caption }}\n</slot>\n </caption>\n <thead :class=\"theadClass\">\n <slot name=\"header\" />\n </thead>\n <tbody :class=\"tbodyClass\">\n <template v-if=\"loading\">\n <slot name=\"loading\">\n <tr v-for=\"row in loadingRowCount\" :key=\"row\" data-gr-table-loading-row>\n <td :colspan=\"serviceColSpan\" :class=\"loadingRowCellClass\">\n <GrSkeleton />\n </td>\n </tr>\n </slot>\n </template>\n\n <tr v-else-if=\"isEmpty\" data-gr-table-empty>\n <td :colspan=\"serviceColSpan\" :class=\"emptyCellClass\">\n <slot name=\"empty\">\n {{ resolvedEmptyText }}\n </slot>\n </td>\n </tr>\n\n <slot v-else />\n </tbody>\n <tfoot v-if=\"slots.footer\" class=\"text-[var(--gr-fg)]\">\n <slot name=\"footer\" />\n </tfoot>\n </table>\n </div>\n</template>\n"],"mappings":"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"}
|