@cognite/aura 1.47284.0 → 1.47358.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/CHANGELOG.md CHANGED
@@ -6,6 +6,10 @@ PR references prefixed with `cognitedata/fusion` were merged in Fusion before th
6
6
 
7
7
  ### Added
8
8
 
9
+ - `DataGridFilterColumn` now accepts an optional `operators` list so each column can restrict which filter operators appear in `DataGridFilterPanel`.
10
+ - `DataGridFilterPanel` accepts optional `hasActiveFilters` (defaults to `true`).
11
+ Pass `false` to disable Clear all when nothing is applied.
12
+ Apply stays disabled until the draft has a non-empty value when `onApply` is provided.
9
13
  - Added `Item` compositional list-row primitive with group, media, actions, tree chevron, checkbox, indent, and section-header parts for flexible lists and tree views, exposed as `@cognite/aura/components/item`. [KCIH-1095] cognitedata/fusion#27311
10
14
  - Added `Tree` hierarchical list primitive with chevron expand/collapse and optional cascading checkboxes built on Headless Tree and `Item` rows, exposed as `@cognite/aura/components/tree`. [KCIH-1096] cognitedata/fusion#27705
11
15
  - Added `Conversation` primitives, exposed as `@cognite/aura/components/conversation`. [AX-442] cognitedata/fusion#26450
@@ -24,6 +28,8 @@ PR references prefixed with `cognitedata/fusion` were merged in Fusion before th
24
28
 
25
29
  ### Changed
26
30
 
31
+ - `DataGridFilterTrigger` now renders as a labeled button with the filter icon and visible text, matching the Data grid toolbar filtering spec.
32
+ The unused `placement` prop was removed.
27
33
  - Regenerated `colors.css` from the Figma Reflect tokens and synced form, overlay, navigation, button, AI, and chart components to them. cognitedata/fusion#26261, cognitedata/fusion#26265
28
34
  - Deprecated the legacy color tokens, which are now aliases of the `colors.css` tokens and live in `@cognite/aura/colors-deprecated.css`. cognitedata/fusion#26260, cognitedata/fusion#26644
29
35
  - Unified the decorative variant slots for `Badge` and `Avatar` while preserving the legacy ramp steps. cognitedata/fusion#26643, cognitedata/fusion#27170
package/DESIGN.md CHANGED
@@ -1201,6 +1201,7 @@ Persistent or dismissible message scoped at page or section level — stronger t
1201
1201
 
1202
1202
  **Storybook-slug:** breadcrumb
1203
1203
  **Docs-slug:** breadcrumbs
1204
+ **Full guidance:** [breadcrumb.md](./src/components/ui/core/breadcrumb/breadcrumb.md)
1204
1205
 
1205
1206
  **Definition**
1206
1207
  Hierarchical navigation aid that shows users their current location within the product's structure. Location-based, not path-based.
@@ -1260,6 +1261,7 @@ Primary control for discrete actions.
1260
1261
  #### Button Group
1261
1262
 
1262
1263
  **Storybook-slug:** button-group
1264
+ **Full guidance:** [button-group.md](./src/components/ui/core/button-group/button-group.md)
1263
1265
 
1264
1266
  **Definition**
1265
1267
  Visually joins related buttons into a connected row, clarifying that the actions belong to the same context.
@@ -1349,6 +1351,7 @@ Enables users to independently select one or multiple options. Can appear standa
1349
1351
 
1350
1352
  **Storybook-slug:** collapsible
1351
1353
  **Docs-slug:** collapsible
1354
+ **Full guidance:** [collapsible.md](./src/components/ui/core/collapsible/collapsible.md)
1352
1355
 
1353
1356
  **Definition**
1354
1357
  A single inline expandable block that toggles content visibility. Designed for one independent optional section, not multiple stacked areas.
