Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .changeset/data-table-filter-redesign.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
"@tailor-platform/app-shell": minor
---

Redesign `DataTable.Filters` for a faster, more direct filtering experience.

- **Add-filter menu**: replaces the popover + nested selects with a `Menu` flyout. Every filterable field is visible on open; hovering a field reveals a type-specific editor. Fields whose operator matters (number, date/time) get a condition step — **field ▸ condition ▸ value** — while others go straight to the value.
- **Segmented filter chips**: each active filter renders as `field │ operator │ value │ ✕`. The operator segment opens a searchable dropdown to switch the condition; the value segment opens the type editor.
- **New `FilterConfig.chooseOperator?: boolean`**: opt a field in/out of the condition step. Defaults to `true` for `number`/`date`/`datetime`/`time` and `false` otherwise. The chip always lets you change the operator regardless.
- Friendlier operator labels (`is`, `is not`, `is between`, `is any of`, …), multi-select enum values summarized as "N items", compact date ranges, and consistent primary-colored checkboxes across all filter surfaces.
- `Menu.Content` gains a `position.trackAnchor` option to keep a menu pinned in place when opening it shifts the trigger.
14 changes: 9 additions & 5 deletions packages/core/src/components/data-table/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,12 @@ export const dataTableLabels = defineI18nLabels({
addFilter: "Add filter",
applyFilter: "Apply",
removeFilter: "Remove filter",
filterOperatorSearchPlaceholder: "Search...",
filterValuePlaceholder: (props: { field: string }) => `Enter ${props.field.toLowerCase()}`,
filterBooleanTrue: "True",
filterBooleanFalse: "False",
filterOperator_eq: "equals",
filterOperator_ne: "not equals",
filterOperator_eq: "is",
filterOperator_ne: "is not",
filterOperator_gt: "greater than",
filterOperator_gte: "greater than or equal",
filterOperator_lt: "less than",
Expand All @@ -47,9 +49,9 @@ export const dataTableLabels = defineI18nLabels({
filterOperator_hasSuffix: "ends with",
filterOperator_notHasPrefix: "does not start with",
filterOperator_notHasSuffix: "does not end with",
filterOperator_between: "between",
filterOperator_in: "in",
filterOperator_nin: "not in",
filterOperator_between: "is between",
filterOperator_in: "is any of",
filterOperator_nin: "is none of",
// Date-specific operator labels (date filters drop gt/lt/ne and treat the
// boundary as inclusive).
filterDateOperator_eq: "exact date",
Expand Down Expand Up @@ -90,6 +92,8 @@ export const dataTableLabels = defineI18nLabels({
addFilter: "フィルタを追加",
applyFilter: "適用",
removeFilter: "フィルタを削除",
filterOperatorSearchPlaceholder: "検索...",
filterValuePlaceholder: (props: { field: string }) => `${props.field}を入力`,
filterBooleanTrue: "真",
filterBooleanFalse: "偽",
filterOperator_eq: "と等しい",
Expand Down
Loading
Loading