Skip to content

Commit

Permalink
wip overrides context
Browse files Browse the repository at this point in the history
  • Loading branch information
Niklas Kiefer committed Sep 12, 2022
1 parent c1bacf1 commit 3604f78
Show file tree
Hide file tree
Showing 7 changed files with 143 additions and 52 deletions.
113 changes: 70 additions & 43 deletions src/PropertiesPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
ErrorsContext,
EventContext,
LayoutContext,
OverridesContext,
PropertiesPanelContext
} from './context';

Expand All @@ -37,6 +38,8 @@ const DEFAULT_LAYOUT = {

const DEFAULT_DESCRIPTION = {};

const DEFAULT_OVERRIDES = {};

const bufferedEvents = [
'propertiesPanel.showEntry',
'propertiesPanel.setErrors'
Expand Down Expand Up @@ -101,27 +104,29 @@ const bufferedEvents = [
* data from implementor to describe *what* will be rendered.
*
* @param {Object} props
* @param {Function} [props.descriptionLoaded]
* @param {DescriptionConfig} [props.descriptionConfig]
* @param {Object} [props.eventBus]
* @param {Object|Array} props.element
* @param {import('./components/Header').HeaderProvider} props.headerProvider
* @param {PlaceholderProvider} [props.placeholderProvider]
* @param {Array<GroupDefinition|ListGroupDefinition>} props.groups
* @param {Object} [props.layoutConfig]
* @param {import('./components/Header').HeaderProvider} props.headerProvider
* @param {Function} [props.layoutChanged]
* @param {DescriptionConfig} [props.descriptionConfig]
* @param {Function} [props.descriptionLoaded]
* @param {Object} [props.eventBus]
* @param {Object} [props.layoutConfig]
* @param {Object} [props.overridesConfig]
* @param {PlaceholderProvider} [props.placeholderProvider]
*/
export default function PropertiesPanel(props) {
const {
descriptionConfig = {},
descriptionLoaded,
element,
headerProvider,
placeholderProvider,
eventBus,
groups,
layoutConfig = {},
headerProvider,
layoutChanged,
descriptionConfig = {},
descriptionLoaded,
eventBus
layoutConfig = {},
overridesConfig = {},
placeholderProvider
} = props;

// set-up layout context
Expand Down Expand Up @@ -166,6 +171,19 @@ export default function PropertiesPanel(props) {
getDescriptionForId
};

// set-up overrides context
const overrides = createOverridesContext(overridesConfig);

const getOverridesForId = (id) => {
return overrides[id] || {};
};

const overridesContext = {
overrides,
getOverridesForId
};

// set-up errors context
useEventBuffer(bufferedEvents, eventBus);

const [ errors, setErrors ] = useState({});
Expand Down Expand Up @@ -199,38 +217,40 @@ export default function PropertiesPanel(props) {
return (
<PropertiesPanelContext.Provider value={ propertiesPanelContext }>
<ErrorsContext.Provider value={ errorsContext }>
<DescriptionContext.Provider value={ descriptionContext }>
<LayoutContext.Provider value={ layoutContext }>
<EventContext.Provider value={ eventContext }>
<div
class={ classnames(
'bio-properties-panel',
layout.open ? 'open' : '')
}>
<Header
element={ element }
headerProvider={ headerProvider } />
<div class="bio-properties-panel-scroll-container">
{
groups.map(group => {
const {
component: Component = Group,
id
} = group;

return (
<Component
{ ...group }
key={ id }
element={ element } />
);
})
}
<OverridesContext.Provider value={ overridesContext }>
<DescriptionContext.Provider value={ descriptionContext }>
<LayoutContext.Provider value={ layoutContext }>
<EventContext.Provider value={ eventContext }>
<div
class={ classnames(
'bio-properties-panel',
layout.open ? 'open' : '')
}>
<Header
element={ element }
headerProvider={ headerProvider } />
<div class="bio-properties-panel-scroll-container">
{
groups.map(group => {
const {
component: Component = Group,
id
} = group;

return (
<Component
{ ...group }
key={ id }
element={ element } />
);
})
}
</div>
</div>
</div>
</EventContext.Provider>
</LayoutContext.Provider>
</DescriptionContext.Provider>
</EventContext.Provider>
</LayoutContext.Provider>
</DescriptionContext.Provider>
</OverridesContext.Provider>
</ErrorsContext.Provider>
</PropertiesPanelContext.Provider>
);
Expand All @@ -251,4 +271,11 @@ function createDescriptionContext(overrides) {
...DEFAULT_DESCRIPTION,
...overrides
};
}

function createOverridesContext(overrides) {
return {
...DEFAULT_OVERRIDES,
...overrides
};
}
16 changes: 13 additions & 3 deletions src/components/entries/Select.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import classNames from 'classnames';

import { isFunction } from 'min-dash';

import {
useError,
useOverridesContext,
useShowEntryEvent
} from '../../hooks';

Expand Down Expand Up @@ -111,8 +114,15 @@ export default function SelectEntry(props) {
disabled
} = props;

const value = getValue(element);
const options = getOptions(element);
const {
getValue: overrideGetValue,
setValue: overrideSetValue,
getOptions: overrideGetOptions
} = useOverridesContext(id);

const value = isFunction(overrideGetValue) ? overrideGetValue(element) : getValue(element);
const options = isFunction(overrideGetOptions) ? overrideGetOptions(element) : getOptions(element);
const onChange = isFunction(overrideSetValue) ? overrideSetValue : setValue;

const error = useError(id);

Expand All @@ -128,7 +138,7 @@ export default function SelectEntry(props) {
key={ element }
label={ label }
value={ value }
onChange={ setValue }
onChange={ onChange }
options={ options }
disabled={ disabled } />
{ error && <div class="bio-properties-panel-error">{ error }</div> }
Expand Down
25 changes: 19 additions & 6 deletions src/components/entries/TextField.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { isFunction } from 'min-dash';

import {
useError,
useOverridesContext,
usePrevious,
useShowEntryEvent
} from '../../hooks';
Expand Down Expand Up @@ -99,29 +100,41 @@ export default function TextfieldEntry(props) {
const globalError = useError(id);
const [ localError, setLocalError ] = useState(null);

let value = getValue(element);
const {
getValue: overrideGetValue,
setValue: overrideSetValue,
validate: overrideValidate
} = useOverridesContext(id);

let value = isFunction(overrideGetValue) ? overrideGetValue(element) : getValue(element);

const previousValue = usePrevious(value);

useEffect(() => {
if (isFunction(validate)) {
const newValidationError = validate(value) || null;
let newValidationError;

setLocalError(newValidationError);
if (isFunction(overrideValidate)) {
newValidationError = overrideValidate(value) || null;
} else if (isFunction(validate)) {
newValidationError = validate(value) || null;
}

newValidationError && setLocalError(newValidationError);
}, [ value ]);

const onInput = (newValue) => {
let newValidationError = null;

if (isFunction(validate)) {
if (isFunction(overrideValidate)) {
newValidationError = overrideValidate(newValue) || null;
} else if (isFunction(validate)) {
newValidationError = validate(newValue) || null;
}

if (newValidationError) {
setCachedInvalidValue(newValue);
} else {
setValue(newValue);
isFunction(overrideSetValue) ? overrideSetValue(newValue) : setValue(newValue);
}

setLocalError(newValidationError);
Expand Down
10 changes: 10 additions & 0 deletions src/context/OverridesContext.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import {
createContext
} from 'preact';

const OverridesContext = createContext({
overrides: {},
getOverridesForId: () => {}
});

export default OverridesContext;
1 change: 1 addition & 0 deletions src/context/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ export { default as DescriptionContext } from './DescriptionContext';
export { default as ErrorsContext } from './ErrorsContext';
export { default as EventContext } from './EventContext';
export { default as LayoutContext } from './LayoutContext';
export { default as OverridesContext } from './OverridesContext';
export { default as PropertiesPanelContext } from './LayoutContext';
1 change: 1 addition & 0 deletions src/hooks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export { useEvent } from './useEvent';
export { useEventBuffer } from './useEventBuffer';
export { useKeyFactory } from './useKeyFactory';
export { useLayoutState } from './useLayoutState';
export { useOverridesContext } from './useOverridesContext';
export { usePrevious } from './usePrevious';
export { useShowEntryEvent } from './useShowEntryEvent';
export { useStickyIntersectionObserver } from './useStickyIntersectionObserver';
Expand Down
29 changes: 29 additions & 0 deletions src/hooks/useOverridesContext.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import {
useContext
} from 'preact/hooks';

import {
OverridesContext
} from '../context';

/**
* Accesses the global OverridesContext and returns custom handlers for a given id and element.
*
* @example
* ```jsx
* function TextField(props) {
* const { getValue } = OverridesContext('input1');
* }
* ```
*
* @param {string} id
*
* @returns {string}
*/
export function useOverridesContext(id) {
const {
getOverridesForId
} = useContext(OverridesContext);

return getOverridesForId(id);
}

0 comments on commit 3604f78

Please sign in to comment.