@drivenets/design-system 0.19.0 → 0.20.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.
Files changed (110) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/index.cjs +12409 -10548
  3. package/dist/index.d.cts +678 -312
  4. package/dist/index.d.cts.map +1 -1
  5. package/dist/index.d.ts +679 -313
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +12404 -10550
  8. package/dist/index.js.map +1 -1
  9. package/dist/index.min.css +1 -1
  10. package/package.json +29 -29
  11. package/src/components/ds-checkbox/ds-checkbox.figma.ts +3 -0
  12. package/src/components/ds-checkbox/ds-checkbox.module.scss +102 -20
  13. package/src/components/ds-checkbox/ds-checkbox.tsx +30 -2
  14. package/src/components/ds-checkbox/ds-checkbox.types.ts +10 -0
  15. package/src/components/ds-code-input/collapsed-code-field/collapsed-code-field.module.scss +169 -0
  16. package/src/components/ds-code-input/collapsed-code-field/collapsed-code-field.tsx +92 -0
  17. package/src/components/ds-code-input/collapsed-code-field/index.ts +1 -0
  18. package/src/components/ds-code-input/ds-code-input-panel/ds-code-input-panel.module.scss +110 -0
  19. package/src/components/ds-code-input/ds-code-input-panel/ds-code-input-panel.tsx +61 -0
  20. package/src/components/ds-code-input/ds-code-input-panel/index.ts +1 -0
  21. package/src/components/ds-code-input/ds-code-input.module.scss +25 -0
  22. package/src/components/ds-code-input/ds-code-input.tsx +401 -0
  23. package/src/components/ds-code-input/ds-code-input.types.ts +166 -0
  24. package/src/components/ds-code-input/ds-code-input.utils.ts +94 -0
  25. package/src/components/ds-code-input/ds-code-input.utils.unit.test.ts +166 -0
  26. package/src/components/ds-code-input/index.ts +2 -0
  27. package/src/components/ds-code-input/use-collapsed-viewport.ts +289 -0
  28. package/src/components/ds-code-input/use-editor-host.ts +87 -0
  29. package/src/components/ds-filters-bar/components/ds-filters-bar-builder/ds-filters-bar-builder.ts +11 -0
  30. package/src/components/ds-filters-bar/components/ds-filters-bar-builder/ds-filters-bar-builder.types.ts +41 -0
  31. package/src/components/ds-filters-bar/components/ds-filters-bar-builder/index.ts +1 -0
  32. package/src/components/ds-filters-bar/components/ds-filters-bar-clear-all.ts +11 -0
  33. package/src/components/ds-filters-bar/components/ds-filters-bar-conditions/ds-filters-bar-conditions.ts +11 -0
  34. package/src/components/ds-filters-bar/components/ds-filters-bar-conditions/ds-filters-bar-conditions.types.ts +30 -0
  35. package/src/components/ds-filters-bar/components/ds-filters-bar-conditions/index.ts +1 -0
  36. package/src/components/ds-filters-bar/components/ds-filters-bar-pinned.ts +31 -0
  37. package/src/components/ds-filters-bar/components/ds-filters-bar-query/ds-filters-bar-query.ts +11 -0
  38. package/src/components/ds-filters-bar/components/ds-filters-bar-query/ds-filters-bar-query.types.ts +22 -0
  39. package/src/components/ds-filters-bar/components/ds-filters-bar-query/index.ts +1 -0
  40. package/src/components/ds-filters-bar/components/ds-filters-bar-saved-filters.ts +19 -0
  41. package/src/components/ds-filters-bar/components/ds-filters-bar-search.ts +11 -0
  42. package/src/components/ds-filters-bar/components/ds-filters-bar-summary.ts +11 -0
  43. package/src/components/ds-filters-bar/components/ds-filters-bar-toolbar.ts +11 -0
  44. package/src/components/ds-filters-bar/components/ds-filters-bar-view-switch.ts +11 -0
  45. package/src/components/ds-filters-bar/components/ds-filters-bar-view.ts +11 -0
  46. package/src/components/ds-filters-bar/components/index.ts +11 -0
  47. package/src/components/ds-filters-bar/ds-filters-bar.context.ts +69 -0
  48. package/src/components/ds-filters-bar/ds-filters-bar.tsx +120 -0
  49. package/src/components/ds-filters-bar/ds-filters-bar.types.ts +440 -0
  50. package/src/components/ds-filters-bar/ds-filters-bar.unit.test.ts +216 -0
  51. package/src/components/ds-filters-bar/ds-filters-bar.utils.ts +141 -0
  52. package/src/components/ds-filters-bar/index.ts +1 -0
  53. package/src/components/ds-form-control/ds-form-control.module.scss +18 -0
  54. package/src/components/ds-form-control/ds-form-control.tsx +43 -9
  55. package/src/components/ds-form-control/ds-form-control.types.ts +2 -1
  56. package/src/components/ds-icon/custom-icons/index.ts +2 -0
  57. package/src/components/ds-icon/custom-icons/special-adv-filters.tsx +28 -0
  58. package/src/components/ds-pin-toggle/ds-pin-toggle.figma.ts +27 -0
  59. package/src/components/ds-pin-toggle/ds-pin-toggle.module.scss +41 -0
  60. package/src/components/ds-pin-toggle/ds-pin-toggle.tsx +43 -0
  61. package/src/components/ds-pin-toggle/ds-pin-toggle.types.ts +29 -0
  62. package/src/components/ds-pin-toggle/index.ts +2 -0
  63. package/src/components/ds-popover/components/popover-trigger/index.ts +1 -0
  64. package/src/components/ds-popover/components/popover-trigger/popover-trigger.tsx +15 -0
  65. package/src/components/ds-popover/ds-popover.context.ts +18 -0
  66. package/src/components/ds-popover/ds-popover.hover-intent.ts +65 -0
  67. package/src/components/ds-popover/ds-popover.tsx +163 -41
  68. package/src/components/ds-popover/ds-popover.types.ts +59 -1
  69. package/src/components/ds-popover/ds-popover.utils.ts +60 -0
  70. package/src/components/ds-popover/ds-popover.utils.unit.test.ts +25 -0
  71. package/src/components/ds-saved-filters/components/ds-saved-filters-delete-confirm.tsx +53 -0
  72. package/src/components/ds-saved-filters/components/ds-saved-filters-name-entry.tsx +64 -0
  73. package/src/components/ds-saved-filters/components/ds-saved-filters-name-modal.tsx +50 -0
  74. package/src/components/ds-saved-filters/components/ds-saved-filters-row/ds-saved-filters-row.module.scss +68 -0
  75. package/src/components/ds-saved-filters/components/ds-saved-filters-row/ds-saved-filters-row.tsx +83 -0
  76. package/src/components/ds-saved-filters/components/ds-saved-filters-row/index.ts +1 -0
  77. package/src/components/ds-saved-filters/components/ds-saved-filters-save.tsx +164 -0
  78. package/src/components/ds-saved-filters/components/ds-saved-filters-trigger/ds-saved-filters-trigger.module.scss +21 -0
  79. package/src/components/ds-saved-filters/components/ds-saved-filters-trigger/ds-saved-filters-trigger.tsx +237 -0
  80. package/src/components/ds-saved-filters/components/ds-saved-filters-trigger/index.ts +1 -0
  81. package/src/components/ds-saved-filters/components/index.ts +2 -0
  82. package/src/components/ds-saved-filters/ds-saved-filters.ts +6 -0
  83. package/src/components/ds-saved-filters/ds-saved-filters.types.ts +106 -0
  84. package/src/components/ds-saved-filters/ds-saved-filters.utils.ts +35 -0
  85. package/src/components/ds-saved-filters/hooks/index.ts +1 -0
  86. package/src/components/ds-saved-filters/hooks/use-picker-outside-dismiss.ts +42 -0
  87. package/src/components/ds-saved-filters/index.ts +2 -0
  88. package/src/components/ds-segment-group/ds-segment-group.module.scss +65 -37
  89. package/src/components/ds-segment-group/ds-segment-group.tsx +17 -5
  90. package/src/components/ds-segment-group/ds-segment-group.types.ts +20 -5
  91. package/src/components/ds-segment-group/figma/ds-segment-group-v2-item.figma.ts +109 -0
  92. package/src/components/ds-segment-group/figma/ds-segment-group-v2.figma.ts +31 -0
  93. package/src/components/ds-tag/ds-tag.figma.ts +23 -3
  94. package/src/components/ds-tag/ds-tag.module.scss +71 -7
  95. package/src/components/ds-tag/ds-tag.tsx +115 -14
  96. package/src/components/ds-tag/ds-tag.types.ts +70 -3
  97. package/src/components/ds-tag/ds-tag.unit.test.ts +23 -4
  98. package/src/components/ds-tag/index.ts +2 -2
  99. package/src/components/ds-text-input/ds-input-field-v02.figma.ts +2 -0
  100. package/src/components/ds-toggle/ds-toggle.tsx +19 -15
  101. package/src/components/ds-toggle/ds-toggle.types.ts +6 -0
  102. package/src/components/ds-toggle-filter-data/ds-toggle-filter-data.module.scss +69 -0
  103. package/src/components/ds-toggle-filter-data/ds-toggle-filter-data.tsx +55 -0
  104. package/src/components/ds-toggle-filter-data/ds-toggle-filter-data.types.ts +43 -0
  105. package/src/components/ds-toggle-filter-data/index.ts +1 -0
  106. package/src/components/ds-tooltip/ds-tooltip.module.scss +8 -0
  107. package/src/components/ds-tooltip/ds-tooltip.tsx +1 -1
  108. package/src/components/ds-tree/ds-tree.tsx +10 -10
  109. package/src/components/ds-tree/ds-tree.types.ts +40 -7
  110. package/src/index.ts +2 -0
