@drivenets/design-system 0.18.1 → 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 (216) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/dist/index.cjs +17038 -10114
  3. package/dist/index.d.cts +1355 -444
  4. package/dist/index.d.cts.map +1 -1
  5. package/dist/index.d.ts +1354 -443
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +17073 -10172
  8. package/dist/index.js.map +1 -1
  9. package/dist/index.min.css +1 -1
  10. package/package.json +41 -41
  11. package/src/components/ds-bot-button/ds-bot-button.figma.ts +38 -0
  12. package/src/components/ds-bot-button/ds-bot-button.module.scss +41 -0
  13. package/src/components/ds-bot-button/ds-bot-button.tsx +48 -0
  14. package/src/components/ds-bot-button/ds-bot-button.types.ts +33 -0
  15. package/src/components/ds-bot-button/index.ts +2 -0
  16. package/src/components/ds-bot-button/net-gen-logo.tsx +46 -0
  17. package/src/components/ds-bulk-actions/components/action-button.tsx +42 -0
  18. package/src/components/ds-bulk-actions/components/menu-entries.tsx +76 -0
  19. package/src/components/ds-bulk-actions/components/overflow.tsx +75 -0
  20. package/src/components/ds-bulk-actions/ds-bulk-actions.figma.ts +28 -0
  21. package/src/components/ds-bulk-actions/ds-bulk-actions.module.scss +199 -0
  22. package/src/components/ds-bulk-actions/ds-bulk-actions.tsx +220 -0
  23. package/src/components/ds-bulk-actions/ds-bulk-actions.types.ts +170 -0
  24. package/src/components/ds-bulk-actions/ds-bulk-actions.unit.test.ts +195 -0
  25. package/src/components/ds-bulk-actions/ds-bulk-actions.utils.ts +91 -0
  26. package/src/components/ds-bulk-actions/ds-bulk-actions.utils.unit.test.ts +134 -0
  27. package/src/components/ds-bulk-actions/hooks/compute-bulk-actions-overflow.ts +85 -0
  28. package/src/components/ds-bulk-actions/hooks/use-bulk-actions-overflow.ts +153 -0
  29. package/src/components/ds-bulk-actions/index.ts +18 -0
  30. package/src/components/ds-button-v3/ds-button-v3.module.scss +2 -2
  31. package/src/components/ds-catalog-layout/ds-catalog-layout.figma.ts +1 -1
  32. package/src/components/ds-checkbox/ds-checkbox.figma.ts +3 -0
  33. package/src/components/ds-checkbox/ds-checkbox.module.scss +102 -20
  34. package/src/components/ds-checkbox/ds-checkbox.tsx +30 -2
  35. package/src/components/ds-checkbox/ds-checkbox.types.ts +10 -0
  36. package/src/components/ds-code-input/collapsed-code-field/collapsed-code-field.module.scss +169 -0
  37. package/src/components/ds-code-input/collapsed-code-field/collapsed-code-field.tsx +92 -0
  38. package/src/components/ds-code-input/collapsed-code-field/index.ts +1 -0
  39. package/src/components/ds-code-input/ds-code-input-panel/ds-code-input-panel.module.scss +110 -0
  40. package/src/components/ds-code-input/ds-code-input-panel/ds-code-input-panel.tsx +61 -0
  41. package/src/components/ds-code-input/ds-code-input-panel/index.ts +1 -0
  42. package/src/components/ds-code-input/ds-code-input.module.scss +25 -0
  43. package/src/components/ds-code-input/ds-code-input.tsx +401 -0
  44. package/src/components/ds-code-input/ds-code-input.types.ts +166 -0
  45. package/src/components/ds-code-input/ds-code-input.utils.ts +94 -0
  46. package/src/components/ds-code-input/ds-code-input.utils.unit.test.ts +166 -0
  47. package/src/components/ds-code-input/index.ts +2 -0
  48. package/src/components/ds-code-input/use-collapsed-viewport.ts +289 -0
  49. package/src/components/ds-code-input/use-editor-host.ts +87 -0
  50. package/src/components/ds-dropdown-menu/ds-dropdown-menu.tsx +2 -0
  51. package/src/components/ds-empty-state/ds-empty-state.module.scss +16 -0
  52. package/src/components/ds-empty-state/ds-empty-state.tsx +45 -0
  53. package/src/components/ds-empty-state/ds-empty-state.types.ts +38 -0
  54. package/src/components/ds-empty-state/index.ts +3 -0
  55. package/src/components/ds-file-upload/ds-file-upload.tsx +4 -1
  56. package/src/components/ds-filters-bar/components/ds-filters-bar-builder/ds-filters-bar-builder.ts +11 -0
  57. package/src/components/ds-filters-bar/components/ds-filters-bar-builder/ds-filters-bar-builder.types.ts +41 -0
  58. package/src/components/ds-filters-bar/components/ds-filters-bar-builder/index.ts +1 -0
  59. package/src/components/ds-filters-bar/components/ds-filters-bar-clear-all.ts +11 -0
  60. package/src/components/ds-filters-bar/components/ds-filters-bar-conditions/ds-filters-bar-conditions.ts +11 -0
  61. package/src/components/ds-filters-bar/components/ds-filters-bar-conditions/ds-filters-bar-conditions.types.ts +30 -0
  62. package/src/components/ds-filters-bar/components/ds-filters-bar-conditions/index.ts +1 -0
  63. package/src/components/ds-filters-bar/components/ds-filters-bar-pinned.ts +31 -0
  64. package/src/components/ds-filters-bar/components/ds-filters-bar-query/ds-filters-bar-query.ts +11 -0
  65. package/src/components/ds-filters-bar/components/ds-filters-bar-query/ds-filters-bar-query.types.ts +22 -0
  66. package/src/components/ds-filters-bar/components/ds-filters-bar-query/index.ts +1 -0
  67. package/src/components/ds-filters-bar/components/ds-filters-bar-saved-filters.ts +19 -0
  68. package/src/components/ds-filters-bar/components/ds-filters-bar-search.ts +11 -0
  69. package/src/components/ds-filters-bar/components/ds-filters-bar-summary.ts +11 -0
  70. package/src/components/ds-filters-bar/components/ds-filters-bar-toolbar.ts +11 -0
  71. package/src/components/ds-filters-bar/components/ds-filters-bar-view-switch.ts +11 -0
  72. package/src/components/ds-filters-bar/components/ds-filters-bar-view.ts +11 -0
  73. package/src/components/ds-filters-bar/components/index.ts +11 -0
  74. package/src/components/ds-filters-bar/ds-filters-bar.context.ts +69 -0
  75. package/src/components/ds-filters-bar/ds-filters-bar.tsx +120 -0
  76. package/src/components/ds-filters-bar/ds-filters-bar.types.ts +440 -0
  77. package/src/components/ds-filters-bar/ds-filters-bar.unit.test.ts +216 -0
  78. package/src/components/ds-filters-bar/ds-filters-bar.utils.ts +141 -0
  79. package/src/components/ds-filters-bar/index.ts +1 -0
  80. package/src/components/ds-form-control/ds-form-control.module.scss +18 -0
  81. package/src/components/ds-form-control/ds-form-control.tsx +61 -19
  82. package/src/components/ds-form-control/ds-form-control.types.ts +2 -1
  83. package/src/components/ds-icon/custom-icons/index.ts +2 -0
  84. package/src/components/ds-icon/custom-icons/special-adv-filters.tsx +28 -0
  85. package/src/components/ds-illustration/ds-illustration.figma.ts +34 -0
  86. package/src/components/ds-illustration/ds-illustration.module.scss +6 -0
  87. package/src/components/ds-illustration/ds-illustration.tsx +29 -0
  88. package/src/components/ds-illustration/ds-illustration.types.ts +45 -0
  89. package/src/components/ds-illustration/illustrations/configuration.tsx +51 -0
  90. package/src/components/ds-illustration/illustrations/device.tsx +133 -0
  91. package/src/components/ds-illustration/illustrations/done.tsx +107 -0
  92. package/src/components/{ds-catalog-layout/catalog-layout-empty-illustration.tsx → ds-illustration/illustrations/empty-inbox.tsx} +10 -14
  93. package/src/components/ds-illustration/illustrations/error.tsx +86 -0
  94. package/src/components/ds-illustration/illustrations/go-filter.tsx +51 -0
  95. package/src/components/ds-illustration/illustrations/illustration-clouds.tsx +10 -0
  96. package/src/components/ds-illustration/illustrations/index.ts +39 -0
  97. package/src/components/ds-illustration/illustrations/no-connection.tsx +54 -0
  98. package/src/components/ds-illustration/illustrations/no-credit-card.tsx +48 -0
  99. package/src/components/ds-illustration/illustrations/no-device.tsx +61 -0
  100. package/src/components/ds-illustration/illustrations/no-documents.tsx +52 -0
  101. package/src/components/ds-illustration/illustrations/no-gps.tsx +57 -0
  102. package/src/components/ds-illustration/illustrations/no-images.tsx +82 -0
  103. package/src/components/ds-illustration/illustrations/no-items-cart.tsx +86 -0
  104. package/src/components/ds-illustration/illustrations/no-messages.tsx +51 -0
  105. package/src/components/ds-illustration/illustrations/no-search-result.tsx +76 -0
  106. package/src/components/ds-illustration/illustrations/no-tasks.tsx +61 -0
  107. package/src/components/ds-illustration/illustrations/site.tsx +80 -0
  108. package/src/components/ds-illustration/index.ts +3 -0
  109. package/src/components/ds-main-menu/components/expanded-item/expanded-item.tsx +108 -0
  110. package/src/components/ds-main-menu/components/expanded-item/expanded-item.types.ts +8 -0
  111. package/src/components/ds-main-menu/components/expanded-item/index.ts +1 -0
  112. package/src/components/ds-main-menu/components/menu-graphic/index.ts +1 -0
  113. package/src/components/ds-main-menu/components/menu-graphic/menu-graphic.tsx +16 -0
  114. package/src/components/ds-main-menu/components/menu-graphic/menu-graphic.types.ts +7 -0
  115. package/src/components/ds-main-menu/components/tile-link/index.ts +1 -0
  116. package/src/components/ds-main-menu/components/tile-link/tile-link.tsx +85 -0
  117. package/src/components/ds-main-menu/components/tile-link/tile-link.types.ts +8 -0
  118. package/src/components/ds-main-menu/components/utility-link/index.ts +1 -0
  119. package/src/components/ds-main-menu/components/utility-link/utility-link.tsx +37 -0
  120. package/src/components/ds-main-menu/components/utility-link/utility-link.types.ts +7 -0
  121. package/src/components/ds-main-menu/ds-main-menu.figma.ts +17 -0
  122. package/src/components/ds-main-menu/ds-main-menu.module.scss +349 -0
  123. package/src/components/ds-main-menu/ds-main-menu.tsx +102 -0
  124. package/src/components/ds-main-menu/ds-main-menu.types.ts +86 -0
  125. package/src/components/ds-main-menu/ds-main-menu.utils.ts +40 -0
  126. package/src/components/ds-main-menu/index.ts +9 -0
  127. package/src/components/ds-modal/figma/ds-modal-footer.figma.ts +1 -1
  128. package/src/components/ds-pin-toggle/ds-pin-toggle.figma.ts +27 -0
  129. package/src/components/ds-pin-toggle/ds-pin-toggle.module.scss +41 -0
  130. package/src/components/ds-pin-toggle/ds-pin-toggle.tsx +43 -0
  131. package/src/components/ds-pin-toggle/ds-pin-toggle.types.ts +29 -0
  132. package/src/components/ds-pin-toggle/index.ts +2 -0
  133. package/src/components/ds-popover/components/popover-trigger/index.ts +1 -0
  134. package/src/components/ds-popover/components/popover-trigger/popover-trigger.tsx +15 -0
  135. package/src/components/ds-popover/ds-popover.context.ts +18 -0
  136. package/src/components/ds-popover/ds-popover.hover-intent.ts +65 -0
  137. package/src/components/ds-popover/ds-popover.tsx +164 -41
  138. package/src/components/ds-popover/ds-popover.types.ts +65 -0
  139. package/src/components/ds-popover/ds-popover.utils.ts +60 -0
  140. package/src/components/ds-popover/ds-popover.utils.unit.test.ts +25 -0
  141. package/src/components/ds-saved-filters/components/ds-saved-filters-delete-confirm.tsx +53 -0
  142. package/src/components/ds-saved-filters/components/ds-saved-filters-name-entry.tsx +64 -0
  143. package/src/components/ds-saved-filters/components/ds-saved-filters-name-modal.tsx +50 -0
  144. package/src/components/ds-saved-filters/components/ds-saved-filters-row/ds-saved-filters-row.module.scss +68 -0
  145. package/src/components/ds-saved-filters/components/ds-saved-filters-row/ds-saved-filters-row.tsx +83 -0
  146. package/src/components/ds-saved-filters/components/ds-saved-filters-row/index.ts +1 -0
  147. package/src/components/ds-saved-filters/components/ds-saved-filters-save.tsx +164 -0
  148. package/src/components/ds-saved-filters/components/ds-saved-filters-trigger/ds-saved-filters-trigger.module.scss +21 -0
  149. package/src/components/ds-saved-filters/components/ds-saved-filters-trigger/ds-saved-filters-trigger.tsx +237 -0
  150. package/src/components/ds-saved-filters/components/ds-saved-filters-trigger/index.ts +1 -0
  151. package/src/components/ds-saved-filters/components/index.ts +2 -0
  152. package/src/components/ds-saved-filters/ds-saved-filters.ts +6 -0
  153. package/src/components/ds-saved-filters/ds-saved-filters.types.ts +106 -0
  154. package/src/components/ds-saved-filters/ds-saved-filters.utils.ts +35 -0
  155. package/src/components/ds-saved-filters/hooks/index.ts +1 -0
  156. package/src/components/ds-saved-filters/hooks/use-picker-outside-dismiss.ts +42 -0
  157. package/src/components/ds-saved-filters/index.ts +2 -0
  158. package/src/components/ds-segment-group/ds-segment-group.module.scss +65 -37
  159. package/src/components/ds-segment-group/ds-segment-group.tsx +17 -5
  160. package/src/components/ds-segment-group/ds-segment-group.types.ts +20 -5
  161. package/src/components/ds-segment-group/figma/ds-segment-group-v2-item.figma.ts +109 -0
  162. package/src/components/ds-segment-group/figma/ds-segment-group-v2.figma.ts +31 -0
  163. package/src/components/ds-site-node/ds-site-node.tsx +2 -2
  164. package/src/components/ds-table/components/ds-table-body-virtualized/ds-table-body-virtualized.module.scss +12 -2
  165. package/src/components/ds-table/components/ds-table-body-virtualized/ds-table-body-virtualized.tsx +2 -3
  166. package/src/components/ds-table/components/ds-table-group-header-cell/ds-table-group-header-cell.module.scss +1 -6
  167. package/src/components/ds-table/components/ds-table-group-header-cell/ds-table-group-header-cell.tsx +6 -3
  168. package/src/components/ds-table/components/ds-table-header/ds-table-header.module.scss +18 -7
  169. package/src/components/ds-table/components/ds-table-header/ds-table-header.tsx +27 -21
  170. package/src/components/ds-table/components/ds-table-header-label.module.scss +12 -0
  171. package/src/components/ds-table/components/ds-table-header-label.tsx +28 -0
  172. package/src/components/ds-table/components/ds-table-row/ds-table-row.module.scss +0 -1
  173. package/src/components/ds-table/context/ds-table-context.tsx +8 -0
  174. package/src/components/ds-table/ds-table.module.scss +26 -16
  175. package/src/components/ds-table/ds-table.tsx +46 -14
  176. package/src/components/ds-table/ds-table.types.ts +33 -3
  177. package/src/components/ds-table/hooks/use-column-resize.ts +114 -11
  178. package/src/components/ds-table/hooks/use-scrollbar-spacer.ts +108 -0
  179. package/src/components/ds-table/hooks/use-scrollbar-spacer.unit.test.ts +26 -0
  180. package/src/components/ds-table/styles/_variables.scss +0 -2
  181. package/src/components/ds-table/utils/column-size.ts +274 -1
  182. package/src/components/ds-table/utils/column-size.unit.test.ts +157 -0
  183. package/src/components/ds-table/utils/constants.ts +13 -5
  184. package/src/components/ds-table/utils/table-columns.tsx +27 -13
  185. package/src/components/ds-table/utils/table-columns.unit.test.ts +44 -0
  186. package/src/components/ds-tag/ds-tag.figma.ts +23 -3
  187. package/src/components/ds-tag/ds-tag.module.scss +71 -7
  188. package/src/components/ds-tag/ds-tag.tsx +115 -14
  189. package/src/components/ds-tag/ds-tag.types.ts +70 -3
  190. package/src/components/ds-tag/ds-tag.unit.test.ts +23 -4
  191. package/src/components/ds-tag/index.ts +2 -2
  192. package/src/components/ds-text-input/ds-input-field-v02.figma.ts +2 -0
  193. package/src/components/ds-toggle/ds-toggle.module.scss +18 -0
  194. package/src/components/ds-toggle/ds-toggle.tsx +15 -9
  195. package/src/components/ds-toggle/ds-toggle.types.ts +6 -0
  196. package/src/components/ds-toggle-filter-data/ds-toggle-filter-data.module.scss +69 -0
  197. package/src/components/ds-toggle-filter-data/ds-toggle-filter-data.tsx +55 -0
  198. package/src/components/ds-toggle-filter-data/ds-toggle-filter-data.types.ts +43 -0
  199. package/src/components/ds-toggle-filter-data/index.ts +1 -0
  200. package/src/components/ds-tooltip/ds-tooltip.module.scss +8 -0
  201. package/src/components/ds-tooltip/ds-tooltip.tsx +7 -3
  202. package/src/components/ds-tooltip/ds-tooltip.types.ts +17 -0
  203. package/src/components/ds-top-bar-navigation/ds-top-bar-navigation.figma.ts +35 -0
  204. package/src/components/ds-top-bar-navigation/ds-top-bar-navigation.module.scss +150 -0
  205. package/src/components/ds-top-bar-navigation/ds-top-bar-navigation.tsx +161 -0
  206. package/src/components/ds-top-bar-navigation/ds-top-bar-navigation.types.ts +117 -0
  207. package/src/components/ds-top-bar-navigation/index.ts +2 -0
  208. package/src/components/ds-tree/ds-tree.tsx +10 -10
  209. package/src/components/ds-tree/ds-tree.types.ts +40 -7
  210. package/src/index.ts +8 -0
  211. package/src/utils/use-is-horizontally-overflowing.ts +35 -0
  212. package/src/components/ds-site-node/hooks/use-is-overflowing.ts +0 -31
  213. package/src/components/ds-table/components/ds-table-bulk-actions/ds-table-bulk-actions.module.scss +0 -112
  214. package/src/components/ds-table/components/ds-table-bulk-actions/ds-table-bulk-actions.tsx +0 -67
  215. package/src/components/ds-table/components/ds-table-bulk-actions/ds-table-bulk-actions.types.ts +0 -41
  216. package/src/components/ds-table/components/ds-table-bulk-actions/index.ts +0 -2
