@redocly/theme 0.9.11 → 0.9.12-alpha.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.
@@ -1,5 +1,7 @@
1
1
  /// <reference types="react" />
2
2
  import type { ResolvedFilter } from '@theme/types/portal/src/shared/types/catalog';
3
3
  export declare function Filter({ filter }: {
4
- filter: ResolvedFilter;
4
+ filter: ResolvedFilter & {
5
+ selectedOptions: any;
6
+ };
5
7
  }): JSX.Element | null;
@@ -7,19 +7,36 @@ exports.Filter = void 0;
7
7
  const react_1 = __importDefault(require("react"));
8
8
  const styled_components_1 = __importDefault(require("styled-components"));
9
9
  const Checkbox_1 = require("../ui/Checkbox");
10
+ // TODO: figure out how to fix this
11
+ const DatePicker =
12
+ // eslint-disable-next-line @typescript-eslint/no-var-requires, import/order, import/no-extraneous-dependencies
13
+ require('react-date-picker').default;
14
+ // disabled type checking for selectedOptions
10
15
  function Filter({ filter }) {
11
- var _a;
16
+ var _a, _b;
12
17
  if (!filter.parentUsed)
13
18
  return null;
14
19
  return (react_1.default.createElement(FilterGroup, { key: filter.property + filter.title },
15
- react_1.default.createElement(FilterTitle, null, filter.title),
16
- filter.type === 'select' ? (react_1.default.createElement(StyledSelect, { onChange: (e) => filter.selectOption(e.target.value), value: ((_a = filter.selectedOptions.values().next()) === null || _a === void 0 ? void 0 : _a.value) || '' },
20
+ react_1.default.createElement(FilterTitle, null,
21
+ filter.title,
22
+ ((_a = filter.selectedOptions) === null || _a === void 0 ? void 0 : _a.size) ? (react_1.default.createElement("a", { onClick: () => filter.selectOption('') }, " Clear ")) : null),
23
+ filter.type === 'select' ? (react_1.default.createElement(StyledSelect, { onChange: (e) => filter.selectOption(e.target.value), value: ((_b = filter.selectedOptions.values().next()) === null || _b === void 0 ? void 0 : _b.value) || '' },
17
24
  react_1.default.createElement("option", { key: "none", value: "" }, "All"),
18
25
  filter.filteredOptions.map((value) => (react_1.default.createElement("option", { key: value.value, value: value.value },
19
26
  value.value,
20
27
  " (",
21
28
  value.count,
22
- ")"))))) : (filter.filteredOptions.map((value) => {
29
+ ")"))))) : filter.type === 'date-range' ? (react_1.default.createElement(react_1.default.Fragment, null,
30
+ react_1.default.createElement(DatePickerWrapper, null,
31
+ react_1.default.createElement("span", null, " From: "),
32
+ react_1.default.createElement(DatePicker, { closeCalendar: true, format: "y-MM-dd", dayPlaceholder: "DD", monthPlaceholder: "MM", yearPlaceholder: "YYYY", value: filter.selectedOptions.from ? new Date(filter.selectedOptions.from) : null, minDetail: "decade", maxDate: new Date(), onChange: (from) => {
33
+ filter.selectOption(Object.assign(Object.assign({}, filter.selectedOptions), { from: formatDateWithNoTimeZone(from) }));
34
+ } })),
35
+ react_1.default.createElement(DatePickerWrapper, null,
36
+ react_1.default.createElement("span", null, " To: "),
37
+ react_1.default.createElement(DatePicker, { closeCalendar: true, dayPlaceholder: "DD", monthPlaceholder: "MM", yearPlaceholder: "YYYY", format: "y-MM-dd", minDate: filter.selectedOptions.from ? new Date(filter.selectedOptions.from) : undefined, value: filter.selectedOptions.to ? new Date(filter.selectedOptions.to) : null, minDetail: "decade", onChange: (to) => {
38
+ filter.selectOption(Object.assign(Object.assign({}, filter.selectedOptions), { to: formatDateWithNoTimeZone(to) }));
39
+ } })))) : (filter.filteredOptions.map((value) => {
23
40
  const id = 'filter--' + filter.property + '--' + slug(value.value);
24
41
  return (react_1.default.createElement(FilterValue, { key: id },
25
42
  react_1.default.createElement(Checkbox_1.Checkbox, { type: "checkbox", id: id, checked: filter.selectedOptions.has(value.value), onChange: () => filter.toggleOption(value.value) }),
@@ -44,6 +61,11 @@ const FilterTitle = styled_components_1.default.h4 `
44
61
  font-weight: var(--font-weight-bold);
45
62
  margin: 0;
46
63
  margin-bottom: 16px;
64
+
65
+ > a {
66
+ font-size: 14px;
67
+ cursor: pointer;
68
+ }
47
69
  `;
48
70
  const FilterValue = styled_components_1.default.label `
49
71
  display: block;
@@ -78,9 +100,66 @@ const StyledSelect = styled_components_1.default.select `
78
100
  background-position: right 10px center;
79
101
  background-size: 1em;
80
102
  width: 100%;
103
+ padding-right: 25px;
81
104
  `;
82
105
  // TODO: import from portal
83
106
  function slug(str) {
84
107
  return str.replace(/\s/g, '-').toLowerCase();
85
108
  }
109
+ const DatePickerWrapper = styled_components_1.default.div `
110
+ display: flex;
111
+ flex-direction: row;
112
+ margin-bottom: 5px;
113
+
114
+ align-items: center;
115
+ gap: 10px;
116
+
117
+ > span {
118
+ width: 50px;
119
+ }
120
+
121
+ .react-date-picker {
122
+ flex: 1;
123
+ }
124
+
125
+ .react-calendar__tile--now {
126
+ background: #cbf7f1;
127
+ color: black;
128
+
129
+ &:enabled:hover,
130
+ &:enabled:focus {
131
+ background: #b1efe7;
132
+ color: black;
133
+ }
134
+ }
135
+
136
+ .react-date-picker__inputGroup__input:invalid {
137
+ background: rgb(255 125 0 / 10%);
138
+ }
139
+
140
+ .react-date-picker__button {
141
+ padding: 4px 4px;
142
+ svg {
143
+ width: 12px;
144
+ }
145
+ }
146
+
147
+ .react-date-picker__wrapper {
148
+ border: 1px solid rgba(0, 0, 0, 0.23);
149
+ border-radius: var(--border-radius);
150
+ padding: var(--input-padding);
151
+ }
152
+
153
+ .react-date-picker__inputGroup__input {
154
+ width: 20px;
155
+ }
156
+ `;
157
+ function padZero(num) {
158
+ return num < 10 ? '0' + num : num;
159
+ }
160
+ function formatDateWithNoTimeZone(date) {
161
+ if (!date)
162
+ return date;
163
+ return `${date.getFullYear()}-${padZero(date.getMonth() + 1)}-${padZero(date.getDate())}`;
164
+ }
86
165
  //# sourceMappingURL=Filter.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redocly/theme",
3
- "version": "0.9.11",
3
+ "version": "0.9.12-alpha.0",
4
4
  "description": "Shared UI components lib",
5
5
  "author": "team@redocly.com",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -83,6 +83,7 @@
83
83
  "dependencies": {
84
84
  "copy-to-clipboard": "^3.3.3",
85
85
  "highlight-words-core": "^1.2.2",
86
+ "react-date-picker": "9.2.0",
86
87
  "hotkeys-js": "^3.10.1",
87
88
  "timeago.js": "^4.0.2"
88
89
  },
@@ -1,18 +1,31 @@
1
1
  import React from 'react';
2
2
  import styled from 'styled-components';
3
3
 
4
+ import type { DatePickerProps } from 'react-date-picker';
5
+
4
6
  import type { ResolvedFilter } from '@theme/types/portal/src/shared/types/catalog';
5
7
  import { Checkbox } from '@theme/ui/Checkbox';
6
8
 
7
- export function Filter({ filter }: { filter: ResolvedFilter }) {
9
+ // TODO: figure out how to fix this
10
+ const DatePicker: React.FC<DatePickerProps> =
11
+ // eslint-disable-next-line @typescript-eslint/no-var-requires, import/order, import/no-extraneous-dependencies
12
+ require('react-date-picker').default;
13
+
14
+ // disabled type checking for selectedOptions
15
+ export function Filter({ filter }: { filter: ResolvedFilter & { selectedOptions: any } }) {
8
16
  if (!filter.parentUsed) return null;
9
17
  return (
10
18
  <FilterGroup key={filter.property + filter.title}>
11
- <FilterTitle>{filter.title}</FilterTitle>
19
+ <FilterTitle>
20
+ {filter.title}
21
+ {filter.selectedOptions?.size ? (
22
+ <a onClick={() => filter.selectOption('')}> Clear </a>
23
+ ) : null}
24
+ </FilterTitle>
12
25
  {filter.type === 'select' ? (
13
26
  <StyledSelect
14
27
  onChange={(e) => filter.selectOption(e.target.value)}
15
- value={filter.selectedOptions.values().next()?.value || ''}
28
+ value={(filter.selectedOptions as Set<any>).values().next()?.value || ''}
16
29
  >
17
30
  <option key="none" value="">
18
31
  All
@@ -23,6 +36,49 @@ export function Filter({ filter }: { filter: ResolvedFilter }) {
23
36
  </option>
24
37
  ))}
25
38
  </StyledSelect>
39
+ ) : filter.type === 'date-range' ? (
40
+ <>
41
+ <DatePickerWrapper>
42
+ <span> From: </span>
43
+ <DatePicker
44
+ closeCalendar={true}
45
+ format="y-MM-dd"
46
+ dayPlaceholder="DD"
47
+ monthPlaceholder="MM"
48
+ yearPlaceholder="YYYY"
49
+ value={filter.selectedOptions.from ? new Date(filter.selectedOptions.from) : null}
50
+ minDetail="decade"
51
+ maxDate={new Date()}
52
+ onChange={(from: Date) => {
53
+ filter.selectOption({
54
+ ...(filter.selectedOptions as any),
55
+ from: formatDateWithNoTimeZone(from),
56
+ });
57
+ }}
58
+ />
59
+ </DatePickerWrapper>
60
+ <DatePickerWrapper>
61
+ <span> To: </span>
62
+ <DatePicker
63
+ closeCalendar={true}
64
+ dayPlaceholder="DD"
65
+ monthPlaceholder="MM"
66
+ yearPlaceholder="YYYY"
67
+ format="y-MM-dd"
68
+ minDate={
69
+ filter.selectedOptions.from ? new Date(filter.selectedOptions.from) : undefined
70
+ }
71
+ value={filter.selectedOptions.to ? new Date(filter.selectedOptions.to) : null}
72
+ minDetail="decade"
73
+ onChange={(to: Date) => {
74
+ filter.selectOption({
75
+ ...filter.selectedOptions,
76
+ to: formatDateWithNoTimeZone(to),
77
+ });
78
+ }}
79
+ />
80
+ </DatePickerWrapper>
81
+ </>
26
82
  ) : (
27
83
  filter.filteredOptions.map((value: any) => {
28
84
  const id = 'filter--' + filter.property + '--' + slug(value.value);
@@ -59,6 +115,11 @@ const FilterTitle = styled.h4`
59
115
  font-weight: var(--font-weight-bold);
60
116
  margin: 0;
61
117
  margin-bottom: 16px;
118
+
119
+ > a {
120
+ font-size: 14px;
121
+ cursor: pointer;
122
+ }
62
123
  `;
63
124
 
64
125
  const FilterValue = styled.label`
@@ -95,9 +156,68 @@ const StyledSelect = styled.select`
95
156
  background-position: right 10px center;
96
157
  background-size: 1em;
97
158
  width: 100%;
159
+ padding-right: 25px;
98
160
  `;
99
161
 
100
162
  // TODO: import from portal
101
163
  function slug(str: string): string {
102
164
  return str.replace(/\s/g, '-').toLowerCase();
103
165
  }
166
+
167
+ const DatePickerWrapper = styled.div`
168
+ display: flex;
169
+ flex-direction: row;
170
+ margin-bottom: 5px;
171
+
172
+ align-items: center;
173
+ gap: 10px;
174
+
175
+ > span {
176
+ width: 50px;
177
+ }
178
+
179
+ .react-date-picker {
180
+ flex: 1;
181
+ }
182
+
183
+ .react-calendar__tile--now {
184
+ background: #cbf7f1;
185
+ color: black;
186
+
187
+ &:enabled:hover,
188
+ &:enabled:focus {
189
+ background: #b1efe7;
190
+ color: black;
191
+ }
192
+ }
193
+
194
+ .react-date-picker__inputGroup__input:invalid {
195
+ background: rgb(255 125 0 / 10%);
196
+ }
197
+
198
+ .react-date-picker__button {
199
+ padding: 4px 4px;
200
+ svg {
201
+ width: 12px;
202
+ }
203
+ }
204
+
205
+ .react-date-picker__wrapper {
206
+ border: 1px solid rgba(0, 0, 0, 0.23);
207
+ border-radius: var(--border-radius);
208
+ padding: var(--input-padding);
209
+ }
210
+
211
+ .react-date-picker__inputGroup__input {
212
+ width: 20px;
213
+ }
214
+ `;
215
+
216
+ function padZero(num: number) {
217
+ return num < 10 ? '0' + num : num;
218
+ }
219
+
220
+ function formatDateWithNoTimeZone(date?: Date | null) {
221
+ if (!date) return date;
222
+ return `${date.getFullYear()}-${padZero(date.getMonth() + 1)}-${padZero(date.getDate())}`;
223
+ }
@@ -8,7 +8,7 @@ export type FilteredCatalog = {
8
8
  };
9
9
 
10
10
  export type Filter = {
11
- type?: 'select' | 'checkboxes';
11
+ type?: 'select' | 'checkboxes' | 'date-range';
12
12
  title: string;
13
13
  property: string;
14
14
  parentFilter?: string;
@@ -44,6 +44,7 @@ export type ResolvedFilter = Omit<Filter, 'options'> & {
44
44
  selectOption: (option: string) => void;
45
45
  parentUsed: boolean;
46
46
  selectedOptions: Set<string>;
47
+ range?: {from?: string; to?: string};
47
48
  };
48
49
 
49
50
  export type CatalogItem = {
@@ -51,5 +52,6 @@ export type CatalogItem = {
51
52
  link: string;
52
53
  description?: string;
53
54
  image?: string;
55
+ docsLink?: string;
54
56
  [k: string]: unknown;
55
57
  };