@@ -0,0 +1,289 @@
1
+ import { type Dispatch, type RefObject, type SetStateAction, useEffect, useState } from 'react';
2
+ import {
3
+ getAdditionalLineCount,
4
+ getLineAtIndex,
5
+ getLineIndexAtOffset,
6
+ getLogicalLineCount,
7
+ getSelectedLineCount,
8
+ getVisibleLineIndex,
9
+ measureTextWidth,
10
+ scrollToLogicalLine,
11
+ } from './ds-code-input.utils';
12
+
13
+ const CARET_INLINE_PADDING_PX = 16;
14
+
15
+ export type CollapsedIndicator =
16
+ | { kind: 'plusN'; count: number }
17
+ | { kind: 'line'; current: number; total: number }
18
+ | { kind: 'selection'; selected: number; total: number };
19
+
20
+ export interface CollapsedViewport {
21
+ focused: boolean;
22
+ visibleLine: number;
23
+ caretLine: number;
24
+ totalLines: number;
25
+ indicator: CollapsedIndicator | null;
26
+ fadeStart: boolean;
27
+ fadeEnd: boolean;
28
+ showEllipsis: boolean;
29
+ echoText: string;
30
+ revealCaretLine: () => void;
31
+ }
32
+
33
+ export interface CollapsedViewportHandlers {
34
+ onSelect: () => void;
35
+ onKeyUp: () => void;
36
+ onClick: () => void;
37
+ onScroll: () => void;
38
+ onFocus: () => void;
39
+ onBlur: () => void;
40
+ onBeforeInput: () => void;
41
+ }
42
+
43
+ interface ViewportSnapshot {
44
+ totalLines: number;
45
+ caretLine: number;
46
+ visibleLine: number;
47
+ selectedLines: number;
48
+ clipped: boolean;
49
+ fadeStart: boolean;
50
+ fadeEnd: boolean;
51
+ }
52
+
53
+ const initialSnapshot: ViewportSnapshot = {
54
+ totalLines: 1,
55
+ caretLine: 1,
56
+ visibleLine: 1,
57
+ selectedLines: 0,
58
+ clipped: false,
59
+ fadeStart: false,
60
+ fadeEnd: false,
61
+ };
62
+
63
+ const snapshotsEqual = (left: ViewportSnapshot, right: ViewportSnapshot) =>
64
+ left.totalLines === right.totalLines &&
65
+ left.caretLine === right.caretLine &&
66
+ left.visibleLine === right.visibleLine &&
67
+ left.selectedLines === right.selectedLines &&
68
+ left.clipped === right.clipped &&
69
+ left.fadeStart === right.fadeStart &&
70
+ left.fadeEnd === right.fadeEnd;
71
+
72
+ const readViewport = (textarea: HTMLTextAreaElement): ViewportSnapshot => {
73
+ const value = textarea.value;
74
+ const totalLines = getLogicalLineCount(value);
75
+ const caretLine = getLineIndexAtOffset(value, textarea.selectionStart) + 1;
76
+ const visibleLine = Math.min(getVisibleLineIndex(textarea) + 1, totalLines);
77
+ const selectedLines = getSelectedLineCount(value, textarea.selectionStart, textarea.selectionEnd);
78
+ const visibleText = getLineAtIndex(value, visibleLine - 1);
79
+ const clipped = measureTextWidth(textarea, visibleText) > textarea.clientWidth;
80
+ const fadeStart = textarea.scrollLeft > 0;
81
+ const fadeEnd = textarea.scrollLeft + textarea.clientWidth < textarea.scrollWidth - 1;
82
+
83
+ return {
84
+ totalLines,
85
+ caretLine,
86
+ visibleLine,
87
+ selectedLines,
88
+ clipped,
89
+ fadeStart,
90
+ fadeEnd,
91
+ };
92
+ };
93
+
94
+ const commitViewport = (
95
+ textarea: HTMLTextAreaElement,
96
+ setSnapshot: Dispatch<SetStateAction<ViewportSnapshot>>,
97
+ ) => {
98
+ const next = readViewport(textarea);
99
+
100
+ setSnapshot((current) => (snapshotsEqual(current, next) ? current : next));
101
+ };
102
+
103
+ /**
104
+ * The collapsed field shows one logical line. This hook tracks which line is
105
+ * visible, where the caret is, overflow fades, and the +N / Ln x/y / selection chip.
106
+ */
107
+ export const useCollapsedViewport = (
108
+ textareaRef: RefObject<HTMLTextAreaElement | null>,
109
+ value: string,
110
+ ready: boolean,
111
+ collapsed: boolean,
112
+ ): CollapsedViewport & CollapsedViewportHandlers => {
113
+ const [focused, setFocused] = useState(false);
114
+ const [snapshot, setSnapshot] = useState(initialSnapshot);
115
+
116
+ const sync = () => {
117
+ const textarea = textareaRef.current;
118
+
119
+ if (textarea) {
120
+ commitViewport(textarea, setSnapshot);
121
+ }
122
+ };
123
+
124
+ // Scroll so the caret line is the one visible row (used after collapse).
125
+ const revealCaretLine = () => {
126
+ const textarea = textareaRef.current;
127
+
128
+ if (!textarea) {
129
+ return;
130
+ }
131
+
132
+ const lineIndex = getLineIndexAtOffset(textarea.value, textarea.selectionStart);
133
+
134
+ scrollToLogicalLine(textarea, lineIndex);
135
+ textarea.scrollLeft = Math.max(0, textarea.scrollLeft - CARET_INLINE_PADDING_PX);
136
+ setSnapshot((current) => ({
137
+ ...current,
138
+ visibleLine: lineIndex + 1,
139
+ caretLine: lineIndex + 1,
140
+ }));
141
+ };
142
+
143
+ const onSelect = sync;
144
+ const onKeyUp = sync;
145
+ const onClick = sync;
146
+
147
+ const onScroll = () => {
148
+ if (collapsed) {
149
+ sync();
150
+ }
151
+ };
152
+
153
+ const onFocus = () => {
154
+ if (!collapsed) {
155
+ return;
156
+ }
157
+
158
+ setFocused(true);
159
+ revealCaretLine();
160
+ sync();
161
+ };
162
+
163
+ const onBlur = () => {
164
+ if (!collapsed) {
165
+ return;
166
+ }
167
+
168
+ const textarea = textareaRef.current;
169
+
170
+ setFocused(false);
171
+
172
+ if (textarea) {
173
+ // Idle field always shows the start of the document.
174
+ scrollToLogicalLine(textarea, 0);
175
+ textarea.scrollLeft = 0;
176
+ }
177
+
178
+ sync();
179
+ };
180
+
181
+ const onBeforeInput = () => {
182
+ if (!collapsed) {
183
+ return;
184
+ }
185
+
186
+ const textarea = textareaRef.current;
187
+
188
+ if (!textarea) {
189
+ return;
190
+ }
191
+
192
+ const next = readViewport(textarea);
193
+
194
+ // Typing while looking at another line: jump to the caret line first.
195
+ if (next.caretLine !== next.visibleLine) {
196
+ revealCaretLine();
197
+ }
198
+ };
199
+
200
+ useEffect(() => {
201
+ const textarea = textareaRef.current;
202
+
203
+ if (!textarea || !ready) {
204
+ setFocused(false);
205
+
206
+ return;
207
+ }
208
+
209
+ const syncFromDom = () => commitViewport(textarea, setSnapshot);
210
+
211
+ // React's onSelect is backed by selectionchange, so programmatic
212
+ // `select` events (tests, setSelectionRange) still need a native listener.
213
+ textarea.addEventListener('select', syncFromDom);
214
+
215
+ // Line-by-line, not native pixel scroll — a one-row textarea would
216
+ // otherwise feel broken. React's onWheel is passive, so this stays native.
217
+ const handleWheel = (event: WheelEvent) => {
218
+ if (document.activeElement !== textarea || event.deltaY === 0) {
219
+ return;
220
+ }
221
+
222
+ const next = readViewport(textarea);
223
+ const direction = event.deltaY > 0 ? 1 : -1;
224
+ const nextLine = next.visibleLine + direction;
225
+
226
+ if (nextLine < 1 || nextLine > next.totalLines) {
227
+ return;
228
+ }
229
+
230
+ event.preventDefault();
231
+ scrollToLogicalLine(textarea, nextLine - 1);
232
+ syncFromDom();
233
+ };
234
+
235
+ let observer: ResizeObserver | undefined;
236
+
237
+ if (collapsed) {
238
+ textarea.addEventListener('wheel', handleWheel, { passive: false });
239
+ setFocused(document.activeElement === textarea);
240
+ observer = new ResizeObserver(syncFromDom);
241
+ observer.observe(textarea);
242
+ } else {
243
+ setFocused(false);
244
+ }
245
+
246
+ syncFromDom();
247
+
248
+ return () => {
249
+ textarea.removeEventListener('select', syncFromDom);
250
+ textarea.removeEventListener('wheel', handleWheel);
251
+ observer?.disconnect();
252
+ };
253
+ }, [ready, collapsed, value, textareaRef]);
254
+
255
+ const additional = getAdditionalLineCount(value);
256
+ // Caret line, painted as a static stand-in while the real textarea lives in the overlay.
257
+ const echoText = getLineAtIndex(value, snapshot.caretLine - 1);
258
+
259
+ // Selection spanning lines > focused line position > idle +N.
260
+ let indicator: CollapsedIndicator | null = null;
261
+
262
+ if (snapshot.selectedLines > 1) {
263
+ indicator = { kind: 'selection', selected: snapshot.selectedLines, total: snapshot.totalLines };
264
+ } else if (focused && additional > 0) {
265
+ indicator = { kind: 'line', current: snapshot.visibleLine, total: snapshot.totalLines };
266
+ } else if (!focused && additional > 0) {
267
+ indicator = { kind: 'plusN', count: additional };
268
+ }
269
+
270
+ return {
271
+ focused,
272
+ visibleLine: snapshot.visibleLine,
273
+ caretLine: snapshot.caretLine,
274
+ totalLines: Math.max(snapshot.totalLines, getLogicalLineCount(value)),
275
+ indicator,
276
+ fadeStart: focused && snapshot.fadeStart,
277
+ fadeEnd: focused && snapshot.fadeEnd,
278
+ showEllipsis: (!focused || !collapsed || !ready) && snapshot.clipped,
279
+ echoText,
280
+ revealCaretLine,
281
+ onSelect,
282
+ onKeyUp,
283
+ onClick,
284
+ onScroll,
285
+ onFocus,
286
+ onBlur,
287
+ onBeforeInput,
288
+ };
289
+ };
@@ -0,0 +1,87 @@
1
+ import { type RefObject, useLayoutEffect, useRef, useState } from 'react';
2
+ import { applyTextSelection, type TextSelection } from './ds-code-input.utils';
3
+
4
+ interface UseEditorHostOptions {
5
+ isExpanded: boolean;
6
+ collapsedSlotRef: RefObject<HTMLDivElement | null>;
7
+ overlaySlotRef: RefObject<HTMLDivElement | null>;
8
+ hostClassName?: string;
9
+ textareaRef: RefObject<HTMLTextAreaElement | null>;
10
+ pendingSelectionRef: RefObject<TextSelection | null>;
11
+ shouldFocus: boolean;
12
+ }
13
+
14
+ /**
15
+ * One host div for the textarea. Attach it to the current slot (collapsed or
16
+ * overlay), then the component portals the same textarea into that host.
17
+ */
18
+ export const useEditorHost = ({
19
+ isExpanded,
20
+ collapsedSlotRef,
21
+ overlaySlotRef,
22
+ hostClassName,
23
+ textareaRef,
24
+ pendingSelectionRef,
25
+ shouldFocus,
26
+ }: UseEditorHostOptions) => {
27
+ const [hostReady, setHostReady] = useState(false);
28
+ const hostRef = useRef<HTMLDivElement | null>(null);
29
+ // True only while appendChild runs, so the component can swallow the
30
+ // focus/blur that moving a focused node fires.
31
+ const isMovingHostRef = useRef(false);
32
+
33
+ useLayoutEffect(() => {
34
+ if (hostRef.current === null) {
35
+ hostRef.current = document.createElement('div');
36
+ }
37
+
38
+ const host = hostRef.current;
39
+ const dest = isExpanded ? overlaySlotRef.current : collapsedSlotRef.current;
40
+
41
+ if (!dest) {
42
+ return;
43
+ }
44
+
45
+ isMovingHostRef.current = true;
46
+ host.className = hostClassName ?? '';
47
+
48
+ if (host.parentElement !== dest) {
49
+ dest.appendChild(host);
50
+ }
51
+
52
+ const textarea = textareaRef.current;
53
+ const pending = pendingSelectionRef.current;
54
+
55
+ // Put the caret back, then focus only if the user opened the overlay
56
+ // (not if it opened from outside).
57
+ if (textarea && pending) {
58
+ applyTextSelection(textarea, pending);
59
+ pendingSelectionRef.current = null;
60
+ }
61
+
62
+ if (textarea && shouldFocus) {
63
+ textarea.focus({ preventScroll: true });
64
+ }
65
+
66
+ isMovingHostRef.current = false;
67
+
68
+ if (!hostReady) {
69
+ setHostReady(true);
70
+ }
71
+ }, [
72
+ isExpanded,
73
+ hostReady,
74
+ shouldFocus,
75
+ hostClassName,
76
+ collapsedSlotRef,
77
+ overlaySlotRef,
78
+ textareaRef,
79
+ pendingSelectionRef,
80
+ ]);
81
+
82
+ return {
83
+ host: hostRef.current,
84
+ hostReady,
85
+ isMovingHostRef,
86
+ };
87
+ };
@@ -0,0 +1,11 @@
1
+ import type { FC } from 'react';
2
+ import { useDsFiltersBarContext } from '../../ds-filters-bar.context';
3
+ import type { DsFiltersBarBuilderProps } from './ds-filters-bar-builder.types';
4
+
5
+ export const Builder: FC<DsFiltersBarBuilderProps> = () => {
6
+ useDsFiltersBarContext();
7
+
8
+ return null;
9
+ };
10
+
11
+ Builder.displayName = 'DsFiltersBar.Builder';
@@ -0,0 +1,41 @@
1
+ import type { CSSProperties } from 'react';
2
+
3
+ export interface DsFiltersBarBuilderLocale {
4
+ title?: string;
5
+ searchField?: string;
6
+ selectField?: string;
7
+ searchSubfield?: string;
8
+ selectSubfield?: string;
9
+ searchOperator?: string;
10
+ selectOperator?: string;
11
+ valuePlaceholder?: string;
12
+ save?: string;
13
+ }
14
+
15
+ export const defaultDsFiltersBarBuilderLocale: Required<DsFiltersBarBuilderLocale> = Object.freeze({
16
+ title: 'Query builder',
17
+ searchField: 'Search field',
18
+ selectField: 'Select a field',
19
+ searchSubfield: 'Search subfield',
20
+ selectSubfield: 'Select a subfield',
21
+ searchOperator: 'Search operator',
22
+ selectOperator: 'Select an operator',
23
+ valuePlaceholder: 'Value',
24
+ save: 'Save query',
25
+ });
26
+
27
+ /**
28
+ * Query builder view: builds one condition step by step. The field's type decides the steps —
29
+ * compound: subfield, operator, value; text and number: operator, value; enum: value.
30
+ */
31
+ export interface DsFiltersBarBuilderProps {
32
+ /**
33
+ * Field ids offered first, in this order — chosen by product or suggested by AI. Every field in
34
+ * the bar stays searchable.
35
+ * @default all fields, in `fields` order
36
+ */
37
+ suggestedFields?: ReadonlyArray<string>;
38
+ locale?: DsFiltersBarBuilderLocale;
39
+ className?: string;
40
+ style?: CSSProperties;
41
+ }
@@ -0,0 +1 @@
1
+ export { Builder } from './ds-filters-bar-builder';
@@ -0,0 +1,11 @@
1
+ import type { FC } from 'react';
2
+ import { useDsFiltersBarContext } from '../ds-filters-bar.context';
3
+ import type { DsFiltersBarClearAllProps } from '../ds-filters-bar.types';
4
+
5
+ export const ClearAll: FC<DsFiltersBarClearAllProps> = () => {
6
+ useDsFiltersBarContext();
7
+
8
+ return null;
9
+ };
10
+
11
+ ClearAll.displayName = 'DsFiltersBar.ClearAll';
@@ -0,0 +1,11 @@
1
+ import type { FC } from 'react';
2
+ import { useDsFiltersBarContext } from '../../ds-filters-bar.context';
3
+ import type { DsFiltersBarConditionsProps } from './ds-filters-bar-conditions.types';
4
+
5
+ export const Conditions: FC<DsFiltersBarConditionsProps> = () => {
6
+ useDsFiltersBarContext();
7
+
8
+ return null;
9
+ };
10
+
11
+ Conditions.displayName = 'DsFiltersBar.Conditions';
@@ -0,0 +1,30 @@
1
+ import type { CSSProperties } from 'react';
2
+
3
+ export interface DsFiltersBarConditionsLocale {
4
+ /**
5
+ * Accessible name of the icon-only button that opens the filters dialog
6
+ */
7
+ addFilter?: string;
8
+ /**
9
+ * Accessible name of a chip's remove button. Receives the chip's field label.
10
+ */
11
+ removeCondition?: (label: string) => string;
12
+ filtersDialogTitle?: string;
13
+ saveFilters?: string;
14
+ }
15
+
16
+ export const defaultDsFiltersBarConditionsLocale: Required<DsFiltersBarConditionsLocale> = Object.freeze({
17
+ addFilter: 'Add filter',
18
+ removeCondition: (label: string) => `Remove filter: ${label}`,
19
+ filtersDialogTitle: 'Filters',
20
+ saveFilters: 'Save filters',
21
+ });
22
+
23
+ /**
24
+ * Filters view: the add-filter button with its filters dialog, and one chip per condition.
25
+ */
26
+ export interface DsFiltersBarConditionsProps {
27
+ locale?: DsFiltersBarConditionsLocale;
28
+ className?: string;
29
+ style?: CSSProperties;
30
+ }
@@ -0,0 +1 @@
1
+ export { Conditions } from './ds-filters-bar-conditions';
@@ -0,0 +1,31 @@
1
+ import type { FC } from 'react';
2
+ import { useDsFiltersBarContext } from '../ds-filters-bar.context';
3
+ import type {
4
+ DsFiltersBarPinnedProps,
5
+ DsFiltersBarPinnedGroupProps,
6
+ DsFiltersBarPinnedToggleProps,
7
+ } from '../ds-filters-bar.types';
8
+
9
+ export const Pinned: FC<DsFiltersBarPinnedProps> = () => {
10
+ useDsFiltersBarContext();
11
+
12
+ return null;
13
+ };
14
+
15
+ Pinned.displayName = 'DsFiltersBar.Pinned';
16
+
17
+ export const PinnedGroup: FC<DsFiltersBarPinnedGroupProps> = () => {
18
+ useDsFiltersBarContext();
19
+
20
+ return null;
21
+ };
22
+
23
+ PinnedGroup.displayName = 'DsFiltersBar.PinnedGroup';
24
+
25
+ export const PinnedToggle: FC<DsFiltersBarPinnedToggleProps> = () => {
26
+ useDsFiltersBarContext();
27
+
28
+ return null;
29
+ };
30
+
31
+ PinnedToggle.displayName = 'DsFiltersBar.PinnedToggle';
@@ -0,0 +1,11 @@
1
+ import type { FC } from 'react';
2
+ import { useDsFiltersBarContext } from '../../ds-filters-bar.context';
3
+ import type { DsFiltersBarQueryProps } from './ds-filters-bar-query.types';
4
+
5
+ export const Query: FC<DsFiltersBarQueryProps> = () => {
6
+ useDsFiltersBarContext();
7
+
8
+ return null;
9
+ };
10
+
11
+ Query.displayName = 'DsFiltersBar.Query';
@@ -0,0 +1,22 @@
1
+ import type { CSSProperties } from 'react';
2
+
3
+ export interface DsFiltersBarQueryLocale {
4
+ placeholder?: string;
5
+ }
6
+
7
+ export const defaultDsFiltersBarQueryLocale: Required<DsFiltersBarQueryLocale> = Object.freeze({
8
+ placeholder: 'status = "Active" AND trigger = "Scheduled"',
9
+ });
10
+
11
+ /**
12
+ * Advanced query view: one-line code field with an overlay for long queries.
13
+ */
14
+ export interface DsFiltersBarQueryProps {
15
+ /**
16
+ * @default false
17
+ */
18
+ disabled?: boolean;
19
+ locale?: DsFiltersBarQueryLocale;
20
+ className?: string;
21
+ style?: CSSProperties;
22
+ }
@@ -0,0 +1 @@
1
+ export { Query } from './ds-filters-bar-query';
@@ -0,0 +1,19 @@
1
+ import type { FC } from 'react';
2
+ import { useDsFiltersBarContext } from '../ds-filters-bar.context';
3
+ import type { DsFiltersBarSavedFiltersProps, DsFiltersBarSaveFilterProps } from '../ds-filters-bar.types';
4
+
5
+ export const SavedFilters: FC<DsFiltersBarSavedFiltersProps> = () => {
6
+ useDsFiltersBarContext();
7
+
8
+ return null;
9
+ };
10
+
11
+ SavedFilters.displayName = 'DsFiltersBar.SavedFilters';
12
+
13
+ export const SaveFilter: FC<DsFiltersBarSaveFilterProps> = () => {
14
+ useDsFiltersBarContext();
15
+
16
+ return null;
17
+ };
18
+
19
+ SaveFilter.displayName = 'DsFiltersBar.SaveFilter';
@@ -0,0 +1,11 @@
1
+ import type { FC } from 'react';
2
+ import { useDsFiltersBarContext } from '../ds-filters-bar.context';
3
+ import type { DsFiltersBarSearchProps } from '../ds-filters-bar.types';
4
+
5
+ export const Search: FC<DsFiltersBarSearchProps> = () => {
6
+ useDsFiltersBarContext();
7
+
8
+ return null;
9
+ };
10
+
11
+ Search.displayName = 'DsFiltersBar.Search';
@@ -0,0 +1,11 @@
1
+ import type { FC } from 'react';
2
+ import { useDsFiltersBarContext } from '../ds-filters-bar.context';
3
+ import type { DsFiltersBarSummaryProps } from '../ds-filters-bar.types';
4
+
5
+ export const Summary: FC<DsFiltersBarSummaryProps> = () => {
6
+ useDsFiltersBarContext();
7
+
8
+ return null;
9
+ };
10
+
11
+ Summary.displayName = 'DsFiltersBar.Summary';
@@ -0,0 +1,11 @@
1
+ import type { FC } from 'react';
2
+ import { useDsFiltersBarContext } from '../ds-filters-bar.context';
3
+ import type { DsFiltersBarToolbarProps } from '../ds-filters-bar.types';
4
+
5
+ export const Toolbar: FC<DsFiltersBarToolbarProps> = () => {
6
+ useDsFiltersBarContext();
7
+
8
+ return null;
9
+ };
10
+
11
+ Toolbar.displayName = 'DsFiltersBar.Toolbar';
@@ -0,0 +1,11 @@
1
+ import type { FC } from 'react';
2
+ import { useDsFiltersBarContext } from '../ds-filters-bar.context';
3
+ import type { DsFiltersBarViewSwitchProps } from '../ds-filters-bar.types';
4
+
5
+ export const ViewSwitch: FC<DsFiltersBarViewSwitchProps> = () => {
6
+ useDsFiltersBarContext();
7
+
8
+ return null;
9
+ };
10
+
11
+ ViewSwitch.displayName = 'DsFiltersBar.ViewSwitch';
@@ -0,0 +1,11 @@
1
+ import type { FC } from 'react';
2
+ import { useDsFiltersBarContext } from '../ds-filters-bar.context';
3
+ import type { DsFiltersBarViewProps } from '../ds-filters-bar.types';
4
+
5
+ export const View: FC<DsFiltersBarViewProps> = () => {
6
+ useDsFiltersBarContext();
7
+
8
+ return null;
9
+ };
10
+
11
+ View.displayName = 'DsFiltersBar.View';
@@ -0,0 +1,11 @@
1
+ export { ClearAll } from './ds-filters-bar-clear-all';
2
+ export { Pinned, PinnedGroup, PinnedToggle } from './ds-filters-bar-pinned';
3
+ export { SavedFilters, SaveFilter } from './ds-filters-bar-saved-filters';
4
+ export { Search } from './ds-filters-bar-search';
5
+ export { Summary } from './ds-filters-bar-summary';
6
+ export { Toolbar } from './ds-filters-bar-toolbar';
7
+ export { View } from './ds-filters-bar-view';
8
+ export { ViewSwitch } from './ds-filters-bar-view-switch';
9
+ export { Builder } from './ds-filters-bar-builder';
10
+ export { Conditions } from './ds-filters-bar-conditions';
11
+ export { Query } from './ds-filters-bar-query';