@@ -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';
@@ -0,0 +1,69 @@
1
+ import { createContext, useContext } from 'react';
2
+ import type {
3
+ DsFilterCondition,
4
+ DsFilterField,
5
+ DsFilterPin,
6
+ DsFiltersBarLocale,
7
+ DsFiltersBarView,
8
+ } from './ds-filters-bar.types';
9
+
10
+ /**
11
+ * The contract every part builds on. View parts read the filter document from here and write it
12
+ * back through these actions only, so all views stay one source of truth.
13
+ */
14
+ export interface DsFiltersBarContextValue {
15
+ fields: ReadonlyArray<DsFilterField>;
16
+ conditions: ReadonlyArray<DsFilterCondition>;
17
+ /**
18
+ * Edited advanced query, or `null` while the conditions are the source
19
+ */
20
+ query: string | null;
21
+ /**
22
+ * What the advanced view shows: the edited query, or the consumer's rendering of the conditions
23
+ */
24
+ queryText: string;
25
+ pins: ReadonlyArray<DsFilterPin>;
26
+ /**
27
+ * No conditions and no edited query
28
+ */
29
+ isEmpty: boolean;
30
+ lockedViews: ReadonlyArray<DsFiltersBarView>;
31
+ expanded: boolean;
32
+ view: DsFiltersBarView;
33
+ /**
34
+ * Id of the expanded toolbar, referenced by the disclosure button's `aria-controls`
35
+ */
36
+ toolbarId: string;
37
+ locale: Required<DsFiltersBarLocale>;
38
+ setConditions: (conditions: ReadonlyArray<DsFilterCondition>) => void;
39
+ addCondition: (condition: DsFilterCondition) => void;
40
+ /**
41
+ * Replaces the condition with the same `id`
42
+ */
43
+ updateCondition: (condition: DsFilterCondition) => void;
44
+ removeCondition: (id: string) => void;
45
+ /**
46
+ * Setting text makes the query the source; blank text or `null` hands control back to the
47
+ * conditions.
48
+ */
49
+ setQuery: (query: string | null) => void;
50
+ setPins: (pins: ReadonlyArray<DsFilterPin>) => void;
51
+ /**
52
+ * Empties the conditions and drops the edited query. Pins stay.
53
+ */
54
+ clear: () => void;
55
+ setExpanded: (expanded: boolean) => void;
56
+ setView: (view: DsFiltersBarView) => void;
57
+ }
58
+
59
+ export const DsFiltersBarContext = createContext<DsFiltersBarContextValue | null>(null);
60
+
61
+ export const useDsFiltersBarContext = () => {
62
+ const context = useContext(DsFiltersBarContext);
63
+
64
+ if (!context) {
65
+ throw new Error('DsFiltersBar compound components must be used within DsFiltersBar.Root');
66
+ }
67
+
68
+ return context;
69
+ };
@@ -0,0 +1,120 @@
1
+ import { useId } from 'react';
2
+ import { useControlled } from '../../utils/use-controlled';
3
+ import {
4
+ Builder,
5
+ ClearAll,
6
+ Conditions,
7
+ Pinned,
8
+ PinnedGroup,
9
+ PinnedToggle,
10
+ Query,
11
+ SavedFilters,
12
+ SaveFilter,
13
+ Search,
14
+ Summary,
15
+ Toolbar,
16
+ View,
17
+ ViewSwitch,
18
+ } from './components';
19
+ import { DsFiltersBarContext } from './ds-filters-bar.context';
20
+ import {
21
+ defaultDsFiltersBarLocale,
22
+ type DsFilterCondition,
23
+ type DsFilterPin,
24
+ type DsFiltersBarRootProps,
25
+ type DsFiltersBarView,
26
+ } from './ds-filters-bar.types';
27
+ import {
28
+ appendCondition,
29
+ lockedViewsFor,
30
+ normalizeQuery,
31
+ removeConditionById,
32
+ replaceCondition,
33
+ } from './ds-filters-bar.utils';
34
+
35
+ const EMPTY_FIELDS = Object.freeze([]);
36
+ const EMPTY_CONDITIONS: ReadonlyArray<DsFilterCondition> = Object.freeze([]);
37
+ const EMPTY_PINS: ReadonlyArray<DsFilterPin> = Object.freeze([]);
38
+ const formatNothing = () => '';
39
+
40
+ // TODO: render. Root only provides the context and every part returns null.
41
+ const Root = ({
42
+ fields = EMPTY_FIELDS,
43
+ conditions: conditionsProp,
44
+ defaultConditions = EMPTY_CONDITIONS,
45
+ query: queryProp,
46
+ defaultQuery = null,
47
+ pins: pinsProp,
48
+ defaultPins = EMPTY_PINS,
49
+ expanded: expandedProp,
50
+ defaultExpanded = false,
51
+ view: viewProp,
52
+ defaultView = 'filters',
53
+ formatQuery = formatNothing,
54
+ locale,
55
+ children,
56
+ onConditionsChange,
57
+ onQueryChange,
58
+ onPinsChange,
59
+ onExpandedChange,
60
+ onViewChange,
61
+ }: DsFiltersBarRootProps) => {
62
+ const [conditions, setConditions] = useControlled(conditionsProp, onConditionsChange, defaultConditions);
63
+ const [query, setQuery] = useControlled<string | null>(queryProp, onQueryChange, defaultQuery);
64
+ const [pins, setPins] = useControlled(pinsProp, onPinsChange, defaultPins);
65
+ const [expanded, setExpanded] = useControlled(expandedProp, onExpandedChange, defaultExpanded);
66
+ const [view, setView] = useControlled<DsFiltersBarView>(viewProp, onViewChange, defaultView);
67
+ const toolbarId = useId();
68
+
69
+ return (
70
+ <DsFiltersBarContext.Provider
71
+ value={{
72
+ fields,
73
+ conditions,
74
+ query,
75
+ queryText: query ?? formatQuery(conditions, fields),
76
+ pins,
77
+ isEmpty: query === null && conditions.length === 0,
78
+ lockedViews: lockedViewsFor(query),
79
+ expanded,
80
+ view,
81
+ toolbarId,
82
+ locale: { ...defaultDsFiltersBarLocale, ...locale },
83
+ setConditions,
84
+ addCondition: (condition) => setConditions(appendCondition(conditions, condition)),
85
+ updateCondition: (condition) => setConditions(replaceCondition(conditions, condition)),
86
+ removeCondition: (id) => setConditions(removeConditionById(conditions, id)),
87
+ setQuery: (next) => setQuery(normalizeQuery(next)),
88
+ setPins,
89
+ clear: () => {
90
+ setConditions(EMPTY_CONDITIONS);
91
+ setQuery(null);
92
+ },
93
+ setExpanded,
94
+ setView,
95
+ }}
96
+ >
97
+ {children}
98
+ </DsFiltersBarContext.Provider>
99
+ );
100
+ };
101
+
102
+ Root.displayName = 'DsFiltersBar.Root';
103
+
104
+ export const DsFiltersBar = {
105
+ Root,
106
+ Summary,
107
+ Toolbar,
108
+ SavedFilters,
109
+ SaveFilter,
110
+ Search,
111
+ ViewSwitch,
112
+ View,
113
+ Conditions,
114
+ Builder,
115
+ Query,
116
+ ClearAll,
117
+ Pinned,
118
+ PinnedGroup,
119
+ PinnedToggle,
120
+ };