@sincpro/web-ui 0.0.0-stage → 0.2.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/LICENSE +21 -0
- package/README.md +184 -2
- package/dist/components/activity/Activity.d.ts +69 -0
- package/dist/components/activity/Activity.js +279 -0
- package/dist/components/activity/Messages.d.ts +66 -0
- package/dist/components/activity/Messages.js +46 -0
- package/dist/components/activity/Timeline.d.ts +21 -0
- package/dist/components/activity/Timeline.js +30 -0
- package/dist/components/activity/index.d.ts +3 -0
- package/dist/components/activity/index.js +4 -0
- package/dist/components/assist/AssistMark.d.ts +64 -0
- package/dist/components/assist/AssistMark.js +108 -0
- package/dist/components/assist/AssistPending.d.ts +24 -0
- package/dist/components/assist/AssistPending.js +26 -0
- package/dist/components/assist/AssistSuggestion.d.ts +42 -0
- package/dist/components/assist/AssistSuggestion.js +55 -0
- package/dist/components/assist/ChangeReview.d.ts +56 -0
- package/dist/components/assist/ChangeReview.js +121 -0
- package/dist/components/assist/assist.d.ts +77 -0
- package/dist/components/assist/assist.js +87 -0
- package/dist/components/assist/index.d.ts +5 -0
- package/dist/components/assist/index.js +7 -0
- package/dist/components/form/Form.d.ts +52 -0
- package/dist/components/form/Form.js +49 -0
- package/dist/components/form/Sheet.d.ts +47 -0
- package/dist/components/form/Sheet.js +90 -0
- package/dist/components/form/index.d.ts +2 -0
- package/dist/components/form/index.js +4 -0
- package/dist/components/frame/Chart.d.ts +13 -0
- package/dist/components/frame/Chart.js +24 -0
- package/dist/components/frame/FrameView.d.ts +33 -0
- package/dist/components/frame/FrameView.js +125 -0
- package/dist/components/frame/index.d.ts +3 -0
- package/dist/components/frame/index.js +3 -0
- package/dist/components/frame/model.d.ts +43 -0
- package/dist/components/frame/model.js +101 -0
- package/dist/components/index.d.ts +10 -0
- package/dist/components/index.js +11 -0
- package/dist/components/lines/LineItems.d.ts +111 -0
- package/dist/components/lines/LineItems.js +317 -0
- package/dist/components/lines/index.d.ts +1 -0
- package/dist/components/lines/index.js +2 -0
- package/dist/components/lines/lines.d.ts +23 -0
- package/dist/components/lines/lines.js +26 -0
- package/dist/components/listing/ColumnsMenu.d.ts +20 -0
- package/dist/components/listing/ColumnsMenu.js +46 -0
- package/dist/components/listing/GroupingLevels.d.ts +35 -0
- package/dist/components/listing/GroupingLevels.js +45 -0
- package/dist/components/listing/Listing.d.ts +27 -0
- package/dist/components/listing/Listing.js +86 -0
- package/dist/components/listing/ListingBar.d.ts +112 -0
- package/dist/components/listing/ListingBar.js +144 -0
- package/dist/components/listing/Pagination.d.ts +36 -0
- package/dist/components/listing/Pagination.js +69 -0
- package/dist/components/listing/RecordCard.d.ts +33 -0
- package/dist/components/listing/RecordCard.js +22 -0
- package/dist/components/listing/RecordLink.d.ts +7 -0
- package/dist/components/listing/RecordLink.js +22 -0
- package/dist/components/listing/Row.d.ts +110 -0
- package/dist/components/listing/Row.js +123 -0
- package/dist/components/listing/SortMenu.d.ts +62 -0
- package/dist/components/listing/SortMenu.js +105 -0
- package/dist/components/listing/ViewSwitcher.d.ts +24 -0
- package/dist/components/listing/ViewSwitcher.js +16 -0
- package/dist/components/listing/columns.d.ts +47 -0
- package/dist/components/listing/columns.js +72 -0
- package/dist/components/listing/grouping.d.ts +35 -0
- package/dist/components/listing/grouping.js +47 -0
- package/dist/components/listing/index.d.ts +17 -0
- package/dist/components/listing/index.js +20 -0
- package/dist/components/listing/modelColumns.d.ts +50 -0
- package/dist/components/listing/modelColumns.js +103 -0
- package/dist/components/listing/pages.d.ts +78 -0
- package/dist/components/listing/pages.js +135 -0
- package/dist/components/listing/selection.d.ts +21 -0
- package/dist/components/listing/selection.js +43 -0
- package/dist/components/listing/set.d.ts +48 -0
- package/dist/components/listing/set.js +24 -0
- package/dist/components/listing/tree.d.ts +28 -0
- package/dist/components/listing/tree.js +23 -0
- package/dist/components/navigation/CommandPalette.d.ts +40 -0
- package/dist/components/navigation/CommandPalette.js +114 -0
- package/dist/components/navigation/NavigationTree.d.ts +31 -0
- package/dist/components/navigation/NavigationTree.js +79 -0
- package/dist/components/navigation/commands.d.ts +30 -0
- package/dist/components/navigation/commands.js +30 -0
- package/dist/components/navigation/index.d.ts +3 -0
- package/dist/components/navigation/index.js +4 -0
- package/dist/components/record/Breadcrumb.d.ts +42 -0
- package/dist/components/record/Breadcrumb.js +98 -0
- package/dist/components/record/DirtyActions.d.ts +26 -0
- package/dist/components/record/DirtyActions.js +22 -0
- package/dist/components/record/Pager.d.ts +18 -0
- package/dist/components/record/Pager.js +33 -0
- package/dist/components/record/RecordHeader.d.ts +75 -0
- package/dist/components/record/RecordHeader.js +104 -0
- package/dist/components/record/RecordNotices.d.ts +37 -0
- package/dist/components/record/RecordNotices.js +75 -0
- package/dist/components/record/RecordSkeleton.d.ts +3 -0
- package/dist/components/record/RecordSkeleton.js +21 -0
- package/dist/components/record/SmartButtons.d.ts +35 -0
- package/dist/components/record/SmartButtons.js +38 -0
- package/dist/components/record/StatusBar.d.ts +51 -0
- package/dist/components/record/StatusBar.js +168 -0
- package/dist/components/record/ThumbBar.d.ts +36 -0
- package/dist/components/record/ThumbBar.js +86 -0
- package/dist/components/record/index.d.ts +6 -0
- package/dist/components/record/index.js +8 -0
- package/dist/components/search/CriteriaBuilder.d.ts +58 -0
- package/dist/components/search/CriteriaBuilder.js +278 -0
- package/dist/components/search/CriteriaChips.d.ts +22 -0
- package/dist/components/search/CriteriaChips.js +64 -0
- package/dist/components/search/FilterBuilder.d.ts +142 -0
- package/dist/components/search/FilterBuilder.js +421 -0
- package/dist/components/search/JoinWord.d.ts +8 -0
- package/dist/components/search/JoinWord.js +47 -0
- package/dist/components/search/JsonEditor.d.ts +19 -0
- package/dist/components/search/JsonEditor.js +78 -0
- package/dist/components/search/SearchBar.d.ts +78 -0
- package/dist/components/search/SearchBar.js +387 -0
- package/dist/components/search/criteria.d.ts +116 -0
- package/dist/components/search/criteria.js +159 -0
- package/dist/components/search/datePeriods.d.ts +122 -0
- package/dist/components/search/datePeriods.js +134 -0
- package/dist/components/search/dateRanges.d.ts +54 -0
- package/dist/components/search/dateRanges.js +89 -0
- package/dist/components/search/index.d.ts +9 -0
- package/dist/components/search/index.js +20 -0
- package/dist/components/search/model.d.ts +54 -0
- package/dist/components/search/model.js +37 -0
- package/dist/components/search/query.d.ts +166 -0
- package/dist/components/search/query.js +436 -0
- package/dist/components/shell/AppFrame.d.ts +14 -0
- package/dist/components/shell/AppFrame.js +80 -0
- package/dist/components/shell/TopBar.d.ts +73 -0
- package/dist/components/shell/TopBar.js +54 -0
- package/dist/components/shell/headerSlot.d.ts +17 -0
- package/dist/components/shell/headerSlot.js +21 -0
- package/dist/components/shell/index.d.ts +2 -0
- package/dist/components/shell/index.js +3 -0
- package/dist/foundations/aria.d.ts +14 -0
- package/dist/foundations/aria.js +18 -0
- package/dist/foundations/calendar.d.ts +28 -0
- package/dist/foundations/calendar.js +183 -0
- package/dist/foundations/copy.d.ts +703 -0
- package/dist/foundations/copy.es.d.ts +2 -0
- package/dist/foundations/copy.es.js +430 -0
- package/dist/foundations/copy.js +520 -0
- package/dist/foundations/density.d.ts +16 -0
- package/dist/foundations/density.js +21 -0
- package/dist/foundations/grouping.d.ts +281 -0
- package/dist/foundations/grouping.js +0 -0
- package/dist/foundations/index.d.ts +14 -0
- package/dist/foundations/index.js +30 -0
- package/dist/foundations/layout.d.ts +9 -0
- package/dist/foundations/layout.js +9 -0
- package/dist/foundations/pivot.d.ts +222 -0
- package/dist/foundations/pivot.js +198 -0
- package/dist/foundations/pivotSheet.d.ts +61 -0
- package/dist/foundations/pivotSheet.js +0 -0
- package/dist/foundations/slots.d.ts +67 -0
- package/dist/foundations/slots.js +63 -0
- package/dist/foundations/sticky.d.ts +53 -0
- package/dist/foundations/sticky.js +150 -0
- package/dist/foundations/surface.d.ts +9 -0
- package/dist/foundations/surface.js +26 -0
- package/dist/foundations/theme.d.ts +42 -0
- package/dist/foundations/theme.js +88 -0
- package/dist/foundations/types.d.ts +23 -0
- package/dist/foundations/types.js +50 -0
- package/dist/foundations/variants.d.ts +19 -0
- package/dist/foundations/variants.js +48 -0
- package/dist/foundations/xlsx.d.ts +86 -0
- package/dist/foundations/xlsx.js +0 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +19 -0
- package/dist/primitives/block/Block.d.ts +66 -0
- package/dist/primitives/block/Block.js +34 -0
- package/dist/primitives/block/Line.d.ts +18 -0
- package/dist/primitives/block/Line.js +45 -0
- package/dist/primitives/block/SectionGrid.d.ts +30 -0
- package/dist/primitives/block/SectionGrid.js +29 -0
- package/dist/primitives/block/Steps.d.ts +76 -0
- package/dist/primitives/block/Steps.js +43 -0
- package/dist/primitives/block/index.d.ts +4 -0
- package/dist/primitives/block/index.js +7 -0
- package/dist/primitives/button/Button.d.ts +137 -0
- package/dist/primitives/button/Button.js +234 -0
- package/dist/primitives/button/index.d.ts +1 -0
- package/dist/primitives/button/index.js +2 -0
- package/dist/primitives/cell/CellStack.d.ts +47 -0
- package/dist/primitives/cell/CellStack.js +33 -0
- package/dist/primitives/cell/index.d.ts +1 -0
- package/dist/primitives/cell/index.js +3 -0
- package/dist/primitives/choice/ComboBox.d.ts +19 -0
- package/dist/primitives/choice/ComboBox.js +52 -0
- package/dist/primitives/choice/RadioGroup.d.ts +18 -0
- package/dist/primitives/choice/RadioGroup.js +50 -0
- package/dist/primitives/choice/SearchField.d.ts +33 -0
- package/dist/primitives/choice/SearchField.js +46 -0
- package/dist/primitives/choice/SegmentedControl.d.ts +16 -0
- package/dist/primitives/choice/SegmentedControl.js +69 -0
- package/dist/primitives/choice/Slider.d.ts +16 -0
- package/dist/primitives/choice/Slider.js +46 -0
- package/dist/primitives/choice/Switch.d.ts +14 -0
- package/dist/primitives/choice/Switch.js +65 -0
- package/dist/primitives/choice/ThemeSwitcher.d.ts +10 -0
- package/dist/primitives/choice/ThemeSwitcher.js +25 -0
- package/dist/primitives/choice/index.d.ts +8 -0
- package/dist/primitives/choice/index.js +11 -0
- package/dist/primitives/choice/options.d.ts +28 -0
- package/dist/primitives/choice/options.js +6 -0
- package/dist/primitives/date/Calendar.d.ts +31 -0
- package/dist/primitives/date/Calendar.js +134 -0
- package/dist/primitives/date/DatePicker.d.ts +42 -0
- package/dist/primitives/date/DatePicker.js +103 -0
- package/dist/primitives/date/DateTime.d.ts +35 -0
- package/dist/primitives/date/DateTime.js +100 -0
- package/dist/primitives/date/index.d.ts +3 -0
- package/dist/primitives/date/index.js +6 -0
- package/dist/primitives/dialog/Dialog.d.ts +118 -0
- package/dist/primitives/dialog/Dialog.js +121 -0
- package/dist/primitives/dialog/Drill.d.ts +90 -0
- package/dist/primitives/dialog/Drill.js +172 -0
- package/dist/primitives/dialog/index.d.ts +2 -0
- package/dist/primitives/dialog/index.js +4 -0
- package/dist/primitives/disclosure/Disclosure.d.ts +36 -0
- package/dist/primitives/disclosure/Disclosure.js +52 -0
- package/dist/primitives/disclosure/index.d.ts +1 -0
- package/dist/primitives/disclosure/index.js +2 -0
- package/dist/primitives/field/Checks.d.ts +57 -0
- package/dist/primitives/field/Checks.js +72 -0
- package/dist/primitives/field/DropZone.d.ts +42 -0
- package/dist/primitives/field/DropZone.js +52 -0
- package/dist/primitives/field/Field.d.ts +178 -0
- package/dist/primitives/field/Field.js +251 -0
- package/dist/primitives/field/Suggest.d.ts +48 -0
- package/dist/primitives/field/Suggest.js +43 -0
- package/dist/primitives/field/aria.d.ts +61 -0
- package/dist/primitives/field/aria.js +70 -0
- package/dist/primitives/field/context.d.ts +30 -0
- package/dist/primitives/field/context.js +13 -0
- package/dist/primitives/field/copy.d.ts +16 -0
- package/dist/primitives/field/copy.js +69 -0
- package/dist/primitives/field/index.d.ts +9 -0
- package/dist/primitives/field/index.js +15 -0
- package/dist/primitives/field/layout.d.ts +24 -0
- package/dist/primitives/field/layout.js +10 -0
- package/dist/primitives/field/mode.d.ts +9 -0
- package/dist/primitives/field/mode.js +13 -0
- package/dist/primitives/field/note.d.ts +55 -0
- package/dist/primitives/field/note.js +117 -0
- package/dist/primitives/hint/Hint.d.ts +31 -0
- package/dist/primitives/hint/Hint.js +42 -0
- package/dist/primitives/hint/index.d.ts +1 -0
- package/dist/primitives/hint/index.js +1 -0
- package/dist/primitives/index.d.ts +20 -0
- package/dist/primitives/index.js +21 -0
- package/dist/primitives/menu/Menu.d.ts +128 -0
- package/dist/primitives/menu/Menu.js +89 -0
- package/dist/primitives/menu/index.d.ts +1 -0
- package/dist/primitives/menu/index.js +2 -0
- package/dist/primitives/notice/Callout.d.ts +49 -0
- package/dist/primitives/notice/Callout.js +28 -0
- package/dist/primitives/notice/Flag.d.ts +13 -0
- package/dist/primitives/notice/Flag.js +31 -0
- package/dist/primitives/notice/Notice.d.ts +45 -0
- package/dist/primitives/notice/Notice.js +61 -0
- package/dist/primitives/notice/Toast.d.ts +55 -0
- package/dist/primitives/notice/Toast.js +142 -0
- package/dist/primitives/notice/index.d.ts +4 -0
- package/dist/primitives/notice/index.js +6 -0
- package/dist/primitives/overlay/Popover.d.ts +6 -0
- package/dist/primitives/overlay/Popover.js +27 -0
- package/dist/primitives/overlay/PopoverTrigger.d.ts +55 -0
- package/dist/primitives/overlay/PopoverTrigger.js +38 -0
- package/dist/primitives/overlay/Preview.d.ts +19 -0
- package/dist/primitives/overlay/Preview.js +60 -0
- package/dist/primitives/overlay/Tooltip.d.ts +38 -0
- package/dist/primitives/overlay/Tooltip.js +74 -0
- package/dist/primitives/overlay/index.d.ts +4 -0
- package/dist/primitives/overlay/index.js +7 -0
- package/dist/primitives/picker/Picker.d.ts +89 -0
- package/dist/primitives/picker/Picker.js +204 -0
- package/dist/primitives/picker/index.d.ts +1 -0
- package/dist/primitives/picker/index.js +2 -0
- package/dist/primitives/surface/Peek.d.ts +60 -0
- package/dist/primitives/surface/Peek.js +71 -0
- package/dist/primitives/surface/index.d.ts +1 -0
- package/dist/primitives/surface/index.js +2 -0
- package/dist/primitives/table/CellCopy.d.ts +20 -0
- package/dist/primitives/table/CellCopy.js +23 -0
- package/dist/primitives/table/CellEditor.d.ts +14 -0
- package/dist/primitives/table/CellEditor.js +83 -0
- package/dist/primitives/table/DataTable.d.ts +189 -0
- package/dist/primitives/table/DataTable.js +330 -0
- package/dist/primitives/table/EditableTable.d.ts +191 -0
- package/dist/primitives/table/EditableTable.js +617 -0
- package/dist/primitives/table/PivotTable.d.ts +14 -0
- package/dist/primitives/table/PivotTable.js +0 -0
- package/dist/primitives/table/ReportTable.d.ts +38 -0
- package/dist/primitives/table/ReportTable.js +106 -0
- package/dist/primitives/table/RowActions.d.ts +16 -0
- package/dist/primitives/table/RowActions.js +28 -0
- package/dist/primitives/table/SheetTable.d.ts +73 -0
- package/dist/primitives/table/SheetTable.js +230 -0
- package/dist/primitives/table/Table.d.ts +106 -0
- package/dist/primitives/table/Table.js +116 -0
- package/dist/primitives/table/index.d.ts +7 -0
- package/dist/primitives/table/index.js +9 -0
- package/dist/primitives/tabs/Tabs.d.ts +91 -0
- package/dist/primitives/tabs/Tabs.js +56 -0
- package/dist/primitives/tabs/index.d.ts +1 -0
- package/dist/primitives/tabs/index.js +1 -0
- package/dist/primitives/tag/Tag.d.ts +36 -0
- package/dist/primitives/tag/Tag.js +68 -0
- package/dist/primitives/tag/Tags.d.ts +57 -0
- package/dist/primitives/tag/Tags.js +104 -0
- package/dist/primitives/tag/TagsField.d.ts +35 -0
- package/dist/primitives/tag/TagsField.js +186 -0
- package/dist/primitives/tag/choices.d.ts +38 -0
- package/dist/primitives/tag/choices.js +26 -0
- package/dist/primitives/tag/index.d.ts +4 -0
- package/dist/primitives/tag/index.js +8 -0
- package/dist/primitives/toolbar/Toolbar.d.ts +13 -0
- package/dist/primitives/toolbar/Toolbar.js +36 -0
- package/dist/primitives/toolbar/index.d.ts +1 -0
- package/dist/primitives/toolbar/index.js +2 -0
- package/dist/primitives/tree/Tree.d.ts +56 -0
- package/dist/primitives/tree/Tree.js +74 -0
- package/dist/primitives/tree/index.d.ts +1 -0
- package/dist/primitives/tree/index.js +3 -0
- package/dist/primitives/value/Copyable.d.ts +48 -0
- package/dist/primitives/value/Copyable.js +71 -0
- package/dist/primitives/value/Fecha.d.ts +12 -0
- package/dist/primitives/value/Fecha.js +89 -0
- package/dist/primitives/value/Meter.d.ts +29 -0
- package/dist/primitives/value/Meter.js +46 -0
- package/dist/primitives/value/Metric.d.ts +42 -0
- package/dist/primitives/value/Metric.js +38 -0
- package/dist/primitives/value/Person.d.ts +90 -0
- package/dist/primitives/value/Person.js +208 -0
- package/dist/primitives/value/ProgressBar.d.ts +31 -0
- package/dist/primitives/value/ProgressBar.js +53 -0
- package/dist/primitives/value/Relation.d.ts +74 -0
- package/dist/primitives/value/Relation.js +74 -0
- package/dist/primitives/value/Totals.d.ts +121 -0
- package/dist/primitives/value/Totals.js +54 -0
- package/dist/primitives/value/Value.d.ts +40 -0
- package/dist/primitives/value/Value.js +80 -0
- package/dist/primitives/value/index.d.ts +9 -0
- package/dist/primitives/value/index.js +10 -0
- package/dist/tokens.css +1062 -0
- package/dist/views/index.d.ts +2 -0
- package/dist/views/index.js +3 -0
- package/dist/views/list/List.d.ts +119 -0
- package/dist/views/list/List.js +101 -0
- package/dist/views/list/ListView.d.ts +6 -0
- package/dist/views/list/ListView.js +295 -0
- package/dist/views/list/columns.d.ts +18 -0
- package/dist/views/list/columns.js +27 -0
- package/dist/views/list/derive.d.ts +87 -0
- package/dist/views/list/derive.js +207 -0
- package/dist/views/list/index.d.ts +2 -0
- package/dist/views/list/index.js +4 -0
- package/dist/views/list/presentations.d.ts +39 -0
- package/dist/views/list/presentations.js +105 -0
- package/dist/views/list/types.d.ts +284 -0
- package/dist/views/list/types.js +1 -0
- package/dist/views/list/useNarrowList.d.ts +17 -0
- package/dist/views/list/useNarrowList.js +32 -0
- package/dist/views/record/Record.d.ts +145 -0
- package/dist/views/record/Record.js +211 -0
- package/dist/views/record/index.d.ts +1 -0
- package/dist/views/record/index.js +2 -0
- package/package.json +113 -4
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LA AGRUPACIÓN, en N niveles.
|
|
3
|
+
*
|
|
4
|
+
* Context: agrupar es partir un conjunto por lo que sus filas comparten, y eso
|
|
5
|
+
* no tiene por qué ser UNA pregunta. «Por procedencia» es una; «por procedencia
|
|
6
|
+
* y después por mes» es la misma pregunta hecha dos veces, y la respuesta es un
|
|
7
|
+
* árbol y no una lista de montones.
|
|
8
|
+
*
|
|
9
|
+
* ── Qué se PIDE y qué se DIBUJA son dos cosas ──────────────────────
|
|
10
|
+
*
|
|
11
|
+
* `GroupLevel` es lo que alguien pidió: por qué campo partir y, si es una
|
|
12
|
+
* fecha, con qué grano. `Pile` es lo que se dibuja: un montón ya armado, con su
|
|
13
|
+
* rótulo, cuántas filas tiene y el nivel de abajo. Están separados porque los
|
|
14
|
+
* montones no siempre los arma esta máquina: los puede armar quien tenga los
|
|
15
|
+
* datos —y contar un catálogo entero es algo que sólo puede contestar quien lo
|
|
16
|
+
* guarda—. Por eso `pilesFrom` es un HELPER y no el único camino: una
|
|
17
|
+
* presentación recibe `piles` y no sabe ni le importa quién los contó.
|
|
18
|
+
*
|
|
19
|
+
* **Esto no conoce ningún motor.** Ni criteria, ni cursores, ni transporte: un
|
|
20
|
+
* montón acá es rótulo, conteo, hijos y filas. Quien traduzca la respuesta de un
|
|
21
|
+
* servidor a esta forma vive afuera, y por eso la misma presentación sirve para
|
|
22
|
+
* un agrupado hecho en el navegador y para uno contado a mil kilómetros.
|
|
23
|
+
*
|
|
24
|
+
* ── La identidad de un montón es su RUTA ────────────────────────────
|
|
25
|
+
*
|
|
26
|
+
* Y no su clave. Con un solo nivel alcanzaba la clave, porque no había dos
|
|
27
|
+
* montones que pudieran llamarse igual. Con N niveles sí: «2026-09» puede ser un
|
|
28
|
+
* mes adentro de «sintético» y otro adentro de «traído», y son montones
|
|
29
|
+
* distintos que se pliegan por separado. La ruta —`["sintético", "2026-09"]`—
|
|
30
|
+
* es lo único que los distingue, así que es lo que se guarda.
|
|
31
|
+
*
|
|
32
|
+
* ── La CLAVE identifica; el RÓTULO se lee ───────────────────────────
|
|
33
|
+
*
|
|
34
|
+
* Y son dos textos. «2026-09» es lo que el motor escribe: lo que se compara con
|
|
35
|
+
* lo que contó el servidor, lo que la ruta lleva, lo que queda plegado. Con eso
|
|
36
|
+
* a la vista la interfaz habla en máquina, así que el montón lleva además su
|
|
37
|
+
* rótulo —«Septiembre»— que es lo que se dibuja y lo único que cambia con el
|
|
38
|
+
* idioma. Al revés no se puede: con el rótulo por identidad, dos septiembres de
|
|
39
|
+
* años distintos se funden en un montón que no existe, y plegar un mes en
|
|
40
|
+
* español lo dejaría abierto en inglés.
|
|
41
|
+
*
|
|
42
|
+
* Para un campo que no es una fecha los dos textos son el mismo —«sintético» se
|
|
43
|
+
* identifica y se lee igual— y por eso el rótulo sólo se pone aparte donde hace
|
|
44
|
+
* falta: en las fechas, que las nombra `system/calendar.ts`.
|
|
45
|
+
*/
|
|
46
|
+
/** El grano de un nivel de fecha. Sin grano, un campo de fecha parte por
|
|
47
|
+
* instante y cada fila termina en su propio montón, que es no agrupar. */
|
|
48
|
+
export type GroupGrain = "day" | "week" | "month" | "quarter" | "year";
|
|
49
|
+
/**
|
|
50
|
+
* De GRUESO a fino. Es el orden en que se anidan los granos de un mismo campo, y
|
|
51
|
+
* no es una preferencia: agrupar por día y después por mes daría montones de un
|
|
52
|
+
* día dentro de meses que ya no parten nada, porque un día entero vive adentro
|
|
53
|
+
* de un solo mes. La jerarquía de un calendario tiene una dirección y es ésta.
|
|
54
|
+
*/
|
|
55
|
+
export declare const GRAIN_ORDER: readonly GroupGrain[];
|
|
56
|
+
/** Un NIVEL: por qué campo se parte, y con qué grano si es una fecha. Es lo que
|
|
57
|
+
* alguien pidió, no lo que se dibuja. */
|
|
58
|
+
export type GroupLevel = {
|
|
59
|
+
field: string;
|
|
60
|
+
grain?: GroupGrain;
|
|
61
|
+
};
|
|
62
|
+
/** Un campo por el que SE PUEDE agrupar, para que el control ofrezca algo. Los
|
|
63
|
+
* granos se declaran acá y no se adivinan del tipo: quién sabe si una fecha se
|
|
64
|
+
* mira por semana o por trimestre es el dominio, y ofrecer los cuatro siempre
|
|
65
|
+
* es ofrecer tres que a nadie le sirven. */
|
|
66
|
+
export type GroupableField = {
|
|
67
|
+
field: string;
|
|
68
|
+
label: string;
|
|
69
|
+
/** Presentes = es una fecha y estos son los cortes que tienen sentido. */
|
|
70
|
+
grains?: readonly GroupGrain[];
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Un MONTÓN ya armado: lo que sus filas comparten, cuántas son, y el nivel de
|
|
74
|
+
* abajo.
|
|
75
|
+
*/
|
|
76
|
+
export type Pile<T> = {
|
|
77
|
+
/** La ruta desde la raíz, en CLAVES. Es la identidad del montón: lo que lo
|
|
78
|
+
* pliega y lo que lo distingue de un hermano homónimo en otra rama. */
|
|
79
|
+
path: readonly string[];
|
|
80
|
+
/** Cuán adentro está. `0` es el primer nivel. Lo usa la sangría. */
|
|
81
|
+
depth: number;
|
|
82
|
+
/** Por qué campo se partió acá. Lo dibuja el encabezado a la izquierda del
|
|
83
|
+
* valor: sin él, «2026-09» no dice si es cuándo se registró o cuándo se
|
|
84
|
+
* corrió. */
|
|
85
|
+
field: string;
|
|
86
|
+
/** Lo que las filas COMPARTEN, en el idioma del motor: «2026-09». Es el último
|
|
87
|
+
* tramo de la ruta, y lo que se compara con lo que contó el servidor. */
|
|
88
|
+
key: string;
|
|
89
|
+
/** El mismo valor, ya legible y en el idioma activo: «Septiembre». Es lo que
|
|
90
|
+
* se dibuja, y lo único de un montón que cambia con el idioma. */
|
|
91
|
+
label: string;
|
|
92
|
+
/**
|
|
93
|
+
* Cuántas filas hay en el montón — TODAS, no las de la página.
|
|
94
|
+
*
|
|
95
|
+
* Es la diferencia entre «hay 187 sintéticos» y «se ven 12»: un conteo que
|
|
96
|
+
* cambia al pasar de página no es un conteo, es un largo de array. Cuando los
|
|
97
|
+
* montones los cuenta quien guarda los datos, este número viene de allá.
|
|
98
|
+
*/
|
|
99
|
+
count: number;
|
|
100
|
+
/** Las filas, en el nivel MÁS PROFUNDO. Vacío en los de arriba: un montón que
|
|
101
|
+
* tiene montones adentro no tiene filas propias. */
|
|
102
|
+
items: readonly T[];
|
|
103
|
+
/** El nivel de abajo. Vacío en el más profundo. */
|
|
104
|
+
piles: readonly Pile<T>[];
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* La identidad de un NIVEL: el campo y, si es fecha, su grano.
|
|
108
|
+
*
|
|
109
|
+
* El campo solo no alcanza desde que un mismo campo puede estar puesto con
|
|
110
|
+
* varios granos —«por mes y adentro por día» son dos niveles del mismo
|
|
111
|
+
* `registered_at`— y dos niveles que se llaman igual no se pueden ni sacar ni
|
|
112
|
+
* mover por separado.
|
|
113
|
+
*/
|
|
114
|
+
export declare function levelKey(level: GroupLevel): string;
|
|
115
|
+
/**
|
|
116
|
+
* Los niveles, acomodados.
|
|
117
|
+
*
|
|
118
|
+
* Dos reglas, y las dos son del calendario y no del gusto de nadie:
|
|
119
|
+
*
|
|
120
|
+
* 1. Los niveles de un MISMO campo quedan juntos. Partir por mes, después por
|
|
121
|
+
* procedencia y después por día del mismo campo deja dos cortes de la misma
|
|
122
|
+
* fecha separados por otra cosa, y eso no es una jerarquía, es un tropiezo.
|
|
123
|
+
* 2. Adentro de un campo van de GRUESO a FINO. Tildar «día» y después «mes»
|
|
124
|
+
* tiene que dar «mes › día», porque al revés el mes no parte nada: un día
|
|
125
|
+
* entero ya vive adentro de un solo mes.
|
|
126
|
+
*
|
|
127
|
+
* El orden ENTRE campos lo decide quien agrupa —es una pregunta del dominio, no
|
|
128
|
+
* del calendario— así que se respeta el de primera aparición y se puede mover.
|
|
129
|
+
*/
|
|
130
|
+
export declare function normalizeLevels(levels: readonly GroupLevel[]): GroupLevel[];
|
|
131
|
+
/**
|
|
132
|
+
* LO QUE HACE AGRUPABLE A UNA VISTA.
|
|
133
|
+
*
|
|
134
|
+
* Cualquier componente que dibuje N cosas —filas, tarjetas, celdas, líneas de un
|
|
135
|
+
* informe, puntos de una serie— puede agrupar aceptando ESTO y nada más. Es
|
|
136
|
+
* deliberadamente corto: cinco campos, ninguno opcional por capricho.
|
|
137
|
+
*
|
|
138
|
+
* ── Lo que el contrato SÍ fija ──────────────────────────────────────
|
|
139
|
+
*
|
|
140
|
+
* levels qué se pregunta, y en qué orden
|
|
141
|
+
* of a qué montón va cada cosa, ya legible
|
|
142
|
+
* piles el árbol ya armado, si lo contó alguien con el conjunto entero
|
|
143
|
+
* collapsed qué está plegado, por ruta
|
|
144
|
+
* onToggle cómo se pliega
|
|
145
|
+
*
|
|
146
|
+
* ── Lo que NO fija, y es el punto ───────────────────────────────────
|
|
147
|
+
*
|
|
148
|
+
* **Cómo se dibuja un montón.** La lista pone un encabezado con filete; la
|
|
149
|
+
* planilla, una banda pegada a la izquierda porque está virtualizada por índice
|
|
150
|
+
* y no puede anidar el marcado; la tabla usa una fila con `colSpan`; el informe
|
|
151
|
+
* hace una línea con sus subtotales; una serie haría una serie por montón. Las
|
|
152
|
+
* cinco son correctas y ninguna sirve para las otras — un contrato que además
|
|
153
|
+
* dictara el dibujo obligaría a todas a parecerse a la primera que se escribió.
|
|
154
|
+
*
|
|
155
|
+
* Por eso lo que se comparte es el ÁRBOL y no el render: quien implementa recibe
|
|
156
|
+
* `Pile[]` de `pilesOf()` y lo recorre como su presentación necesite.
|
|
157
|
+
*
|
|
158
|
+
* ── Cómo se implementa ──────────────────────────────────────────────
|
|
159
|
+
*
|
|
160
|
+
* function MiVista<T>({ items, grouping }: { items: readonly T[]; grouping?: Grouping<T> }) {
|
|
161
|
+
* const piles = pilesOf(items, grouping);
|
|
162
|
+
* if (piles === null) return <>{items.map(dibujar)}</>;
|
|
163
|
+
* return recorrer(piles); // ← acá manda la presentación
|
|
164
|
+
* }
|
|
165
|
+
*/
|
|
166
|
+
export type Grouping<T> = {
|
|
167
|
+
/**
|
|
168
|
+
* Los niveles pedidos, de afuera hacia adentro. Vacío = sin agrupar.
|
|
169
|
+
*
|
|
170
|
+
* El ORDEN es la jerarquía: `[origen, mes]` y `[mes, origen]` son dos lecturas
|
|
171
|
+
* distintas del mismo conjunto.
|
|
172
|
+
*/
|
|
173
|
+
levels: readonly GroupLevel[];
|
|
174
|
+
/** A qué montón va cada cosa, en cada nivel: la CLAVE. Recortar una fecha a su
|
|
175
|
+
* grano es de quien conoce el dato, no del sistema. */
|
|
176
|
+
of: PileOf<T>;
|
|
177
|
+
/** Cómo se lee una clave. Sin esto, una fecha la nombra el calendario del
|
|
178
|
+
* sistema en el idioma activo y lo demás se dibuja tal cual. */
|
|
179
|
+
label?: PileLabelOf;
|
|
180
|
+
/**
|
|
181
|
+
* El árbol YA armado, cuando lo contó quien tiene el conjunto entero.
|
|
182
|
+
*
|
|
183
|
+
* Existe porque un conteo que sólo conoce la página no es un conteo: «187
|
|
184
|
+
* sintéticos» no lo pueden contestar las doce filas que se trajeron. Quién
|
|
185
|
+
* cuenta no es asunto de esta capa — dibuja el mismo árbol en los dos casos.
|
|
186
|
+
*
|
|
187
|
+
* Un árbol contado afuera llega con sus rótulos PUESTOS, y esta capa no se los
|
|
188
|
+
* toca: quien lo tradujo sabe cuál de sus claves es una fecha y cuál es un
|
|
189
|
+
* código con nombre propio. `dateLabel` está exportado para que los ponga con
|
|
190
|
+
* las mismas palabras que el árbol armado acá.
|
|
191
|
+
*/
|
|
192
|
+
piles?: readonly Pile<T>[];
|
|
193
|
+
/** Qué montones están plegados, por `pathKey(pile.path)`. */
|
|
194
|
+
collapsed?: readonly string[];
|
|
195
|
+
onToggle?: (key: string) => void;
|
|
196
|
+
};
|
|
197
|
+
/**
|
|
198
|
+
* El árbol que hay que dibujar, o `null` si no se agrupa.
|
|
199
|
+
*
|
|
200
|
+
* Es la única línea que un componente necesita escribir para volverse agrupable:
|
|
201
|
+
* decide entre el árbol que le pasaron y el que arma con las cosas en la mano, y
|
|
202
|
+
* contesta `null` cuando no hay nada que partir — que es distinto de un árbol
|
|
203
|
+
* vacío, porque un árbol vacío significa «se agrupó y no quedó nada».
|
|
204
|
+
*/
|
|
205
|
+
export declare function pilesOf<T>(items: readonly T[], grouping: Grouping<T> | undefined): readonly Pile<T>[] | null;
|
|
206
|
+
/** Si un montón está abierto, según lo plegado. Abierto es el default: agrupar y
|
|
207
|
+
* después tener que abrir cada montón son dos gestos para lo que se pidió en
|
|
208
|
+
* uno. */
|
|
209
|
+
export declare function pileIsOpen<T>(pile: Pile<T>, grouping: Grouping<T> | undefined): boolean;
|
|
210
|
+
/** La clave de plegado de una ruta. El separador es un carácter que no aparece
|
|
211
|
+
* en un valor real, así que dos rutas distintas no pueden producir la misma
|
|
212
|
+
* clave por concatenación — `["a", "b"]` y `["ab"]` sí podrían con un
|
|
213
|
+
* separador escribible. */
|
|
214
|
+
export declare function pathKey(path: readonly string[]): string;
|
|
215
|
+
/** Qué montón le toca a cada fila en cada nivel: su CLAVE. Recortar una fecha a
|
|
216
|
+
* su grano es cosa de quien conoce el dato —`dateKey` la recorta con el mismo
|
|
217
|
+
* texto que el motor— y ponerle nombre es cosa del rótulo. */
|
|
218
|
+
export type PileOf<T> = (item: T, level: GroupLevel) => string;
|
|
219
|
+
/**
|
|
220
|
+
* Cómo se lee la clave de un montón.
|
|
221
|
+
*
|
|
222
|
+
* `within` son los granos que los montones de ARRIBA, del mismo campo, ya
|
|
223
|
+
* dijeron: con el año afuera, un mes se rotula «Septiembre» y no «Septiembre de
|
|
224
|
+
* 2026». Decirlo dos veces llena la sangría con lo que está dos renglones más
|
|
225
|
+
* arriba.
|
|
226
|
+
*/
|
|
227
|
+
export type PileLabelOf = (key: string, level: GroupLevel, within: readonly GroupGrain[]) => string;
|
|
228
|
+
/** El rótulo por default: una fecha la nombra el calendario en el idioma activo,
|
|
229
|
+
* y lo que no es una fecha se dibuja tal cual —«sintético» se identifica y se
|
|
230
|
+
* lee con la misma palabra, y traducirlo sería inventar un valor que nadie
|
|
231
|
+
* guardó. */
|
|
232
|
+
export declare function pileLabel(key: string, level: GroupLevel, within: readonly GroupGrain[]): string;
|
|
233
|
+
/**
|
|
234
|
+
* CÓMO SE LEE UNA RUTA de claves, tramo por tramo.
|
|
235
|
+
*
|
|
236
|
+
* La clave identifica y el rótulo se lee: «2026-09» es lo que el motor escribe y
|
|
237
|
+
* «Septiembre» lo que se dibuja. Cualquiera que tenga una ruta —el eje de un
|
|
238
|
+
* pivote, el título de un montón, una miga— la dice con esto, porque una ruta
|
|
239
|
+
* que se lee distinta según quién la dibuje es el mismo corte con dos caras.
|
|
240
|
+
*
|
|
241
|
+
* `within` sale de los niveles de ARRIBA del mismo campo: con el año afuera, el
|
|
242
|
+
* mes se dice «Septiembre» y no «Septiembre de 2026», porque eso ya está escrito
|
|
243
|
+
* un tramo antes.
|
|
244
|
+
*/
|
|
245
|
+
export declare function pathLabels(levels: readonly GroupLevel[], path: readonly string[], label?: PileLabelOf): string[];
|
|
246
|
+
/**
|
|
247
|
+
* Arma el árbol de montones a partir de las filas que hay EN LA MANO.
|
|
248
|
+
*
|
|
249
|
+
* Sirve cuando el conjunto entero está en el navegador. Cuando no lo está —un
|
|
250
|
+
* catálogo de ciento ochenta y siete del que se bajaron doce—, los montones los
|
|
251
|
+
* cuenta quien los guarda y esto no se usa: la presentación recibe `piles` ya
|
|
252
|
+
* hechos. Las dos formas dibujan igual porque dibujan el mismo tipo.
|
|
253
|
+
*
|
|
254
|
+
* El orden de los montones es el de PRIMERA APARICIÓN de cada valor, en cada
|
|
255
|
+
* nivel. No se ordena alfabéticamente: el orden de las filas ya lo decidió
|
|
256
|
+
* alguien —una columna, un criterio, el motor— y reordenar los montones acá lo
|
|
257
|
+
* contradiría.
|
|
258
|
+
*/
|
|
259
|
+
export declare function pilesFrom<T>(items: readonly T[], levels: readonly GroupLevel[], of: PileOf<T>, label?: PileLabelOf): readonly Pile<T>[];
|
|
260
|
+
/**
|
|
261
|
+
* La ruta de UNA fila: el montón que le toca en cada nivel.
|
|
262
|
+
*
|
|
263
|
+
* Es la identidad del montón más profundo que la contiene, sin armar el árbol.
|
|
264
|
+
* Sirve para preguntar «¿estas dos filas son vecinas?», que con un solo nivel se
|
|
265
|
+
* contestaba comparando una clave y con N hay que comparar la ruta entera: dos
|
|
266
|
+
* datasets del mismo mes son vecinos sólo si además comparten la procedencia,
|
|
267
|
+
* porque si no están en montones distintos aunque el último tramo coincida.
|
|
268
|
+
*/
|
|
269
|
+
export declare function itemPath<T>(item: T, levels: readonly GroupLevel[], of: PileOf<T>): string[];
|
|
270
|
+
/** Las filas de un árbol, en el orden en que se dibujan. Lo usan las
|
|
271
|
+
* presentaciones que necesitan la secuencia y no el árbol —la planilla
|
|
272
|
+
* virtualizada, que cuenta índices— y el que quiera saber qué quedó visible. */
|
|
273
|
+
export declare function pileItems<T>(piles: readonly Pile<T>[]): readonly T[];
|
|
274
|
+
/** Cuántas filas hay en total. Suma los conteos del primer nivel, que ya
|
|
275
|
+
* incluyen los de abajo — no recorre las filas, porque puede no tenerlas. */
|
|
276
|
+
export declare function pileCount<T>(piles: readonly Pile<T>[]): number;
|
|
277
|
+
/** Mueve un nivel `delta` lugares. Se queda en los bordes en vez de dar la
|
|
278
|
+
* vuelta: llegar al primero y volver al último no es lo que nadie espera de una
|
|
279
|
+
* flecha «subir». El orden de los niveles ES la jerarquía, así que esto cambia
|
|
280
|
+
* la pregunta y no sólo la lista. */
|
|
281
|
+
export declare function moveLevel(levels: readonly GroupLevel[], field: string, delta: number): GroupLevel[];
|
|
Binary file
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export { currentCopy, currentCopyLocale, ENGLISH_COPY, fillCopy, installCopy, mergeCopy, type UiCopy, type UiCopyOverride, UiCopyProvider, useUiCopy, } from "./copy.js";
|
|
2
|
+
export { byDensity, type Density, DensityProvider, useDensity, } from "./density.js";
|
|
3
|
+
export { bySurface, SurfaceProvider, useSurface } from "./surface.js";
|
|
4
|
+
export { applyTheme, isTheme, type ResolvedTheme, resolveTheme, type Theme, THEME_ATTRIBUTE, ThemeProvider, type ThemeProviderProps, THEMES, useTheme, } from "./theme.js";
|
|
5
|
+
export type { Size, Surface, Tone } from "./types.js";
|
|
6
|
+
/** El castellano del sistema, para quien lo quiera instalar entero. */
|
|
7
|
+
export { SPANISH_COPY } from "./copy.es.js";
|
|
8
|
+
export { flatten, loose, pick, pickAll, propsOf, slot, slotOf, type Slotted, } from "./slots.js";
|
|
9
|
+
export { dateKey, dateLabel, grainName, monthName, } from "./calendar.js";
|
|
10
|
+
export { GRAIN_ORDER, type GroupableField, type GroupGrain, type Grouping, type GroupLevel, itemPath, levelKey, moveLevel, normalizeLevels, pathKey, pathLabels, type Pile, pileCount, pileIsOpen, pileItems, pileLabel, type PileLabelOf, type PileOf, pilesFrom, pilesOf, } from "./grouping.js";
|
|
11
|
+
export { axisLabels, axisSpans, keyStarts, type Pivot, type PivotAxis, type PivotCell, type PivotCrossing, type PivotFold, pivotFrom, pivotIsEmpty, type PivotKey, type PivotLevel, type PivotMargin, type PivotMeasure, pivotOf, type PivotSource, type PivotSpec, } from "./pivot.js";
|
|
12
|
+
export { downloadPivot, pivotSheet, type PivotSheetOptions, pivotXlsx, } from "./pivotSheet.js";
|
|
13
|
+
export { STICKY_TOP, stickyReset, stickyTop, useScrollBox, useStickyLayer, } from "./sticky.js";
|
|
14
|
+
export { columnName, downloadXlsx, writeXlsx, type XlsxCell, type XlsxMerge, type XlsxSheet, } from "./xlsx.js";
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/* What is shared by more than one family and belongs to none of them. */
|
|
2
|
+
export { currentCopy, currentCopyLocale, ENGLISH_COPY, fillCopy, installCopy, mergeCopy, UiCopyProvider, useUiCopy, } from "./copy.js";
|
|
3
|
+
export { byDensity, DensityProvider, useDensity, } from "./density.js";
|
|
4
|
+
/* EL TEMA — claro, oscuro o el del sistema operativo. Las paletas viven en `tokens.css`; esto
|
|
5
|
+
sólo escribe `data-theme`. */
|
|
6
|
+
export { bySurface, SurfaceProvider, useSurface } from "./surface.js";
|
|
7
|
+
export { applyTheme, isTheme, resolveTheme, THEME_ATTRIBUTE, ThemeProvider, THEMES, useTheme, } from "./theme.js";
|
|
8
|
+
/** El castellano del sistema, para quien lo quiera instalar entero. */
|
|
9
|
+
export { SPANISH_COPY } from "./copy.es.js";
|
|
10
|
+
/* LAS RANURAS — cómo un arquetipo se escribe como ÁRBOL. Vive acá y no adentro
|
|
11
|
+
de uno porque lo hablan todos los que lo son: mientras estuvo escondido en
|
|
12
|
+
`Record.tsx`, ser un árbol era un privilegio de los registros. */
|
|
13
|
+
export { flatten, loose, pick, pickAll, propsOf, slot, slotOf, } from "./slots.js";
|
|
14
|
+
/* EL CALENDARIO — de una fecha a una clave y de una clave a un rótulo. Los meses
|
|
15
|
+
y los días de la semana los dice `Intl` con el `locale` de la copia; la semana
|
|
16
|
+
y el trimestre son las dos únicas palabras que hay que escribir. */
|
|
17
|
+
export { dateKey, dateLabel, grainName, monthName, } from "./calendar.js";
|
|
18
|
+
/* LA AGRUPACIÓN — el vocabulario, que hablan las dos capas: la lista arma el
|
|
19
|
+
árbol de montones y la tabla lo dibuja. Vive acá y no en `contexts/list`
|
|
20
|
+
porque una primitiva no puede importar de un contexto. */
|
|
21
|
+
export { GRAIN_ORDER, itemPath, levelKey, moveLevel, normalizeLevels, pathKey, pathLabels, pileCount, pileIsOpen, pileItems, pileLabel, pilesFrom, pilesOf, } from "./grouping.js";
|
|
22
|
+
/* EL PIVOTE — el mismo reparto: el vocabulario acá, la grilla en `primitives`.
|
|
23
|
+
Que los márgenes vengan de la base y que un agujero no sea un cero son reglas
|
|
24
|
+
del CONTRATO, no del dibujo, y por eso viven de este lado. */
|
|
25
|
+
export { axisLabels, axisSpans, keyStarts, pivotFrom, pivotIsEmpty, pivotOf, } from "./pivot.js";
|
|
26
|
+
/* LA PLANILLA: la misma grilla, en un archivo. El escritor es genérico y no
|
|
27
|
+
sabe de pivotes; `pivotSheet` es el que traduce uno. */
|
|
28
|
+
export { downloadPivot, pivotSheet, pivotXlsx, } from "./pivotSheet.js";
|
|
29
|
+
export { STICKY_TOP, stickyReset, stickyTop, useScrollBox, useStickyLayer, } from "./sticky.js";
|
|
30
|
+
export { columnName, downloadXlsx, writeXlsx, } from "./xlsx.js";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context: `--container-handheld` (40rem, `tokens.css`) in pixels. A container query cannot
|
|
3
|
+
* swap a `<table>` for a list, so the two components that must decide in code — `ListView`
|
|
4
|
+
* (which presentations to offer) and `EditableTable` (grid or stacked cards) — ask a
|
|
5
|
+
* `ResizeObserver` for pixels and compare against this one figure. It used to be written
|
|
6
|
+
* twice, `HANDHELD` in one and `NARROW_LIST` in the other, and the day one moved the two
|
|
7
|
+
* would have disagreed about what a phone is. Keep it equal to the token.
|
|
8
|
+
*/
|
|
9
|
+
export declare const HANDHELD_WIDTH = 640;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context: `--container-handheld` (40rem, `tokens.css`) in pixels. A container query cannot
|
|
3
|
+
* swap a `<table>` for a list, so the two components that must decide in code — `ListView`
|
|
4
|
+
* (which presentations to offer) and `EditableTable` (grid or stacked cards) — ask a
|
|
5
|
+
* `ResizeObserver` for pixels and compare against this one figure. It used to be written
|
|
6
|
+
* twice, `HANDHELD` in one and `NARROW_LIST` in the other, and the day one moved the two
|
|
7
|
+
* would have disagreed about what a phone is. Keep it equal to the token.
|
|
8
|
+
*/
|
|
9
|
+
export const HANDHELD_WIDTH = 640;
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import { type GroupLevel, type PileLabelOf, type PileOf } from "./grouping.js";
|
|
2
|
+
/**
|
|
3
|
+
* EL PIVOTE: montones cruzados por montones.
|
|
4
|
+
*
|
|
5
|
+
* Agrupar parte un conjunto por lo que sus filas comparten. Pivotear lo parte
|
|
6
|
+
* DOS VECES a la vez, por ejes distintos, y lee el número donde los dos cortes
|
|
7
|
+
* se encuentran: el cliente hacia abajo, el mes hacia la derecha, y en el
|
|
8
|
+
* cruce cuántas filas hay y cuánto suman.
|
|
9
|
+
*
|
|
10
|
+
* ── Tres reglas, y ninguna es cosmética ─────────────────────────────
|
|
11
|
+
*
|
|
12
|
+
* 1. **La grilla se dibuja desde los EJES, no desde los cruces.** `rows.keys` y
|
|
13
|
+
* `columns.keys` traen cada clave que apareció, en orden; los cruces se
|
|
14
|
+
* PREGUNTAN de a uno. Un pivote es mayormente agujeros —doce clientes
|
|
15
|
+
* por veinticuatro meses son 288 celdas y cuarenta con filas— y deducir la
|
|
16
|
+
* grilla recorriendo los cruces deja afuera el mes en que no pasó nada, que
|
|
17
|
+
* es justo la columna que alguien está buscando.
|
|
18
|
+
*
|
|
19
|
+
* 2. **Los márgenes vienen plegados de la BASE.** Un promedio de promedios no
|
|
20
|
+
* es un promedio y una mediana de medianas no es nada, así que `rowTotal`,
|
|
21
|
+
* `columnTotal` y `total` se reciben: esta capa nunca los inventa sumando la
|
|
22
|
+
* fila que acaba de dibujar. Sin ellos no hay banda de totales, que es la
|
|
23
|
+
* respuesta honesta cuando nadie los calculó.
|
|
24
|
+
*
|
|
25
|
+
* 3. **Un agujero no es un cero.** `undefined` es «ahí no hay ninguna fila» y
|
|
26
|
+
* `0` es «hay filas y suman cero». La grilla los dibuja distinto porque
|
|
27
|
+
* significan cosas distintas.
|
|
28
|
+
*
|
|
29
|
+
* ── Qué se PIDE y qué se DIBUJA ─────────────────────────────────────
|
|
30
|
+
*
|
|
31
|
+
* Igual que con los montones: `PivotSpec` es lo que alguien pidió —por qué
|
|
32
|
+
* campos partir cada eje, qué medidas plegar— y `Pivot` es lo que se dibuja, ya
|
|
33
|
+
* plegado. Están separados porque plegar no siempre lo hace esta máquina: un
|
|
34
|
+
* libro de ventas de ciento ochenta y siete del que se bajaron doce lo pliega quien lo
|
|
35
|
+
* guarda, y `pivotFrom` es un helper para cuando el conjunto entero está en el
|
|
36
|
+
* navegador, no el único camino.
|
|
37
|
+
*
|
|
38
|
+
* **Esto no conoce ningún motor.** Ni criteria, ni cursores, ni transporte: un
|
|
39
|
+
* eje acá es una lista de rutas legibles y un cruce es un conteo con números al
|
|
40
|
+
* lado. Quien traduzca la respuesta de un servidor a esta forma vive afuera, y
|
|
41
|
+
* por eso la misma grilla sirve para un pivote armado en el navegador y para uno
|
|
42
|
+
* plegado a mil kilómetros.
|
|
43
|
+
*/
|
|
44
|
+
/**
|
|
45
|
+
* La clave de una fila o de una columna: la RUTA por los niveles de su eje, ya
|
|
46
|
+
* legible.
|
|
47
|
+
*
|
|
48
|
+
* Es una ruta y no un valor por la misma razón que la de un montón: con dos
|
|
49
|
+
* niveles puestos, «2026-09» puede ser un mes adentro de «Ferretería Sur» y otro
|
|
50
|
+
* adentro de «Distribuidora Andina», y son dos filas distintas de la grilla.
|
|
51
|
+
*/
|
|
52
|
+
export type PivotKey = readonly string[];
|
|
53
|
+
/**
|
|
54
|
+
* UN NIVEL de un eje: por qué se partió, y cómo se lee.
|
|
55
|
+
*
|
|
56
|
+
* Lleva el nivel ENTERO y no sólo su rótulo porque el rótulo de un nivel no
|
|
57
|
+
* alcanza para leer sus claves: con «registrado» a la vista, «2026-09» sigue
|
|
58
|
+
* siendo «2026-09». El grano es lo que deja decir «Septiembre», y el campo es lo
|
|
59
|
+
* que deja saber que el mes cuelga del año de más arriba y entonces no hace
|
|
60
|
+
* falta repetirlo.
|
|
61
|
+
*/
|
|
62
|
+
export type PivotLevel = GroupLevel & {
|
|
63
|
+
/** Cómo se llama este corte: es lo que dice la esquina de la grilla. Sin él,
|
|
64
|
+
* una columna no aclara si es cuándo se registró o cuándo se corrió. */
|
|
65
|
+
label: string;
|
|
66
|
+
};
|
|
67
|
+
/** Un EJE del pivote: qué se preguntó, y qué claves aparecieron. */
|
|
68
|
+
export type PivotAxis = {
|
|
69
|
+
/** Los niveles, de afuera hacia adentro. */
|
|
70
|
+
levels: readonly PivotLevel[];
|
|
71
|
+
/** Cada clave que apareció, en orden. **La grilla se dibuja desde acá.** */
|
|
72
|
+
keys: readonly PivotKey[];
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* CÓMO SE LEE UNA CLAVE del eje, tramo por tramo.
|
|
76
|
+
*
|
|
77
|
+
* La clave identifica —«2026-09» es lo que el motor escribe y lo que se compara
|
|
78
|
+
* con lo que contó el servidor— y el rótulo se lee. Son dos textos, igual que en
|
|
79
|
+
* un montón, y por la misma razón: con el rótulo por identidad, dos septiembres
|
|
80
|
+
* de años distintos serían el mismo.
|
|
81
|
+
*
|
|
82
|
+
* `within` sale de los niveles de ARRIBA del mismo campo: con el año afuera, el
|
|
83
|
+
* mes se dice «Septiembre» y no «Septiembre de 2026», porque eso ya está escrito
|
|
84
|
+
* dos columnas antes.
|
|
85
|
+
*/
|
|
86
|
+
export declare function axisLabels(axis: PivotAxis, key: PivotKey, label?: PileLabelOf): readonly string[];
|
|
87
|
+
/** Una MEDIDA: uno de los números que se pliegan en cada cruce. */
|
|
88
|
+
export type PivotMeasure = {
|
|
89
|
+
id: string;
|
|
90
|
+
header: string;
|
|
91
|
+
/** Para un porcentaje o una variación, que no se leen como un importe. */
|
|
92
|
+
format?: (value: number) => string;
|
|
93
|
+
/**
|
|
94
|
+
* Cómo se lee la medida en una PLANILLA: el código de formato de Excel,
|
|
95
|
+
* `#,##0.00`, `0.0%`, `#,##0 "Bs."`.
|
|
96
|
+
*
|
|
97
|
+
* Va aparte de `format` porque son dos cosas distintas: `format` es una
|
|
98
|
+
* función de JavaScript, y un archivo no se puede llevar una función adentro.
|
|
99
|
+
* Sin esto el número sale con el formato general — sigue siendo un número y se
|
|
100
|
+
* sigue pudiendo sumar, que es lo que no se puede perder.
|
|
101
|
+
*/
|
|
102
|
+
numberFormat?: string;
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* Un CRUCE ya plegado: cuántas filas hay debajo y qué dan las medidas.
|
|
106
|
+
*
|
|
107
|
+
* `count` va aparte de las medidas y no como una más: es la única que siempre se
|
|
108
|
+
* puede contestar, y es la que dice si una celda vacía está vacía porque no hay
|
|
109
|
+
* filas o porque las que hay no tienen ese número.
|
|
110
|
+
*/
|
|
111
|
+
export type PivotCell = {
|
|
112
|
+
count: number;
|
|
113
|
+
/** Un número por medida, por id. `null` es «esta medida no se contesta acá» y
|
|
114
|
+
* es distinto de `0`. */
|
|
115
|
+
values: Readonly<Record<string, number | null>>;
|
|
116
|
+
};
|
|
117
|
+
/** EL PIVOTE, listo para dibujar. */
|
|
118
|
+
export type Pivot = {
|
|
119
|
+
rows: PivotAxis;
|
|
120
|
+
columns: PivotAxis;
|
|
121
|
+
measures: readonly PivotMeasure[];
|
|
122
|
+
/** El cruce donde una fila encuentra a una columna, o `undefined` cuando no
|
|
123
|
+
* hay ninguna fila ahí. Se pregunta y no se recorre: ver la regla 1. */
|
|
124
|
+
cell: (row: PivotKey, column: PivotKey) => PivotCell | undefined;
|
|
125
|
+
/** La fila entera, plegada de la base. Ausente = no hay banda de totales a la
|
|
126
|
+
* derecha, porque nadie los calculó y acá no se suman celdas. */
|
|
127
|
+
rowTotal?: (row: PivotKey) => PivotCell | undefined;
|
|
128
|
+
/** La columna entera, plegada de la base. */
|
|
129
|
+
columnTotal?: (column: PivotKey) => PivotCell | undefined;
|
|
130
|
+
/** Todo lo que entró, plegado una vez. */
|
|
131
|
+
total?: PivotCell;
|
|
132
|
+
};
|
|
133
|
+
/** Un cruce, con sus dos claves. Es la forma en que viaja una grilla dispersa:
|
|
134
|
+
* sólo los cruces que tienen filas. */
|
|
135
|
+
export type PivotCrossing = PivotCell & {
|
|
136
|
+
row: PivotKey;
|
|
137
|
+
column: PivotKey;
|
|
138
|
+
};
|
|
139
|
+
/** Un margen: la clave de su eje y lo que da esa fila —o esa columna— entera. */
|
|
140
|
+
export type PivotMargin = PivotCell & {
|
|
141
|
+
key: PivotKey;
|
|
142
|
+
};
|
|
143
|
+
export type PivotSource = {
|
|
144
|
+
rows: PivotAxis;
|
|
145
|
+
columns: PivotAxis;
|
|
146
|
+
measures: readonly PivotMeasure[];
|
|
147
|
+
/** Sólo los cruces con filas. Los que faltan son agujeros. */
|
|
148
|
+
crossings: readonly PivotCrossing[];
|
|
149
|
+
/** Uno por clave de fila. Sin esto no hay columna de totales. */
|
|
150
|
+
rowMargins?: readonly PivotMargin[];
|
|
151
|
+
/** Uno por clave de columna. Sin esto no hay fila de totales. */
|
|
152
|
+
columnMargins?: readonly PivotMargin[];
|
|
153
|
+
total?: PivotCell;
|
|
154
|
+
};
|
|
155
|
+
/**
|
|
156
|
+
* Indexa un pivote que ya viene plegado.
|
|
157
|
+
*
|
|
158
|
+
* Los cruces viajan como lista —es lo que sabe serializar cualquier transporte—
|
|
159
|
+
* y se dibujan preguntando de a uno, así que en el medio hace falta un índice.
|
|
160
|
+
* Se arma una vez acá y no en cada celda de cada render: una grilla de 288
|
|
161
|
+
* celdas buscando en una lista de 40 son 11.520 comparaciones por pintada.
|
|
162
|
+
*/
|
|
163
|
+
export declare function pivotOf(source: PivotSource): Pivot;
|
|
164
|
+
/** Una medida y cómo se pliega. El pliegue recibe las filas de la BASE —las del
|
|
165
|
+
* cruce, las de la fila entera, las de todo—, que es lo que hace que el margen
|
|
166
|
+
* salga del mismo lugar que la celda y no de sumar celdas. */
|
|
167
|
+
export type PivotFold<T> = PivotMeasure & {
|
|
168
|
+
fold: (items: readonly T[]) => number | null;
|
|
169
|
+
};
|
|
170
|
+
export type PivotSpec<T> = {
|
|
171
|
+
/** Los niveles del eje vertical, de afuera hacia adentro. */
|
|
172
|
+
rows: readonly GroupLevel[];
|
|
173
|
+
/** Los niveles del eje horizontal. */
|
|
174
|
+
columns: readonly GroupLevel[];
|
|
175
|
+
/** A qué montón va cada fila, en cada nivel de cada eje, ya legible. Es el
|
|
176
|
+
* mismo contrato que agrupa una lista: recortar una fecha a su grano es de
|
|
177
|
+
* quien conoce el dato. */
|
|
178
|
+
of: PileOf<T>;
|
|
179
|
+
measures: readonly PivotFold<T>[];
|
|
180
|
+
/** Cómo se llama cada nivel. Sin esto se muestra el nombre del campo. */
|
|
181
|
+
labelOf?: (level: GroupLevel) => string;
|
|
182
|
+
};
|
|
183
|
+
/**
|
|
184
|
+
* Arma el pivote con las filas que hay EN LA MANO.
|
|
185
|
+
*
|
|
186
|
+
* Sirve cuando el conjunto entero está en el navegador. Cuando no lo está, el
|
|
187
|
+
* pivote lo pliega quien guarda los datos y esto no se usa: la grilla recibe un
|
|
188
|
+
* `Pivot` de `pivotOf` y dibuja igual, porque dibuja el mismo tipo.
|
|
189
|
+
*
|
|
190
|
+
* **Los márgenes se pliegan sobre las filas de la base y no sobre los cruces**,
|
|
191
|
+
* que es la regla 2 escrita en código: el margen de «Ferretería Sur» pliega sus 187
|
|
192
|
+
* facturas de una, no los doce números mensuales que ya se dibujaron. Es
|
|
193
|
+
* lo único que hace que una medida que no sea una suma —un promedio, una
|
|
194
|
+
* mediana, un distintos— diga la verdad en el borde.
|
|
195
|
+
*/
|
|
196
|
+
export declare function pivotFrom<T>(items: readonly T[], spec: PivotSpec<T>): Pivot;
|
|
197
|
+
/** Si el pivote no tiene ni una fila que cruzar. Un eje vacío no es un pivote
|
|
198
|
+
* chico: es la vista vacía, y se dice con la frase del conjunto y no con una
|
|
199
|
+
* grilla de un renglón. */
|
|
200
|
+
export declare function pivotIsEmpty(pivot: Pivot): boolean;
|
|
201
|
+
/**
|
|
202
|
+
* Los tramos de una clave que hay que ESCRIBIR, comparada con la anterior.
|
|
203
|
+
*
|
|
204
|
+
* En el área de filas de un pivote, el valor de un nivel se escribe sólo cuando
|
|
205
|
+
* cambia: repetir «Ferretería Sur» en las doce filas de sus doce meses convierte la
|
|
206
|
+
* jerarquía en una columna de ruido y hace desaparecer justamente el corte que
|
|
207
|
+
* se pidió. Devuelve, por nivel, si ese tramo arranca acá.
|
|
208
|
+
*/
|
|
209
|
+
export declare function keyStarts(key: PivotKey, previous: PivotKey | undefined): readonly boolean[];
|
|
210
|
+
/**
|
|
211
|
+
* Cuánto abarca cada tramo del eje horizontal, nivel por nivel.
|
|
212
|
+
*
|
|
213
|
+
* El encabezado de un pivote es una jerarquía acostada: un renglón por nivel, y
|
|
214
|
+
* cada rótulo cubriendo las columnas que cuelgan de él. Esto lo resuelve una vez
|
|
215
|
+
* —de a tramos consecutivos iguales, que es lo que hace que «2026» cubra sus
|
|
216
|
+
* cuatro trimestres— y la grilla sólo lo dibuja.
|
|
217
|
+
*/
|
|
218
|
+
export declare function axisSpans(axis: PivotAxis, level: number): readonly {
|
|
219
|
+
label: string;
|
|
220
|
+
span: number;
|
|
221
|
+
at: number;
|
|
222
|
+
}[];
|