@redocly/theme 0.42.2 → 0.43.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 (112) hide show
  1. package/lib/components/Dropdown/DropdownMenu.d.ts +2 -0
  2. package/lib/components/Dropdown/DropdownMenu.js +3 -1
  3. package/lib/components/Loaders/SpinnerLoader.d.ts +5 -0
  4. package/lib/components/Loaders/SpinnerLoader.js +32 -0
  5. package/lib/components/Search/FilterFields/SearchFilterFieldSelect.d.ts +12 -0
  6. package/lib/components/Search/FilterFields/SearchFilterFieldSelect.js +113 -0
  7. package/lib/components/Search/FilterFields/SearchFilterFieldTags.d.ts +10 -0
  8. package/lib/components/Search/FilterFields/SearchFilterFieldTags.js +37 -0
  9. package/lib/components/Search/Search.js +1 -1
  10. package/lib/components/Search/SearchDialog.js +109 -27
  11. package/lib/components/Search/SearchFilter.d.ts +11 -0
  12. package/lib/components/Search/SearchFilter.js +71 -0
  13. package/lib/components/Search/SearchFilterField.d.ts +11 -0
  14. package/lib/components/Search/SearchFilterField.js +43 -0
  15. package/lib/components/Search/SearchGroups.d.ts +9 -0
  16. package/lib/components/Search/SearchGroups.js +69 -0
  17. package/lib/components/Search/SearchHighlight.d.ts +1 -1
  18. package/lib/components/Search/SearchHighlight.js +28 -5
  19. package/lib/components/Search/SearchInput.d.ts +1 -1
  20. package/lib/components/Search/SearchInput.js +5 -2
  21. package/lib/components/Search/SearchItem.d.ts +2 -2
  22. package/lib/components/Search/SearchItem.js +24 -15
  23. package/lib/components/Search/variables.js +48 -2
  24. package/lib/components/Segmented/Segmented.d.ts +2 -5
  25. package/lib/components/Select/Select.d.ts +2 -36
  26. package/lib/components/Select/Select.js +136 -98
  27. package/lib/components/Select/SelectInput.d.ts +23 -0
  28. package/lib/components/Select/SelectInput.js +129 -0
  29. package/lib/components/Select/variables.js +12 -1
  30. package/lib/components/Tag/Tag.d.ts +4 -2
  31. package/lib/components/Tag/Tag.js +40 -4
  32. package/lib/components/Tag/variables.dark.js +20 -5
  33. package/lib/components/Tag/variables.js +49 -17
  34. package/lib/components/VersionPicker/VersionPicker.d.ts +2 -3
  35. package/lib/components/VersionPicker/VersionPicker.js +13 -30
  36. package/lib/core/hooks/__mocks__/index.d.ts +2 -1
  37. package/lib/core/hooks/__mocks__/index.js +2 -1
  38. package/lib/core/hooks/__mocks__/search/use-search-filter.d.ts +9 -0
  39. package/lib/core/hooks/__mocks__/search/use-search-filter.js +14 -0
  40. package/lib/core/hooks/__mocks__/use-theme-hooks.d.ts +6 -1
  41. package/lib/core/hooks/__mocks__/use-theme-hooks.js +6 -1
  42. package/lib/core/hooks/index.d.ts +2 -1
  43. package/lib/core/hooks/index.js +2 -1
  44. package/lib/core/hooks/search/use-recent-searches.js +2 -0
  45. package/lib/core/hooks/{use-search.d.ts → search/use-search-dialog.d.ts} +1 -1
  46. package/lib/core/hooks/{use-search.js → search/use-search-dialog.js} +5 -5
  47. package/lib/core/hooks/search/use-search-filter.d.ts +9 -0
  48. package/lib/core/hooks/search/use-search-filter.js +50 -0
  49. package/lib/core/types/hooks.d.ts +17 -4
  50. package/lib/core/types/index.d.ts +1 -1
  51. package/lib/core/types/index.js +1 -1
  52. package/lib/core/types/l10n.d.ts +1 -2
  53. package/lib/core/types/search.d.ts +42 -2
  54. package/lib/core/types/select.d.ts +31 -0
  55. package/lib/core/types/{select-option.js → select.js} +1 -1
  56. package/lib/core/utils/index.d.ts +1 -0
  57. package/lib/core/utils/index.js +1 -0
  58. package/lib/core/utils/text-trimmer.d.ts +1 -0
  59. package/lib/core/utils/text-trimmer.js +16 -0
  60. package/lib/icons/ResetIcon/ResetIcon.d.ts +9 -0
  61. package/lib/icons/ResetIcon/ResetIcon.js +22 -0
  62. package/lib/icons/SettingsIcon/SettingsIcon.d.ts +9 -0
  63. package/lib/icons/SettingsIcon/SettingsIcon.js +23 -0
  64. package/lib/index.d.ts +8 -1
  65. package/lib/index.js +8 -1
  66. package/lib/markdoc/components/Cards/Card.js +6 -6
  67. package/package.json +3 -3
  68. package/src/components/Dropdown/DropdownMenu.tsx +2 -1
  69. package/src/components/Filter/FilterSelect.tsx +3 -3
  70. package/src/components/Loaders/SpinnerLoader.tsx +31 -0
  71. package/src/components/Search/FilterFields/SearchFilterFieldSelect.tsx +135 -0
  72. package/src/components/Search/FilterFields/SearchFilterFieldTags.tsx +61 -0
  73. package/src/components/Search/Search.tsx +2 -2
  74. package/src/components/Search/SearchDialog.tsx +183 -41
  75. package/src/components/Search/SearchFilter.tsx +90 -0
  76. package/src/components/Search/SearchFilterField.tsx +84 -0
  77. package/src/components/Search/SearchGroups.tsx +81 -0
  78. package/src/components/Search/SearchHighlight.tsx +29 -2
  79. package/src/components/Search/SearchInput.tsx +9 -3
  80. package/src/components/Search/SearchItem.tsx +39 -24
  81. package/src/components/Search/variables.ts +48 -2
  82. package/src/components/Segmented/Segmented.tsx +2 -2
  83. package/src/components/Select/Select.tsx +208 -157
  84. package/src/components/Select/SelectInput.tsx +201 -0
  85. package/src/components/Select/variables.ts +12 -1
  86. package/src/components/Tag/Tag.tsx +57 -6
  87. package/src/components/Tag/variables.dark.ts +20 -5
  88. package/src/components/Tag/variables.ts +49 -17
  89. package/src/components/VersionPicker/VersionPicker.tsx +15 -39
  90. package/src/core/hooks/__mocks__/index.ts +2 -1
  91. package/src/core/hooks/__mocks__/search/use-search-filter.ts +10 -0
  92. package/src/core/hooks/__mocks__/use-theme-hooks.ts +6 -1
  93. package/src/core/hooks/index.ts +2 -1
  94. package/src/core/hooks/search/use-recent-searches.ts +3 -0
  95. package/src/core/hooks/{use-search.ts → search/use-search-dialog.ts} +1 -1
  96. package/src/core/hooks/search/use-search-filter.ts +57 -0
  97. package/src/core/types/hooks.ts +25 -4
  98. package/src/core/types/index.ts +1 -1
  99. package/src/core/types/l10n.ts +110 -38
  100. package/src/core/types/search.ts +53 -2
  101. package/src/core/types/select.ts +33 -0
  102. package/src/core/utils/index.ts +1 -0
  103. package/src/core/utils/text-trimmer.ts +7 -0
  104. package/src/icons/ResetIcon/ResetIcon.tsx +26 -0
  105. package/src/icons/SettingsIcon/SettingsIcon.tsx +30 -0
  106. package/src/index.ts +8 -1
  107. package/src/markdoc/components/Cards/Card.tsx +15 -15
  108. package/lib/core/types/select-option.d.ts +0 -4
  109. package/src/core/types/select-option.ts +0 -4
  110. /package/lib/components/{Loading → Loaders}/Loading.d.ts +0 -0
  111. /package/lib/components/{Loading → Loaders}/Loading.js +0 -0
  112. /package/src/components/{Loading → Loaders}/Loading.tsx +0 -0