@@ -0,0 +1,2 @@
1
+ import type { ReactElement } from "react";
2
+ export declare function BreadcrumbGallery(): ReactElement;
@@ -0,0 +1,31 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator } from "./breadcrumb.js";
3
+ export function BreadcrumbGallery() {
4
+ return /*#__PURE__*/ _jsx(Breadcrumb, {
5
+ children: /*#__PURE__*/ _jsxs(BreadcrumbList, {
6
+ children: [
7
+ /*#__PURE__*/ _jsx(BreadcrumbItem, {
8
+ children: /*#__PURE__*/ _jsx(BreadcrumbLink, {
9
+ href: "/",
10
+ children: "Home"
11
+ })
12
+ }),
13
+ /*#__PURE__*/ _jsx(BreadcrumbSeparator, {}),
14
+ /*#__PURE__*/ _jsx(BreadcrumbItem, {
15
+ children: /*#__PURE__*/ _jsx(BreadcrumbLink, {
16
+ href: "/projects",
17
+ children: "Projects"
18
+ })
19
+ }),
20
+ /*#__PURE__*/ _jsx(BreadcrumbSeparator, {}),
21
+ /*#__PURE__*/ _jsx(BreadcrumbItem, {
22
+ children: /*#__PURE__*/ _jsx(BreadcrumbPage, {
23
+ children: "Project Alpha"
24
+ })
25
+ })
26
+ ]
27
+ })
28
+ });
29
+ }
30
+
31
+ //# sourceMappingURL=breadcrumb.gallery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../src/components/ui/core/breadcrumb/breadcrumb.gallery.tsx"],"sourcesContent":["import type { ReactElement } from 'react';\n\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from './breadcrumb';\n\nexport function BreadcrumbGallery(): ReactElement {\n return (\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem>\n <BreadcrumbLink href=\"/\">Home</BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbLink href=\"/projects\">Projects</BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbPage>Project Alpha</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n );\n}\n"],"names":["Breadcrumb","BreadcrumbItem","BreadcrumbLink","BreadcrumbList","BreadcrumbPage","BreadcrumbSeparator","BreadcrumbGallery","href"],"mappings":";AAEA,SACEA,UAAU,EACVC,cAAc,EACdC,cAAc,EACdC,cAAc,EACdC,cAAc,EACdC,mBAAmB,QACd,kBAAe;AAEtB,OAAO,SAASC;IACd,qBACE,KAACN;kBACC,cAAA,MAACG;;8BACC,KAACF;8BACC,cAAA,KAACC;wBAAeK,MAAK;kCAAI;;;8BAE3B,KAACF;8BACD,KAACJ;8BACC,cAAA,KAACC;wBAAeK,MAAK;kCAAY;;;8BAEnC,KAACF;8BACD,KAACJ;8BACC,cAAA,KAACG;kCAAe;;;;;;AAK1B"}
@@ -0,0 +1,2 @@
1
+ import type { ReactElement } from "react";
2
+ export declare function ButtonGroupGallery(): ReactElement;
@@ -0,0 +1,62 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button } from "../button/button.js";
3
+ import { ButtonGroup } from "./button-group.js";
4
+ export function ButtonGroupGallery() {
5
+ return /*#__PURE__*/ _jsxs("div", {
6
+ className: "flex flex-col gap-8",
7
+ children: [
8
+ /*#__PURE__*/ _jsxs("div", {
9
+ children: [
10
+ /*#__PURE__*/ _jsx("h3", {
11
+ className: "mb-3 font-semibold text-sm",
12
+ children: "Horizontal"
13
+ }),
14
+ /*#__PURE__*/ _jsxs(ButtonGroup, {
15
+ orientation: "horizontal",
16
+ children: [
17
+ /*#__PURE__*/ _jsx(Button, {
18
+ variant: "outline",
19
+ children: "First"
20
+ }),
21
+ /*#__PURE__*/ _jsx(Button, {
22
+ variant: "outline",
23
+ children: "Second"
24
+ }),
25
+ /*#__PURE__*/ _jsx(Button, {
26
+ variant: "outline",
27
+ children: "Third"
28
+ })
29
+ ]
30
+ })
31
+ ]
32
+ }),
33
+ /*#__PURE__*/ _jsxs("div", {
34
+ children: [
35
+ /*#__PURE__*/ _jsx("h3", {
36
+ className: "mb-3 font-semibold text-sm",
37
+ children: "Vertical"
38
+ }),
39
+ /*#__PURE__*/ _jsxs(ButtonGroup, {
40
+ orientation: "vertical",
41
+ children: [
42
+ /*#__PURE__*/ _jsx(Button, {
43
+ variant: "outline",
44
+ children: "First"
45
+ }),
46
+ /*#__PURE__*/ _jsx(Button, {
47
+ variant: "outline",
48
+ children: "Second"
49
+ }),
50
+ /*#__PURE__*/ _jsx(Button, {
51
+ variant: "outline",
52
+ children: "Third"
53
+ })
54
+ ]
55
+ })
56
+ ]
57
+ })
58
+ ]
59
+ });
60
+ }
61
+
62
+ //# sourceMappingURL=button-group.gallery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../src/components/ui/core/button-group/button-group.gallery.tsx"],"sourcesContent":["import type { ReactElement } from 'react';\n\nimport { Button } from '../button/button';\n\nimport { ButtonGroup } from './button-group';\n\nexport function ButtonGroupGallery(): ReactElement {\n return (\n <div className=\"flex flex-col gap-8\">\n <div>\n <h3 className=\"mb-3 font-semibold text-sm\">Horizontal</h3>\n <ButtonGroup orientation=\"horizontal\">\n <Button variant=\"outline\">First</Button>\n <Button variant=\"outline\">Second</Button>\n <Button variant=\"outline\">Third</Button>\n </ButtonGroup>\n </div>\n <div>\n <h3 className=\"mb-3 font-semibold text-sm\">Vertical</h3>\n <ButtonGroup orientation=\"vertical\">\n <Button variant=\"outline\">First</Button>\n <Button variant=\"outline\">Second</Button>\n <Button variant=\"outline\">Third</Button>\n </ButtonGroup>\n </div>\n </div>\n );\n}\n"],"names":["Button","ButtonGroup","ButtonGroupGallery","div","className","h3","orientation","variant"],"mappings":";AAEA,SAASA,MAAM,QAAQ,sBAAmB;AAE1C,SAASC,WAAW,QAAQ,oBAAiB;AAE7C,OAAO,SAASC;IACd,qBACE,MAACC;QAAIC,WAAU;;0BACb,MAACD;;kCACC,KAACE;wBAAGD,WAAU;kCAA6B;;kCAC3C,MAACH;wBAAYK,aAAY;;0CACvB,KAACN;gCAAOO,SAAQ;0CAAU;;0CAC1B,KAACP;gCAAOO,SAAQ;0CAAU;;0CAC1B,KAACP;gCAAOO,SAAQ;0CAAU;;;;;;0BAG9B,MAACJ;;kCACC,KAACE;wBAAGD,WAAU;kCAA6B;;kCAC3C,MAACH;wBAAYK,aAAY;;0CACvB,KAACN;gCAAOO,SAAQ;0CAAU;;0CAC1B,KAACP;gCAAOO,SAAQ;0CAAU;;0CAC1B,KAACP;gCAAOO,SAAQ;0CAAU;;;;;;;;AAKpC"}
@@ -0,0 +1,2 @@
1
+ import type { ReactElement } from "react";
2
+ export declare function CollapsibleGallery(): ReactElement;
@@ -0,0 +1,39 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { IconSelector } from "@tabler/icons-react";
3
+ import { Badge } from "../badge/badge.js";
4
+ import { Button } from "../button/button.js";
5
+ import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "./collapsible.js";
6
+ export function CollapsibleGallery() {
7
+ return /*#__PURE__*/ _jsxs(Collapsible, {
8
+ className: "w-120 max-w-full space-y-2",
9
+ children: [
10
+ /*#__PURE__*/ _jsx(CollapsibleTrigger, {
11
+ render: /*#__PURE__*/ _jsxs(Button, {
12
+ variant: "ghost",
13
+ className: "h-9 w-full justify-between rounded-sm px-3 py-2 gap-2",
14
+ children: [
15
+ /*#__PURE__*/ _jsx("span", {
16
+ className: "flex-1 text-left",
17
+ children: "What is a collapsible?"
18
+ }),
19
+ /*#__PURE__*/ _jsx(Badge, {
20
+ className: "h-5 bg-decorative-background-mountain px-1 text-decorative-foreground-mountain",
21
+ children: "Badge"
22
+ }),
23
+ /*#__PURE__*/ _jsx(IconSelector, {
24
+ className: "h-4 w-4 transition-transform duration-200 group-data-panel-open/collapsible-trigger:rotate-180"
25
+ })
26
+ ]
27
+ })
28
+ }),
29
+ /*#__PURE__*/ _jsx(CollapsibleContent, {
30
+ children: /*#__PURE__*/ _jsx("div", {
31
+ className: "px-3 py-0",
32
+ children: "A collapsible is an interactive component that expands and collapses to show or hide content. Multiple collapsibles can be open at the same time, unlike accordions which are mutually exclusive."
33
+ })
34
+ })
35
+ ]
36
+ });
37
+ }
38
+
39
+ //# sourceMappingURL=collapsible.gallery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../src/components/ui/core/collapsible/collapsible.gallery.tsx"],"sourcesContent":["import type { ReactElement } from 'react';\n\nimport { IconSelector } from '@tabler/icons-react';\n\nimport { Badge } from '../badge/badge';\nimport { Button } from '../button/button';\n\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from './collapsible';\n\nexport function CollapsibleGallery(): ReactElement {\n return (\n <Collapsible className=\"w-120 max-w-full space-y-2\">\n <CollapsibleTrigger\n render={\n <Button\n variant=\"ghost\"\n className=\"h-9 w-full justify-between rounded-sm px-3 py-2 gap-2\"\n >\n <span className=\"flex-1 text-left\">What is a collapsible?</span>\n <Badge className=\"h-5 bg-decorative-background-mountain px-1 text-decorative-foreground-mountain\">\n Badge\n </Badge>\n <IconSelector className=\"h-4 w-4 transition-transform duration-200 group-data-panel-open/collapsible-trigger:rotate-180\" />\n </Button>\n }\n />\n <CollapsibleContent>\n <div className=\"px-3 py-0\">\n A collapsible is an interactive component that expands and collapses\n to show or hide content. Multiple collapsibles can be open at the same\n time, unlike accordions which are mutually exclusive.\n </div>\n </CollapsibleContent>\n </Collapsible>\n );\n}\n"],"names":["IconSelector","Badge","Button","Collapsible","CollapsibleContent","CollapsibleTrigger","CollapsibleGallery","className","render","variant","span","div"],"mappings":";AAEA,SAASA,YAAY,QAAQ,sBAAsB;AAEnD,SAASC,KAAK,QAAQ,oBAAiB;AACvC,SAASC,MAAM,QAAQ,sBAAmB;AAE1C,SACEC,WAAW,EACXC,kBAAkB,EAClBC,kBAAkB,QACb,mBAAgB;AAEvB,OAAO,SAASC;IACd,qBACE,MAACH;QAAYI,WAAU;;0BACrB,KAACF;gBACCG,sBACE,MAACN;oBACCO,SAAQ;oBACRF,WAAU;;sCAEV,KAACG;4BAAKH,WAAU;sCAAmB;;sCACnC,KAACN;4BAAMM,WAAU;sCAAiF;;sCAGlG,KAACP;4BAAaO,WAAU;;;;;0BAI9B,KAACH;0BACC,cAAA,KAACO;oBAAIJ,WAAU;8BAAY;;;;;AAQnC"}
@@ -1,8 +1,9 @@
1
1
  import { type ComponentProps, type ForwardRefExoticComponent, type RefAttributes } from "react";
