react-icons/fa#FaSave TypeScript Examples
The following examples show how to use
react-icons/fa#FaSave.
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: ExportMenuItem.tsx From openchakra with MIT License | 6 votes |
ExportMenuItem = () => {
const components = useSelector(getComponents)
return (
<MenuItem onClick={() => saveAsJSON(components)}>
<Box mr={2} as={FaSave} />
Save components
</MenuItem>
)
}
Example #2
Source File: UserSettings.tsx From convoychat with GNU General Public License v3.0 | 4 votes |
UserSettings: React.FC = () => {
const { user } = useAuthContext();
const { state, dispatch } = useModalContext();
const [color, setColor] = useState<string>("");
const [socialLinks, setSocialLinks] = useState<Omit<UserLinks, "__typename">>(
{}
);
const handleSocialLinks = (e: any) => {
setSocialLinks({ ...socialLinks, [e.type]: e.value });
};
const handleColorChange = (color: any) => {
setColor(color.hex);
};
const closeModal = () => dispatch({ modal: "UserSettings", type: "CLOSE" });
const [setUserSettings, { loading }] = useSetUserSettingsMutation({
onError(err) {
console.log(err);
},
onCompleted() {
closeModal();
},
});
useEffect(() => {
setColor(user?.color);
setSocialLinks({
github: user?.links?.github,
twitter: user?.links?.twitter,
instagram: user?.links?.instagram,
website: user?.links?.website,
});
}, [user?.color, user?.links]);
const onSubmit = () => {
setUserSettings({
variables: {
color: color,
...socialLinks,
},
});
};
return (
<Modal
isOpen={state.isUserSettingsModalOpen}
closeTimeoutMS={300}
onRequestClose={closeModal}
contentLabel="User Settings"
className="ModalContent user-settings__modal"
overlayClassName="ModalOverlay"
>
<h2>User Settings</h2>
<small className="textcolor--gray">
Who does not loves a useless modal
</small>
<Spacer gap="xlarge" />
<UserSettingsStyles>
<p style={{ fontSize: 14 }}>Add your personal color</p>
<ColorPreview
color={color}
handleColorChange={handleColorChange}
preview={
<Message>
<Message.MetaInfo
author={{
color: color,
avatarUrl: user?.avatarUrl,
name: user?.name,
}}
/>
<Message.Content>Hello world</Message.Content>
</Message>
}
/>
<Spacer gap="huge" />
<SocialLinkInput onSubmit={handleSocialLinks} />
<Spacer gap="xlarge" />
<section className="social-links__grid">
{Object.keys(socialLinks).map((type: ILinkTypes) => {
return socialLinks[type] ? (
<SocialLink
key={type}
type={type}
url={socialLinks[type]}
onDelete={() => {
setSocialLinks({
...socialLinks,
[type]: null,
});
}}
/>
) : null;
})}
</section>
<Spacer gap="huge" />
<ButtonGroup gap="medium" float="right">
<Button onClick={closeModal} variant="danger" icon={FaTimes}>
Cancel
</Button>
<Button isLoading={loading} onClick={onSubmit} icon={FaSave}>
Save Changes
</Button>
</ButtonGroup>
</UserSettingsStyles>
</Modal>
);
}
Example #3
Source File: SlideViewer.tsx From slim with Apache License 2.0 | 4 votes |
render (): React.ReactNode {
const rois: dmv.roi.ROI[] = []
const segments: dmv.segment.Segment[] = []
const mappings: dmv.mapping.ParameterMapping[] = []
const annotationGroups: dmv.annotation.AnnotationGroup[] = []
rois.push(...this.volumeViewer.getAllROIs())
segments.push(...this.volumeViewer.getAllSegments())
mappings.push(...this.volumeViewer.getAllParameterMappings())
annotationGroups.push(...this.volumeViewer.getAllAnnotationGroups())
const openSubMenuItems = ['specimens', 'opticalpaths', 'annotations']
let report: React.ReactNode
const dataset = this.state.generatedReport
if (dataset !== undefined) {
report = <Report dataset={dataset} />
}
let annotationMenuItems: React.ReactNode
if (rois.length > 0) {
annotationMenuItems = (
<AnnotationList
rois={rois}
selectedRoiUIDs={this.state.selectedRoiUIDs}
visibleRoiUIDs={this.state.visibleRoiUIDs}
onSelection={this.handleAnnotationSelection}
onVisibilityChange={this.handleAnnotationVisibilityChange}
/>
)
}
const findingOptions = this.findingOptions.map(finding => {
return (
<Select.Option
key={finding.CodeValue}
value={finding.CodeValue}
>
{finding.CodeMeaning}
</Select.Option>
)
})
const geometryTypeOptionsMapping: { [key: string]: React.ReactNode } = {
point: <Select.Option key='point' value='point'>Point</Select.Option>,
circle: <Select.Option key='circle' value='circle'>Circle</Select.Option>,
box: <Select.Option key='box' value='box'>Box</Select.Option>,
polygon: <Select.Option key='polygon' value='polygon'>Polygon</Select.Option>,
line: <Select.Option key='line' value='line'>Line</Select.Option>,
freehandpolygon: (
<Select.Option key='freehandpolygon' value='freehandpolygon'>
Polygon (freehand)
</Select.Option>
),
freehandline: (
<Select.Option key='freehandline' value='freehandline'>
Line (freehand)
</Select.Option>
)
}
const selections: React.ReactNode[] = [
(
<Select
style={{ minWidth: 130 }}
onSelect={this.handleAnnotationFindingSelection}
key='annotation-finding'
defaultActiveFirstOption
>
{findingOptions}
</Select>
)
]
const selectedFinding = this.state.selectedFinding
if (selectedFinding !== undefined) {
const key = _buildKey(selectedFinding)
this.evaluationOptions[key].forEach(evaluation => {
const evaluationOptions = evaluation.values.map(code => {
return (
<Select.Option
key={code.CodeValue}
value={code.CodeValue}
label={evaluation.name}
>
{code.CodeMeaning}
</Select.Option>
)
})
selections.push(
<>
{evaluation.name.CodeMeaning}
<Select
style={{ minWidth: 130 }}
onSelect={this.handleAnnotationEvaluationSelection}
allowClear
onClear={this.handleAnnotationEvaluationClearance}
defaultActiveFirstOption={false}
>
{evaluationOptions}
</Select>
</>
)
})
const geometryTypeOptions = this.geometryTypeOptions[key].map(name => {
return geometryTypeOptionsMapping[name]
})
selections.push(
<Select
style={{ minWidth: 130 }}
onSelect={this.handleAnnotationGeometryTypeSelection}
key='annotation-geometry-type'
>
{geometryTypeOptions}
</Select>
)
selections.push(
<Checkbox
onChange={this.handleAnnotationMeasurementActivation}
key='annotation-measurement'
>
measure
</Checkbox>
)
}
const specimenMenu = (
<Menu.SubMenu key='specimens' title='Specimens'>
<SpecimenList
metadata={this.props.slide.volumeImages[0]}
showstain={false}
/>
</Menu.SubMenu>
)
const equipmentMenu = (
<Menu.SubMenu key='equipment' title='Equipment'>
<Equipment metadata={this.props.slide.volumeImages[0]} />
</Menu.SubMenu>
)
const defaultOpticalPathStyles: {
[identifier: string]: {
opacity: number
color?: number[]
limitValues?: number[]
}
} = {}
const opticalPathMetadata: {
[identifier: string]: dmv.metadata.VLWholeSlideMicroscopyImage[]
} = {}
const opticalPaths = this.volumeViewer.getAllOpticalPaths()
opticalPaths.sort((a, b) => {
if (a.identifier < b.identifier) {
return -1
} else if (a.identifier > b.identifier) {
return 1
}
return 0
})
opticalPaths.forEach(opticalPath => {
const identifier = opticalPath.identifier
const metadata = this.volumeViewer.getOpticalPathMetadata(identifier)
opticalPathMetadata[identifier] = metadata
const style = this.volumeViewer.getOpticalPathStyle(identifier)
defaultOpticalPathStyles[identifier] = style
})
const opticalPathMenu = (
<Menu.SubMenu key='opticalpaths' title='Optical Paths'>
<OpticalPathList
metadata={opticalPathMetadata}
opticalPaths={opticalPaths}
defaultOpticalPathStyles={defaultOpticalPathStyles}
visibleOpticalPathIdentifiers={this.state.visibleOpticalPathIdentifiers}
activeOpticalPathIdentifiers={this.state.activeOpticalPathIdentifiers}
onOpticalPathVisibilityChange={this.handleOpticalPathVisibilityChange}
onOpticalPathStyleChange={this.handleOpticalPathStyleChange}
onOpticalPathActivityChange={this.handleOpticalPathActivityChange}
selectedPresentationStateUID={this.state.selectedPresentationStateUID}
/>
</Menu.SubMenu>
)
let presentationStateMenu
console.log('DEBUG: ', this.state.presentationStates)
if (this.state.presentationStates.length > 0) {
const presentationStateOptions = this.state.presentationStates.map(
presentationState => {
return (
<Select.Option
key={presentationState.SOPInstanceUID}
value={presentationState.SOPInstanceUID}
dropdownMatchSelectWidth={false}
size='small'
>
{presentationState.ContentDescription}
</Select.Option>
)
}
)
presentationStateMenu = (
<Menu.SubMenu key='presentationStates' title='Presentation States'>
<Space align='center' size={20} style={{ padding: '14px' }}>
<Select
style={{ minWidth: 200, maxWidth: 200 }}
onSelect={this.handlePresentationStateSelection}
key='presentation-states'
defaultValue={this.props.selectedPresentationStateUID}
value={this.state.selectedPresentationStateUID}
>
{presentationStateOptions}
</Select>
<Tooltip title='Reset'>
<Btn
icon={<UndoOutlined />}
type='primary'
onClick={this.handlePresentationStateReset}
/>
</Tooltip>
</Space>
</Menu.SubMenu>
)
}
let segmentationMenu
if (segments.length > 0) {
const defaultSegmentStyles: {
[segmentUID: string]: {
opacity: number
}
} = {}
const segmentMetadata: {
[segmentUID: string]: dmv.metadata.Segmentation[]
} = {}
const segments = this.volumeViewer.getAllSegments()
segments.forEach(segment => {
defaultSegmentStyles[segment.uid] = this.volumeViewer.getSegmentStyle(
segment.uid
)
segmentMetadata[segment.uid] = this.volumeViewer.getSegmentMetadata(
segment.uid
)
})
segmentationMenu = (
<Menu.SubMenu key='segmentations' title='Segmentations'>
<SegmentList
segments={segments}
metadata={segmentMetadata}
defaultSegmentStyles={defaultSegmentStyles}
visibleSegmentUIDs={this.state.visibleSegmentUIDs}
onSegmentVisibilityChange={this.handleSegmentVisibilityChange}
onSegmentStyleChange={this.handleSegmentStyleChange}
/>
</Menu.SubMenu>
)
openSubMenuItems.push('segmentations')
}
let parametricMapMenu
if (mappings.length > 0) {
const defaultMappingStyles: {
[mappingUID: string]: {
opacity: number
}
} = {}
const mappingMetadata: {
[mappingUID: string]: dmv.metadata.ParametricMap[]
} = {}
mappings.forEach(mapping => {
defaultMappingStyles[mapping.uid] = this.volumeViewer.getParameterMappingStyle(
mapping.uid
)
mappingMetadata[mapping.uid] = this.volumeViewer.getParameterMappingMetadata(
mapping.uid
)
})
parametricMapMenu = (
<Menu.SubMenu key='parmetricmaps' title='Parametric Maps'>
<MappingList
mappings={mappings}
metadata={mappingMetadata}
defaultMappingStyles={defaultMappingStyles}
visibleMappingUIDs={this.state.visibleMappingUIDs}
onMappingVisibilityChange={this.handleMappingVisibilityChange}
onMappingStyleChange={this.handleMappingStyleChange}
/>
</Menu.SubMenu>
)
openSubMenuItems.push('parametricmaps')
}
let annotationGroupMenu
if (annotationGroups.length > 0) {
const defaultAnnotationGroupStyles: {
[annotationGroupUID: string]: {
opacity: number
}
} = {}
const annotationGroupMetadata: {
[annotationGroupUID: string]: dmv.metadata.MicroscopyBulkSimpleAnnotations
} = {}
const annotationGroups = this.volumeViewer.getAllAnnotationGroups()
annotationGroups.forEach(annotationGroup => {
defaultAnnotationGroupStyles[annotationGroup.uid] = this.volumeViewer.getAnnotationGroupStyle(
annotationGroup.uid
)
annotationGroupMetadata[annotationGroup.uid] = this.volumeViewer.getAnnotationGroupMetadata(
annotationGroup.uid
)
})
annotationGroupMenu = (
<Menu.SubMenu key='annotationGroups' title='Annotation Groups'>
<AnnotationGroupList
annotationGroups={annotationGroups}
metadata={annotationGroupMetadata}
defaultAnnotationGroupStyles={defaultAnnotationGroupStyles}
visibleAnnotationGroupUIDs={this.state.visibleAnnotationGroupUIDs}
onAnnotationGroupVisibilityChange={this.handleAnnotationGroupVisibilityChange}
onAnnotationGroupStyleChange={this.handleAnnotationGroupStyleChange}
/>
</Menu.SubMenu>
)
openSubMenuItems.push('annotationGroups')
}
let toolbar
let toolbarHeight = '0px'
if (this.props.enableAnnotationTools) {
toolbar = (
<Row>
<Button
tooltip='Draw ROI [d]'
icon={FaDrawPolygon}
onClick={this.handleRoiDrawing}
isSelected={this.state.isRoiDrawingActive}
/>
<Button
tooltip='Modify ROIs [m]'
icon={FaHandPointer}
onClick={this.handleRoiModification}
isSelected={this.state.isRoiModificationActive}
/>
<Button
tooltip='Translate ROIs [t]'
icon={FaHandPaper}
onClick={this.handleRoiTranslation}
isSelected={this.state.isRoiTranslationActive}
/>
<Button
tooltip='Remove selected ROI [r]'
onClick={this.handleRoiRemoval}
icon={FaTrash}
/>
<Button
tooltip='Show/Hide ROIs [v]'
icon={this.state.areRoisHidden ? FaEye : FaEyeSlash}
onClick={this.handleRoiVisibilityChange}
isSelected={this.state.areRoisHidden}
/>
<Button
tooltip='Save ROIs [s]'
icon={FaSave}
onClick={this.handleReportGeneration}
/>
</Row>
)
toolbarHeight = '50px'
}
/* It would be nicer to use the ant Spin component, but that causes issues
* with the positioning of the viewport.
*/
let loadingDisplay = 'none'
if (this.state.isLoading) {
loadingDisplay = 'block'
}
return (
<Layout style={{ height: '100%' }} hasSider>
<Layout.Content style={{ height: '100%' }}>
{toolbar}
<div className='dimmer' style={{ display: loadingDisplay }} />
<div className='spinner' style={{ display: loadingDisplay }} />
<div
style={{
height: `calc(100% - ${toolbarHeight})`,
overflow: 'hidden'
}}
ref={this.volumeViewportRef}
/>
<Modal
visible={this.state.isAnnotationModalVisible}
title='Configure annotations'
onOk={this.handleAnnotationConfigurationCompletion}
onCancel={this.handleAnnotationConfigurationCancellation}
okText='Select'
>
<Space align='start' direction='vertical'>
{selections}
</Space>
</Modal>
<Modal
visible={this.state.isReportModalVisible}
title='Verify and save report'
onOk={this.handleReportVerification}
onCancel={this.handleReportCancellation}
okText='Save'
>
{report}
</Modal>
</Layout.Content>
<Layout.Sider
width={300}
reverseArrow
style={{
borderLeft: 'solid',
borderLeftWidth: 0.25,
overflow: 'hidden',
background: 'none'
}}
>
<Menu
mode='inline'
defaultOpenKeys={openSubMenuItems}
style={{ height: '100%' }}
inlineIndent={14}
forceSubMenuRender
>
<Menu.SubMenu key='label' title='Slide label'>
<Menu.Item style={{ height: '100%' }}>
<div
style={{ height: '220px' }}
ref={this.labelViewportRef}
/>
</Menu.Item>
</Menu.SubMenu>
{specimenMenu}
{equipmentMenu}
{opticalPathMenu}
{presentationStateMenu}
<Menu.SubMenu key='annotations' title='Annotations'>
{annotationMenuItems}
</Menu.SubMenu>
{annotationGroupMenu}
{segmentationMenu}
{parametricMapMenu}
</Menu>
</Layout.Sider>
</Layout>
)
}
Example #4
Source File: AlternateSolutionEditor.tsx From crosshare with GNU Affero General Public License v3.0 | 4 votes |
export function AlternateSolutionEditor(props: {
grid: string[];
width: number;
height: number;
vBars: Set<number>;
hBars: Set<number>;
hidden: Set<number>;
highlighted: Set<number>;
highlight: 'circle' | 'shade';
cancel: () => void;
save: (alt: Record<number, string>) => Promise<void>;
}) {
const initialGrid = fromCells({
mapper: (e) => e,
width: props.width,
height: props.height,
cells: props.grid,
vBars: props.vBars,
hBars: props.hBars,
allowBlockEditing: false,
highlighted: props.highlighted,
highlight: props.highlight,
hidden: props.hidden,
});
const [state, dispatch] = useReducer(gridInterfaceReducer, {
type: 'alternate-editor',
active: { col: 0, row: 0, dir: Direction.Across },
grid: initialGrid,
wasEntryClick: false,
showExtraKeyLayout: false,
isEnteringRebus: false,
rebusValue: '',
downsOnly: false,
isEditable: () => true,
});
const [muted, setMuted] = usePersistedBoolean('muted', false);
const [toggleKeyboard, setToggleKeyboard] = usePersistedBoolean(
'keyboard',
false
);
const gridRef = useRef<HTMLDivElement | null>(null);
const focusGrid = useCallback(() => {
if (gridRef.current) {
gridRef.current.focus();
}
}, []);
const physicalKeyboardHandler = useCallback(
(e: KeyboardEvent) => {
const mkey = fromKeyboardEvent(e);
if (isSome(mkey)) {
const kpa: KeypressAction = { type: 'KEYPRESS', key: mkey.value };
dispatch(kpa);
e.preventDefault();
}
},
[dispatch]
);
useEventListener(
'keydown',
physicalKeyboardHandler,
gridRef.current || undefined
);
const pasteHandler = useCallback(
(e: ClipboardEvent) => {
const tagName = (e.target as HTMLElement)?.tagName?.toLowerCase();
if (tagName === 'textarea' || tagName === 'input') {
return;
}
const pa: PasteAction = {
type: 'PASTE',
content: e.clipboardData?.getData('Text') || '',
};
dispatch(pa);
e.preventDefault();
},
[dispatch]
);
useEventListener('paste', pasteHandler);
const keyboardHandler = useCallback(
(key: string) => {
const mkey = fromKeyString(key);
if (isSome(mkey)) {
const kpa: KeypressAction = { type: 'KEYPRESS', key: mkey.value };
dispatch(kpa);
}
},
[dispatch]
);
const topBarChildren = useMemo(() => {
return (
<>
<TopBarLink
icon={<FaSave />}
text="Add Alternate"
onClick={async () => {
const alt: Record<number, string> = {};
let hadAny = false;
for (const [idx, cellValue] of state.grid.cells.entries()) {
const defaultCellValue = initialGrid.cells[idx];
if (
cellValue.trim() &&
cellValue.trim() != defaultCellValue?.trim()
) {
hadAny = true;
alt[idx] = cellValue;
}
}
if (!hadAny) {
props.cancel();
return;
}
return props.save(alt).then(() => props.cancel());
}}
/>
<TopBarLink
icon={<FaWindowClose />}
text="Cancel"
onClick={props.cancel}
/>
<TopBarDropDown onClose={focusGrid} icon={<FaEllipsisH />} text="More">
{() => (
<>
<TopBarDropDownLink
icon={<Rebus />}
text="Enter Rebus"
shortcutHint={<EscapeKey />}
onClick={() => {
const a: KeypressAction = {
type: 'KEYPRESS',
key: { k: KeyK.Escape },
};
dispatch(a);
}}
/>
{muted ? (
<TopBarDropDownLink
icon={<FaVolumeUp />}
text="Unmute"
onClick={() => setMuted(false)}
/>
) : (
<TopBarDropDownLink
icon={<FaVolumeMute />}
text="Mute"
onClick={() => setMuted(true)}
/>
)}
<TopBarDropDownLink
icon={<FaKeyboard />}
text="Toggle Keyboard"
onClick={() => setToggleKeyboard(!toggleKeyboard)}
/>
</>
)}
</TopBarDropDown>
</>
);
}, [
focusGrid,
initialGrid.cells,
muted,
props,
setMuted,
setToggleKeyboard,
state.grid.cells,
toggleKeyboard,
]);
const parentRef = useRef<HTMLDivElement | null>(null);
return (
<>
<div
css={{
display: 'flex',
flexDirection: 'column',
height: '100%',
}}
>
<div css={{ flex: 'none' }}>
<TopBar>{topBarChildren}</TopBar>
</div>
<div
css={{ flex: '1 1 auto', overflow: 'scroll', position: 'relative' }}
>
<div
// eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
tabIndex={0}
ref={(instance) => {
parentRef.current = instance;
}}
css={{
outline: 'none',
display: 'flex',
flex: '1 1 auto',
flexDirection: 'column',
alignItems: 'center',
height: '100%',
width: '100%',
position: 'absolute',
flexWrap: 'nowrap',
}}
>
<Square
noColumns={true}
waitToResize={false}
parentRef={parentRef}
aspectRatio={props.width / props.height}
contents={(width: number, _height: number) => {
return (
<GridView
isEnteringRebus={state.isEnteringRebus}
rebusValue={state.rebusValue}
squareWidth={width}
grid={state.grid}
defaultGrid={initialGrid}
active={state.active}
dispatch={dispatch}
allowBlockEditing={false}
autofill={[]}
/>
);
}}
/>
</div>
</div>
<div css={{ flex: 'none', width: '100%' }}>
<Keyboard
toggleKeyboard={toggleKeyboard}
keyboardHandler={keyboardHandler}
muted={muted}
showExtraKeyLayout={state.showExtraKeyLayout}
includeBlockKey={false}
/>
</div>
</div>
</>
);
}