@@ -24,6 +24,7 @@ export * from '@redocly/theme/core/hooks/use-tabs';
24
24
  export * from '@redocly/theme/core/hooks/use-focus-trap';
25
25
  export * from '@redocly/theme/core/hooks/use-language-picker';
26
26
  export * from '@redocly/theme/core/hooks/use-product-picker';
27
- export * from '@redocly/theme/core/hooks/use-search';
27
+ export * from '@redocly/theme/core/hooks/search/use-search-dialog';
28
+ export * from '@redocly/theme/core/hooks/search/use-search-filter';
28
29
  export * from '@redocly/theme/core/hooks/use-controlled-state';
29
30
  export * from '@redocly/theme/core/hooks/use-codeblock-tabs-controls';
@@ -19,6 +19,9 @@ function updateRecentSearches(value: string, isAdd: boolean) {
19
19
  if (!isBrowser()) return [];
20
20
 
21
21
  const recentSearches = getRecentSearches();
22
+
23
+ if (value === '') return recentSearches;
24
+
22
25
  const valueIndex = recentSearches.indexOf(value);
23
26
 
24
27
  if (valueIndex !== -1) recentSearches.splice(valueIndex, 1);
@@ -4,7 +4,7 @@ import hotkeys from 'hotkeys-js';
4
4
 
5
5
  import { useThemeHooks, useThemeConfig } from '@redocly/theme/core/hooks';
6
6
 
7
- export function useSearch() {
7
+ export function useSearchDialog() {
8
8
  const [isOpen, setIsOpen] = useState(false);
9
9
  const themeSettings = useThemeConfig();
10
10
  const location = useLocation();
@@ -0,0 +1,57 @@
1
+ import { useCallback, useState } from 'react';
2
+
3
+ import type { SearchFilterItem } from '@redocly/theme/core/types';
4
+
5
+ export function useSearchFilter(
6
+ filter: SearchFilterItem[],
7
+ setFilter: React.Dispatch<React.SetStateAction<SearchFilterItem[]>>,
8
+ ) {
9
+ const [isFilterOpen, setIsFilterOpen] = useState(false);
10
+
11
+ const onFilterToggle = useCallback(() => {
12
+ setIsFilterOpen(!isFilterOpen);
13
+ }, [isFilterOpen]);
14
+
15
+ const onFilterChange = (field: string, value: string | string[] | undefined, isTop?: boolean) => {
16
+ const values = value ? (Array.isArray(value) ? value : [value]) : [];
17
+
18
+ const _filter = [...filter];
19
+ const fieldIndex = _filter.findIndex((filter) => filter.field === field);
20
+ if (fieldIndex > -1) {
21
+ // filter field already exists
22
+ _filter[fieldIndex].values = values;
23
+ } else {
24
+ if (!values.length) return;
25
+ _filter.push({ field, values, isTop });
26
+ }
27
+
28
+ setFilter(_filter.filter((item) => item.values.length));
29
+ };
30
+
31
+ const onFilterReset = () => {
32
+ setFilter([]);
33
+ };
34
+
35
+ const onTopFacetsReset = () => {
36
+ const _filter = [...filter];
37
+ setFilter(_filter.filter((item) => !item.isTop));
38
+ };
39
+
40
+ const onFacetReset = (field: string) => {
41
+ const _filter = [...filter];
42
+ const fieldIndex = _filter.findIndex((filter) => filter.field === field);
43
+ if (fieldIndex !== -1) {
44
+ _filter[fieldIndex].values = [];
45
+ }
46
+ setFilter(_filter.filter((item) => item.values.length));
47
+ };
48
+
49
+ return {
50
+ onFacetReset,
51
+ onTopFacetsReset,
52
+ onFilterChange,
53
+ onFilterReset,
54
+ onFilterToggle,
55
+ isFilterOpen,
56
+ };
57
+ }
@@ -6,11 +6,14 @@ import type {
6
6
  UserMenuData,
7
7
  FilteredCatalog,
8
8
  ItemState,
9
- SearchDocument,
9
+ SearchItemData,
10
10
  SubmitFeedbackParams,
11
11
  TFunction,
12
12
  BreadcrumbItem,
13
13
  DrilldownMenuItemDetails,
14
+ SearchFacet,
15
+ SearchFilterItem,
16
+ SearchFacetQuery,
14
17
  } from '@redocly/theme/core/types';
15
18
 
16
19
  export type ThemeHooks = {
@@ -51,11 +54,29 @@ export type ThemeHooks = {
51
54
  location: Location;
52
55
  };
53
56
  useBreadcrumbs: () => BreadcrumbItem[];
54
- useFuseSearch: (product?: string) => {
57
+ useSearch: (product?: string) => {
55
58
  query: string;
56
59
  setQuery: React.Dispatch<React.SetStateAction<string>>;
57
- items: SearchDocument[] | null;
58
- isLoading: boolean;
60
+ filter: SearchFilterItem[];
61
+ setFilter: React.Dispatch<React.SetStateAction<SearchFilterItem[]>>;
62
+ items: Record<string, SearchItemData[] | null>;
63
+ isSearchLoading: boolean;
64
+ facets: SearchFacet[];
65
+ setLoadMore: React.Dispatch<
66
+ React.SetStateAction<
67
+ | {
68
+ groupKey: string;
69
+ offset: number;
70
+ }
71
+ | undefined
72
+ >
73
+ >;
74
+ advancedSearch?: boolean;
75
+ };
76
+ useFacetQuery: (field: string) => {
77
+ searchFacet: SearchFacet | null;
78
+ setSearchFacet: React.Dispatch<React.SetStateAction<SearchFacet | null>>;
79
+ setSearchFacetQuery: React.Dispatch<React.SetStateAction<SearchFacetQuery | null>>;
59
80
  };
60
81
  useSidebarItems: (activeVersion?: Version | null) => {
61
82
  currentItems: ItemState[];
@@ -6,7 +6,7 @@ export * from '@redocly/theme/core/types/hooks';
6
6
  export * from '@redocly/theme/core/types/markdown';
7
7
  export * from '@redocly/theme/core/types/navbar';
8
8
  export * from '@redocly/theme/core/types/search';
9
- export * from '@redocly/theme/core/types/select-option';
9
+ export * from '@redocly/theme/core/types/select';
10
10
  export * from '@redocly/theme/core/types/sidebar';
11
11
  export * from '@redocly/theme/core/types/filter';
12
12
  export * from '@redocly/theme/core/types/user-menu';
@@ -69,7 +69,9 @@ export type TranslationKey =
69
69
  | 'dev.app.overview.created'
70
70
  | 'dev.app.overview.visibilityToggle.hide'
71
71
  | 'dev.app.overview.visibilityToggle.show'
72
- | 'theme.search.noResults'
72
+ | 'theme.search.loading'
73
+ | 'theme.search.noResults.title'
74
+ | 'theme.search.noResults.description'
73
75
  | 'theme.search.keys.navigate'
74
76
  | 'theme.search.keys.select'
75
77
  | 'theme.search.keys.exit'
@@ -78,6 +80,10 @@ export type TranslationKey =
78
80
  | 'theme.search.recent'
79
81
  | 'theme.search.navbar.label'
80
82
  | 'theme.search.suggested'
83
+ | 'theme.search.showMore'
84
+ | 'theme.search.filter.title'
85
+ | 'theme.search.filter.reset'
86
+ | 'theme.search.filter.field.reset'
81
87
  | 'theme.toc.header'
82
88
  | 'theme.footer.copyrightText'
83
89
  | 'theme.page.homeButton'
@@ -129,43 +135,109 @@ export type TranslationKey =
129
135
  | 'theme.mobileMenu.previous'
130
136
  | 'theme.mobileMenu.products'
131
137
  | 'theme.page.nextButton'
132
- | 'theme.page.previousButton';
133
-
134
- export type GraphQLTranslationKey =
135
- | 'graphql.sidebar.group.queries'
136
- | 'graphql.sidebar.group.mutations'
137
- | 'graphql.sidebar.group.subscriptions'
138
- | 'graphql.sidebar.group.directives'
139
- | 'graphql.sidebar.group.objects'
140
- | 'graphql.sidebar.group.interfaces'
141
- | 'graphql.sidebar.group.unions'
142
- | 'graphql.sidebar.group.enums'
143
- | 'graphql.sidebar.group.inputs'
144
- | 'graphql.sidebar.group.scalars'
145
- | 'graphql.sidebar.group.scalars'
146
- | 'graphql.content.arguments.label'
147
- | 'graphql.content.arguments.show'
148
- | 'graphql.content.arguments.hide'
149
- | 'graphql.content.returnTypes.label'
150
- | 'graphql.content.returnTypes.show'
151
- | 'graphql.content.returnTypes.hide'
152
- | 'graphql.content.defaultValue'
153
- | 'graphql.content.deprecationReason'
154
- | 'graphql.content.implementedInterfaces'
155
- | 'graphql.content.argumentsHere'
156
- | 'graphql.content.nonNull'
157
- | 'graphql.content.required'
158
- | 'graphql.content.deprecated'
159
- | 'graphql.rightSection.variables'
160
- | 'graphql.rightSection.querySample'
161
- | 'graphql.rightSection.mutationSample'
162
- | 'graphql.rightSection.subscriptionSample'
163
- | 'graphql.rightSection.responseSample'
164
- | 'graphql.rightSection.locations'
165
- | 'graphql.rightSection.sample'
166
- | 'graphql.rightSection.referenced'
167
- | 'graphql.navigation.next'
168
- | 'graphql.navigation.previous';
138
+ | 'theme.page.previousButton'
139
+ | 'openapi.download.description.title'
140
+ | 'openapi.info.title'
141
+ | 'openapi.info.contact.url'
142
+ | 'openapi.info.contact.name'
143
+ | 'openapi.info.license'
144
+ | 'openapi.info.termsOfService'
145
+ | 'openapi.info.metadata.title'
146
+ | 'openapi.key'
147
+ | 'openapi.value'
148
+ | 'openapi.enum'
149
+ | 'openapi.items'
150
+ | 'openapi.default'
151
+ | 'openapi.variable'
152
+ | 'openapi.variables'
153
+ | 'openapi.actions.show'
154
+ | 'openapi.actions.hide'
155
+ | 'openapi.actions.more'
156
+ | 'openapi.languages.title'
157
+ | 'openapi.servers.title'
158
+ | 'openapi.operations'
159
+ | 'openapi.webhooks'
160
+ | 'openapi.description'
161
+ | 'openapi.badges.deprecated'
162
+ | 'openapi.badges.required'
163
+ | 'openapi.badges.webhook'
164
+ | 'openapi.request'
165
+ | 'openapi.path'
166
+ | 'openapi.query'
167
+ | 'openapi.cookie'
168
+ | 'openapi.header'
169
+ | 'openapi.body'
170
+ | 'openapi.responses'
171
+ | 'openapi.response'
172
+ | 'openapi.callbacks'
173
+ | 'openapi.callbackRequest'
174
+ | 'openapi.callbackResponse'
175
+ | 'openapi.payload'
176
+ | 'openapi.discriminator'
177
+ | 'openapi.contentType'
178
+ | 'openapi.tryIt'
179
+ | 'openapi.loading'
180
+ | 'openapi.example'
181
+ | 'openapi.examples'
182
+ | 'openapi.additionalProperties'
183
+ | 'openapi.patternProperties'
184
+ | 'openapi.required'
185
+ | 'openapi.recursive'
186
+ | 'openapi.deprecated'
187
+ | 'openapi.hideExample'
188
+ | 'openapi.showExample'
189
+ | 'openapi.expandAll'
190
+ | 'openapi.collapseAll'
191
+ | 'openapi.pdfFileSample'
192
+ | 'openapi.noResponseExample'
193
+ | 'openapi.noRequestPayload'
194
+ | 'openapi.hidePattern'
195
+ | 'openapi.showPattern'
196
+ | 'openapi.authorizationUrl'
197
+ | 'openapi.tokenUrl'
198
+ | 'openapi.refreshUrl'
199
+ | 'openapi.scopes'
200
+ | 'openapi.security'
201
+ | 'openapi.httpAuthorizationScheme'
202
+ | 'openapi.bearerFormat'
203
+ | 'openapi.parameterName'
204
+ | 'openapi.flowType'
205
+ | 'openapi.connectUrl'
206
+ | 'openapi.requiredScopes'
207
+ | 'openapi.unsupportedLanguage'
208
+ | 'openapi.failedToGenerateCodeSample'
209
+ | 'graphql.queries'
210
+ | 'graphql.mutations'
211
+ | 'graphql.subscriptions'
212
+ | 'graphql.directives'
213
+ | 'graphql.objects'
214
+ | 'graphql.interfaces'
215
+ | 'graphql.unions'
216
+ | 'graphql.enums'
217
+ | 'graphql.inputs'
218
+ | 'graphql.scalars'
219
+ | 'graphql.arguments.label'
220
+ | 'graphql.arguments.show'
221
+ | 'graphql.arguments.hide'
222
+ | 'graphql.arguments.here'
223
+ | 'graphql.returnTypes.label'
224
+ | 'graphql.returnTypes.show'
225
+ | 'graphql.returnTypes.hide'
226
+ | 'graphql.possibleTypes'
227
+ | 'graphql.defaultValue'
228
+ | 'graphql.deprecationReason'
229
+ | 'graphql.implementedInterfaces'
230
+ | 'graphql.nonNull'
231
+ | 'graphql.required'
232
+ | 'graphql.deprecated'
233
+ | 'graphql.variables'
234
+ | 'graphql.querySample'
235
+ | 'graphql.mutationSample'
236
+ | 'graphql.subscriptionSample'
237
+ | 'graphql.responseSample'
238
+ | 'graphql.locations'
239
+ | 'graphql.sample'
240
+ | 'graphql.referenced';
169
241
 
170
242
  export type Locale = { code: string; name: string };
171
243
 
@@ -14,9 +14,9 @@ export type SearchDocument = {
14
14
  title: string | string[];
15
15
  text: string | string[];
16
16
  path?: string[];
17
- httpVerb?: string;
17
+ httpMethod?: string;
18
+ httpPath?: string | string[];
18
19
  deprecated?: boolean;
19
- pathName?: string | string[];
20
20
  parameters?: OperationParameter[];
21
21
  metadata?: Record<string, any>;
22
22
  version?: string;
@@ -26,4 +26,55 @@ export type SearchDocument = {
26
26
  'redocly::teams-rbac'?: { [x: string]: string };
27
27
  [REDOCLY_ROUTE_RBAC]?: { slug?: string; fsPath?: string };
28
28
  badges?: ItemBadge[];
29
+ facets?: Record<string, string>;
30
+ tags?: string[];
31
+ rbacTeams?: string[];
32
+ };
33
+
34
+ export type ParameterHighlight = {
35
+ name: string;
36
+ description: string;
37
+ place: string;
38
+ path: string[];
39
+ };
40
+
41
+ export type SearchItemData = {
42
+ document: SearchDocument;
43
+ highlight: Record<string, string> & { parameters?: ParameterHighlight[]; path?: string[] };
44
+ };
45
+
46
+ export type SearchFacet = {
47
+ name: string;
48
+ field: string;
49
+ type: SearchFacetType;
50
+ values: string[] | SearchFacetCount[];
51
+ isTop?: boolean;
52
+ index?: number;
53
+ };
54
+
55
+ export type SearchFacetCount = {
56
+ value: string;
57
+ count: number;
58
+ isCounterVisible?: boolean;
59
+ };
60
+
61
+ export type SearchFacetQuery = {
62
+ query: string;
63
+ filter: SearchFilterItem[];
64
+ facetQuery: string;
65
+ };
66
+
67
+ export type SearchFacetType =
68
+ | 'input'
69
+ | 'multi-select'
70
+ | 'select'
71
+ | 'switch'
72
+ | 'radio'
73
+ | 'tags'
74
+ | 'checkbox';
75
+
76
+ export type SearchFilterItem = {
77
+ field: string;
78
+ values: string[];
79
+ isTop?: boolean;
29
80
  };
@@ -0,0 +1,33 @@
1
+ import type React from 'react';
2
+
3
+ export type SelectOption<T> = {
4
+ value: T;
5
+ element?: React.ReactNode | JSX.Element | string;
6
+ label?: string;
7
+ };
8
+
9
+ export type SelectProps<T = any> = {
10
+ value?: SelectOption<T> | SelectOption<T>[] | T | T[];
11
+ options: SelectOption<T>[];
12
+ multiple?: boolean;
13
+ searchable?: boolean;
14
+ clearable?: boolean;
15
+ dataAttributes?: Record<string, string>;
16
+ className?: string;
17
+ withArrow?: boolean;
18
+ triggerEvent?: 'click' | 'hover';
19
+ placement?: 'top' | 'bottom';
20
+ alignment?: 'start' | 'end';
21
+ onlyIcon?: boolean;
22
+ placeholder?: string;
23
+ disabled?: boolean;
24
+ hideCheckmarkIcon?: boolean;
25
+ checkmarkIconPosition?: 'start' | 'end';
26
+ dataTestId?: string;
27
+ icon?: React.ReactNode;
28
+ footer?: React.ReactNode;
29
+ onChange?: (value: T | T[]) => void;
30
+ renderInput?: () => React.ReactElement;
31
+ renderDivider?: () => React.ReactElement;
32
+ onSearch?: (value: T | null) => void;
33
+ };
@@ -24,3 +24,4 @@ export * from '@redocly/theme/core/utils/format-date-without-timezone';
24
24
  export * from '@redocly/theme/core/utils/details';
25
25
  export * from '@redocly/theme/core/utils/get-navbar-element';
26
26
  export * from '@redocly/theme/core/utils/with-load-progress';
27
+ export * from '@redocly/theme/core/utils/text-trimmer';
@@ -0,0 +1,7 @@
1
+ export function trimText(text: string | string[], maxLength: number = 150): string | string[] {
2
+ if (typeof text === 'string') {
3
+ if (text.length <= maxLength) {
4
+ return text;
5
+ } else return `${text.slice(0, maxLength)}...`;
6
+ } else return text;
7
+ }
@@ -0,0 +1,26 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+
4
+ import type { IconProps } from '@redocly/theme/icons/types';
5
+
6
+ import { getCssColorVariable } from '@redocly/theme/core/utils';
7
+
8
+ const Icon = (props: IconProps) => (
9
+ <svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
10
+ <path
11
+ d="M9 14C10.1867 14 11.3467 13.6481 12.3334 12.9888C13.3201 12.3295 14.0892 11.3925 14.5433 10.2961C14.9974 9.19975 15.1162 7.99335 14.8847 6.82946C14.6532 5.66558 14.0818 4.59648 13.2426 3.75736C12.4035 2.91825 11.3344 2.3468 10.1705 2.11529C9.00666 1.88378 7.80026 2.0026 6.7039 2.45673C5.60754 2.91085 4.67047 3.67989 4.01118 4.66658C3.35189 5.65328 3 6.81331 3 8V11.1L1.2 9.3L0.5 10L3.5 13L6.5 10L5.8 9.3L4 11.1V8C4 7.0111 4.29324 6.0444 4.84265 5.22215C5.39206 4.39991 6.17295 3.75904 7.08658 3.38061C8.00021 3.00217 9.00555 2.90315 9.97545 3.09608C10.9454 3.289 11.8363 3.76521 12.5355 4.46447C13.2348 5.16373 13.711 6.05465 13.9039 7.02455C14.0969 7.99446 13.9978 8.99979 13.6194 9.91342C13.241 10.8271 12.6001 11.6079 11.7779 12.1574C10.9556 12.7068 9.98891 13 9 13V14Z"
12
+ fill="#1A1C21"
13
+ />
14
+ </svg>
15
+ );
16
+
17
+ export const ResetIcon = styled(Icon).attrs(() => ({
18
+ 'data-component-name': 'icons/ResetIcon/ResetIcon',
19
+ }))<IconProps>`
20
+ path {
21
+ fill: ${({ color }) => getCssColorVariable(color)};
22
+ }
23
+
24
+ height: ${({ size }) => size || '16px'};
25
+ width: ${({ size }) => size || '16px'};
26
+ `;
@@ -0,0 +1,30 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+
4
+ import type { IconProps } from '@redocly/theme/icons/types';
5
+
6
+ import { getCssColorVariable } from '@redocly/theme/core/utils';
7
+
8
+ const Icon = (props: IconProps) => (
9
+ <svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
10
+ <path
11
+ d="M15.875 2.5H13.5687C13.2875 1.20625 12.1625 0.25 10.8125 0.25C9.4625 0.25 8.3375 1.20625 8.05625 2.5H0.125V3.625H8.05625C8.3375 4.91875 9.4625 5.875 10.8125 5.875C12.1625 5.875 13.2875 4.91875 13.5687 3.625H15.875V2.5ZM10.8125 4.75C9.85625 4.75 9.125 4.01875 9.125 3.0625C9.125 2.10625 9.85625 1.375 10.8125 1.375C11.7688 1.375 12.5 2.10625 12.5 3.0625C12.5 4.01875 11.7688 4.75 10.8125 4.75Z"
12
+ fill="#22242B"
13
+ />
14
+ <path
15
+ d="M0.125 11.5H2.43125C2.7125 12.7937 3.8375 13.75 5.1875 13.75C6.5375 13.75 7.6625 12.7937 7.94375 11.5H15.875V10.375H7.94375C7.6625 9.08125 6.5375 8.125 5.1875 8.125C3.8375 8.125 2.7125 9.08125 2.43125 10.375H0.125V11.5ZM5.1875 9.25C6.14375 9.25 6.875 9.98125 6.875 10.9375C6.875 11.8938 6.14375 12.625 5.1875 12.625C4.23125 12.625 3.5 11.8938 3.5 10.9375C3.5 9.98125 4.23125 9.25 5.1875 9.25Z"
16
+ fill="#22242B"
17
+ />
18
+ </svg>
19
+ );
20
+
21
+ export const SettingsIcon = styled(Icon).attrs(() => ({
22
+ 'data-component-name': 'icons/SettingsIcon/SettingsIcon',
23
+ }))<IconProps>`
24
+ path {
25
+ fill: ${({ color }) => getCssColorVariable(color)};
26
+ }
27
+
28
+ height: ${({ size }) => size || '16px'};
29
+ width: ${({ size }) => size || '16px'};
30
+ `;
package/src/index.ts CHANGED
@@ -13,7 +13,7 @@ export * from '@redocly/theme/components/Badge/Badge';
13
13
  export * from '@redocly/theme/components/Dropdown/Dropdown';
14
14
  export * from '@redocly/theme/components/Dropdown/DropdownMenu';
15
15
  export * from '@redocly/theme/components/Dropdown/DropdownMenuItem';
16
- export * from '@redocly/theme/components/Loading/Loading';
16
+ export * from '@redocly/theme/components/Loaders/Loading';
17
17
  export * from '@redocly/theme/components/Link/Link';
18
18
  export * from '@redocly/theme/components/Portal/Portal';
19
19
  export * from '@redocly/theme/components/Segmented/Segmented';
@@ -135,6 +135,11 @@ export * from '@redocly/theme/components/Search/SearchShortcut';
135
135
  export * from '@redocly/theme/components/Search/SearchTrigger';
136
136
  export * from '@redocly/theme/components/Search/SearchRecent';
137
137
  export * from '@redocly/theme/components/Search/SearchSuggestedPages';
138
+ export * from '@redocly/theme/components/Search/SearchGroups';
139
+ export * from '@redocly/theme/components/Search/SearchFilter';
140
+ export * from '@redocly/theme/components/Search/SearchFilterField';
141
+ export * from '@redocly/theme/components/Search/FilterFields/SearchFilterFieldSelect';
142
+ export * from '@redocly/theme/components/Search/FilterFields/SearchFilterFieldTags';
138
143
  /* Icons */
139
144
  export * from '@redocly/theme/icons/ArrowRightIcon/ArrowRightIcon';
140
145
  export * from '@redocly/theme/icons/ArrowUpRightIcon/ArrowUpRightIcon';
@@ -150,6 +155,7 @@ export * from '@redocly/theme/icons/FolderAddIcon/FolderAddIcon';
150
155
  export * from '@redocly/theme/icons/FolderIcon/FolderIcon';
151
156
  export * from '@redocly/theme/icons/FolderMoveToIcon/FolderMoveToIcon';
152
157
  export * from '@redocly/theme/icons/SelectIcon/SelectIcon';
158
+ export * from '@redocly/theme/icons/SettingsIcon/SettingsIcon';
153
159
  export * from '@redocly/theme/icons/CloseIcon/CloseIcon';
154
160
  export * from '@redocly/theme/icons/CloseOutlineIcon/CloseOutlineIcon';
155
161
  export * from '@redocly/theme/icons/CloseFilledIcon/CloseFilledIcon';
@@ -197,6 +203,7 @@ export * from '@redocly/theme/icons/MobileSidebarIcon/MobileSidebarIcon';
197
203
  export * from '@redocly/theme/icons/CopyLinkIcon/CopyLinkIcon';
198
204
  export * from '@redocly/theme/icons/OverflowMenuHorizontalIcon/OverflowMenuHorizontalIcon';
199
205
  export * from '@redocly/theme/icons/RenewIcon/RenewIcon';
206
+ export * from '@redocly/theme/icons/ResetIcon/ResetIcon';
200
207
  export * from '@redocly/theme/icons/WarningAltIcon/WarningAltIcon';
201
208
  export * from '@redocly/theme/icons/MoonIcon/MoonIcon';
202
209
  export * from '@redocly/theme/icons/SunIcon/SunIcon';
@@ -47,17 +47,17 @@ export function Card({
47
47
  as={to ? Link : 'div'}
48
48
  to={to}
49
49
  aria-labelledby={cardTitleId}
50
- variant={variant}
51
- layout={layout}
52
- isCardLink={!!to}
50
+ $variant={variant}
51
+ $layout={layout}
52
+ $isCardLink={!!to}
53
53
  >
54
54
  <>
55
55
  {image ? <CardImage src={image} alt={title} position={imagePosition} /> : null}
56
56
  <CardContentWrapper
57
- layout={layout}
58
- alignItems={alignItems}
59
- textAlign={textAlign}
60
- hasImage={image !== undefined}
57
+ $layout={layout}
58
+ $alignItems={alignItems}
59
+ $textAlign={textAlign}
60
+ $hasImage={image !== undefined}
61
61
  >
62
62
  {icon && <CardIcon variant={iconVariant} src={icon} rawContent={iconRawContent} />}
63
63
  <ContentWrapper>
@@ -74,19 +74,19 @@ export function Card({
74
74
  }
75
75
 
76
76
  const CardContentWrapper = styled.div<{
77
- layout?: string;
78
- alignItems: string;
79
- textAlign: string;
80
- hasImage: boolean;
77
+ $layout?: string;
78
+ $alignItems: string;
79
+ $textAlign: string;
80
+ $hasImage: boolean;
81
81
  }>`
82
82
  display: flex;
83
- flex-direction: ${({ layout }) => (layout === 'horizontal' ? 'row' : 'column')};
83
+ flex-direction: ${({ $layout }) => ($layout === 'horizontal' ? 'row' : 'column')};
84
84
  gap: var(--card-icon-gap);
85
- align-items: ${({ alignItems }) => alignItems};
86
- text-align: ${({ textAlign }) => textAlign};
85
+ align-items: ${({ $alignItems }) => $alignItems};
86
+ text-align: ${({ $textAlign }) => $textAlign};
87
87
  flex-grow: 1;
88
88
  padding: var(--card-padding);
89
- height: ${({ hasImage }) => (hasImage ? 'auto' : '100%')};
89
+ height: ${({ $hasImage }) => ($hasImage ? 'auto' : '100%')};
90
90
  `;
91
91
 
92
92
  const ContentWrapper = styled.div`
@@ -1,4 +0,0 @@
1
- export type SelectOption<T> = {
2
- value: T;
3
- label: string;
4
- };
@@ -1,4 +0,0 @@
1
- export type SelectOption<T> = {
2
- value: T;
3
- label: string;
4
- };
File without changes
File without changes