2
- import type { DataGridFilterClause } from "./data-grid-filter-clauses";
2
+ import type { DataGridFilterClause, DataGridFilterOperator } from "./data-grid-filter-clauses";
3
3
  type DataGridFilterColumn = {
4
4
  id: string;
5
5
  label: string;
6
+ operators?: DataGridFilterOperator[];
6
7
  };
7
8
  type DataGridFilterPanelLabels = {
8
9
  title: string;
@@ -36,6 +37,7 @@ type DataGridFilterPanelProps = Omit<ComponentProps<"div">, "onChange"> & {
36
37
  onClearAll: () => void;
37
38
  onClose?: () => void;
38
39
  onApply?: () => void;
40
+ hasActiveFilters?: boolean;
39
41
  };
40
42
  declare const DataGridFilterPanel: ForwardRefExoticComponent<DataGridFilterPanelProps & RefAttributes<HTMLDivElement>>;
41
43
  export { DataGridFilterPanel, type DataGridFilterColumn, type DataGridFilterPanelLabels };
@@ -5,6 +5,15 @@ import { cn } from "../../../../lib/utils.js";
5
5
  import { Button } from "../button/button.js";
6
6
  import { Input } from "../input/input.js";
7
7
  import { Select, SelectContent, SelectItem, SelectTrigger } from "../select/select.js";
8
+ const DEFAULT_COLUMN_OPERATORS = [
9
+ 'contains',
10
+ 'equals',
11
+ 'startsWith'
12
+ ];
13
+ function operatorsForColumnId(columns, columnId) {
14
+ const custom = columns.find((column)=>column.id === columnId)?.operators;
15
+ return custom != null && custom.length > 0 ? custom : DEFAULT_COLUMN_OPERATORS;
16
+ }
8
17
  const isDataGridFilterJoin = (value)=>value === 'and' || value === 'or';
9
18
  const isDataGridFilterOperator = (value)=>value === 'contains' || value === 'equals' || value === 'startsWith';
10
19
  const defaultDataGridFilterPanelLabels = {
@@ -28,13 +37,16 @@ const defaultDataGridFilterPanelLabels = {
28
37
  results: (filteredResultCount)=>`Results ${filteredResultCount.toLocaleString()}`,
29
38
  maxClausesReached: (maxClauses)=>`Maximum ${maxClauses} conditions`
30
39
  };
31
- const DataGridFilterPanel = /*#__PURE__*/ forwardRef(function DataGridFilterPanel({ clauses, columns, maxClauses = 5, filteredResultCount, lockedColumnId, labels: labelOverrides, onChange, onClearAll, onClose, onApply, className, ...props }, ref) {
40
+ const DataGridFilterPanel = /*#__PURE__*/ forwardRef(function DataGridFilterPanel({ clauses, columns, maxClauses = 5, filteredResultCount, lockedColumnId, labels: labelOverrides, onChange, onClearAll, onClose, onApply, hasActiveFilters = true, className, ...props }, ref) {
32
41
  const labels = {
33
42
  ...defaultDataGridFilterPanelLabels,
34
43
  ...labelOverrides
35
44
  };
36
45
  const canAddClause = clauses.length < maxClauses;
37
46
  const uniformJoinValue = clauses[1]?.join ?? 'and';
47
+ const draftHasActiveClause = clauses.some((clause)=>clause.value.trim() !== '');
48
+ const canApply = draftHasActiveClause;
49
+ const columnSelectDisabled = lockedColumnId != null || columns.length <= 1;
38
50
  const operatorLabel = {
39
51
  contains: labels.operatorContains,
40
52
  equals: labels.operatorEquals,
@@ -51,12 +63,16 @@ const DataGridFilterPanel = /*#__PURE__*/ forwardRef(function DataGridFilterPane
51
63
  ...patch
52
64
  } : clause));
53
65
  };
54
- const createClause = (join = 'and')=>({
55
- columnId: lockedColumnId ?? columns[0]?.id ?? '',
56
- operator: 'contains',
66
+ const createClause = (join = 'and')=>{
67
+ const columnId = lockedColumnId ?? columns[0]?.id ?? '';
68
+ const allowed = operatorsForColumnId(columns, columnId);
69
+ return {
70
+ columnId,
71
+ operator: allowed[0],
57
72
  value: '',
58
73
  join
59
- });
74
+ };
75
+ };
60
76
  const addClause = ()=>{
61
77
  if (!canAddClause) return;
62
78
  onChange([
@@ -147,10 +163,15 @@ const DataGridFilterPanel = /*#__PURE__*/ forwardRef(function DataGridFilterPane
147
163
  }),
148
164
  /*#__PURE__*/ _jsxs(Select, {
149
165
  value: clause.columnId,
150
- onValueChange: (value)=>updateClause(index, {
151
- columnId: value
152
- }),
153
- disabled: lockedColumnId != null,
166
+ onValueChange: (value)=>{
167
+ const allowed = operatorsForColumnId(columns, value);
168
+ const operator = allowed.includes(clause.operator) ? clause.operator : allowed[0];
169
+ updateClause(index, {
170
+ columnId: value,
171
+ operator
172
+ });
173
+ },
174
+ disabled: columnSelectDisabled,
154
175
  children: [
155
176
  /*#__PURE__*/ _jsx(SelectTrigger, {
156
177
  "aria-label": labels.column,
@@ -174,27 +195,18 @@ const DataGridFilterPanel = /*#__PURE__*/ forwardRef(function DataGridFilterPane
174
195
  });
175
196
  }
176
197
  },
198
+ disabled: operatorsForColumnId(columns, clause.columnId).length <= 1,
177
199
  children: [
178
200
  /*#__PURE__*/ _jsx(SelectTrigger, {
179
201
  "aria-label": labels.operator,
180
202
  className: "h-8 min-w-0 w-full text-sm",
181
203
  children: operatorLabel[clause.operator]
182
204
  }),
183
- /*#__PURE__*/ _jsxs(SelectContent, {
184
- children: [
185
- /*#__PURE__*/ _jsx(SelectItem, {
186
- value: "contains",
187
- children: labels.operatorContains
188
- }),
189
- /*#__PURE__*/ _jsx(SelectItem, {
190
- value: "equals",
191
- children: labels.operatorEquals
192
- }),
193
- /*#__PURE__*/ _jsx(SelectItem, {
194
- value: "startsWith",
195
- children: labels.operatorStartsWith
196
- })
197
- ]
205
+ /*#__PURE__*/ _jsx(SelectContent, {
206
+ children: operatorsForColumnId(columns, clause.columnId).map((operator)=>/*#__PURE__*/ _jsx(SelectItem, {
207
+ value: operator,
208
+ children: operatorLabel[operator]
209
+ }, operator))
198
210
  })
199
211
  ]
200
212
  }),
@@ -254,10 +266,12 @@ const DataGridFilterPanel = /*#__PURE__*/ forwardRef(function DataGridFilterPane
254
266
  /*#__PURE__*/ _jsx(Button, {
255
267
  variant: "ghost",
256
268
  onClick: onClearAll,
269
+ disabled: !hasActiveFilters,
257
270
  children: labels.clearAll
258
271
  }),
259
272
  onApply ? /*#__PURE__*/ _jsx(Button, {
260
273
  onClick: onApply,
274
+ disabled: !canApply,
261
275
  children: labels.apply
262
276
  }) : null
263
277
  ]
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/components/ui/core/data-grid/data-grid-filter-panel.tsx"],"sourcesContent":["import {\n type ChangeEvent,\n type ComponentProps,\n type ComponentRef,\n type ForwardRefExoticComponent,\n type Ref,\n type RefAttributes,\n forwardRef,\n} from 'react';\n\nimport { IconMinus, IconPlus, IconX } from '@tabler/icons-react';\n\nimport { cn } from '../../../../lib/utils';\nimport { Button } from '../button/button';\nimport { Input } from '../input/input';\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n} from '../select/select';\n\nimport type {\n DataGridFilterClause,\n DataGridFilterJoin,\n DataGridFilterOperator,\n} from './data-grid-filter-clauses';\n\ntype DataGridFilterColumn = {\n id: string;\n label: string;\n};\n\nconst isDataGridFilterJoin = (value: string): value is DataGridFilterJoin =>\n value === 'and' || value === 'or';\n\nconst isDataGridFilterOperator = (\n value: string\n): value is DataGridFilterOperator =>\n value === 'contains' || value === 'equals' || value === 'startsWith';\n\ntype DataGridFilterPanelLabels = {\n title: string;\n close: string;\n showFieldsWhere: string;\n join: string;\n joinAnd: string;\n joinOr: string;\n column: string;\n operator: string;\n operatorContains: string;\n operatorEquals: string;\n operatorStartsWith: string;\n value: string;\n valuePlaceholder: string;\n removeClause: string;\n addClause: string;\n clearAll: string;\n apply: string;\n results: (filteredResultCount: number) => string;\n maxClausesReached: (maxClauses: number) => string;\n};\n\nconst defaultDataGridFilterPanelLabels: DataGridFilterPanelLabels = {\n title: 'Filters',\n close: 'Close filters',\n showFieldsWhere: 'Show fields where',\n join: 'Filter join',\n joinAnd: 'And',\n joinOr: 'Or',\n column: 'Filter column',\n operator: 'Filter operator',\n operatorContains: 'Contains',\n operatorEquals: 'Equals',\n operatorStartsWith: 'Starts with',\n value: 'Filter value',\n valuePlaceholder: 'Enter value',\n removeClause: 'Remove filter',\n addClause: 'Add condition',\n clearAll: 'Clear all',\n apply: 'Apply filters',\n results: (filteredResultCount: number) =>\n `Results ${filteredResultCount.toLocaleString()}`,\n maxClausesReached: (maxClauses: number) => `Maximum ${maxClauses} conditions`,\n};\n\ntype DataGridFilterPanelProps = Omit<ComponentProps<'div'>, 'onChange'> & {\n clauses: DataGridFilterClause[];\n columns: DataGridFilterColumn[];\n maxClauses?: number;\n filteredResultCount?: number;\n lockedColumnId?: string;\n labels?: Partial<DataGridFilterPanelLabels>;\n onChange: (clauses: DataGridFilterClause[]) => void;\n onClearAll: () => void;\n onClose?: () => void;\n onApply?: () => void;\n};\n\nconst DataGridFilterPanel: ForwardRefExoticComponent<\n DataGridFilterPanelProps & RefAttributes<HTMLDivElement>\n> = forwardRef<ComponentRef<'div'>, DataGridFilterPanelProps>(\n function DataGridFilterPanel(\n {\n clauses,\n columns,\n maxClauses = 5,\n filteredResultCount,\n lockedColumnId,\n labels: labelOverrides,\n onChange,\n onClearAll,\n onClose,\n onApply,\n className,\n ...props\n }: DataGridFilterPanelProps,\n ref: Ref<ComponentRef<'div'>>\n ) {\n const labels = { ...defaultDataGridFilterPanelLabels, ...labelOverrides };\n const canAddClause = clauses.length < maxClauses;\n const uniformJoinValue = clauses[1]?.join ?? 'and';\n\n const operatorLabel: Record<DataGridFilterOperator, string> = {\n contains: labels.operatorContains,\n equals: labels.operatorEquals,\n startsWith: labels.operatorStartsWith,\n };\n const joinLabel: Record<DataGridFilterJoin, string> = {\n and: labels.joinAnd,\n or: labels.joinOr,\n };\n const columnLabel = (id: string) =>\n columns.find((column: DataGridFilterColumn) => column.id === id)?.label ??\n id;\n\n const updateClause = (\n index: number,\n patch: Partial<DataGridFilterClause>\n ) => {\n onChange(\n clauses.map((clause: DataGridFilterClause, clauseIndex: number) =>\n clauseIndex === index ? { ...clause, ...patch } : clause\n )\n );\n };\n\n const createClause = (\n join: DataGridFilterJoin = 'and'\n ): DataGridFilterClause => ({\n columnId: lockedColumnId ?? columns[0]?.id ?? '',\n operator: 'contains',\n value: '',\n join,\n });\n\n const addClause = () => {\n if (!canAddClause) return;\n onChange([\n ...clauses,\n createClause(clauses[clauses.length - 1]?.join ?? 'and'),\n ]);\n };\n\n const removeClause = (index: number) => {\n const next = clauses.filter(\n (_clause: DataGridFilterClause, clauseIndex: number) =>\n clauseIndex !== index\n );\n onChange(next.length > 0 ? next : [createClause()]);\n };\n\n return (\n <div\n ref={ref}\n data-slot=\"data-grid-filter-panel\"\n className={cn(\n 'w-[min(52rem,calc(100vw-2rem))] rounded-lg border border-border bg-background p-4 shadow-default',\n className\n )}\n {...props}\n >\n <div className=\"mb-2 flex items-center justify-between gap-3\">\n <p className=\"text-base font-medium text-foreground\">\n {labels.title}\n </p>\n {onClose != null && (\n <Button\n size=\"icon-sm\"\n variant=\"ghost\"\n className=\"shrink-0\"\n aria-label={labels.close}\n onClick={onClose}\n >\n <IconX className=\"size-4\" aria-hidden />\n </Button>\n )}\n </div>\n\n <div className=\"grid gap-2\">\n <div className=\"grid grid-cols-[75px_minmax(0,1fr)_minmax(0,1fr)_minmax(0,1fr)_36px] gap-2\">\n <span />\n <span className=\"text-sm font-medium text-muted-foreground\">\n {labels.showFieldsWhere}\n </span>\n </div>\n {clauses.map((clause: DataGridFilterClause, index: number) => (\n <div\n key={clause.id ?? index}\n className=\"grid grid-cols-[75px_minmax(0,1fr)_minmax(0,1fr)_minmax(0,1fr)_36px] items-center gap-2\"\n >\n {index === 0 ? (\n <span />\n ) : index > 1 ? (\n <span className=\"px-3 text-sm font-medium text-foreground capitalize\">\n {uniformJoinValue}\n </span>\n ) : (\n <Select\n value={uniformJoinValue}\n onValueChange={(join: string) => {\n if (isDataGridFilterJoin(join)) {\n onChange(\n clauses.map(\n (\n joined: DataGridFilterClause,\n joinedIndex: number\n ) =>\n joinedIndex === 0 ? joined : { ...joined, join }\n )\n );\n }\n }}\n >\n <SelectTrigger\n aria-label={labels.join}\n className=\"h-8 min-w-0 w-full text-sm\"\n >\n {joinLabel[uniformJoinValue]}\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"and\">{labels.joinAnd}</SelectItem>\n <SelectItem value=\"or\">{labels.joinOr}</SelectItem>\n </SelectContent>\n </Select>\n )}\n <Select\n value={clause.columnId}\n onValueChange={(value: string) =>\n updateClause(index, { columnId: value })\n }\n disabled={lockedColumnId != null}\n >\n <SelectTrigger\n aria-label={labels.column}\n className=\"h-8 min-w-0 w-full text-sm\"\n >\n {columnLabel(clause.columnId)}\n </SelectTrigger>\n <SelectContent>\n {columns.map((column: DataGridFilterColumn) => (\n <SelectItem key={column.id} value={column.id}>\n {column.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <Select\n value={clause.operator}\n onValueChange={(value: string) => {\n if (isDataGridFilterOperator(value)) {\n updateClause(index, { operator: value });\n }\n }}\n >\n <SelectTrigger\n aria-label={labels.operator}\n className=\"h-8 min-w-0 w-full text-sm\"\n >\n {operatorLabel[clause.operator]}\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"contains\">\n {labels.operatorContains}\n </SelectItem>\n <SelectItem value=\"equals\">\n {labels.operatorEquals}\n </SelectItem>\n <SelectItem value=\"startsWith\">\n {labels.operatorStartsWith}\n </SelectItem>\n </SelectContent>\n </Select>\n <Input\n aria-label={labels.value}\n value={clause.value}\n placeholder={labels.valuePlaceholder}\n onChange={(event: ChangeEvent<HTMLInputElement>) =>\n updateClause(index, { value: event.target.value })\n }\n />\n {index === 0 ? (\n <span />\n ) : (\n <Button\n size=\"icon\"\n variant=\"ghost\"\n aria-label={labels.removeClause}\n onClick={() => removeClause(index)}\n >\n <IconMinus className=\"size-4\" aria-hidden=\"true\" />\n </Button>\n )}\n </div>\n ))}\n </div>\n\n <div className=\"mt-3 flex items-center justify-between gap-2 pl-[83px]\">\n <div className=\"flex items-center gap-2\">\n <Button\n variant=\"outline\"\n onClick={addClause}\n disabled={!canAddClause}\n >\n <IconPlus className=\"size-4\" aria-hidden=\"true\" />\n {labels.addClause}\n </Button>\n {filteredResultCount != null && (\n <span className=\"text-sm font-medium text-foreground\">\n {labels.results(filteredResultCount)}\n </span>\n )}\n {!canAddClause ? (\n <span className=\"text-sm text-muted-foreground\">\n {labels.maxClausesReached(maxClauses)}\n </span>\n ) : null}\n </div>\n <div className=\"flex items-center gap-2\">\n <Button variant=\"ghost\" onClick={onClearAll}>\n {labels.clearAll}\n </Button>\n {onApply ? <Button onClick={onApply}>{labels.apply}</Button> : null}\n </div>\n </div>\n </div>\n );\n }\n);\nDataGridFilterPanel.displayName = 'DataGridFilterPanel';\n\nexport {\n DataGridFilterPanel,\n type DataGridFilterColumn,\n type DataGridFilterPanelLabels,\n};\n"],"names":["forwardRef","IconMinus","IconPlus","IconX","cn","Button","Input","Select","SelectContent","SelectItem","SelectTrigger","isDataGridFilterJoin","value","isDataGridFilterOperator","defaultDataGridFilterPanelLabels","title","close","showFieldsWhere","join","joinAnd","joinOr","column","operator","operatorContains","operatorEquals","operatorStartsWith","valuePlaceholder","removeClause","addClause","clearAll","apply","results","filteredResultCount","toLocaleString","maxClausesReached","maxClauses","DataGridFilterPanel","clauses","columns","lockedColumnId","labels","labelOverrides","onChange","onClearAll","onClose","onApply","className","props","ref","canAddClause","length","uniformJoinValue","operatorLabel","contains","equals","startsWith","joinLabel","and","or","columnLabel","id","find","label","updateClause","index","patch","map","clause","clauseIndex","createClause","columnId","next","filter","_clause","div","data-slot","p","size","variant","aria-label","onClick","aria-hidden","span","onValueChange","joined","joinedIndex","disabled","placeholder","event","target","displayName"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../src/components/ui/core/data-grid/data-grid-filter-panel.tsx"],"sourcesContent":["import {\n type ChangeEvent,\n type ComponentProps,\n type ComponentRef,\n type ForwardRefExoticComponent,\n type Ref,\n type RefAttributes,\n forwardRef,\n} from 'react';\n\nimport { IconMinus, IconPlus, IconX } from '@tabler/icons-react';\n\nimport { cn } from '../../../../lib/utils';\nimport { Button } from '../button/button';\nimport { Input } from '../input/input';\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n} from '../select/select';\n\nimport type {\n DataGridFilterClause,\n DataGridFilterJoin,\n DataGridFilterOperator,\n} from './data-grid-filter-clauses';\n\nconst DEFAULT_COLUMN_OPERATORS: DataGridFilterOperator[] = [\n 'contains',\n 'equals',\n 'startsWith',\n];\n\ntype DataGridFilterColumn = {\n id: string;\n label: string;\n operators?: DataGridFilterOperator[];\n};\n\nfunction operatorsForColumnId(\n columns: DataGridFilterColumn[],\n columnId: string\n): DataGridFilterOperator[] {\n const custom = columns.find(\n (column: DataGridFilterColumn) => column.id === columnId\n )?.operators;\n return custom != null && custom.length > 0\n ? custom\n : DEFAULT_COLUMN_OPERATORS;\n}\n\nconst isDataGridFilterJoin = (value: string): value is DataGridFilterJoin =>\n value === 'and' || value === 'or';\n\nconst isDataGridFilterOperator = (\n value: string\n): value is DataGridFilterOperator =>\n value === 'contains' || value === 'equals' || value === 'startsWith';\n\ntype DataGridFilterPanelLabels = {\n title: string;\n close: string;\n showFieldsWhere: string;\n join: string;\n joinAnd: string;\n joinOr: string;\n column: string;\n operator: string;\n operatorContains: string;\n operatorEquals: string;\n operatorStartsWith: string;\n value: string;\n valuePlaceholder: string;\n removeClause: string;\n addClause: string;\n clearAll: string;\n apply: string;\n results: (filteredResultCount: number) => string;\n maxClausesReached: (maxClauses: number) => string;\n};\n\nconst defaultDataGridFilterPanelLabels: DataGridFilterPanelLabels = {\n title: 'Filters',\n close: 'Close filters',\n showFieldsWhere: 'Show fields where',\n join: 'Filter join',\n joinAnd: 'And',\n joinOr: 'Or',\n column: 'Filter column',\n operator: 'Filter operator',\n operatorContains: 'Contains',\n operatorEquals: 'Equals',\n operatorStartsWith: 'Starts with',\n value: 'Filter value',\n valuePlaceholder: 'Enter value',\n removeClause: 'Remove filter',\n addClause: 'Add condition',\n clearAll: 'Clear all',\n apply: 'Apply filters',\n results: (filteredResultCount: number) =>\n `Results ${filteredResultCount.toLocaleString()}`,\n maxClausesReached: (maxClauses: number) => `Maximum ${maxClauses} conditions`,\n};\n\ntype DataGridFilterPanelProps = Omit<ComponentProps<'div'>, 'onChange'> & {\n clauses: DataGridFilterClause[];\n columns: DataGridFilterColumn[];\n maxClauses?: number;\n filteredResultCount?: number;\n lockedColumnId?: string;\n labels?: Partial<DataGridFilterPanelLabels>;\n onChange: (clauses: DataGridFilterClause[]) => void;\n onClearAll: () => void;\n onClose?: () => void;\n onApply?: () => void;\n hasActiveFilters?: boolean;\n};\n\nconst DataGridFilterPanel: ForwardRefExoticComponent<\n DataGridFilterPanelProps & RefAttributes<HTMLDivElement>\n> = forwardRef<ComponentRef<'div'>, DataGridFilterPanelProps>(\n function DataGridFilterPanel(\n {\n clauses,\n columns,\n maxClauses = 5,\n filteredResultCount,\n lockedColumnId,\n labels: labelOverrides,\n onChange,\n onClearAll,\n onClose,\n onApply,\n hasActiveFilters = true,\n className,\n ...props\n }: DataGridFilterPanelProps,\n ref: Ref<ComponentRef<'div'>>\n ) {\n const labels = { ...defaultDataGridFilterPanelLabels, ...labelOverrides };\n const canAddClause = clauses.length < maxClauses;\n const uniformJoinValue = clauses[1]?.join ?? 'and';\n const draftHasActiveClause = clauses.some(\n (clause: DataGridFilterClause) => clause.value.trim() !== ''\n );\n const canApply = draftHasActiveClause;\n const columnSelectDisabled = lockedColumnId != null || columns.length <= 1;\n\n const operatorLabel: Record<DataGridFilterOperator, string> = {\n contains: labels.operatorContains,\n equals: labels.operatorEquals,\n startsWith: labels.operatorStartsWith,\n };\n const joinLabel: Record<DataGridFilterJoin, string> = {\n and: labels.joinAnd,\n or: labels.joinOr,\n };\n const columnLabel = (id: string) =>\n columns.find((column: DataGridFilterColumn) => column.id === id)?.label ??\n id;\n\n const updateClause = (\n index: number,\n patch: Partial<DataGridFilterClause>\n ) => {\n onChange(\n clauses.map((clause: DataGridFilterClause, clauseIndex: number) =>\n clauseIndex === index ? { ...clause, ...patch } : clause\n )\n );\n };\n\n const createClause = (\n join: DataGridFilterJoin = 'and'\n ): DataGridFilterClause => {\n const columnId = lockedColumnId ?? columns[0]?.id ?? '';\n const allowed = operatorsForColumnId(columns, columnId);\n return {\n columnId,\n operator: allowed[0],\n value: '',\n join,\n };\n };\n\n const addClause = () => {\n if (!canAddClause) return;\n onChange([\n ...clauses,\n createClause(clauses[clauses.length - 1]?.join ?? 'and'),\n ]);\n };\n\n const removeClause = (index: number) => {\n const next = clauses.filter(\n (_clause: DataGridFilterClause, clauseIndex: number) =>\n clauseIndex !== index\n );\n onChange(next.length > 0 ? next : [createClause()]);\n };\n\n return (\n <div\n ref={ref}\n data-slot=\"data-grid-filter-panel\"\n className={cn(\n 'w-[min(52rem,calc(100vw-2rem))] rounded-lg border border-border bg-background p-4 shadow-default',\n className\n )}\n {...props}\n >\n <div className=\"mb-2 flex items-center justify-between gap-3\">\n <p className=\"text-base font-medium text-foreground\">\n {labels.title}\n </p>\n {onClose != null && (\n <Button\n size=\"icon-sm\"\n variant=\"ghost\"\n className=\"shrink-0\"\n aria-label={labels.close}\n onClick={onClose}\n >\n <IconX className=\"size-4\" aria-hidden />\n </Button>\n )}\n </div>\n\n <div className=\"grid gap-2\">\n <div className=\"grid grid-cols-[75px_minmax(0,1fr)_minmax(0,1fr)_minmax(0,1fr)_36px] gap-2\">\n <span />\n <span className=\"text-sm font-medium text-muted-foreground\">\n {labels.showFieldsWhere}\n </span>\n </div>\n {clauses.map((clause: DataGridFilterClause, index: number) => (\n <div\n key={clause.id ?? index}\n className=\"grid grid-cols-[75px_minmax(0,1fr)_minmax(0,1fr)_minmax(0,1fr)_36px] items-center gap-2\"\n >\n {index === 0 ? (\n <span />\n ) : index > 1 ? (\n <span className=\"px-3 text-sm font-medium text-foreground capitalize\">\n {uniformJoinValue}\n </span>\n ) : (\n <Select\n value={uniformJoinValue}\n onValueChange={(join: string) => {\n if (isDataGridFilterJoin(join)) {\n onChange(\n clauses.map(\n (\n joined: DataGridFilterClause,\n joinedIndex: number\n ) =>\n joinedIndex === 0 ? joined : { ...joined, join }\n )\n );\n }\n }}\n >\n <SelectTrigger\n aria-label={labels.join}\n className=\"h-8 min-w-0 w-full text-sm\"\n >\n {joinLabel[uniformJoinValue]}\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"and\">{labels.joinAnd}</SelectItem>\n <SelectItem value=\"or\">{labels.joinOr}</SelectItem>\n </SelectContent>\n </Select>\n )}\n <Select\n value={clause.columnId}\n onValueChange={(value: string) => {\n const allowed = operatorsForColumnId(columns, value);\n const operator = allowed.includes(clause.operator)\n ? clause.operator\n : allowed[0];\n updateClause(index, { columnId: value, operator });\n }}\n disabled={columnSelectDisabled}\n >\n <SelectTrigger\n aria-label={labels.column}\n className=\"h-8 min-w-0 w-full text-sm\"\n >\n {columnLabel(clause.columnId)}\n </SelectTrigger>\n <SelectContent>\n {columns.map((column: DataGridFilterColumn) => (\n <SelectItem key={column.id} value={column.id}>\n {column.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <Select\n value={clause.operator}\n onValueChange={(value: string) => {\n if (isDataGridFilterOperator(value)) {\n updateClause(index, { operator: value });\n }\n }}\n disabled={\n operatorsForColumnId(columns, clause.columnId).length <= 1\n }\n >\n <SelectTrigger\n aria-label={labels.operator}\n className=\"h-8 min-w-0 w-full text-sm\"\n >\n {operatorLabel[clause.operator]}\n </SelectTrigger>\n <SelectContent>\n {operatorsForColumnId(columns, clause.columnId).map(\n (operator: DataGridFilterOperator) => (\n <SelectItem key={operator} value={operator}>\n {operatorLabel[operator]}\n </SelectItem>\n )\n )}\n </SelectContent>\n </Select>\n <Input\n aria-label={labels.value}\n value={clause.value}\n placeholder={labels.valuePlaceholder}\n onChange={(event: ChangeEvent<HTMLInputElement>) =>\n updateClause(index, { value: event.target.value })\n }\n />\n {index === 0 ? (\n <span />\n ) : (\n <Button\n size=\"icon\"\n variant=\"ghost\"\n aria-label={labels.removeClause}\n onClick={() => removeClause(index)}\n >\n <IconMinus className=\"size-4\" aria-hidden=\"true\" />\n </Button>\n )}\n </div>\n ))}\n </div>\n\n <div className=\"mt-3 flex items-center justify-between gap-2 pl-[83px]\">\n <div className=\"flex items-center gap-2\">\n <Button\n variant=\"outline\"\n onClick={addClause}\n disabled={!canAddClause}\n >\n <IconPlus className=\"size-4\" aria-hidden=\"true\" />\n {labels.addClause}\n </Button>\n {filteredResultCount != null && (\n <span className=\"text-sm font-medium text-foreground\">\n {labels.results(filteredResultCount)}\n </span>\n )}\n {!canAddClause ? (\n <span className=\"text-sm text-muted-foreground\">\n {labels.maxClausesReached(maxClauses)}\n </span>\n ) : null}\n </div>\n <div className=\"flex items-center gap-2\">\n <Button\n variant=\"ghost\"\n onClick={onClearAll}\n disabled={!hasActiveFilters}\n >\n {labels.clearAll}\n </Button>\n {onApply ? (\n <Button onClick={onApply} disabled={!canApply}>\n {labels.apply}\n </Button>\n ) : null}\n </div>\n </div>\n </div>\n );\n }\n);\nDataGridFilterPanel.displayName = 'DataGridFilterPanel';\n\nexport {\n DataGridFilterPanel,\n type DataGridFilterColumn,\n type DataGridFilterPanelLabels,\n};\n"],"names":["forwardRef","IconMinus","IconPlus","IconX","cn","Button","Input","Select","SelectContent","SelectItem","SelectTrigger","DEFAULT_COLUMN_OPERATORS","operatorsForColumnId","columns","columnId","custom","find","column","id","operators","length","isDataGridFilterJoin","value","isDataGridFilterOperator","defaultDataGridFilterPanelLabels","title","close","showFieldsWhere","join","joinAnd","joinOr","operator","operatorContains","operatorEquals","operatorStartsWith","valuePlaceholder","removeClause","addClause","clearAll","apply","results","filteredResultCount","toLocaleString","maxClausesReached","maxClauses","DataGridFilterPanel","clauses","lockedColumnId","labels","labelOverrides","onChange","onClearAll","onClose","onApply","hasActiveFilters","className","props","ref","canAddClause","uniformJoinValue","draftHasActiveClause","some","clause","trim","canApply","columnSelectDisabled","operatorLabel","contains","equals","startsWith","joinLabel","and","or","columnLabel","label","updateClause","index","patch","map","clauseIndex","createClause","allowed","next","filter","_clause","div","data-slot","p","size","variant","aria-label","onClick","aria-hidden","span","onValueChange","joined","joinedIndex","includes","disabled","placeholder","event","target","displayName"],"mappings":";AAAA,SAOEA,UAAU,QACL,QAAQ;AAEf,SAASC,SAAS,EAAEC,QAAQ,EAAEC,KAAK,QAAQ,sBAAsB;AAEjE,SAASC,EAAE,QAAQ,2BAAwB;AAC3C,SAASC,MAAM,QAAQ,sBAAmB;AAC1C,SAASC,KAAK,QAAQ,oBAAiB;AACvC,SACEC,MAAM,EACNC,aAAa,EACbC,UAAU,EACVC,aAAa,QACR,sBAAmB;AAQ1B,MAAMC,2BAAqD;IACzD;IACA;IACA;CACD;AAQD,SAASC,qBACPC,OAA+B,EAC/BC,QAAgB;IAEhB,MAAMC,SAASF,QAAQG,IAAI,CACzB,CAACC,SAAiCA,OAAOC,EAAE,KAAKJ,WAC/CK;IACH,OAAOJ,UAAU,QAAQA,OAAOK,MAAM,GAAG,IACrCL,SACAJ;AACN;AAEA,MAAMU,uBAAuB,CAACC,QAC5BA,UAAU,SAASA,UAAU;AAE/B,MAAMC,2BAA2B,CAC/BD,QAEAA,UAAU,cAAcA,UAAU,YAAYA,UAAU;AAwB1D,MAAME,mCAA8D;IAClEC,OAAO;IACPC,OAAO;IACPC,iBAAiB;IACjBC,MAAM;IACNC,SAAS;IACTC,QAAQ;IACRb,QAAQ;IACRc,UAAU;IACVC,kBAAkB;IAClBC,gBAAgB;IAChBC,oBAAoB;IACpBZ,OAAO;IACPa,kBAAkB;IAClBC,cAAc;IACdC,WAAW;IACXC,UAAU;IACVC,OAAO;IACPC,SAAS,CAACC,sBACR,CAAC,QAAQ,EAAEA,oBAAoBC,cAAc,IAAI;IACnDC,mBAAmB,CAACC,aAAuB,CAAC,QAAQ,EAAEA,WAAW,WAAW,CAAC;AAC/E;AAgBA,MAAMC,oCAEF7C,WACF,SAAS6C,oBACP,EACEC,OAAO,EACPjC,OAAO,EACP+B,aAAa,CAAC,EACdH,mBAAmB,EACnBM,cAAc,EACdC,QAAQC,cAAc,EACtBC,QAAQ,EACRC,UAAU,EACVC,OAAO,EACPC,OAAO,EACPC,mBAAmB,IAAI,EACvBC,SAAS,EACT,GAAGC,OACsB,EAC3BC,GAA6B;IAE7B,MAAMT,SAAS;QAAE,GAAGxB,gCAAgC;QAAE,GAAGyB,cAAc;IAAC;IACxE,MAAMS,eAAeZ,QAAQ1B,MAAM,GAAGwB;IACtC,MAAMe,mBAAmBb,OAAO,CAAC,EAAE,EAAElB,QAAQ;IAC7C,MAAMgC,uBAAuBd,QAAQe,IAAI,CACvC,CAACC,SAAiCA,OAAOxC,KAAK,CAACyC,IAAI,OAAO;IAE5D,MAAMC,WAAWJ;IACjB,MAAMK,uBAAuBlB,kBAAkB,QAAQlC,QAAQO,MAAM,IAAI;IAEzE,MAAM8C,gBAAwD;QAC5DC,UAAUnB,OAAOhB,gBAAgB;QACjCoC,QAAQpB,OAAOf,cAAc;QAC7BoC,YAAYrB,OAAOd,kBAAkB;IACvC;IACA,MAAMoC,YAAgD;QACpDC,KAAKvB,OAAOnB,OAAO;QACnB2C,IAAIxB,OAAOlB,MAAM;IACnB;IACA,MAAM2C,cAAc,CAACvD,KACnBL,QAAQG,IAAI,CAAC,CAACC,SAAiCA,OAAOC,EAAE,KAAKA,KAAKwD,SAClExD;IAEF,MAAMyD,eAAe,CACnBC,OACAC;QAEA3B,SACEJ,QAAQgC,GAAG,CAAC,CAAChB,QAA8BiB,cACzCA,gBAAgBH,QAAQ;gBAAE,GAAGd,MAAM;gBAAE,GAAGe,KAAK;YAAC,IAAIf;IAGxD;IAEA,MAAMkB,eAAe,CACnBpD,OAA2B,KAAK;QAEhC,MAAMd,WAAWiC,kBAAkBlC,OAAO,CAAC,EAAE,EAAEK,MAAM;QACrD,MAAM+D,UAAUrE,qBAAqBC,SAASC;QAC9C,OAAO;YACLA;YACAiB,UAAUkD,OAAO,CAAC,EAAE;YACpB3D,OAAO;YACPM;QACF;IACF;IAEA,MAAMS,YAAY;QAChB,IAAI,CAACqB,cAAc;QACnBR,SAAS;eACJJ;YACHkC,aAAalC,OAAO,CAACA,QAAQ1B,MAAM,GAAG,EAAE,EAAEQ,QAAQ;SACnD;IACH;IAEA,MAAMQ,eAAe,CAACwC;QACpB,MAAMM,OAAOpC,QAAQqC,MAAM,CACzB,CAACC,SAA+BL,cAC9BA,gBAAgBH;QAEpB1B,SAASgC,KAAK9D,MAAM,GAAG,IAAI8D,OAAO;YAACF;SAAe;IACpD;IAEA,qBACE,MAACK;QACC5B,KAAKA;QACL6B,aAAU;QACV/B,WAAWnD,GACT,oGACAmD;QAED,GAAGC,KAAK;;0BAET,MAAC6B;gBAAI9B,WAAU;;kCACb,KAACgC;wBAAEhC,WAAU;kCACVP,OAAOvB,KAAK;;oBAEd2B,WAAW,sBACV,KAAC/C;wBACCmF,MAAK;wBACLC,SAAQ;wBACRlC,WAAU;wBACVmC,cAAY1C,OAAOtB,KAAK;wBACxBiE,SAASvC;kCAET,cAAA,KAACjD;4BAAMoD,WAAU;4BAASqC,aAAW;;;;;0BAK3C,MAACP;gBAAI9B,WAAU;;kCACb,MAAC8B;wBAAI9B,WAAU;;0CACb,KAACsC;0CACD,KAACA;gCAAKtC,WAAU;0CACbP,OAAOrB,eAAe;;;;oBAG1BmB,QAAQgC,GAAG,CAAC,CAAChB,QAA8Bc,sBAC1C,MAACS;4BAEC9B,WAAU;;gCAETqB,UAAU,kBACT,KAACiB,cACCjB,QAAQ,kBACV,KAACiB;oCAAKtC,WAAU;8CACbI;mDAGH,MAACpD;oCACCe,OAAOqC;oCACPmC,eAAe,CAAClE;wCACd,IAAIP,qBAAqBO,OAAO;4CAC9BsB,SACEJ,QAAQgC,GAAG,CACT,CACEiB,QACAC,cAEAA,gBAAgB,IAAID,SAAS;oDAAE,GAAGA,MAAM;oDAAEnE;gDAAK;wCAGvD;oCACF;;sDAEA,KAAClB;4CACCgF,cAAY1C,OAAOpB,IAAI;4CACvB2B,WAAU;sDAETe,SAAS,CAACX,iBAAiB;;sDAE9B,MAACnD;;8DACC,KAACC;oDAAWa,OAAM;8DAAO0B,OAAOnB,OAAO;;8DACvC,KAACpB;oDAAWa,OAAM;8DAAM0B,OAAOlB,MAAM;;;;;;8CAI3C,MAACvB;oCACCe,OAAOwC,OAAOhD,QAAQ;oCACtBgF,eAAe,CAACxE;wCACd,MAAM2D,UAAUrE,qBAAqBC,SAASS;wCAC9C,MAAMS,WAAWkD,QAAQgB,QAAQ,CAACnC,OAAO/B,QAAQ,IAC7C+B,OAAO/B,QAAQ,GACfkD,OAAO,CAAC,EAAE;wCACdN,aAAaC,OAAO;4CAAE9D,UAAUQ;4CAAOS;wCAAS;oCAClD;oCACAmE,UAAUjC;;sDAEV,KAACvD;4CACCgF,cAAY1C,OAAO/B,MAAM;4CACzBsC,WAAU;sDAETkB,YAAYX,OAAOhD,QAAQ;;sDAE9B,KAACN;sDACEK,QAAQiE,GAAG,CAAC,CAAC7D,uBACZ,KAACR;oDAA2Ba,OAAOL,OAAOC,EAAE;8DACzCD,OAAOyD,KAAK;mDADEzD,OAAOC,EAAE;;;;8CAMhC,MAACX;oCACCe,OAAOwC,OAAO/B,QAAQ;oCACtB+D,eAAe,CAACxE;wCACd,IAAIC,yBAAyBD,QAAQ;4CACnCqD,aAAaC,OAAO;gDAAE7C,UAAUT;4CAAM;wCACxC;oCACF;oCACA4E,UACEtF,qBAAqBC,SAASiD,OAAOhD,QAAQ,EAAEM,MAAM,IAAI;;sDAG3D,KAACV;4CACCgF,cAAY1C,OAAOjB,QAAQ;4CAC3BwB,WAAU;sDAETW,aAAa,CAACJ,OAAO/B,QAAQ,CAAC;;sDAEjC,KAACvB;sDACEI,qBAAqBC,SAASiD,OAAOhD,QAAQ,EAAEgE,GAAG,CACjD,CAAC/C,yBACC,KAACtB;oDAA0Ba,OAAOS;8DAC/BmC,aAAa,CAACnC,SAAS;mDADTA;;;;8CAOzB,KAACzB;oCACCoF,cAAY1C,OAAO1B,KAAK;oCACxBA,OAAOwC,OAAOxC,KAAK;oCACnB6E,aAAanD,OAAOb,gBAAgB;oCACpCe,UAAU,CAACkD,QACTzB,aAAaC,OAAO;4CAAEtD,OAAO8E,MAAMC,MAAM,CAAC/E,KAAK;wCAAC;;gCAGnDsD,UAAU,kBACT,KAACiB,4BAED,KAACxF;oCACCmF,MAAK;oCACLC,SAAQ;oCACRC,cAAY1C,OAAOZ,YAAY;oCAC/BuD,SAAS,IAAMvD,aAAawC;8CAE5B,cAAA,KAAC3E;wCAAUsD,WAAU;wCAASqC,eAAY;;;;2BA3GzC9B,OAAO5C,EAAE,IAAI0D;;;0BAkHxB,MAACS;gBAAI9B,WAAU;;kCACb,MAAC8B;wBAAI9B,WAAU;;0CACb,MAAClD;gCACCoF,SAAQ;gCACRE,SAAStD;gCACT6D,UAAU,CAACxC;;kDAEX,KAACxD;wCAASqD,WAAU;wCAASqC,eAAY;;oCACxC5C,OAAOX,SAAS;;;4BAElBI,uBAAuB,sBACtB,KAACoD;gCAAKtC,WAAU;0CACbP,OAAOR,OAAO,CAACC;;4BAGnB,CAACiB,6BACA,KAACmC;gCAAKtC,WAAU;0CACbP,OAAOL,iBAAiB,CAACC;iCAE1B;;;kCAEN,MAACyC;wBAAI9B,WAAU;;0CACb,KAAClD;gCACCoF,SAAQ;gCACRE,SAASxC;gCACT+C,UAAU,CAAC5C;0CAEVN,OAAOV,QAAQ;;4BAEjBe,wBACC,KAAChD;gCAAOsF,SAAStC;gCAAS6C,UAAU,CAAClC;0CAClChB,OAAOT,KAAK;iCAEb;;;;;;;AAKd;AAEFM,oBAAoByD,WAAW,GAAG;AAElC,SACEzD,mBAAmB,GAGnB"}
@@ -117,8 +117,6 @@ declare const DataGridResultCount: ForwardRefExoticComponent<DataGridResultCount
117
117
  type DataGridFilterTriggerProps = ComponentProps<typeof Button> & {
118
118
  activeCount?: number;
119
119
  label?: string;
120
- activeLabel?: (activeCount: number) => string;
121
- placement?: "toolbar" | "column-header";
122
120
  };
123
121
  declare const DataGridFilterTrigger: ForwardRefExoticComponent<DataGridFilterTriggerProps & RefAttributes<ComponentRef<typeof Button>>>;
124
122
  declare function useDataGridContext(): DataGridContextValue;
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { createContext, forwardRef, useContext, useImperativeHandle, useMemo, useRef } from "react";
3
3
  import { Checkbox as CheckboxPrimitive } from "@base-ui/react/checkbox";
4
4
  import { IconCheck, IconFilter, IconMinus } from "@tabler/icons-react";
@@ -493,21 +493,27 @@ function DataGridState({ type, title, description, action }) {
493
493
  ]
494
494
  });
495
495
  }
496
- const DataGridFilterTrigger = /*#__PURE__*/ forwardRef(function DataGridFilterTrigger({ activeCount = 0, label = 'Filters', activeLabel, placement = 'toolbar', className, children, ...props }, ref) {
496
+ const DataGridFilterTrigger = /*#__PURE__*/ forwardRef(function DataGridFilterTrigger({ activeCount = 0, label = 'Filters', className, children, ...props }, ref) {
497
497
  const hasActiveFilters = activeCount > 0;
498
498
  return /*#__PURE__*/ _jsx(Button, {
499
499
  ref: ref,
500
500
  "data-slot": "data-grid-filter-trigger",
501
- "data-placement": placement,
502
501
  "data-active-count": activeCount,
503
- size: placement === 'column-header' ? 'icon-sm' : 'icon',
502
+ size: "default",
504
503
  variant: hasActiveFilters ? 'secondary' : 'ghost',
505
504
  className: cn('min-w-0', className),
506
- "aria-label": hasActiveFilters ? activeLabel?.(activeCount) ?? `${label}, ${activeCount} active` : label,
505
+ "aria-label": children != null ? label : undefined,
507
506
  ...props,
508
- children: children ?? /*#__PURE__*/ _jsx(IconFilter, {
509
- className: "size-4 shrink-0",
510
- "aria-hidden": "true"
507
+ children: children ?? /*#__PURE__*/ _jsxs(_Fragment, {
508
+ children: [
509
+ /*#__PURE__*/ _jsx(IconFilter, {
510
+ className: "size-4 shrink-0",
511
+ "aria-hidden": "true"
512
+ }),
513
+ /*#__PURE__*/ _jsx("span", {
514
+ children: label
515
+ })
516
+ ]
511
517
  })
512
518
  });
513
519
  });