react#ForwardRefRenderFunction TypeScript Examples
The following examples show how to use
react#ForwardRefRenderFunction.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: BaseCurrentTime.tsx From rewind with MIT License | 7 votes |
ForwardCurrentTime: ForwardRefRenderFunction<GameCurrentTimeHandle, GameCurrentTimeProps> = (props, ref) => {
const refMain = useRef<HTMLSpanElement>(null);
const refMs = useRef<HTMLSpanElement>(null);
useImperativeHandle(ref, () => ({
updateTime(timeInMs) {
const [timeHMS, timeMS] = formatGameTime(timeInMs, true).split(".");
if (refMain.current) refMain.current.textContent = timeHMS;
if (refMs.current) refMs.current.textContent = "." + timeMS;
},
}));
return (
<Typography component={"span"} sx={{ userSelect: "all" }}>
<span ref={refMain}>0:00</span>
<Typography component={"span"} sx={{ color: (theme) => darken(theme.palette.text.primary, 0.6) }} ref={refMs}>
<span ref={refMs}>.000</span>
</Typography>
</Typography>
);
}
Example #2
Source File: FunnelBarGraph.tsx From posthog-foss with MIT License | 6 votes |
export function ValueInspectorButton({
icon,
onClick,
children,
disabled = false,
style,
title,
innerRef: refProp,
}: ValueInspectorButtonProps): JSX.Element {
const props = {
type: 'link' as const,
icon,
onClick,
className: 'funnel-inspect-button',
disabled,
style,
title,
children: <span className="funnel-inspect-label">{children}</span>,
}
if (refProp) {
const InnerComponent: ForwardRefRenderFunction<HTMLElement | null, ButtonProps> = (_, ref) => (
<Button ref={ref} {...props} />
)
const RefComponent = React.forwardRef(InnerComponent)
return <RefComponent ref={refProp} />
} else {
return <Button {...props} />
}
}
Example #3
Source File: DateConditionConfiguration.tsx From datart with Apache License 2.0 | 5 votes |
DateConditionConfiguration: ForwardRefRenderFunction<
FilterOptionForwardRef,
{
condition?: ChartFilterCondition;
onChange: (condition: ChartFilterCondition) => void;
} & I18NComponentProps
> = ({ i18nPrefix, condition, onChange: onConditionChange }, ref) => {
const t = useI18NPrefix(i18nPrefix);
const [type, setType] = useState<string>(() =>
condition?.type === FilterConditionType.RangeTime
? String(FilterConditionType.RangeTime)
: String(FilterConditionType.RecommendTime),
);
useImperativeHandle(ref, () => ({
onValidate: (args: ChartFilterCondition) => {
if (isEmpty(args?.operator)) {
return false;
}
if (
[FilterSqlOperator.Between, FilterSqlOperator.NotBetween].includes(
args?.operator as FilterSqlOperator,
)
) {
return !isEmpty(args?.value) && !isEmptyArray(args?.value);
}
return false;
},
}));
const clearFilterWhenTypeChange = (type: string) => {
setType(type);
const conditionType = Number(type);
if (conditionType === FilterConditionType.RecommendTime) {
const filter = new ConditionBuilder(condition)
.setValue(RECOMMEND_TIME.TODAY)
.asRecommendTime();
onConditionChange?.(filter);
} else if (conditionType === FilterConditionType.RangeTime) {
const filterRow = new ConditionBuilder(condition)
.setValue([
formatTime(moment(), TIME_FORMATTER),
formatTime(moment(), TIME_FORMATTER),
])
.asRangeTime();
onConditionChange?.(filterRow);
}
};
return (
<StyledDateConditionConfiguration
activeKey={type}
onChange={clearFilterWhenTypeChange}
destroyInactiveTabPane={true}
>
<Tabs.TabPane
tab={t('recommend')}
key={FilterConditionType.RecommendTime}
>
<TimeSelector.RecommendRangeTimeSelector
i18nPrefix={i18nPrefix}
condition={condition}
onConditionChange={onConditionChange}
/>
</Tabs.TabPane>
<Tabs.TabPane tab={t('manual')} key={FilterConditionType.RangeTime}>
<TimeSelector.ManualRangeTimeSelector
i18nPrefix={i18nPrefix}
condition={condition}
onConditionChange={onConditionChange}
/>
</Tabs.TabPane>
</StyledDateConditionConfiguration>
);
}
Example #4
Source File: ChartComputedFieldEditor.tsx From datart with Apache License 2.0 | 4 votes |
ChartComputedFieldEditor: ForwardRefRenderFunction<
ChartComputedFieldHandle,
{
value?: string;
functionDescriptions?: FunctionDescription[];
onChange: (expression: string) => void;
}
> = (props, ref) => {
const editorRef = useRef<MonacoEditor>(null);
const [editorText, setEditorText] = useState(props.value);
const [description, setDescription] = useState<FunctionDescription>();
useImperativeHandle(ref, () => ({
insertField: (value, funcDesc) => {
if (!value) {
return;
}
if (funcDesc) {
setDescription(funcDesc);
}
editorRef?.current?.editor?.trigger('keyboard', 'type', { text: value });
editorRef?.current?.editor?.focus();
},
}));
const getEditorNewLineCharactor = () => {
return editorRef?.current?.editor?.getModel()?.getEOL();
};
const onChange = debounce(newValue => {
setEditorText(newValue);
const removeNewLineCharactor = value =>
value.replace(getEditorNewLineCharactor(), ' ');
props.onChange && props.onChange(removeNewLineCharactor(newValue));
}, 200);
const handleDescriptionChange = debounce(descKey => {
if (!descKey) {
return;
}
const funcDesc = props.functionDescriptions?.find(d => d.name === descKey);
if (!!funcDesc) {
setDescription(funcDesc);
}
}, 200);
const handleEdtiorWillMount = monacoEditor => {
monacoEditor.languages.register({ id: 'dql' });
monacoEditor.languages.setMonarchTokensProvider('dql', {
...DatartQueryLanguageSpecification,
builtinFunctions: (props?.functionDescriptions || []).map(f => f.name),
});
monacoEditor.editor.defineTheme(
'dqlTheme',
ChartComputedFieldEditorDarkTheme,
);
};
const handleEditorDidMount = (editor, monaco) => {
const model = editor.getModel();
editor.onDidChangeCursorPosition(listener => {
const positionWord = model.getWordAtPosition(listener.position);
handleDescriptionChange(positionWord?.word);
});
};
const renderFunctionDescriptionInfo = () => {
if (!description) {
return '';
}
return `${description.description}: ${description.syntax}`;
};
return (
<StyledChartComputedFieldEditor>
<Row>
<MonacoEditor
ref={editorRef}
theme="dqlTheme"
language="dql"
defaultValue={editorText}
onChange={onChange}
editorWillMount={handleEdtiorWillMount}
editorDidMount={handleEditorDidMount}
overrideServices={
{
// onDidChangeCursorPosition: () => console.log('overrideServices |onDidChangeCursorPosition ---->'),
}
}
options={{
lineDecorationsWidth: 1,
}}
/>
</Row>
<Row>
<Divider />
<p>{renderFunctionDescriptionInfo()}</p>
</Row>
</StyledChartComputedFieldEditor>
);
}
Example #5
Source File: CategoryConditionConfiguration.tsx From datart with Apache License 2.0 | 4 votes |
CategoryConditionConfiguration: ForwardRefRenderFunction<
FilterOptionForwardRef,
{
colName: string;
dataView?: ChartDataView;
condition?: ChartFilterCondition;
onChange: (condition: ChartFilterCondition) => void;
fetchDataByField?: (fieldId) => Promise<string[]>;
} & I18NComponentProps
> = (
{
colName,
i18nPrefix,
condition,
dataView,
onChange: onConditionChange,
fetchDataByField,
},
ref,
) => {
const t = useI18NPrefix(i18nPrefix);
const [curTab, setCurTab] = useState<FilterConditionType>(() => {
if (
[
FilterConditionType.List,
FilterConditionType.Condition,
FilterConditionType.Customize,
].includes(condition?.type!)
) {
return condition?.type!;
}
return FilterConditionType.List;
});
const [targetKeys, setTargetKeys] = useState<string[]>(() => {
let values;
if (condition?.operator === FilterSqlOperator.In) {
values = condition?.value;
if (Array.isArray(condition?.value)) {
const firstValues =
(condition?.value as [])?.filter(n => {
if (IsKeyIn(n as RelationFilterValue, 'key')) {
return (n as RelationFilterValue).isSelected;
}
return false;
}) || [];
values = firstValues?.map((n: RelationFilterValue) => n.key);
}
}
return values || [];
});
const [selectedKeys, setSelectedKeys] = useState<string[]>([]);
const [isTree, setIsTree] = useState(isTreeModel(condition?.value));
const [treeOptions, setTreeOptions] = useState<string[]>([]);
const [listDatas, setListDatas] = useState<RelationFilterValue[]>([]);
const [treeDatas, setTreeDatas] = useState<RelationFilterValue[]>([]);
useImperativeHandle(ref, () => ({
onValidate: (args: ChartFilterCondition) => {
if (isEmpty(args?.operator)) {
return false;
}
if (args?.operator === FilterSqlOperator.In) {
return !isEmptyArray(args?.value);
} else if (
[
FilterSqlOperator.Contain,
FilterSqlOperator.PrefixContain,
FilterSqlOperator.SuffixContain,
FilterSqlOperator.Equal,
FilterSqlOperator.NotContain,
FilterSqlOperator.NotPrefixContain,
FilterSqlOperator.NotSuffixContain,
FilterSqlOperator.NotEqual,
].includes(args?.operator as FilterSqlOperator)
) {
return !isEmpty(args?.value);
} else if (
[FilterSqlOperator.Null, FilterSqlOperator.NotNull].includes(
args?.operator as FilterSqlOperator,
)
) {
return true;
}
return false;
},
}));
useMount(() => {
if (curTab === FilterConditionType.List) {
handleFetchData();
}
});
const getDataOptionFields = () => {
return dataView?.meta || [];
};
const isChecked = (selectedKeys, eventKey) =>
selectedKeys.indexOf(eventKey) !== -1;
const fetchNewDataset = async (viewId, colName: string) => {
const fieldDataset = await getDistinctFields(
viewId,
[colName],
undefined,
undefined,
);
return fieldDataset;
};
const setListSelectedState = (
list?: RelationFilterValue[],
keys?: string[],
) => {
return (list || []).map(c =>
Object.assign(c, { isSelected: isChecked(keys, c.key) }),
);
};
const setTreeCheckableState = (
treeList?: RelationFilterValue[],
keys?: string[],
) => {
return (treeList || []).map(c => {
c.isSelected = isChecked(keys, c.key);
c.children = setTreeCheckableState(c.children, keys);
return c;
});
};
const handleGeneralListChange = async selectedKeys => {
const items = setListSelectedState(listDatas, selectedKeys);
setTargetKeys(selectedKeys);
setListDatas(items);
const generalTypeItems = items?.filter(i => i.isSelected);
const filter = new ConditionBuilder(condition)
.setOperator(FilterSqlOperator.In)
.setValue(generalTypeItems)
.asGeneral();
onConditionChange(filter);
};
const filterGeneralListOptions = useCallback(
(inputValue, option) => option.label?.includes(inputValue) || false,
[],
);
const handleGeneralTreeChange = async treeSelectedKeys => {
const selectedKeys = treeSelectedKeys.checked;
const treeItems = setTreeCheckableState(treeDatas, selectedKeys);
setTargetKeys(selectedKeys);
setTreeDatas(treeItems);
const filter = new ConditionBuilder(condition)
.setOperator(FilterSqlOperator.In)
.setValue(treeItems)
.asTree();
onConditionChange(filter);
};
const onSelectChange = (
sourceSelectedKeys: string[],
targetSelectedKeys: string[],
) => {
const newSelectedKeys = [...sourceSelectedKeys, ...targetSelectedKeys];
setSelectedKeys(newSelectedKeys);
};
const handleTreeOptionChange = (
associateField: string,
labelField: string,
) => {
setTreeOptions([associateField, labelField]);
};
const handleFetchData = () => {
fetchNewDataset?.(dataView?.id, colName).then(dataset => {
if (isTree) {
// setTreeDatas(convertToTree(dataset?.columns, selectedKeys));
// setListDatas(convertToList(dataset?.columns, selectedKeys));
} else {
setListDatas(convertToList(dataset?.rows, selectedKeys));
}
});
};
const convertToList = (collection, selectedKeys) => {
const items: string[] = (collection || []).flatMap(c => c);
const uniqueKeys = Array.from(new Set(items));
return uniqueKeys.map(item => ({
key: item,
label: item,
isSelected: selectedKeys.includes(item),
}));
};
const convertToTree = (collection, selectedKeys) => {
const associateField = treeOptions?.[0];
const labelField = treeOptions?.[1];
if (!associateField || !labelField) {
return [];
}
const associateKeys = Array.from(
new Set(collection?.map(c => c[associateField])),
);
const treeNodes = associateKeys
.map(key => {
const associateItem = collection?.find(c => c[colName] === key);
if (!associateItem) {
return null;
}
const associateChildren = collection
.filter(c => c[associateField] === key)
.map(c => {
const itemKey = c[labelField];
return {
key: itemKey,
label: itemKey,
isSelected: isChecked(selectedKeys, itemKey),
};
});
const itemKey = associateItem?.[colName];
return {
key: itemKey,
label: itemKey,
isSelected: isChecked(selectedKeys, itemKey),
children: associateChildren,
};
})
.filter(i => Boolean(i)) as RelationFilterValue[];
return treeNodes;
};
const handleTabChange = (activeKey: string) => {
const conditionType = +activeKey;
setCurTab(conditionType);
const filter = new ConditionBuilder(condition)
.setOperator(null!)
.setValue(null)
.asFilter(conditionType);
setTreeDatas([]);
setTargetKeys([]);
setListDatas([]);
onConditionChange(filter);
};
return (
<StyledTabs activeKey={curTab.toString()} onChange={handleTabChange}>
<Tabs.TabPane
tab={t('general')}
key={FilterConditionType.List.toString()}
>
<Row>
<Space>
<Button type="primary" onClick={handleFetchData}>
{t('load')}
</Button>
{/* <Checkbox
checked={isTree}
disabled
onChange={e => setIsTree(e.target.checked)}
>
{t('useTree')}
</Checkbox> */}
</Space>
</Row>
<Row>
<Space>
{isTree && (
<>
{t('associateField')}
<Select
value={treeOptions?.[0]}
options={getDataOptionFields()?.map(f => ({
label: f.name,
value: f.id,
}))}
onChange={value =>
handleTreeOptionChange(value, treeOptions?.[1])
}
/>
{t('labelField')}
<Select
value={treeOptions?.[1]}
options={getDataOptionFields()?.map(f => ({
label: f.name,
value: f.id,
}))}
onChange={value =>
handleTreeOptionChange(treeOptions?.[0], value)
}
/>
</>
)}
</Space>
</Row>
{isTree && (
<Tree
blockNode
checkable
checkStrictly
defaultExpandAll
checkedKeys={targetKeys}
treeData={treeDatas}
onCheck={handleGeneralTreeChange}
onSelect={handleGeneralTreeChange}
/>
)}
{!isTree && (
<Transfer
operations={[t('moveToRight'), t('moveToLeft')]}
dataSource={listDatas}
titles={[`${t('sourceList')}`, `${t('targetList')}`]}
targetKeys={targetKeys}
selectedKeys={selectedKeys}
onChange={handleGeneralListChange}
onSelectChange={onSelectChange}
render={item => item.label}
filterOption={filterGeneralListOptions}
showSearch
pagination
/>
)}
</Tabs.TabPane>
<Tabs.TabPane
tab={t('customize')}
key={FilterConditionType.Customize.toString()}
>
<CategoryConditionEditableTable
dataView={dataView}
i18nPrefix={i18nPrefix}
condition={condition}
onConditionChange={onConditionChange}
fetchDataByField={fetchDataByField}
/>
</Tabs.TabPane>
<Tabs.TabPane
tab={t('condition')}
key={FilterConditionType.Condition.toString()}
>
<CategoryConditionRelationSelector
condition={condition}
onConditionChange={onConditionChange}
/>
</Tabs.TabPane>
</StyledTabs>
);
}
Example #6
Source File: ValueConditionConfiguration.tsx From datart with Apache License 2.0 | 4 votes |
ValueConditionConfiguration: ForwardRefRenderFunction<
FilterOptionForwardRef,
{
condition?: ChartFilterCondition;
onChange: (condition: ChartFilterCondition) => void;
} & I18NComponentProps
> = ({ i18nPrefix, condition, onChange: onConditionChange }, ref) => {
const [curFilter, setCurFilter] = useState<ChartFilterCondition>(
new ConditionBuilder(condition).asSelf(),
);
useImperativeHandle(ref, () => ({
onValidate: (args: ChartFilterCondition) => {
if (isEmpty(args?.operator)) {
return false;
}
if (
[FilterSqlOperator.Between, FilterSqlOperator.NotBetween].includes(
args?.operator as FilterSqlOperator,
)
) {
return args?.value?.filter(v => !isEmpty(v))?.length === 2;
} else if (
[
FilterSqlOperator.Equal,
FilterSqlOperator.NotEqual,
FilterSqlOperator.GreaterThanOrEqual,
FilterSqlOperator.LessThanOrEqual,
FilterSqlOperator.LessThan,
FilterSqlOperator.GreaterThan,
].includes(args?.operator as FilterSqlOperator)
) {
return (
!isEmpty(args?.value) &&
!isEmptyArray(args?.value?.filter(v => !isEmpty(v)))
);
} else if (
[FilterSqlOperator.Null, FilterSqlOperator.NotNull].includes(
args?.operator as FilterSqlOperator,
)
) {
return true;
}
return false;
},
}));
const handleFilterChanged = (filter: ChartFilterCondition) => {
setCurFilter(filter);
onConditionChange && onConditionChange(filter);
};
const handleAddBrotherFilter = () => {
const filter = curFilter;
filter.appendChild();
setCurFilter(filter);
handleFilterChanged(filter);
};
const handleDeleteSelfFilter = () => {
let newFilter = new ConditionBuilder(curFilter).asFilter();
handleFilterChanged(newFilter);
};
const renderFilters = () => {
if (curFilter?.type === FilterConditionType.Relation) {
return (
<MultiFilterRow
rowName={'root'}
condition={curFilter}
onConditionChange={handleFilterChanged}
/>
);
}
return (
<SingleFilterRow
rowName={'root'}
condition={curFilter}
onAddBrotherFilter={handleAddBrotherFilter}
onDeleteSelfFilter={handleDeleteSelfFilter}
onConditionChange={handleFilterChanged}
/>
);
};
return renderFilters();
}