@d4gger/design-system 3.0.0 → 3.0.1
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/{components/controlGroup/ControlGroup.cjs → _internal/floatingLayer.cjs} +11 -26
- package/dist/_internal/floatingLayer.cjs.map +7 -0
- package/dist/_internal/floatingLayer.d.cts +28 -0
- package/dist/_internal/floatingLayer.d.cts.map +1 -0
- package/dist/_internal/floatingLayer.d.mts +28 -0
- package/dist/_internal/floatingLayer.d.mts.map +1 -0
- package/dist/_internal/floatingLayer.d.ts +28 -0
- package/dist/_internal/floatingLayer.d.ts.map +1 -0
- package/dist/_internal/floatingLayer.js +11 -0
- package/dist/_internal/floatingLayer.js.map +7 -0
- package/dist/components/banner/Banner.cjs +105 -0
- package/dist/components/banner/Banner.cjs.map +7 -0
- package/dist/components/banner/Banner.d.cts +27 -0
- package/dist/components/banner/Banner.d.cts.map +1 -0
- package/dist/components/banner/Banner.d.mts +27 -0
- package/dist/components/banner/Banner.d.mts.map +1 -0
- package/dist/components/banner/Banner.d.ts +27 -0
- package/dist/components/banner/Banner.d.ts.map +1 -0
- package/dist/components/banner/Banner.js +80 -0
- package/dist/components/banner/Banner.js.map +7 -0
- package/dist/components/{controlGroup/controlGroup.props.cjs → banner/banner.props.cjs} +23 -16
- package/dist/components/banner/banner.props.cjs.map +7 -0
- package/dist/components/banner/banner.props.d.cts +32 -0
- package/dist/components/banner/banner.props.d.cts.map +1 -0
- package/dist/components/banner/banner.props.d.mts +32 -0
- package/dist/components/banner/banner.props.d.mts.map +1 -0
- package/dist/components/banner/banner.props.d.ts +32 -0
- package/dist/components/banner/banner.props.d.ts.map +1 -0
- package/dist/components/banner/banner.props.js +27 -0
- package/dist/components/banner/banner.props.js.map +7 -0
- package/dist/components/banner.css +60 -0
- package/dist/components/button-group.css +25 -0
- package/dist/components/button.css +9 -0
- package/dist/components/card.css +3 -0
- package/dist/components/carousel/Carousel.cjs +109 -39
- package/dist/components/carousel/Carousel.cjs.map +3 -3
- package/dist/components/carousel/Carousel.d.cts.map +1 -1
- package/dist/components/carousel/Carousel.d.mts.map +1 -1
- package/dist/components/carousel/Carousel.d.ts.map +1 -1
- package/dist/components/carousel/Carousel.js +111 -41
- package/dist/components/carousel/Carousel.js.map +3 -3
- package/dist/components/carousel.css +93 -26
- package/dist/components/chart/Chart.cjs +61 -11
- package/dist/components/chart/Chart.cjs.map +2 -2
- package/dist/components/chart/Chart.d.cts.map +1 -1
- package/dist/components/chart/Chart.d.mts.map +1 -1
- package/dist/components/chart/Chart.d.ts.map +1 -1
- package/dist/components/chart/Chart.js +62 -11
- package/dist/components/chart/Chart.js.map +2 -2
- package/dist/components/chart.css +10 -1
- package/dist/components/checkbox.css +14 -0
- package/dist/components/combobox/Combobox.cjs +3 -1
- package/dist/components/combobox/Combobox.cjs.map +2 -2
- package/dist/components/combobox/Combobox.d.cts.map +1 -1
- package/dist/components/combobox/Combobox.d.mts.map +1 -1
- package/dist/components/combobox/Combobox.d.ts.map +1 -1
- package/dist/components/combobox/Combobox.js +3 -1
- package/dist/components/combobox/Combobox.js.map +2 -2
- package/dist/components/combobox.css +5 -1
- package/dist/components/command/Command.cjs +1 -1
- package/dist/components/command/Command.cjs.map +2 -2
- package/dist/components/command/Command.js +1 -1
- package/dist/components/command/Command.js.map +2 -2
- package/dist/components/context-menu.css +1 -1
- package/dist/components/copy-field.css +18 -0
- package/dist/components/copyField/CopyField.cjs +3 -3
- package/dist/components/copyField/CopyField.cjs.map +2 -2
- package/dist/components/copyField/CopyField.d.cts.map +1 -1
- package/dist/components/copyField/CopyField.d.mts.map +1 -1
- package/dist/components/copyField/CopyField.d.ts.map +1 -1
- package/dist/components/copyField/CopyField.js +3 -3
- package/dist/components/copyField/CopyField.js.map +2 -2
- package/dist/components/data-list.css +19 -4
- package/dist/components/data-table.css +190 -0
- package/dist/components/dataTable/DataTable.cjs +193 -68
- package/dist/components/dataTable/DataTable.cjs.map +3 -3
- package/dist/components/dataTable/DataTable.d.cts +29 -1
- package/dist/components/dataTable/DataTable.d.cts.map +1 -1
- package/dist/components/dataTable/DataTable.d.mts +29 -1
- package/dist/components/dataTable/DataTable.d.mts.map +1 -1
- package/dist/components/dataTable/DataTable.d.ts +29 -1
- package/dist/components/dataTable/DataTable.d.ts.map +1 -1
- package/dist/components/dataTable/DataTable.js +193 -68
- package/dist/components/dataTable/DataTable.js.map +2 -2
- package/dist/components/dataTable/DataTableContext.cjs +41 -0
- package/dist/components/dataTable/DataTableContext.cjs.map +7 -0
- package/dist/components/dataTable/DataTableContext.d.cts +23 -0
- package/dist/components/dataTable/DataTableContext.d.cts.map +1 -0
- package/dist/components/dataTable/DataTableContext.d.mts +23 -0
- package/dist/components/dataTable/DataTableContext.d.mts.map +1 -0
- package/dist/components/dataTable/DataTableContext.d.ts +23 -0
- package/dist/components/dataTable/DataTableContext.d.ts.map +1 -0
- package/dist/components/dataTable/DataTableContext.js +11 -0
- package/dist/components/dataTable/DataTableContext.js.map +7 -0
- package/dist/components/dataTable/DataTablePagination.cjs +72 -47
- package/dist/components/dataTable/DataTablePagination.cjs.map +2 -2
- package/dist/components/dataTable/DataTablePagination.d.cts +5 -1
- package/dist/components/dataTable/DataTablePagination.d.cts.map +1 -1
- package/dist/components/dataTable/DataTablePagination.d.mts +5 -1
- package/dist/components/dataTable/DataTablePagination.d.mts.map +1 -1
- package/dist/components/dataTable/DataTablePagination.d.ts +5 -1
- package/dist/components/dataTable/DataTablePagination.d.ts.map +1 -1
- package/dist/components/dataTable/DataTablePagination.js +75 -47
- package/dist/components/dataTable/DataTablePagination.js.map +2 -2
- package/dist/components/dataTable/DataTableToolbar.cjs +122 -93
- package/dist/components/dataTable/DataTableToolbar.cjs.map +2 -2
- package/dist/components/dataTable/DataTableToolbar.d.cts +6 -5
- package/dist/components/dataTable/DataTableToolbar.d.cts.map +1 -1
- package/dist/components/dataTable/DataTableToolbar.d.mts +6 -5
- package/dist/components/dataTable/DataTableToolbar.d.mts.map +1 -1
- package/dist/components/dataTable/DataTableToolbar.d.ts +6 -5
- package/dist/components/dataTable/DataTableToolbar.d.ts.map +1 -1
- package/dist/components/dataTable/DataTableToolbar.js +123 -94
- package/dist/components/dataTable/DataTableToolbar.js.map +2 -2
- package/dist/components/dataTable/dataTable.export.cjs +83 -0
- package/dist/components/dataTable/dataTable.export.cjs.map +7 -0
- package/dist/components/dataTable/dataTable.export.d.cts +11 -0
- package/dist/components/dataTable/dataTable.export.d.cts.map +1 -0
- package/dist/components/dataTable/dataTable.export.d.mts +11 -0
- package/dist/components/dataTable/dataTable.export.d.mts.map +1 -0
- package/dist/components/dataTable/dataTable.export.d.ts +11 -0
- package/dist/components/dataTable/dataTable.export.d.ts.map +1 -0
- package/dist/components/dataTable/dataTable.export.js +63 -0
- package/dist/components/dataTable/dataTable.export.js.map +7 -0
- package/dist/components/dataTable/dataTable.props.cjs +23 -1
- package/dist/components/dataTable/dataTable.props.cjs.map +2 -2
- package/dist/components/dataTable/dataTable.props.d.cts +21 -1
- package/dist/components/dataTable/dataTable.props.d.cts.map +1 -1
- package/dist/components/dataTable/dataTable.props.d.mts +21 -1
- package/dist/components/dataTable/dataTable.props.d.mts.map +1 -1
- package/dist/components/dataTable/dataTable.props.d.ts +21 -1
- package/dist/components/dataTable/dataTable.props.d.ts.map +1 -1
- package/dist/components/dataTable/dataTable.props.js +23 -1
- package/dist/components/dataTable/dataTable.props.js.map +2 -2
- package/dist/components/dialog/Dialog.cjs +2 -1
- package/dist/components/dialog/Dialog.cjs.map +2 -2
- package/dist/components/dialog/Dialog.d.cts.map +1 -1
- package/dist/components/dialog/Dialog.d.mts.map +1 -1
- package/dist/components/dialog/Dialog.d.ts.map +1 -1
- package/dist/components/dialog/Dialog.js +2 -1
- package/dist/components/dialog/Dialog.js.map +2 -2
- package/dist/components/dropdown-menu.css +1 -1
- package/dist/components/empty-state.css +5 -0
- package/dist/components/fileUpload/FileUpload.cjs +10 -1
- package/dist/components/fileUpload/FileUpload.cjs.map +2 -2
- package/dist/components/fileUpload/FileUpload.d.cts +1 -0
- package/dist/components/fileUpload/FileUpload.d.cts.map +1 -1
- package/dist/components/fileUpload/FileUpload.d.mts +1 -0
- package/dist/components/fileUpload/FileUpload.d.mts.map +1 -1
- package/dist/components/fileUpload/FileUpload.d.ts +1 -0
- package/dist/components/fileUpload/FileUpload.d.ts.map +1 -1
- package/dist/components/fileUpload/FileUpload.js +10 -1
- package/dist/components/fileUpload/FileUpload.js.map +2 -2
- package/dist/components/filter-bar.css +380 -8
- package/dist/components/filterBar/FilterBar.cjs +630 -1
- package/dist/components/filterBar/FilterBar.cjs.map +2 -2
- package/dist/components/filterBar/FilterBar.d.cts +132 -2
- package/dist/components/filterBar/FilterBar.d.cts.map +1 -1
- package/dist/components/filterBar/FilterBar.d.mts +132 -2
- package/dist/components/filterBar/FilterBar.d.mts.map +1 -1
- package/dist/components/filterBar/FilterBar.d.ts +132 -2
- package/dist/components/filterBar/FilterBar.d.ts.map +1 -1
- package/dist/components/filterBar/FilterBar.js +631 -2
- package/dist/components/filterBar/FilterBar.js.map +2 -2
- package/dist/components/floating-panel.css +1 -1
- package/dist/components/fontProvider/FontProvider.cjs +1 -1
- package/dist/components/fontProvider/FontProvider.cjs.map +1 -1
- package/dist/components/fontProvider/FontProvider.js +1 -1
- package/dist/components/fontProvider/FontProvider.js.map +1 -1
- package/dist/components/icon/Icon.cjs +25 -2
- package/dist/components/icon/Icon.cjs.map +2 -2
- package/dist/components/icon/Icon.d.cts +29 -1
- package/dist/components/icon/Icon.d.cts.map +1 -1
- package/dist/components/icon/Icon.d.mts +29 -1
- package/dist/components/icon/Icon.d.mts.map +1 -1
- package/dist/components/icon/Icon.d.ts +29 -1
- package/dist/components/icon/Icon.d.ts.map +1 -1
- package/dist/components/icon/Icon.js +33 -2
- package/dist/components/icon/Icon.js.map +2 -2
- package/dist/components/icon/icons.cjs +16 -0
- package/dist/components/icon/icons.cjs.map +2 -2
- package/dist/components/icon/icons.d.cts +40 -0
- package/dist/components/icon/icons.d.cts.map +1 -1
- package/dist/components/icon/icons.d.mts +40 -0
- package/dist/components/icon/icons.d.mts.map +1 -1
- package/dist/components/icon/icons.d.ts +40 -0
- package/dist/components/icon/icons.d.ts.map +1 -1
- package/dist/components/icon/icons.js +16 -0
- package/dist/components/icon/icons.js.map +2 -2
- package/dist/components/icon-button.css +29 -0
- package/dist/components/index.cjs +1 -1
- package/dist/components/index.cjs.map +2 -2
- package/dist/components/index.d.cts +1 -1
- package/dist/components/index.d.cts.map +1 -1
- package/dist/components/index.d.mts +1 -1
- package/dist/components/index.d.mts.map +1 -1
- package/dist/components/index.d.ts +1 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +1 -1
- package/dist/components/index.js.map +1 -1
- package/dist/components/item/Item.cjs +1 -1
- package/dist/components/item/Item.cjs.map +2 -2
- package/dist/components/item/Item.js +1 -1
- package/dist/components/item/Item.js.map +2 -2
- package/dist/components/item.css +12 -1
- package/dist/components/marquee/Marquee.cjs +1 -1
- package/dist/components/marquee/Marquee.cjs.map +2 -2
- package/dist/components/marquee/Marquee.js +1 -1
- package/dist/components/marquee/Marquee.js.map +2 -2
- package/dist/components/marquee.css +6 -0
- package/dist/components/menu/Menu.cjs +3 -1
- package/dist/components/menu/Menu.cjs.map +2 -2
- package/dist/components/menu/Menu.d.cts.map +1 -1
- package/dist/components/menu/Menu.d.mts.map +1 -1
- package/dist/components/menu/Menu.d.ts.map +1 -1
- package/dist/components/menu/Menu.js +3 -1
- package/dist/components/menu/Menu.js.map +2 -2
- package/dist/components/menubar.css +1 -1
- package/dist/components/metric.css +5 -0
- package/dist/components/pagination/Pagination.cjs +143 -17
- package/dist/components/pagination/Pagination.cjs.map +2 -2
- package/dist/components/pagination/Pagination.d.cts +64 -4
- package/dist/components/pagination/Pagination.d.cts.map +1 -1
- package/dist/components/pagination/Pagination.d.mts +64 -4
- package/dist/components/pagination/Pagination.d.mts.map +1 -1
- package/dist/components/pagination/Pagination.d.ts +64 -4
- package/dist/components/pagination/Pagination.d.ts.map +1 -1
- package/dist/components/pagination/Pagination.js +143 -17
- package/dist/components/pagination/Pagination.js.map +2 -2
- package/dist/components/pagination.css +50 -8
- package/dist/components/phoneInput/PhoneInput.cjs +18 -13
- package/dist/components/phoneInput/PhoneInput.cjs.map +2 -2
- package/dist/components/phoneInput/PhoneInput.d.cts.map +1 -1
- package/dist/components/phoneInput/PhoneInput.d.mts.map +1 -1
- package/dist/components/phoneInput/PhoneInput.d.ts.map +1 -1
- package/dist/components/phoneInput/PhoneInput.js +19 -14
- package/dist/components/phoneInput/PhoneInput.js.map +2 -2
- package/dist/components/popover/Popover.cjs +2 -1
- package/dist/components/popover/Popover.cjs.map +2 -2
- package/dist/components/popover/Popover.d.cts.map +1 -1
- package/dist/components/popover/Popover.d.mts.map +1 -1
- package/dist/components/popover/Popover.d.ts.map +1 -1
- package/dist/components/popover/Popover.js +2 -1
- package/dist/components/popover/Popover.js.map +2 -2
- package/dist/components/prose.css +1 -1
- package/dist/components/qr-code.css +5 -15
- package/dist/components/radio-group.css +19 -0
- package/dist/components/radioGroup/RadioGroup.cjs +3 -2
- package/dist/components/radioGroup/RadioGroup.cjs.map +2 -2
- package/dist/components/radioGroup/RadioGroup.d.cts.map +1 -1
- package/dist/components/radioGroup/RadioGroup.d.mts.map +1 -1
- package/dist/components/radioGroup/RadioGroup.d.ts.map +1 -1
- package/dist/components/radioGroup/RadioGroup.js +3 -2
- package/dist/components/radioGroup/RadioGroup.js.map +2 -2
- package/dist/components/radioGroup/radioGroup.props.cjs +1 -1
- package/dist/components/radioGroup/radioGroup.props.cjs.map +2 -2
- package/dist/components/radioGroup/radioGroup.props.d.cts +1 -1
- package/dist/components/radioGroup/radioGroup.props.d.mts +1 -1
- package/dist/components/radioGroup/radioGroup.props.d.ts +1 -1
- package/dist/components/radioGroup/radioGroup.props.js +1 -1
- package/dist/components/radioGroup/radioGroup.props.js.map +2 -2
- package/dist/components/rating.css +12 -0
- package/dist/components/result.css +2 -1
- package/dist/components/richTextEditor/RichTextEditor.cjs +11 -3
- package/dist/components/richTextEditor/RichTextEditor.cjs.map +2 -2
- package/dist/components/richTextEditor/RichTextEditor.d.cts.map +1 -1
- package/dist/components/richTextEditor/RichTextEditor.d.mts.map +1 -1
- package/dist/components/richTextEditor/RichTextEditor.d.ts.map +1 -1
- package/dist/components/richTextEditor/RichTextEditor.js +11 -3
- package/dist/components/richTextEditor/RichTextEditor.js.map +2 -2
- package/dist/components/segmented-control.css +80 -4
- package/dist/components/segmentedControl/SegmentedControl.cjs +18 -5
- package/dist/components/segmentedControl/SegmentedControl.cjs.map +2 -2
- package/dist/components/segmentedControl/SegmentedControl.d.cts.map +1 -1
- package/dist/components/segmentedControl/SegmentedControl.d.mts.map +1 -1
- package/dist/components/segmentedControl/SegmentedControl.d.ts.map +1 -1
- package/dist/components/segmentedControl/SegmentedControl.js +18 -5
- package/dist/components/segmentedControl/SegmentedControl.js.map +2 -2
- package/dist/components/segmentedControl/segmentedControl.props.cjs +10 -0
- package/dist/components/segmentedControl/segmentedControl.props.cjs.map +2 -2
- package/dist/components/segmentedControl/segmentedControl.props.d.cts +9 -0
- package/dist/components/segmentedControl/segmentedControl.props.d.cts.map +1 -1
- package/dist/components/segmentedControl/segmentedControl.props.d.mts +9 -0
- package/dist/components/segmentedControl/segmentedControl.props.d.mts.map +1 -1
- package/dist/components/segmentedControl/segmentedControl.props.d.ts +9 -0
- package/dist/components/segmentedControl/segmentedControl.props.d.ts.map +1 -1
- package/dist/components/segmentedControl/segmentedControl.props.js +10 -0
- package/dist/components/segmentedControl/segmentedControl.props.js.map +2 -2
- package/dist/components/select/Select.cjs +3 -1
- package/dist/components/select/Select.cjs.map +2 -2
- package/dist/components/select/Select.d.cts.map +1 -1
- package/dist/components/select/Select.d.mts.map +1 -1
- package/dist/components/select/Select.d.ts.map +1 -1
- package/dist/components/select/Select.js +3 -1
- package/dist/components/select/Select.js.map +2 -2
- package/dist/components/select.css +1 -1
- package/dist/components/sonner.css +1 -1
- package/dist/components/sortableList/SortableList.cjs +8 -2
- package/dist/components/sortableList/SortableList.cjs.map +2 -2
- package/dist/components/sortableList/SortableList.d.cts.map +1 -1
- package/dist/components/sortableList/SortableList.d.mts.map +1 -1
- package/dist/components/sortableList/SortableList.d.ts.map +1 -1
- package/dist/components/sortableList/SortableList.js +8 -2
- package/dist/components/sortableList/SortableList.js.map +2 -2
- package/dist/components/stat-card.css +2 -0
- package/dist/components/table/Table.cjs +3 -2
- package/dist/components/table/Table.cjs.map +2 -2
- package/dist/components/table/Table.d.cts.map +1 -1
- package/dist/components/table/Table.d.mts.map +1 -1
- package/dist/components/table/Table.d.ts.map +1 -1
- package/dist/components/table/Table.js +3 -2
- package/dist/components/table/Table.js.map +2 -2
- package/dist/components/table/table.props.cjs +6 -0
- package/dist/components/table/table.props.cjs.map +2 -2
- package/dist/components/table/table.props.d.cts +5 -0
- package/dist/components/table/table.props.d.cts.map +1 -1
- package/dist/components/table/table.props.d.mts +5 -0
- package/dist/components/table/table.props.d.mts.map +1 -1
- package/dist/components/table/table.props.d.ts +5 -0
- package/dist/components/table/table.props.d.ts.map +1 -1
- package/dist/components/table/table.props.js +6 -0
- package/dist/components/table/table.props.js.map +2 -2
- package/dist/components/table.css +20 -13
- package/dist/components/tabs.css +10 -0
- package/dist/components/timeline.css +54 -18
- package/dist/components/toast.css +33 -1
- package/dist/components/toggle-group.css +5 -0
- package/dist/components.css +1 -2
- package/dist/docs/README.md +1 -1
- package/dist/docs/component-contract.md +4 -4
- package/dist/docs/component-index.json +9 -9
- package/dist/docs/components/banner.md +152 -0
- package/dist/docs/components/button-group.md +4 -3
- package/dist/docs/components/button.md +2 -2
- package/dist/docs/components/card.md +1 -0
- package/dist/docs/components/carousel.md +55 -32
- package/dist/docs/components/chart.md +25 -7
- package/dist/docs/components/checkbox.md +4 -0
- package/dist/docs/components/combobox.md +3 -1
- package/dist/docs/components/command.md +2 -2
- package/dist/docs/components/copy-field.md +2 -2
- package/dist/docs/components/data-list.md +15 -3
- package/dist/docs/components/data-table.md +98 -17
- package/dist/docs/components/dialog.md +4 -0
- package/dist/docs/components/dropdown-menu.md +2 -1
- package/dist/docs/components/empty-state.md +3 -1
- package/dist/docs/components/file-upload.md +1 -0
- package/dist/docs/components/filter-bar.md +193 -8
- package/dist/docs/components/floating-panel.md +8 -8
- package/dist/docs/components/icon-button.md +4 -1
- package/dist/docs/components/item.md +18 -13
- package/dist/docs/components/marquee.md +2 -2
- package/dist/docs/components/menu.md +4 -1
- package/dist/docs/components/metric.md +4 -1
- package/dist/docs/components/pagination.md +88 -17
- package/dist/docs/components/pills.md +1 -1
- package/dist/docs/components/popover.md +2 -0
- package/dist/docs/components/prose.md +5 -1
- package/dist/docs/components/qr-code.md +14 -13
- package/dist/docs/components/radio-group.md +5 -2
- package/dist/docs/components/rating.md +2 -0
- package/dist/docs/components/result.md +6 -0
- package/dist/docs/components/segmented-control.md +7 -2
- package/dist/docs/components/select.md +3 -2
- package/dist/docs/components/sidebar.md +3 -1
- package/dist/docs/components/sonner.md +1 -1
- package/dist/docs/components/sortable-list.md +2 -0
- package/dist/docs/components/stat-card.md +5 -4
- package/dist/docs/components/stepper.md +1 -0
- package/dist/docs/components/table.md +14 -5
- package/dist/docs/components/tag.md +4 -2
- package/dist/docs/components/timeline.md +9 -5
- package/dist/docs/components/toast.md +1 -1
- package/dist/docs/components/toggle-group.md +2 -1
- package/dist/fonts.css +1 -1
- package/dist/generated/tokens.cjs +1 -1
- package/dist/generated/tokens.cjs.map +1 -1
- package/dist/generated/tokens.js +1 -1
- package/dist/generated/tokens.js.map +1 -1
- package/dist/motion.css +18 -3
- package/dist/styles.css +1249 -292
- package/dist/tokens.css +21 -15
- package/package.json +1 -1
- package/dist/components/control-group.css +0 -142
- package/dist/components/controlGroup/ControlGroup.cjs.map +0 -7
- package/dist/components/controlGroup/ControlGroup.d.cts +0 -16
- package/dist/components/controlGroup/ControlGroup.d.cts.map +0 -1
- package/dist/components/controlGroup/ControlGroup.d.mts +0 -16
- package/dist/components/controlGroup/ControlGroup.d.mts.map +0 -1
- package/dist/components/controlGroup/ControlGroup.d.ts +0 -16
- package/dist/components/controlGroup/ControlGroup.d.ts.map +0 -1
- package/dist/components/controlGroup/ControlGroup.js +0 -26
- package/dist/components/controlGroup/ControlGroup.js.map +0 -7
- package/dist/components/controlGroup/controlGroup.props.cjs.map +0 -7
- package/dist/components/controlGroup/controlGroup.props.d.cts +0 -18
- package/dist/components/controlGroup/controlGroup.props.d.cts.map +0 -1
- package/dist/components/controlGroup/controlGroup.props.d.mts +0 -18
- package/dist/components/controlGroup/controlGroup.props.d.mts.map +0 -1
- package/dist/components/controlGroup/controlGroup.props.d.ts +0 -18
- package/dist/components/controlGroup/controlGroup.props.d.ts.map +0 -1
- package/dist/components/controlGroup/controlGroup.props.js +0 -20
- package/dist/components/controlGroup/controlGroup.props.js.map +0 -7
- package/dist/docs/components/control-group.md +0 -261
|
@@ -7,22 +7,33 @@ depends_on:
|
|
|
7
7
|
- Table
|
|
8
8
|
- Pagination
|
|
9
9
|
- Toolbar
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
10
|
+
- Input
|
|
11
|
+
- Checkbox
|
|
12
|
+
- Button
|
|
13
|
+
- Badge
|
|
14
|
+
- DropdownMenu
|
|
15
|
+
- Result
|
|
13
16
|
---
|
|
14
17
|
|
|
15
18
|
# DataTable
|
|
16
19
|
|
|
20
|
+
Pagination's page-size label and select wrap together inside their group when the available container is narrow. The full mode continues to expose both; `dense` remains an explicit consumer choice.
|
|
21
|
+
|
|
22
|
+
Sorting buttons retain their visible header geometry and extend the pointer target to at least 24px through an invisible hit layer inside the padded header cell.
|
|
23
|
+
|
|
17
24
|
> Consumer note: this document describes public intent and contracts; the package TypeScript declarations are the exact API.
|
|
18
25
|
|
|
19
26
|
## Purpose
|
|
20
27
|
|
|
21
|
-
|
|
28
|
+
Turnkey data-workspace shell with query tools, sortable and selectable tabular payload, contextual row actions, and pagination. The design system owns the coherent three-zone composition and controlled client state. The app owns data fetching, domain actions, permissions, and the `PaginatedResponse` contract.
|
|
29
|
+
|
|
30
|
+
**Relationship:** `Table` is the primitive (semantic rows and cells, own density/typography); `DataTable` is the shell over `Table` (`DataTable.tsx` renders `<Table>` and adds toolbar, selection, pagination, and state). Use `Table` for plain data presentation; reach for `DataTable` when sort, filter, density toggling, or pagination is required. See `table.md` for the primitive's ownership statement.
|
|
22
31
|
|
|
23
32
|
## 2.6 contract
|
|
24
33
|
|
|
25
|
-
This section supersedes narrower 2.5 notes below. Columns additionally accept fixed or `{ min, max }` fluid `width`, `align`, `numeric`, `sortable`, `truncate`, and canonical `hideBelow` breakpoints. At most one column may truncate. `sortBy`, `sortOrder`, and `onSortChange`
|
|
34
|
+
This section supersedes narrower 2.5 notes below. Columns additionally accept fixed or `{ min, max }` fluid `width`, `align`, `numeric`, `sortable`, `truncate`, and canonical `hideBelow` breakpoints. At most one column may truncate. Uncontrolled sorting cycles unsorted → ascending → descending → unsorted. Additive `sorting` / `defaultSorting` / `onSortingChange` provide nullable tri-state control; legacy `sortBy`, `sortOrder`, and `onSortChange` retain their two-state controlled contract. `stickyHeader`, controlled/uncontrolled selected row IDs, `onSelectedRowIdsChange`, and `selectionMode="multiple" | "none"` are supported; multiple selection remains the compatibility default.
|
|
35
|
+
|
|
36
|
+
The default toolbar is composed from the public `DataTable.Toolbar` slots. Inside the nearest DataTable, zero-prop Search, ColumnVisibility, Export, and RowCount slots bind to table state; their existing explicit props remain valid for standalone use. Query, faceted-filter, and tri-state sort changes reset page to 1 and clear selection by default; `resetPageOnViewChange={false}` and `clearSelectionOnViewChange={false}` opt out independently.
|
|
26
37
|
|
|
27
38
|
`listState="loading" | "empty" | "no-results" | "error"` renders the canonical Result path, or `result` supplies custom content. Fixed columns retain width while the lone truncating fluid column absorbs overflow. Apps continue to own fetching and server query execution; the component emits state changes only.
|
|
28
39
|
|
|
@@ -38,20 +49,36 @@ This section supersedes narrower 2.5 notes below. Columns additionally accept fi
|
|
|
38
49
|
| `DataTable.Toolbar` | `<div>` | `DataTableToolbar` with class | Toolbar container for search, column visibility, export, and row count controls. |
|
|
39
50
|
| `DataTable.Toolbar.Search` | `<Input>` | Search input | Text search input with `type="search"`. Filters rows client-side. |
|
|
40
51
|
| `DataTable.Toolbar.ColumnVisibility` | `<DropdownMenu>` | Column toggle dropdown | Dropdown with checkbox items for toggling column visibility. |
|
|
41
|
-
| `DataTable.Toolbar.Export` | `<DropdownMenu>` | Export dropdown | Dropdown with CSV and JSON export options. |
|
|
52
|
+
| `DataTable.Toolbar.Export` | `<DropdownMenu>` | Export dropdown | Dropdown with CSV and JSON export options. Menu items state what they export (`CSV file · N rows`, filtered or standalone count); exports over 1000 rows build in chunks with a determinate `Exporting N%` trigger state and polite live announcements instead of a silent freeze. |
|
|
42
53
|
| `DataTable.Toolbar.RowCount` | `<div>` | Row count display | Displays total, filtered, and selected row counts. |
|
|
43
54
|
| `DataTable.Pagination` | `<div>` | `DataTablePagination` with class | Pagination controls with page size selector and page navigation. |
|
|
44
55
|
| `DataTable.FacetedFilter` | `<div>` | `DataTableFacetedFilter` with class | Faceted filter dropdown with checkbox list and search. |
|
|
56
|
+
| `DataTable.BulkBar` | `<div>` | Contextual selection action group | Renders as a second row beneath the query toolbar while rows are selected — the toolbar stays mounted and interactive so filters are never lost. Shows the `{count} selected` status, the `bulkActions` slot, and a built-in Deselect all button. |
|
|
45
57
|
|
|
46
58
|
The root `DataTable` component is a flat export, not a compound. Subcomponents are attached as static properties: `DataTable.Toolbar`, `DataTable.Pagination`, `DataTable.FacetedFilter`.
|
|
47
59
|
|
|
60
|
+
## Bulk action guidance
|
|
61
|
+
|
|
62
|
+
The selection bar answers two questions: how many, and what can I do.
|
|
63
|
+
|
|
64
|
+
- Count: the `{count} selected` pill is rendered by the shell; the toolbar `RowCount` additionally badges the selected count while unselected. No consumer counting needed.
|
|
65
|
+
- Actions: pass domain actions through `bulkActions` in runway order — Export selected, mutating actions (Assign, Archive), destructive Delete selected last. Deselect all is built-in and always trailing.
|
|
66
|
+
- Scope: bulk actions operate on all selected row IDs across pages, not just the visible page. The demo Delete/export handlers must say so in their notices.
|
|
67
|
+
- Empty selection dissolves the bar; the query toolbar underneath was never unmounted.
|
|
68
|
+
|
|
69
|
+
## Composition recipes (app-owned, documented here)
|
|
70
|
+
|
|
71
|
+
- **Header-anchored filters.** A column header may host its own filter trigger (funnel icon button beside the sort button) opening the `FacetedFilter` content for that column. Column option management (add/rename/delete options, per the Topics-editor reference) stays consumer-owned; the DS owns the trigger, the checklist, and select-all.
|
|
72
|
+
- **Row actions.** Per-row operations render as an `actions` column of `IconButton`s (edit, delete) via the column `cell` renderer. Row actions act on one row; `bulkActions` act on the selection — never duplicate one as the other.
|
|
73
|
+
- **Saved searches.** Named filter presets ("Invoices over 500€") are consumer state (a preset → `{ query, rules, sort }` applier); the bar renders the applied result like any other filter state. The DS owns no preset storage.
|
|
74
|
+
|
|
48
75
|
## Props contract
|
|
49
76
|
|
|
50
77
|
| Prop | Type | Default | Required | Description | Responsive |
|
|
51
78
|
|---|---|---|---|---|---|
|
|
52
79
|
| `columns` | `Array<DataTableColumn<Row>>` | `undefined` | yes | Column definitions with `id`, `header`, `accessorKey`, and optional `cell` renderer. | no |
|
|
53
80
|
| `data` | `Row[]` | `undefined` | yes | Row data array. | no |
|
|
54
|
-
| `emptyState` | `ReactNode` |
|
|
81
|
+
| `emptyState` | `ReactNode` | (default empty content) | no | Content rendered when no rows match filters. Omitted, the default distinguishes two meanings: a non-empty dataset renders the no-results state (search icon, recovery hint, and a Clear search and filters button whenever query or faceted filters are active — the button clears the query and emits empty faceted filters); an empty dataset renders the dataset-empty state (inbox icon, no action — creation actions are app-owned). | no |
|
|
55
82
|
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | no | Table density. Maps to `data-size` attribute. | no |
|
|
56
83
|
| `getRowId` | `(row: Row, rowIndex: number) => React.Key` | `undefined` | no | Custom row ID extractor. Defaults to `rowIndex`. | no |
|
|
57
84
|
| `visibleColumnIds` | `Set<string>` | `undefined` | no | Controlled visible column IDs. Defaults to all columns. | no |
|
|
@@ -61,8 +88,24 @@ The root `DataTable` component is a flat export, not a compound. Subcomponents a
|
|
|
61
88
|
| `facetedFilters` | `Array<DataTableFacetedFilterState>` | `undefined` | no | Controlled faceted filter state array. | no |
|
|
62
89
|
| `onFacetedFiltersChange` | `(facetedFilters: Array<DataTableFacetedFilterState>) => void` | `undefined` | no | Callback when faceted filters change. | no |
|
|
63
90
|
| `toolbar` | `ReactNode` | `undefined` | no | Custom toolbar content. Replaces default search toolbar. | no |
|
|
91
|
+
| `query` | `string` | `undefined` | no | Controlled client query. | no |
|
|
92
|
+
| `defaultQuery` | `string` | `''` | no | Initial uncontrolled client query. | no |
|
|
93
|
+
| `onQueryChange` | `(query: string) => void` | `undefined` | no | Fires when the built-in or context-bound search changes. | no |
|
|
64
94
|
| `showToolbar` | `boolean` | `true` | no | Whether to show the default toolbar. | no |
|
|
65
95
|
| `showPagination` | `boolean` | `false` | no | Whether to show pagination controls. | no |
|
|
96
|
+
| `paginationPosition` | `'top' \| 'bottom' \| 'both'` | `'bottom'` | no | Where the pagination footer renders relative to the table. | no |
|
|
97
|
+
| `paginationAlign` | `'start' \| 'center' \| 'end'` | `undefined` | no | Justification of the pagination footer. Omitted keeps the default `space-between` (range info left, controls right). | no |
|
|
98
|
+
| `paginationFirstLast` | `boolean` | `false` | no | Shows First/Last edge links in the pagination footer (round-2 gap fill). Additive; default renders Previous/numbered/Next only. | no |
|
|
99
|
+
| `paginationPageInput` | `boolean` | `false` | no | Shows the "Page N of M" jump input in the pagination footer (round-2 gap fill). Additive; default hides it. | no |
|
|
100
|
+
| `onTableChange` | `(action: 'paginate' \| 'sort' \| 'filter', state: { pagination, sortBy, sortOrder }) => void` | `undefined` | no | Action-tagged change event for server-side apps. `paginate` fires on page/page-size change, `sort` on sort change, `filter` on built-in search change. Coexists with `onPaginationChange` / `onSortChange` / `onFacetedFiltersChange`. | no |
|
|
101
|
+
| `bulkActions` | `ReactNode` | `undefined` | no | Action slot rendered inside the contextual selection bar after the count label (e.g. Export, Delete buttons). The bar stacks beneath the query toolbar while rows are selected; no actions means count + Deselect all only. | no |
|
|
102
|
+
| `sorting` | `DataTableSortState \| null` | `undefined` | no | Additive controlled tri-state sorting. Explicit `null` means unsorted and takes precedence over legacy sort props. | no |
|
|
103
|
+
| `defaultSorting` | `DataTableSortState \| null` | `null` | no | Initial uncontrolled sort state. | no |
|
|
104
|
+
| `onSortingChange` | `(sorting: DataTableSortState \| null) => void` | `undefined` | no | Emits all tri-state transitions, including unsort. | no |
|
|
105
|
+
| `resetPageOnViewChange` | `boolean` | `true` | no | Resets pagination to page 1 when query, filters, or sort change. | no |
|
|
106
|
+
| `clearSelectionOnViewChange` | `boolean` | `true` | no | Clears row selection when query, filters, or sort change. | no |
|
|
107
|
+
| `wrapScrollArea` | `boolean` | `true` | no | Inner `Table` always rides in a horizontal `ScrollArea` so wide column sets scroll instead of clipping inside the shell (TMA slice-1: `overflow: hidden` shell clipped unreachable columns at 320px). Pass-through of the `Table` prop; set `false` only to restore the bare table. | no |
|
|
108
|
+
| `separator` | `'rules' \| 'grid'` | `'rules'` | no | Separator treatment of the inner `Table`. Pass-through of the `Table` prop. | no |
|
|
66
109
|
|
|
67
110
|
Rules:
|
|
68
111
|
|
|
@@ -88,14 +131,30 @@ Rules:
|
|
|
88
131
|
| Slot | Class | CSS file |
|
|
89
132
|
|---|---|---|
|
|
90
133
|
| `DataTable.Toolbar` | `dsx-data-table-toolbar` | inline styles |
|
|
134
|
+
| Toolbar region | `dsx-data-table__toolbar-region` | `data-table.css` |
|
|
135
|
+
| Toolbar trailing actions | `dsx-data-table-toolbar__actions` | `data-table.css` |
|
|
91
136
|
| `DataTable.Pagination` | `dsx-data-table-pagination` | inline styles |
|
|
137
|
+
| Pagination range | `dsx-data-table-pagination__info` | `data-table.css` |
|
|
138
|
+
| Pagination navigation | `dsx-data-table-pagination__navigation` | `data-table.css` |
|
|
139
|
+
| Pagination page size | `dsx-data-table-pagination__page-size` | `data-table.css` |
|
|
140
|
+
| `DataTable.Pagination` (top) | `dsx-data-table-pagination dsx-data-table__pagination-top` | `data-table.css` (flips the separator to `border-bottom`) |
|
|
141
|
+
| `DataTable.BulkBar` | `dsx-data-table__bulk-bar` | `data-table.css` |
|
|
142
|
+
| `DataTable.BulkBar` count | `dsx-data-table__bulk-bar-count` | `data-table.css` |
|
|
143
|
+
| `DataTable.BulkBar` actions | `dsx-data-table__bulk-bar-actions` | `data-table.css` |
|
|
144
|
+
| `DataTable.BulkBar` clear | `dsx-data-table__bulk-bar-clear` | `data-table.css` |
|
|
92
145
|
| `DataTable.FacetedFilter` | `dsx-data-table-faceted-filter` | inline styles |
|
|
146
|
+
| Sort button | `dsx-data-table__sort-button` | `data-table.css` |
|
|
147
|
+
| Sort indicator | `dsx-data-table__sort-indicator` (`data-direction="none" \| "asc" \| "desc"`) | `data-table.css` |
|
|
93
148
|
| Empty cell | `dsx-data-table__empty` | inline styles |
|
|
149
|
+
| Empty content | `dsx-data-table__empty-content` | `data-table.css` |
|
|
94
150
|
|
|
95
151
|
**Responsive behavior:**
|
|
96
152
|
|
|
97
|
-
- The
|
|
98
|
-
-
|
|
153
|
+
- The toolbar and pagination use intrinsic wrapping rather than product breakpoints. At narrow widths the range, navigation, and page-size regions reflow without removing labels or controls — unless the consumer opts into `dense`, which omits the page-size region (and the status summary that duplicates the range) by explicit prop, never by width.
|
|
154
|
+
- Column visibility remains governed by each column's canonical `hideBelow` value.
|
|
155
|
+
|
|
156
|
+
- Toolbar search and commands form intrinsic flex regions with wrapping at available container width; no toolbar width query is used. The bulk-selection bar wraps count, action group, and deselect control, and its action group can shrink.
|
|
157
|
+
- Legacy `hideBelow` column queries remain an existing public contract. The current breakpoint gate verifies token values; it does not enforce component ownership. Migrating that column contract requires a separate compatibility decision.
|
|
99
158
|
|
|
100
159
|
**Reduced motion:**
|
|
101
160
|
|
|
@@ -109,12 +168,18 @@ DataTable uses inline styles with token references. Every CSS value the componen
|
|
|
109
168
|
|---|---|---|
|
|
110
169
|
| Gap | `var(--dsx-space-sm)`, `var(--dsx-space-xs)` | Spacing between controls |
|
|
111
170
|
| Padding | `var(--dsx-space-md)`, `var(--dsx-space-sm)` | Internal gutter |
|
|
112
|
-
| Font size | `var(--dsx-font-size
|
|
171
|
+
| Font size | `var(--dsx-typography-label-small-font-size)` | Small text |
|
|
113
172
|
| Color | `var(--dsx-color-on-surface)`, `var(--dsx-color-on-surface-variant)` | Text colors |
|
|
114
173
|
| Border | `var(--dsx-color-outline)` | Edge |
|
|
115
174
|
| Radius | `var(--dsx-radius-sm)` | Standard roundness |
|
|
116
175
|
| Background | `var(--dsx-color-surface)`, `var(--dsx-color-surface-raised)` | Surface colors |
|
|
117
176
|
| Accent | `var(--dsx-color-accent-primary)`, `var(--dsx-color-on-accent-primary)` | Active page button |
|
|
177
|
+
| Bulk bar background | `var(--dsx-color-accent-surface)` | Theme-aware tinted surface for the selection bar (round-2: replaces the high-contrast inverse, which read as a broken light strip in dark theme) |
|
|
178
|
+
| Bulk bar text | `var(--dsx-color-on-surface)` | Count, actions, and Clear on the bar |
|
|
179
|
+
| Bulk bar accent edge | `var(--dsx-color-accent-indicator)` | Inset start edge (`box-shadow`) tying the bar to the active accent |
|
|
180
|
+
| Bulk bar separator | `var(--dsx-border-width-sm) solid var(--dsx-color-outline)` | Edge below the bar |
|
|
181
|
+
|
|
182
|
+
Density: `size` writes `data-size` on the shell root and is forwarded to the inner `Table`, so `sm` / `md` / `lg` cell padding visibly renders through the primitive's size rules (`table.css`). The shell adds no separate row-height scale.
|
|
118
183
|
|
|
119
184
|
Rules:
|
|
120
185
|
|
|
@@ -164,7 +229,7 @@ Rules:
|
|
|
164
229
|
|
|
165
230
|
**Color and meaning:**
|
|
166
231
|
|
|
167
|
-
- Sort direction is communicated by
|
|
232
|
+
- Sort direction is communicated by a single Lucide arrow indicator and `aria-sort`, not by color alone. Unsorted columns show a subdued `arrow-up-down` at reduced emphasis; the active direction collapses to one full-emphasis accent-colored `arrow-up` / `arrow-down` in a fixed-width slot so labels never shift.
|
|
168
233
|
- Selection state is communicated by checkbox checked state and `data-selected` attribute on the row.
|
|
169
234
|
|
|
170
235
|
**Naming:**
|
|
@@ -180,8 +245,8 @@ The Playground docs surface has two parts: the registry entry in `playground_reg
|
|
|
180
245
|
|
|
181
246
|
**Default story:**
|
|
182
247
|
|
|
183
|
-
- Renders the component with
|
|
184
|
-
- Asserts the root class is `dsx-data-table
|
|
248
|
+
- Renders the component with enough rows to produce multiple pages and keeps pagination visible, so pagination-position and pagination-control variants are observable instead of identical two-row shells.
|
|
249
|
+
- Asserts the root class is `dsx-data-table` and exercises the page-size selector against a meaningful dataset.
|
|
185
250
|
|
|
186
251
|
**Variant story** (one per variant):
|
|
187
252
|
|
|
@@ -192,6 +257,18 @@ The Playground docs surface has two parts: the registry entry in `playground_reg
|
|
|
192
257
|
|
|
193
258
|
- Renders the component with `showPagination={true}` and a custom `toolbar` prop.
|
|
194
259
|
- Asserts pagination controls and toolbar render.
|
|
260
|
+
- **Turnkey workspace:** one primary, initially unselected story demonstrates context-bound search, row count, column visibility, export, tri-state sorting, selection actions, and the three-zone pagination footer. Selecting rows stacks the selection bar beneath the query toolbar with real Export selected / Delete selected actions — the toolbar stays mounted so filters are never lost; Deselect all drops the bar.
|
|
261
|
+
- The toolbar is one row at tablet/desktop widths: search occupies the flexible query zone, while row count, Columns, and Export form the trailing tool cluster. Columns and Export use package icons; Export exposes direct `CSV file` / `JSON file` actions rather than checkbox-like format state.
|
|
262
|
+
- The default no-results state is a compact, centred search state with a title and recovery hint; consumers may still replace it through `emptyState` or the richer `result` / `listState` path.
|
|
263
|
+
- **Compact secondary coverage:** density and empty/list-state examples remain concise. Pagination placement/alignment stays unit-tested instead of producing a nine-table fixture wall.
|
|
264
|
+
|
|
265
|
+
**Composition patterns** (documented guidance, composed by the app — no new DataTable props):
|
|
266
|
+
|
|
267
|
+
- **KPI header over table:** render a `StatCard` / `Metric` row above the `DataTable` (outside the shell). The shell owns the table; the app owns the summary strip. Keep the strip outside `DataTable.Root` so toolbar, bulk bar, and pagination borders stay contiguous.
|
|
268
|
+
- **Visualization cells:** a column `cell` renderer may return inline visuals — a progress track (filled `div` width `%`, token background) or a sparkline (`ChartArea` with `spark`, or a minimal inline SVG). Cells stay text-sized; visuals never set row height. No `Chart` card chrome inside cells.
|
|
269
|
+
- **View switcher:** a `SegmentedControl` (Table / Board / List) above the shell, owned by the app, toggling between the `DataTable` and alternate surfaces. The switcher is not part of the shell.
|
|
270
|
+
- **Rich person cell:** a column `cell` returning avatar + name + title stacked (avatar `sm`, name label, title muted caption). Compose from `Avatar` + `Text`, not from new table slots.
|
|
271
|
+
- **No ghost variant, by rule:** a borderless read-only table with no toolbar, selection, or pagination is plain `Table`, not a `DataTable` variant. The shell's identity is its workspace chrome (toolbar, bulk bar, pagination borders); stripping all three leaves nothing to vary. Compliance: reach for `Table`, never a ghost prop on `DataTable`.
|
|
195
272
|
|
|
196
273
|
**State story:**
|
|
197
274
|
|
|
@@ -214,20 +291,24 @@ The Playground docs surface has two parts: the registry entry in `playground_reg
|
|
|
214
291
|
| `size` | `select` | `md` |
|
|
215
292
|
| `showPagination` | `boolean` | `false` |
|
|
216
293
|
| `showToolbar` | `boolean` | `true` |
|
|
294
|
+
| `paginationPosition` | `select` | `bottom` |
|
|
295
|
+
| `paginationAlign` | `select` | (unset = `space-between`) |
|
|
296
|
+
| `paginationFirstLast` | `boolean` | `false` |
|
|
297
|
+
| `paginationPageInput` | `boolean` | `false` |
|
|
217
298
|
|
|
218
299
|
## Wiring notes
|
|
219
300
|
|
|
220
301
|
**Composes from:**
|
|
221
302
|
|
|
222
303
|
- `Table`: Renders the semantic table structure (`<table>`, `<thead>`, `<tbody>`, `<tr>`, `<th>`, `<td>`).
|
|
223
|
-
- `Pagination`: Renders pagination controls when `showPagination={true}`. DataTable uses its own `DataTablePagination` subcomponent, not the standalone `Pagination` component.
|
|
304
|
+
- `Pagination`: Renders pagination controls when `showPagination={true}`. DataTable uses its own `DataTablePagination` subcomponent, not the standalone `Pagination` component. `paginationFirstLast` / `paginationPageInput` pass through to it; `DataTablePagination` itself accepts `showFirstLast` / `showPageInput` for standalone use.
|
|
224
305
|
- `Toolbar`: Renders toolbar controls. DataTable uses its own `DataTableToolbar` subcomponent, not the standalone `Toolbar` component.
|
|
225
|
-
- `
|
|
306
|
+
- `Input`: `DataTable.Toolbar.Search` renders the client-side query field. The default toolbar uses this public slot rather than a private search row.
|
|
226
307
|
- `EmptyState`: DataTable does not compose `EmptyState`. It renders the `emptyState` prop content in a table cell when no rows match.
|
|
227
308
|
- `Pills`: DataTable does not compose `Pills`. Faceted filters use `DataTableFacetedFilter` subcomponents.
|
|
228
309
|
- `Input`: Renders the search input in the default toolbar.
|
|
229
310
|
- `Checkbox`: Renders row selection checkboxes and the select-all checkbox.
|
|
230
|
-
- `Button`: Renders pagination
|
|
311
|
+
- `Button`: Renders toolbar, export, pagination, and Deselect all actions.
|
|
231
312
|
- `Badge`: Renders active filter count badges in toolbar and faceted filter.
|
|
232
313
|
- `DropdownMenu`: Renders column visibility, export, and faceted filter dropdowns.
|
|
233
314
|
|
|
@@ -237,7 +318,7 @@ The Playground docs surface has two parts: the registry entry in `playground_reg
|
|
|
237
318
|
|
|
238
319
|
**State boundaries:**
|
|
239
320
|
|
|
240
|
-
- Owned by this component:
|
|
321
|
+
- Owned by this component: controlled/uncontrolled query, nullable sort, row selection, pagination, faceted filters, and visible-column state. View-changing transactions reset page and selection by default so stale selections cannot silently cross result sets.
|
|
241
322
|
- Owned by the consumer: row data, column definitions, custom toolbar content, custom empty state content. The consumer passes these in as props.
|
|
242
323
|
|
|
243
324
|
**Boundary rules:**
|
|
@@ -168,6 +168,8 @@ Rules:
|
|
|
168
168
|
| Property | Token | Role |
|
|
169
169
|
|---|---|---|
|
|
170
170
|
| Overlay padding | `var(--dsx-space-md)` | Edge gutter between overlay and content. |
|
|
171
|
+
| Overlay z-index | `var(--dsx-z-index-overlay)` | Masks page content (including standalone menu-tier floating content at the dropdown tier). |
|
|
172
|
+
| Content z-index | `var(--dsx-z-index-modal)` | Modal surface; host tier for the shared nested floating tier contract. |
|
|
171
173
|
| Content gap | `var(--dsx-space-lg)` | Vertical rhythm inside the content frame. |
|
|
172
174
|
| Content padding | `var(--dsx-space-lg)` | Internal gutter. |
|
|
173
175
|
| Content border radius | `var(--dsx-rounded-xl)` | Rounded corners. |
|
|
@@ -298,6 +300,7 @@ Rules:
|
|
|
298
300
|
- `Spinner` (from `../spinner/Spinner`): `Dialog.ActionTrigger` renders a spinner while the action promise is in flight.
|
|
299
301
|
- `Theme`: `DialogContent` mirrors the portal theme into a `Theme` wrapper so `data-dsx-*` attributes resolve inside the portal.
|
|
300
302
|
- `framer-motion`: provides the `motion.div` for mount and exit. The reduced motion preset is read from `usePrefersReducedMotion`.
|
|
303
|
+
- `_internal/floatingLayer`: `Dialog.Content` provides `FloatingLayerHostContext` to its body, so menu-tier content (`Select`, `Combobox`, `DropdownMenu`) nested inside the dialog escalates via `dsx-menu__nested` (see the shared nested floating tier contract in `menu.md`). `AlertDialog.Content` inherits this through `Dialog.Content`.
|
|
301
304
|
|
|
302
305
|
**Used by:**
|
|
303
306
|
|
|
@@ -308,6 +311,7 @@ Rules:
|
|
|
308
311
|
**State boundaries:**
|
|
309
312
|
|
|
310
313
|
- Owned by `Dialog`: open state when uncontrolled, presence context, portal theme mirroring, action-trigger loading state, motion preset.
|
|
314
|
+
- Owned by `Dialog`: the nested-host signal — `Dialog.Content` marks its body as a modal-tier host for the shared nested floating tier contract.
|
|
311
315
|
- Owned by the consumer: title copy, description copy, the body content, the action handlers, the close behavior.
|
|
312
316
|
|
|
313
317
|
**Boundary rules:**
|
|
@@ -160,7 +160,7 @@ Every CSS value the component paints is a `var(--dsx-*)` token. The `dropdown-me
|
|
|
160
160
|
| Content border radius | `var(--dsx-rounded-lg)` | Content corner roundness. |
|
|
161
161
|
| Content background | `var(--dsx-color-panel-translucent)` | Dropdown surface. |
|
|
162
162
|
| Content border | `var(--dsx-border-width-sm) solid var(--dsx-color-outline)` | Dropdown edge. |
|
|
163
|
-
| Content z-index | `var(--dsx-z-index-dropdown)` | Stack above page. |
|
|
163
|
+
| Content z-index | `var(--dsx-z-index-dropdown)` standalone; `calc(var(--dsx-z-index-modal, 90) + 2)` when nested inside a modal-tier host (`dsx-menu__nested`, see the shared nested floating tier contract in `menu.md`) | Stack above page; nested menus clear their host surface. |
|
|
164
164
|
| Item min-height | `var(--dsx-size-lg)` | Item touch target. |
|
|
165
165
|
| Item padding | `var(--dsx-space-sm) var(--dsx-space-sm) var(--dsx-space-sm) calc(var(--dsx-space-lg) + var(--dsx-space-sm))` | Item gutter with indicator gutter. |
|
|
166
166
|
| Item border radius | `var(--dsx-rounded-md)` | Item corner roundness. |
|
|
@@ -273,6 +273,7 @@ Rules:
|
|
|
273
273
|
- `_internal/usePrefersReducedMotion`: gates the open / close animation.
|
|
274
274
|
- `_internal/helpers/extractProps`: turns the `Item`, `SubTrigger`, and `Shortcut` prop defs into merged class + style output.
|
|
275
275
|
- `Icon`: the `chevron-right` glyph on the sub-trigger; the `check` / `minus` glyphs on checkbox items.
|
|
276
|
+
- `_internal/floatingLayer`: `useFloatingLayerHost` (consumed in `MenuContent`, covering `Content` and `SubContent`) adds `dsx-menu__nested` when the menu renders inside a modal-tier host (`Popover.Content` / `Dialog.Content`), so the menu paints above its host. Standalone menus never carry the class (see the shared nested floating tier contract in `menu.md`).
|
|
276
277
|
|
|
277
278
|
**Used by:**
|
|
278
279
|
|
|
@@ -87,6 +87,7 @@ Rules:
|
|
|
87
87
|
**Responsive behavior:**
|
|
88
88
|
|
|
89
89
|
- The component does not write `@media` rules. `size` is single-value only.
|
|
90
|
+
- The root and header can shrink within the available width. Long titles and identifiers wrap in both the default Result host and the legacy `asChild` host.
|
|
90
91
|
|
|
91
92
|
**Reduced motion:**
|
|
92
93
|
|
|
@@ -152,7 +153,7 @@ The component is static.
|
|
|
152
153
|
|
|
153
154
|
**Naming:**
|
|
154
155
|
|
|
155
|
-
- `title`
|
|
156
|
+
- `title` provides the visible heading; it does not automatically name the section. Consumers use `aria-labelledby` or `aria-label` when a named region is needed. The action's accessible name is the consumer's responsibility.
|
|
156
157
|
|
|
157
158
|
## Playground demo spec
|
|
158
159
|
|
|
@@ -196,6 +197,7 @@ The component is static.
|
|
|
196
197
|
|
|
197
198
|
- `Icon`, `Text`, `Button`: the typical content of the illustration, description, and action slots. EmptyState does not import any of these; the consumer supplies the nodes.
|
|
198
199
|
- `@radix-ui/react-slot`: enables `asChild` on the root.
|
|
200
|
+
- `Result`: supplies the normal section host with `state="empty"`; the legacy `asChild` path uses Slot directly.
|
|
199
201
|
- `Card` is not composed; the base card surface is inherited through the CSS import (`@import '../../_internal/baseCard.css'`) so the EmptyState background, border, and shadow resolve through the same tokens as `Card`.
|
|
200
202
|
|
|
201
203
|
**Used by:**
|
|
@@ -58,6 +58,7 @@ A card-based file selection surface with a dropzone, a list of file rows, and a
|
|
|
58
58
|
| `onActionClick` | `MouseEventHandler<HTMLButtonElement>` | `undefined` | no | Default action click handler. | no |
|
|
59
59
|
| `accept` | `Accept` (`react-dropzone`) | `undefined` | no | Accepted MIME types / extensions forwarded to `useDropzone`. | no |
|
|
60
60
|
| `multiple` | `boolean` | `undefined` | no | When `true`, the hidden input and drop accept multiple files. | no |
|
|
61
|
+
| `capture` | `boolean \| 'user' \| 'environment'` | `undefined` | no | Mobile capture hint forwarded to the hidden input (`getInputProps`); pairs with `accept="image/*"` for direct camera capture. Omitted by default so desktop file dialogs are unaffected. | no |
|
|
61
62
|
| `onFiles` | `(files: File[]) => void` | `undefined` | no | File capture handler. When set, the dropzone mounts the hidden input and forwards drops and picks; when absent, the dropzone is a visual-only shell (`useDropzone` disabled, no input). | no |
|
|
62
63
|
| `dragging` | `boolean` | `false` | no | Active drop state. Drives `data-dragging="true"`. | no |
|
|
63
64
|
| `asChild` | `boolean` | `false` | no | Renders the dropzone through `Slot` from `@radix-ui/react-slot`. | no |
|
|
@@ -6,17 +6,26 @@ archetype: composite
|
|
|
6
6
|
depends_on:
|
|
7
7
|
- Toolbar
|
|
8
8
|
- Button
|
|
9
|
+
- IconButton
|
|
10
|
+
- Icon
|
|
11
|
+
- Pills
|
|
12
|
+
- Popover
|
|
13
|
+
- Select
|
|
14
|
+
- Input
|
|
15
|
+
- NumberInput
|
|
16
|
+
- TagsInput
|
|
17
|
+
- Badge
|
|
9
18
|
---
|
|
10
19
|
|
|
11
20
|
# FilterBar
|
|
12
21
|
|
|
13
22
|
## 2.6 contract
|
|
14
23
|
|
|
15
|
-
Root accepts optional `activeCount`. `FilterBar.Control` applies the same wrapper contract to search, select, date, and custom filters and writes `data-active`. `FilterBar.Count` reads the root count. `FilterBar.Clear` is disabled when an explicit active count is zero; omitting `activeCount` preserves the 2.5 uncontrolled compatibility behavior.
|
|
24
|
+
Root accepts optional `activeCount`. `FilterBar.Control` applies the same wrapper contract to search, select, date, and custom filters and writes `data-active`. `FilterBar.Count` reads the root count. `FilterBar.Clear` is disabled when an explicit active count is zero; omitting `activeCount` preserves the 2.5 uncontrolled compatibility behavior. `FilterBar.Search`, `FilterBar.Rules`, `FilterBar.Rule`, `FilterBar.ConditionGroup`, `FilterBar.Condition`, and `FilterBar.Builder` are additive slots: every pre-existing prop and slot keeps working unchanged.
|
|
16
25
|
|
|
17
26
|
## Purpose
|
|
18
27
|
|
|
19
|
-
A product-agnostic
|
|
28
|
+
A product-agnostic filter system that organizes consumer-controlled filters three ways: the classic grouped-controls shell (search, select, date, custom filters plus summary, actions, clear), the first-class rule-builder composition (rule chips showing field/operator/value plus a field → operator → value → Apply builder popup), and the advanced-condition composition (AND/OR condition groups with nesting, per-condition trash delete, Clear all). Consumers own all filter values, reset logic, query execution, date-range policy, and domain fields. The DS owns layout, slots, accessible naming, Clear styling, the rule-chip presentation, and the builder popup shell.
|
|
20
29
|
|
|
21
30
|
## Anatomy & slots
|
|
22
31
|
|
|
@@ -26,6 +35,13 @@ A product-agnostic, wrapping filter toolbar that organizes consumer-controlled f
|
|
|
26
35
|
|---|---|---|---|
|
|
27
36
|
| `FilterBar.Root` | `div role="toolbar"` | `dsx-filter-bar` | Default accessible name is `Filters`. |
|
|
28
37
|
| `FilterBar.Group` | `div role="group"` | `dsx-filter-bar__group` | Groups related controls. |
|
|
38
|
+
| `FilterBar.Search` | `div` | `dsx-filter-bar__search` | Flex-growing search cell for the toolbar cluster. |
|
|
39
|
+
| `FilterBar.Rules` | `Pills (ul)` | `dsx-filter-bar__rules` + `dsx-pills` | Rule-chip cluster; accepts `size` (`sm`/`md`/`lg`, default `md`). Optional `maxVisible` collapses overflow behind `+N more` / `Show less` with an optional `Clear` (`onClearAll`). |
|
|
40
|
+
| `FilterBar.Rule` | `Pill (li)` | `dsx-filter-bar__rule` + `dsx-pill` | One rule chip: `field`/`operator`/`value`, optional `count`, remove, click-to-reopen. |
|
|
41
|
+
| `FilterBar.ConditionGroup` | `div` (+ `role="group"` when named) | `dsx-filter-bar__condition-group` | AND/OR condition group with nesting: combinator toggle, `Add condition` / `Add subgroup`, `Clear all`. Buttons render only for the handlers passed. |
|
|
42
|
+
| `FilterBar.Condition` | `div` | `dsx-filter-bar__condition` | One advanced condition: `field`/`operator`/`value`, optional `count`, click-to-reopen, trash delete (`onRemove`). |
|
|
43
|
+
| `FilterBar.ConditionEditor` | `div role="group"` | `dsx-filter-bar__condition-editor` | Docked BI-panel editor for condition trees that outgrow the Builder popup: field rail, operator/value config, Apply/New. |
|
|
44
|
+
| `FilterBar.Builder` | `Popover` | `dsx-filter-bar__builder` on the popup | Field → operator → value → Apply popup. |
|
|
29
45
|
| `FilterBar.Summary` | `div` | `dsx-filter-bar__summary` | Result/filter summary. |
|
|
30
46
|
| `FilterBar.Actions` | `div` | `dsx-filter-bar__actions` | Action cluster. |
|
|
31
47
|
| `FilterBar.Clear` | `Button` | `dsx-filter-bar__clear` | Styled callback only. |
|
|
@@ -40,31 +56,200 @@ A product-agnostic, wrapping filter toolbar that organizes consumer-controlled f
|
|
|
40
56
|
|
|
41
57
|
`FilterBar.Clear` accepts Button props and an optional `onClear: () => void`; its default children are `Clear filters`. All wrapper slots accept standard div attributes.
|
|
42
58
|
|
|
59
|
+
`FilterBar.Rules` accepts `size: 'sm' \| 'md' \| 'lg'` (default `'md'`) plus standard list attributes; it renders a `Pills` cluster so rule chips inherit the Pills contract. `maxVisible: number` collapses the cluster: only the first `maxVisible` chips render, followed by an overflow row with `+N more` (expands; `aria-label="Show N more filters"`, `aria-expanded`), `Show less` (collapses), and an optional `Clear` wired to `onClearAll` (rendered only when the handler is passed, `aria-label="Clear all filters"`). Expansion is controlled (`expanded` + `onExpandedChange`) or uncontrolled (`defaultExpanded`, default `false`). `showMoreLabel(hiddenCount)`, `showLessLabel`, and `clearAllLabel` override the overflow chrome. Omitting `maxVisible` preserves the flat chip list.
|
|
60
|
+
|
|
61
|
+
`FilterBar.Rule` accepts `field`, `operator`, `value` (`ReactNode`, typically strings), `count` (`ReactNode`, typically a number: per-option match count), `size` (default `'md'`), and `active`. `onRemove` adds the Pills removable affordance (omitting it hides the remove button); `onEdit` wraps the field/operator/value label in a button named `Edit filter: <field> <operator> <value>` that reopens the builder (click-to-reopen). Omitting `onEdit` renders static text. Extra children render after the label inside the chip.
|
|
62
|
+
|
|
63
|
+
`FilterBar.ConditionGroup` accepts `combinator: 'and' | 'or'` (default `'and'`) plus standard div attributes. `editor` docks a `FilterBar.ConditionEditor` inside the group card between the combinator and the rows, making one composed unit: the group owns add/remove/clear, the editor owns field/operator/value. `rowsLabel` (e.g. `Where:`) heads the row stack; `allLabel`/`anyLabel` (e.g. `All/Any of the following are true:`) head the combinator, falling back to `Match all`/`Match any` when only one is set. `gapCombinators` (one combinator per gap, index-aligned to children) with `onGapCombinatorChange` renders And/Or pills between rows for independent per-gap logic (react-querybuilder pattern) and replaces the header toggle; omitting it keeps the single group combinator. Grouping evaluation (e.g. AND-precedence) is consumer-owned. `onCombinatorChange` renders the AND/OR toggle (buttons with `aria-pressed` inside a group named by `combinatorLabel`, default `Match`); omitting it renders the combinator as static text. `onAddCondition`, `onAddSubgroup`, and `onClearAll` render `Add condition` / `Add subgroup` / `Clear all` (overridable via `addConditionLabel`, `addSubgroupLabel`, `clearAllLabel`); each button renders only when its handler is passed, so there are never dead controls. An empty group (no conditions or subgroups) renders the `emptyHint` line (default `No conditions yet — add one below.`) instead of a void, and writes `data-empty="true"` with a dashed frame. Nested groups indent through a rail (inset start border), not just a margin, so depth reads at a glance. Children are conditions (`FilterBar.Condition`) and nested `FilterBar.ConditionGroup`s to any depth. With an `aria-label` the group takes `role="group"`; without one it renders a plain div so unnamed groups never fail naming rules.
|
|
64
|
+
|
|
65
|
+
`FilterBar.Condition` accepts `field`, `operator`, `value` (`ReactNode`), optional `count`, and standard div attributes. An empty-string `value` renders an explicit `empty` pill (`data-empty="true"`) instead of blank space, in both `Condition` and `Rule`. `onEdit` wraps the label in a button named `Edit filter: <field> <operator> <value>` (click-to-reopen, same naming as `Rule`); `editLabel` overrides that name (needed when `value` is rich content rather than text). `dragProps` (spread onto the row root) enables native drag reorder and renders the grip handle; omitting it hides the grip. Passing `fields` with `onFieldChange`/`onOperatorChange`/`onValueChange` renders the row as live inline editors (field select, operator select, shared value renderer with `renderValue` support) instead of the display label — the Gyaan pattern; omitting `fields` keeps display mode with click-to-reopen. `onRemove` renders a trash `IconButton` (`aria-label` from `removeLabel`, default `Remove condition`); omitting it hides the delete affordance. Extra children render after the delete button.
|
|
66
|
+
|
|
67
|
+
`FilterBar.Builder` accepts `fields: Array<{ value: string; label?: ReactNode; type?: 'text' | 'number' | 'enum' | 'multi' | 'range' | 'date' | 'person'; operators?: string[]; options?: Array<{ value: string; label?: ReactNode }>; min?: number; max?: number; step?: number; renderValue?: (state: { value: string; onChange: (nextValue: string) => void; id: string }) => ReactNode }>` and an optional global `operators` fallback (default `is`, `is not`, `contains`, `does not contain`). The value editor resolves in order: `renderValue` when provided; a `Select` when `options` are present (or `type: 'enum'`); a `NumberInput` for `type: 'number'` (bridged to the string rule value); a `TagsInput` for `type: 'multi'` (values are comma-joined into the string rule value); a dual-thumb `Slider` for `type: 'range'` (value encodes as `"min..max"`, bounds from `min`/`max`/`step`, default `0`/`100`/`1`); otherwise a free-text `Input` (`date` hints `YYYY-MM-DD`, `person` hints a name). `date` and `person` are intentionally Input-backed in the package: `DatePicker` and `Combobox` carry optional peers the root barrel must not eagerly load, so consumers plug them through `renderValue` from their dedicated subpaths. `count` renders an active-count `Badge` inside the default `+ Add filter` trigger so the bar has one adhesive filter entry with its number attached. `initialRule` seeds the draft and is re-read every time the popup opens, so editing an existing rule is `initialRule={rule}` plus open state. Open state is controlled (`open` + `onOpenChange`) or uncontrolled (`defaultOpen`). `trigger` overrides the default `+ Add filter` outline button. Pass `trigger={null}` for a triggerless controlled popup (the click-to-reopen edit flow: `open` + `onOpenChange` with no visible trigger) — the popup anchors to a zero-size viewport-center span (`dsx-filter-bar__builder-anchor`), so it opens centered and clickable. `title` (default `Add filter`), `submitLabel` (default `Apply`), and `cancelLabel` (default `Cancel`) override the popup chrome. `onApply(rule: { field; operator; value })` fires on Apply; `onCancel` fires on Cancel. Apply stays disabled until field and operator are chosen; Apply and Cancel both close the popup.
|
|
68
|
+
|
|
69
|
+
## Density scale
|
|
70
|
+
|
|
71
|
+
All three sizes render explicit rules through `--dsx-filter-bar-*` custom properties (selected with `:where([data-size])` so specificity stays at the policy baseline):
|
|
72
|
+
|
|
73
|
+
| Size | Padding | Gap | Control height | Summary type |
|
|
74
|
+
|---|---|---|---|---|
|
|
75
|
+
| `sm` | `space-sm` | `space-xs` | `density-control-height-sm` | `label-small` |
|
|
76
|
+
| `md` | `space-md` | `space-sm` | `density-control-height` | `body-small` |
|
|
77
|
+
| `lg` | `space-lg` | `space-md` | `density-control-height-lg` | `body-medium` |
|
|
78
|
+
|
|
79
|
+
`FilterBar.Rules` stretches to the row control height so chips align with sibling controls. Pair `Rules`/`Rule` `size` with the root `size` so chips and shell step together.
|
|
80
|
+
|
|
81
|
+
Editable rule labels retain their typography and chip paint with a centered invisible hit layer at least `size-md` (24px) high. Static labels have no hit layer. The layer stays within the label's horizontal bounds so removal remains a separate action.
|
|
82
|
+
|
|
83
|
+
Inside FilterBar rules, the Pill remove button likewise has a centered invisible `size-md` floor in both dimensions; its icon paint stays unchanged and the button does not shrink as the label wraps. This scoped rule does not alter other Pills compositions.
|
|
84
|
+
|
|
85
|
+
Rules clusters and individual chips shrink within their parent. Label parts wrap intrinsically and long identifiers can break inside their part, preserving the separate remove button within the chip at narrow widths.
|
|
86
|
+
|
|
87
|
+
## Rule-builder composition
|
|
88
|
+
|
|
89
|
+
The prescribed composition for structured filters (LemonSqueezy-style query builders):
|
|
90
|
+
|
|
91
|
+
```tsx
|
|
92
|
+
<FilterBar activeCount={rules.length}>
|
|
93
|
+
<FilterBar.Search>{/* search input, consumer-owned */}</FilterBar.Search>
|
|
94
|
+
<FilterBar.Rules>
|
|
95
|
+
{rules.map((rule) => (
|
|
96
|
+
<FilterBar.Rule
|
|
97
|
+
key={rule.id}
|
|
98
|
+
field={rule.fieldLabel}
|
|
99
|
+
operator={rule.operator}
|
|
100
|
+
value={rule.valueLabel}
|
|
101
|
+
onRemove={() => removeRule(rule.id)}
|
|
102
|
+
onEdit={() => editRule(rule)}
|
|
103
|
+
/>
|
|
104
|
+
))}
|
|
105
|
+
</FilterBar.Rules>
|
|
106
|
+
<FilterBar.Builder fields={fieldDefs} initialRule={editingRule} onApply={applyRule} />
|
|
107
|
+
<FilterBar.Summary>{summary}</FilterBar.Summary>
|
|
108
|
+
<FilterBar.Actions>{/* toolbar cluster */}</FilterBar.Actions>
|
|
109
|
+
</FilterBar>
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Rule chips belong to the Pills family per the F6 cardinality rule (Tag = lone dismissible chip, Pills = selectable cluster): `Rule` renders a `Pill` with `removable`, never a `Tag`. The builder popup renders a `Popover` whose title wires the popup's accessible name. Consumers own rule state, field definitions, and what Apply executes; the DS owns chip presentation, popup layout, and the field → operator → value step order.
|
|
113
|
+
|
|
114
|
+
## Advanced-condition composition
|
|
115
|
+
|
|
116
|
+
The prescribed composition for Gyaan-style advanced filters (AND/OR groups with nesting):
|
|
117
|
+
|
|
118
|
+
```tsx
|
|
119
|
+
const [group, setGroup] = useState<ConditionGroupState>({ combinator: 'and', conditions: [...], subgroups: [...] })
|
|
120
|
+
|
|
121
|
+
<FilterBar>
|
|
122
|
+
<FilterBar.ConditionGroup
|
|
123
|
+
aria-label="Advanced conditions"
|
|
124
|
+
combinator={group.combinator}
|
|
125
|
+
onCombinatorChange={(next) => setGroup({ ...group, combinator: next })}
|
|
126
|
+
onAddCondition={addCondition}
|
|
127
|
+
onAddSubgroup={addSubgroup}
|
|
128
|
+
onClearAll={clearGroup}
|
|
129
|
+
>
|
|
130
|
+
{group.conditions.map((cond) => (
|
|
131
|
+
<FilterBar.Condition
|
|
132
|
+
key={cond.id}
|
|
133
|
+
field={labelFor(cond.field)}
|
|
134
|
+
operator={cond.operator}
|
|
135
|
+
value={cond.value}
|
|
136
|
+
onRemove={() => removeCondition(cond.id)}
|
|
137
|
+
/>
|
|
138
|
+
))}
|
|
139
|
+
{group.subgroups.map((sub, i) => (
|
|
140
|
+
<FilterBar.ConditionGroup key={sub.id} aria-label={`Subgroup ${i + 1}`} /* ...same handlers, nested */ />
|
|
141
|
+
))}
|
|
142
|
+
</FilterBar.ConditionGroup>
|
|
143
|
+
</FilterBar>
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Conditions reuse the rule part presentation (`field`/`operator`/`value` spans) but render as group rows with trash delete instead of Pills remove, so the Pill remove affordance and the condition trash affordance never compete. Consumers own the group tree, combinator state, and what Add/Clear executes; the DS owns group layout, nesting indent, toggle presentation, and the action row.
|
|
147
|
+
|
|
148
|
+
## Condition editor (docked BI panel)
|
|
149
|
+
|
|
150
|
+
For condition trees that outgrow the Builder popup, `FilterBar.ConditionEditor` docks the editor beside the accumulation surface instead of floating it: a field rail (one button per field def, `aria-pressed` on the active field) on the left, the selected field's operator select plus its value editor on the right, Apply/New beneath. It accepts `fields` (same shape as `Builder`), a controlled `draft` (`{ field, operator, value }`) with `onDraftChange`, an `operators` fallback, `title` (default `Condition editor`), `submitLabel` (default `Apply`), and `newLabel` (default `New`); `onApply` fires Apply (disabled until field and operator are set), `onNew` fires New and renders the New button only when passed — omit it when the hosting group already offers Add condition, so there is exactly one entry point. The operator/value editors are the same internals as the Builder popup — typed editors, `renderValue` hatch, and range encoding behave identically in both. The editor is a single slot (no sub-slots): the value-editor machinery stays internal so the two surfaces cannot drift. Consumers own the draft and what Apply/New executes; the DS owns rail/config/actions layout, the framed card surface, and the named `Condition editor` group.
|
|
151
|
+
|
|
152
|
+
## Checked-filter pills with counts and overflow
|
|
153
|
+
|
|
154
|
+
The drill-down multi-select pattern (counts per option, collapse, clear) on the Rules cluster:
|
|
155
|
+
|
|
156
|
+
```tsx
|
|
157
|
+
<FilterBar.Rules aria-label="Checked filters" maxVisible={2} onClearAll={clearChecked}>
|
|
158
|
+
{checked.map((f) => (
|
|
159
|
+
<FilterBar.Rule key={f.id} field={f.field} operator={f.operator} value={f.value} count={f.count} onRemove={() => uncheck(f.id)} />
|
|
160
|
+
))}
|
|
161
|
+
</FilterBar.Rules>
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
`count` paints the per-option match count after the value. Past `maxVisible`, the cluster collapses behind `+N more` with `Show less` to collapse and `Clear` to reset. Faceted drill-down with select-all stays DataTable-owned (`DataTable.FacetedFilter`); this pattern covers the standalone-bar equivalent without duplicating it.
|
|
165
|
+
|
|
166
|
+
## Toolbar cluster prescription
|
|
167
|
+
|
|
168
|
+
The shared toolbar cluster, in order: search (`FilterBar.Search`), Columns control (DataTable-owned, see below), Filters button with active-count `Badge`, Export action. The order and behavior are shared with `DataTable.Toolbar`; only the host differs.
|
|
169
|
+
|
|
170
|
+
- Search flex-grows (`flex: 1 1 12rem`) and collapses first on narrow widths.
|
|
171
|
+
- The Filters button carries a `Badge` count (`FilterBar.Count` reads the root `activeCount` for the same number) and opens the filter surface; it is never a second clear affordance.
|
|
172
|
+
- Export is a plain action; it never mutates filter state.
|
|
173
|
+
|
|
174
|
+
## FilterBar vs DataTable.Toolbar
|
|
175
|
+
|
|
176
|
+
`FilterBar` is the standalone bar for custom surfaces: consumer-composed controls, rule chips, and actions with no table attached. `DataTable.Toolbar` is the built-in shell toolbar: search, column visibility, export, and row counts wired to table state (`Search`, `ColumnVisibility`, `Export`, `RowCount`). Use `FilterBar` when the surface is custom; use `DataTable.Toolbar` when the table owns the query. Columns visibility and faceted drill-down multi-select (counts per option, select-all) stay DataTable-owned (`ColumnVisibility`, `FacetedFilter`) and are deliberately not re-implemented here — the toolbar cluster prescription above references them without duplicating them.
|
|
177
|
+
|
|
178
|
+
## FilterBar → DataTable bridge
|
|
179
|
+
|
|
180
|
+
Rules are consumer state; `DataTable` consumes them through its controlled filter/search/sort props. The connection story, worked through:
|
|
181
|
+
|
|
182
|
+
```tsx
|
|
183
|
+
// 1. FilterBar owns the rule drafts (consumer state, never table state).
|
|
184
|
+
const [rules, setRules] = useState<FilterRule[]>([])
|
|
185
|
+
const [query, setQuery] = useState('')
|
|
186
|
+
const [sort, setSort] = useState<{ sortBy: string; sortOrder: 'asc' | 'desc' } | null>(null)
|
|
187
|
+
|
|
188
|
+
// 2. Translate rules into the table's faceted-filter shape
|
|
189
|
+
// (DataTableFacetedFilterState: { columnId, accessorKey, selectedValues: Set<string> }).
|
|
190
|
+
const facetedFilters = rules.map((rule) => ({
|
|
191
|
+
columnId: rule.field,
|
|
192
|
+
accessorKey: rule.field,
|
|
193
|
+
selectedValues: new Set([rule.value]),
|
|
194
|
+
}))
|
|
195
|
+
|
|
196
|
+
// 3. Feed the table; take sort/search back out of it.
|
|
197
|
+
<DataTable
|
|
198
|
+
columns={columns}
|
|
199
|
+
data={rows}
|
|
200
|
+
facetedFilters={facetedFilters}
|
|
201
|
+
onFacetedFiltersChange={(next) => setRules(fromFaceted(next))}
|
|
202
|
+
sortBy={sort?.sortBy}
|
|
203
|
+
sortOrder={sort?.sortOrder}
|
|
204
|
+
onSortChange={(sortBy, sortOrder) => setSort({ sortBy, sortOrder })}
|
|
205
|
+
/>
|
|
206
|
+
<FilterBar activeCount={rules.length}>
|
|
207
|
+
{/* rule chips + builder writing `rules`, search writing `query` */}
|
|
208
|
+
</FilterBar>
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Direction of travel: FilterBar → consumer state → DataTable props. The table never reads FilterBar slots, and FilterBar never reads table state; the consumer's translation layer (`rules ↔ facetedFilters`) is the only coupling. Sort travels the same road (controlled `sortBy`/`sortOrder`/`onSortChange`). Search stays consumer-side (`FilterBar.Search` writes `query`): client-side apps filter rows with `rules + query` together, and server-side apps send the translated state (`facetedFilters`, `sortBy`/`sortOrder`, `query`) as their query params instead of filtering client-side.
|
|
212
|
+
|
|
213
|
+
## Composition recipes (app-owned, documented here)
|
|
214
|
+
|
|
215
|
+
- **Single-filter backends.** When the API accepts one filter, the Builder's `onApply` replaces instead of appends (`setRules([rule])`), and `Rules` renders at most one chip. No Builder prop changes; the cardinality lives in consumer state.
|
|
216
|
+
- **Searchable enums.** Enum fields past ~7 options switch the value editor from `Select` to `Combobox` (list search) via `renderValue`. Below the threshold the built-in `Select` applies.
|
|
217
|
+
- **Refine entry with count.** The `Builder` `count` prop badges the default `+ Add filter` trigger, giving the bar one adhesive filter entry with its number attached. Pair with a view switcher (`SegmentedControl`) and a result count (`FilterBar.Summary`) for the Refine | View | Count trio — composed by the app, never a new slot.
|
|
218
|
+
- **BI-panel advanced builder.** For AND/OR condition trees that outgrow the popup, dock the editor beside the accumulation surface instead of floating it: a field rail (one button per field def) on the left, the selected field's operator select plus its `renderValue` editor on the right, Apply/Cancel beneath, and the `ConditionGroup` rows as the top-to-bottom accumulation below or beside. Row click loads the condition into the panel (selected state); trash removes in place. Every typed editor is reused through `renderValue`, so date/person/number/range behave identically in the panel and the popup. No new slots — arrangement only.
|
|
219
|
+
|
|
43
220
|
## CSS class contract
|
|
44
221
|
|
|
45
|
-
Root `dsx-filter-bar` writes `data-size`. Slot classes are `dsx-filter-bar__group`, `__summary`, `__actions`, and `__clear`. The shell uses flex wrapping without embedded product breakpoints.
|
|
222
|
+
Root `dsx-filter-bar` writes `data-size`. Slot classes are `dsx-filter-bar__group`, `__search`, `__rules`, `__rule`, `__condition-group`, `__condition`, `__summary`, `__actions`, and `__clear`. Rule parts are `dsx-filter-bar__rule-label`, `__rule-field`, `__rule-operator`, `__rule-value` (empty string renders an `empty` pill via `data-empty="true"`), and `__rule-count` (shared by `Rule` and `Condition`); an `active` rule writes `data-active` on the chip. Rules overflow is `dsx-filter-bar__rules-overflow`. Condition-group parts are `__condition-combinator`, `__condition-combinator-label`, `__condition-match-label` (Any/All sentence header), `__condition-children`, `__condition-rows-label` (`Where:` head), `__condition-empty` (hint line for childless groups, which also write `data-empty="true"`), `__condition`, `__condition-label`, and `__condition-actions`; condition rows prepend `__condition-grip` when draggable and lay inline editors out as `__condition-field` / `__condition-operator` / `__condition-value`. Per-gap logic renders `__condition-gap` pill rows between children. nesting indents through a rail (inset start border on the descendant selector), not a depth attribute. Condition rows are full-width flex top-to-bottom: the label grows (long values ellipsize) and the trash delete pins to the right edge. Builder parts are `dsx-filter-bar__builder`, `__builder-anchor` (triggerless centering span), `__builder-field`, `__builder-label`, `__builder-actions`. Condition-editor parts are `dsx-filter-bar__condition-editor` (framed card, `role="group"` named by `title`), `__condition-editor-title`, `__condition-editor-body` (rail + config grid), `__condition-editor-fields` (rail), `__condition-editor-config`, `__condition-editor-field`, `__condition-editor-label`, `__condition-editor-actions`. The editor writes no `data-*` attributes; the rail's active field is `aria-pressed` on the button. The Builder's field/operator/value selects ride the shared nested floating tier (see the contract in `menu.md`): the Builder popup is a `Popover` host, so its option lists escalate to `modal + 2` automatically via `dsx-menu__nested` — the round-3 scoped `dsx-filter-bar__builder-select` override is retired. Rule parts render in the chip font throughout (field, operator, and value share one weight; the operator is distinguished by `on-surface-variant` color only). The shell uses flex wrapping without embedded product breakpoints. No new `data-variant`, `data-accent-color`, `data-radius`, or `data-high-contrast` attributes are written by FilterBar source (Pills, Badge, Popover, Select, Input, IconButton, Icon, and Button write their own in their files), so the component-contract profile stays size-only.
|
|
46
223
|
|
|
47
224
|
## Token mapping
|
|
48
225
|
|
|
49
226
|
| Property | Token | Role |
|
|
50
227
|
|---|---|---|
|
|
51
|
-
| Gap/padding |
|
|
228
|
+
| Gap/padding | `--dsx-filter-bar-gap` / `--dsx-filter-bar-padding` (per-size: `space-xs`–`space-md` / `space-sm`–`space-lg`) | Responsive wrapping rhythm |
|
|
52
229
|
| Border | `var(--dsx-control-separator-color)` | Muted toolbar edge |
|
|
53
230
|
| Background | `var(--dsx-color-surface-raised)` | Toolbar surface |
|
|
54
231
|
| Radius | `var(--dsx-rounded-lg)` | Shell roundness |
|
|
232
|
+
| Control height | `--dsx-filter-bar-control-height` (`density-control-height-sm` / `-height` / `-height-lg`) | Row alignment for chips |
|
|
233
|
+
| Summary type | per-size `label-small` / `body-small` / `body-medium` | Density-matched summary |
|
|
234
|
+
| Rule operator/label | `on-surface-variant`, chip font throughout | Chip part hierarchy |
|
|
235
|
+
| Builder label | `on-surface-variant`, `label-small` | Popup field labels |
|
|
55
236
|
|
|
56
237
|
## Motion contract
|
|
57
238
|
|
|
58
|
-
No motion.
|
|
239
|
+
No motion. The builder popup inherits the Popover motion contract (reduced-motion aware); rule chips have no transitions.
|
|
59
240
|
|
|
60
241
|
## Accessibility
|
|
61
242
|
|
|
62
|
-
The root is a named toolbar. Tab order follows DOM order and controls retain their own semantics; FilterBar does not implement roving focus because it may contain form controls. Groups may provide their own accessible names. Clear is a native button and never mutates sibling controls automatically.
|
|
243
|
+
The root is a named toolbar. Tab order follows DOM order and controls retain their own semantics; FilterBar does not implement roving focus because it may contain form controls. Groups may provide their own accessible names. Clear is a native button and never mutates sibling controls automatically. Rule chips render in a list (`Rules` is a `ul`, including the overflow row which is an `li`); the remove affordance is the Pills remove button and the edit affordance is a named button (`Edit filter: field operator value`), so both are keyboard-reachable with no nested-interactive violation. Condition groups take `role="group"` only when named via `aria-label`; the AND/OR toggle is an `aria-pressed` button pair, the overflow `+N more` carries `aria-expanded` with a counted label, and condition delete is a named trash button (`Remove condition` by default). The builder popup is a Popover with a title-wired accessible name; its field/operator/value controls are labelled (visible label spans for the selects, native label for the value input).
|
|
63
244
|
|
|
64
245
|
## Playground demo spec
|
|
65
246
|
|
|
66
|
-
|
|
247
|
+
The orders workspace separates three consumer-defined bands: search plus the Add filter/More command group; applied rules followed immediately by one Clear filters action; and a passive results count. The applied band exists only while a query or condition is active. Clear resets the query, simple rules, advanced conditions, selection, and page, then hides the emptied advanced editor. Its position follows the labels rather than the far edge of the results row. Advanced conditions have an editable/removable summary chip even while their editor is hidden; hiding that editor does not disable applied conditions. A group's Clear conditions action resets only that group. Advanced filters and Export live in the More menu at every width. Group slots accept layout styles for these full-width bands; the package does not invent a width-driven mode. Search clamps its minimum to the available width. Related commands stay together, with intrinsic wrapping as the containment fallback.
|
|
248
|
+
|
|
249
|
+
Research: [PatternFly toolbar guidelines](https://www.patternfly.org/components/toolbar/design-guidelines/) group related controls and use overflow for secondary actions. Local Primer Table's named filter/actions regions and ActionBar's grouping/overflow model informed the composition; see the data-stream decisions for pinned source references.
|
|
250
|
+
|
|
251
|
+
Show ONE complete workspace in the live example: a 28-row orders dataset (text, person, status, currency, date, tag columns) with FilterBar query + typed rule Builder, removable and editable rule chips, a toggleable advanced AND/OR condition group wired to the same rows, a passive selectable DataTable payload with bulk actions and the DataTable pagination footer. The workspace Builder plugs `renderValue` with the `DatePicker` (Placed) and `Combobox` (Owner) dedicated subpaths — the package stays Input-backed per barrel policy; rule chips display owner labels while rule state keeps raw values. The workspace DataTable sets `wrapScrollArea` so the 7-column table scrolls internally at narrow widths and the bar wraps into clean rows instead of stretching past the viewport. Consumer-owned `query`, rules, and group tree filter the same dataset; the summary counts visible rows (`N of M orders`); Export downloads those rows with a count label; Clear resets query, rules, group, selection, and page. The result table uses `showToolbar={false}` so the FilterBar is the only tool zone, with `selectionMode="multiple"` so the bulk bar proves itself against live filters. Use a ten-row page to make filtering and pagination directly testable. The dataset-empty state is proven on the DataTable route; the workspace proves the filtered-empty state with its Clear recovery. Advanced condition-group and overflow mechanics stay unit-tested component capabilities; the workspace additionally wires one live group tree.
|
|
67
252
|
|
|
68
253
|
## Wiring notes
|
|
69
254
|
|
|
70
|
-
Consumers own all filter values, reset logic, query execution, date-range policy, and domain fields. The DS owns only layout, slots, accessible naming, and
|
|
255
|
+
Consumers own all filter values, rule state, field definitions, reset logic, query execution, date-range policy, and domain fields. The DS owns only layout, slots, accessible naming, Clear styling, rule-chip presentation, and the builder popup shell. Drill-down multi-select with per-option counts and select-all is owned by `DataTable.FacetedFilter`; column visibility is owned by `DataTable.Toolbar.ColumnVisibility`.
|