@stellar-expert/ui-framework 1.19.0 → 1.19.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1048,9 +1048,9 @@ import {FilterView, parseFiltersFromQuery} from '@stellar-expert/ui-framework'
1048
1048
  onChange={filters => setActiveFilters(filters)}/>
1049
1049
  ```
1050
1050
 
1051
- #### `parseFiltersFromQuery()`
1051
+ #### `parseFiltersFromQuery(fields)`
1052
1052
 
1053
- Parses and validates filter parameters from the current URL query string against registered field definitions. Returns an object with matched filter key-value pairs.
1053
+ Parses and validates filter parameters from the current URL query string against passed field definitions. Returns an object with matched filter key-value pairs.
1054
1054
 
1055
1055
  ---
1056
1056
 
@@ -1,5 +1,5 @@
1
1
  import React, {useCallback, useEffect, useState} from 'react'
2
- import {parseQuery} from '@stellar-expert/navigation'
2
+ import {navigation, parseQuery} from '@stellar-expert/navigation'
3
3
  import deepmerge from 'deepmerge'
4
4
  import {Dropdown} from '../controls/dropdown'
5
5
  import {resolveFilterEditor} from './filter-editors'
@@ -10,10 +10,16 @@ let fieldDescriptionMapping = {}
10
10
  function FilterCondition({field, value, setValue, removeFilter, edit}) {
11
11
  const updateValue = useCallback(function (value) {
12
12
  setValue(field, value)
13
+ //reset cursor when apply filter
14
+ navigation.updateQuery({cursor: undefined})
13
15
  }, [field, setValue])
14
16
 
15
17
  const removeValue = useCallback(function () {
16
18
  removeFilter(field, value)
19
+ //reset cursor when remove applied filter
20
+ if (!!value) {
21
+ navigation.updateQuery({cursor: undefined})
22
+ }
17
23
  }, [field, value, removeFilter])
18
24
 
19
25
  const childProps = {value, edit}
@@ -27,19 +33,22 @@ function FilterCondition({field, value, setValue, removeFilter, edit}) {
27
33
  return <span className="filter-condition condensed" title={edit ? '' : filter.description}>
28
34
  <span className={'icon-' + filter.icon}/>
29
35
  {title} {React.createElement(editor, childProps)}
30
- {removeFilter ? <a href="#" className="icon-delete-circle" onClick={removeValue} title="Remove filter"/> : <>&emsp;</>}
36
+ {removeFilter ?
37
+ <a href="#" className="icon-delete-circle" onClick={removeValue} title="Remove filter"/> :
38
+ !!setValue ? <>&emsp;&nbsp;&nbsp;</> : <>&emsp;</>}
31
39
  </span>
32
40
  }
33
41
  /**
34
42
  * Parses and validates filter parameters from the current URL query string
43
+ * @param {object} [fields] - Custom filter field definitions
35
44
  * @return {object}
36
45
  */
37
- export function parseFiltersFromQuery() {
46
+ export function parseFiltersFromQuery(fields = fieldDescriptionMapping) {
38
47
  const params = parseQuery()
39
48
  const filters = {}
40
49
  let isEmpty = true
41
50
  for (const [key, value] of Object.entries(params)) {
42
- const filterDescriptor = fieldDescriptionMapping[key]
51
+ const filterDescriptor = fields[key]
43
52
  if (!filterDescriptor)
44
53
  continue //skip unrelated query parameters
45
54
  filters[key] = value
@@ -124,10 +133,10 @@ export function FilterView({presetFilter, fields = {}, onChange}) {
124
133
  }, [onChange])
125
134
 
126
135
  useEffect(() => {
127
- const queryParams = parseFiltersFromQuery()
136
+ const queryParams = parseFiltersFromQuery(fields)
128
137
  setFilters(queryParams)
129
138
  updateExternalFilters(queryParams)
130
- }, [])
139
+ }, [fields])
131
140
 
132
141
 
133
142
  const replaceFilter = useCallback((field, value) => setTimeout(() => setFilters(prev => {
@@ -202,7 +211,7 @@ export function FilterView({presetFilter, fields = {}, onChange}) {
202
211
  <div className="mobile-only micro-space"/>
203
212
  <span className="icon-filter"/>&nbsp;Filters&emsp;
204
213
  <FiltersGroup filters={presetFilter}/>
205
- <FiltersGroup filters={readyFilters} replaceFilter={replaceFilter} removeFilter={removeFilter}/>
214
+ <FiltersGroup filters={readyFilters} replaceFilter={replaceFilter} removeFilter={!editorMode ? removeFilter : null}/>
206
215
  {!editorMode ?
207
216
  <Dropdown title={title} options={availableFields} onChange={addFilter}/> :
208
217
  <div className="micro-space">
package/index.d.ts CHANGED
@@ -1207,7 +1207,7 @@ export interface FilterViewProps {
1207
1207
  export function FilterView(props: FilterViewProps): React.ReactElement;
1208
1208
 
1209
1209
  /** Parse and validate filter parameters from the current URL query string */
1210
- export function parseFiltersFromQuery(): Record<string, any>;
1210
+ export function parseFiltersFromQuery(fields: FilterFieldDescriptor): Record<string, any>;
1211
1211
 
1212
1212
  // ============================================================================
1213
1213
  // Stellar Utilities
@@ -1,28 +1,34 @@
1
1
  import React from 'react'
2
+ import {createPortal} from 'react-dom'
2
3
  import PropTypes from 'prop-types'
4
+ import cn from 'classnames'
3
5
  import './dialog.scss'
4
6
 
5
7
  /**
6
8
  * Modal dialog
7
9
  * @param {boolean} dialogOpen - Whether a dialog is shown
10
+ * @param {boolean} [big] - Increases dialog max-width to 42em
11
+ * @param {string} [className] - Extra CSS classes for the dialog container
8
12
  * @param {*} children - Dialog content
9
13
  * @return {JSX.Element|null}
10
14
  * @constructor
11
15
  */
12
- export const Dialog = React.memo(function Dialog({dialogOpen, children}) {
16
+ export const Dialog = React.memo(function Dialog({dialogOpen, big, className, children}) {
13
17
  if (!dialogOpen)
14
18
  return null
15
- return <div className="dialog">
19
+ return createPortal(<div className="dialog">
16
20
  <div className="dialog-backdrop"/>
17
21
  <div className="dialog-content container">
18
- <div className="container">
22
+ <div className={cn('container', {big}, className)}>
19
23
  {children}
20
24
  </div>
21
25
  </div>
22
- </div>
26
+ </div>, document.body)
23
27
  })
24
28
 
25
29
  Dialog.propTypes = {
26
30
  dialogOpen: PropTypes.bool,
31
+ big: PropTypes.bool,
32
+ className: PropTypes.string,
27
33
  children: PropTypes.any
28
34
  }
@@ -20,16 +20,28 @@
20
20
  > .dialog-content {
21
21
  display: flex;
22
22
  flex-direction: column;
23
- justify-content: center;
23
+ align-items: center;
24
+ overflow-y: auto;
24
25
  height: 100%;
25
26
 
27
+ &::before,
28
+ &::after {
29
+ content: '';
30
+ flex: 1 0 0;
31
+ }
32
+
26
33
  > .container {
34
+ margin: $space-standard 0;
27
35
  background: var(--color-bg);
28
36
  border: 1px solid var(--color-contrast-border);
29
37
  border-radius: $border-radius-input;
30
38
  box-shadow: 0 2px 4px 0 var(--color-modal-bg);
31
39
  padding: $space-micro $space-standard $space-standard;
32
40
  max-width: 32em;
41
+
42
+ &.big {
43
+ max-width: 42em;
44
+ }
33
45
  }
34
46
  }
35
47
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stellar-expert/ui-framework",
3
- "version": "1.19.0",
3
+ "version": "1.19.2",
4
4
  "description": "StellarExpert shared UI components library",
5
5
  "main": "index.js",
6
6
  "module": "./index.js",