react-color#SketchPicker TypeScript Examples
The following examples show how to use
react-color#SketchPicker.
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: BubbleBackgroundColorSlider.tsx From Oratio with MIT License | 6 votes |
export default function BubbleBackgroundColorPicker() {
const { t } = useTranslation();
const initColor = localStorage.getItem('bubbleColor') || '#ffffff';
const [bubbleColor, setBackgroundColor] = React.useState<string>(initColor);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const handlebackgroundColorChange = (color: any) => {
setBackgroundColor(color.hex);
localStorage.setItem('bubbleColor', color.hex);
};
return (
<div>
<Typography id="color-selector" gutterBottom>
<ColorLensIcon /> {t('Speech Bubble Color')}
</Typography>
<Grid container spacing={3}>
<Grid item xs>
<SketchPicker
color={bubbleColor}
onChangeComplete={handlebackgroundColorChange}
/>
</Grid>
</Grid>
</div>
);
}
Example #2
Source File: FontColorPicker.tsx From Oratio with MIT License | 6 votes |
export default function FontColorPicker() {
const { t } = useTranslation();
const initColor = localStorage.getItem('fontColor') || '#ffffff';
const [fontColor, setFontColor] = React.useState<string>(initColor);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const handleFontColorChange = (color: any) => {
setFontColor(color.hex);
localStorage.setItem('fontColor', color.hex);
};
return (
<div>
<Typography id="color-selector" gutterBottom>
<ColorLensIcon /> {t('Text Color')}
</Typography>
<Grid container spacing={3}>
<Grid item xs>
<SketchPicker
color={fontColor}
onChangeComplete={handleFontColorChange}
/>
</Grid>
</Grid>
</div>
);
}
Example #3
Source File: custom-manual-palette.tsx From S2 with MIT License | 6 votes |
function ColorTable({ palette, onChange }) {
const columns = [
{
title: '#',
render(r, v, idx) {
return idx + 1;
},
},
{
title: '色值',
dataIndex: 'color',
},
{
title: '点击调整',
dataIndex: 'color',
render(val, _, idx) {
return (
<Popover
trigger="click"
content={
<SketchPicker
disableAlpha
presetColors={[]}
color={val}
onChangeComplete={(evt) => {
const nextBasicColors = [...palette.basicColors];
nextBasicColors.splice(idx, 1, evt.hex);
onChange({
...palette,
basicColors: nextBasicColors,
});
}}
/>
}
>
<Row justify="center">
<div
style={{
width: 30,
height: 30,
boxShadow: `0 0 8px rgba(0, 0, 0, 0.2)`,
cursor: 'pointer',
backgroundColor: val,
}}
/>
</Row>
</Popover>
);
},
},
{
title: '说明',
dataIndex: 'desc',
},
];
const dataSource = palette.basicColors.map((color, idx) => ({
color,
desc: paletteDesc[idx],
}));
return (
<Table
size="small"
rowKey="desc"
bordered
columns={columns}
pagination={false}
dataSource={dataSource}
/>
);
}
Example #4
Source File: PropertiesPanel.tsx From MagicUI with Apache License 2.0 | 6 votes |
function BackgroundProperties(props: IBackgroundPropertiesProps) {
const dispatch = useDispatch();
const [color, setColor] = useState('');
const [opacity, setOpacity] = useState(0);
const [showPicker, toggleShowPicker, pickerRef] = useShowPicker(false);
useEffect(() => setColor(props.background.fill), [props.background.fill]);
useEffect(() => setOpacity(props.background.opacity), [props.background.opacity]);
const handleChangeColor = (e: any) => {
setColor(e.hex);
dispatch(changeComponentBackground(e.hex, props.background.opacity));
};
const handleChangeOpacity = (e: any) => {
setOpacity(+e.target.value);
dispatch(changeComponentBackground(props.background.fill, +e.target.value));
};
return (
<PropertiesItem name="BACKGROUND">
<div className={style.bg_color_props}>
<span>Fill</span>
<input value={color} onClick={() => toggleShowPicker()}/>
<div className={cls(style.bg_color_picker, showPicker && style.show)} ref={pickerRef}>
<SketchPicker color={color} onChange={handleChangeColor}/>
</div>
</div>
<div className={style.bg_opacity_props}>
<span>Opacity</span>
<input value={opacity} onChange={handleChangeOpacity}/>
</div>
</PropertiesItem>
);
}
Example #5
Source File: index.tsx From screenshot.rocks with MIT License | 6 votes |
ColorPicker = ({initialColor, onColorChange}: IColorPickerProps) => {
const [displayColorPicker, setDisplayColorPicker] = useState(false);
const [color, setColor] = useState<RGBColor>(hex2rgba(initialColor))
const handleClick = () => {
setDisplayColorPicker(!displayColorPicker);
};
const handleClose = () => {
setDisplayColorPicker(false)
};
const handleChange = (color: any) => {
setColor(color.rgb)
onColorChange(color.rgb);
};
return (
<div className={styles(color)}>
<div className="swatch" onClick={handleClick}>
<div className="color"/>
</div>
{displayColorPicker ?
<div className="popup">
<div className="cover" onClick={handleClose}/>
<SketchPicker color={color} onChange={handleChange}/>
</div> : null}
</div>
);
}
Example #6
Source File: ColorEditorItem.spec.tsx From next-basics with GNU General Public License v3.0 | 6 votes |
describe("ColorEditor", () => {
jest.spyOn(window, "getComputedStyle").mockReturnValue({
getPropertyValue: () => {
return "#e8e8e8";
},
} as any);
it("ColorEditorItem should work", () => {
const wrapper = mount(
<Form>
<ColorEditorItem name="color" label="颜色" />
</Form>
);
expect(wrapper.find(".popover").length).toEqual(0);
wrapper.find(".colorCube").simulate("click");
wrapper.update();
expect(wrapper.find(".popover").length).toEqual(1);
wrapper.find(SketchPicker).invoke("onChangeComplete")({
hex: "#e9e9e9",
});
expect(wrapper.find(ColorPick).prop("value")).toEqual("#e9e9e9");
wrapper.find(".cover").simulate("click");
expect(wrapper.find(".popover").length).toEqual(0);
});
});
Example #7
Source File: ColorPickerInput.tsx From yana with MIT License | 6 votes |
ColorPickerInput: React.FC<{
color: string;
onChange: (newColor: string) => void;
inputProps?: IInputGroupProps & HTMLInputProps;
}> = props => {
return (
<Popover content={<SketchPicker color={props.color} onChangeComplete={col => props.onChange(col.hex)} />}>
<InputGroup
value={props.color}
leftIcon={<Icon icon={'symbol-square'} color={props.color} />}
{...(props.inputProps || {})}
/>
</Popover>
);
}
Example #8
Source File: index.tsx From imove with MIT License | 6 votes |
ColorPicker: React.FC<IProps> = (props) => {
const { color, onChangeComplete: changeCb } = props;
const [curColor, setCurColor] = useState(color);
// life
useEffect(() => setCurColor(color), [color]);
// events
const onChange = (color: ColorResult): void => setCurColor(color.hex);
const onChangeComplete = (color: ColorResult): void => changeCb(color.hex);
return (
<SketchPicker
color={curColor}
onChange={onChange}
onChangeComplete={onChangeComplete}
/>
);
}
Example #9
Source File: ColorEditorItem.tsx From next-basics with GNU General Public License v3.0 | 5 votes |
export function LegacyColorPick(
props: ColorEditorItemProps,
ref: React.Ref<any>
) {
const [value, setValue] = useState(props.value);
const [visible, setVisible] = useState(false);
useEffect(() => {
setValue(props.value);
}, [props.value]);
const handleChangeComplete = (color: ColorResult) => {
setValue(color.hex);
props.onChange(color.hex);
};
const handleClick = () => {
setVisible(true);
};
return (
<div className={styles.colorContainer}>
<div className={styles.colorCube} onClick={handleClick}>
<div
className={styles.colorContent}
style={{ backgroundColor: value }}
/>
</div>
{visible && (
<div className={styles.popover}>
<div className={styles.cover} onClick={() => setVisible(false)} />
<SketchPicker
width="230px"
ref={ref}
color={value}
onChangeComplete={handleChangeComplete}
presetColors={getPresetColors(COLORS_MAP)}
/>
</div>
)}
</div>
);
}
Example #10
Source File: PropertiesPanel.tsx From MagicUI with Apache License 2.0 | 5 votes |
function TextProperties(props: ITextPropertiesProps) {
const dispatch = useDispatch();
const [text, setText] = useState('');
const [color, setColor] = useState('');
const [fontSize, setFontSize] = useState(0);
const [showPicker, toggleShowPicker, pickerRef] = useShowPicker(false);
useEffect(() => setText(props.text.text), [props.text.text]);
useEffect(() => setColor(props.text.fill), [props.text.fill]);
useEffect(() => setFontSize(props.text.fontSize), [props.text.fontSize]);
const handleChangeText = (e: any) => {
const value = e.target.value;
setText(value);
dispatch(changeComponentText(color, value, fontSize));
};
const handleChangeFontSize = (e: any) => {
const value = e.target.value;
setFontSize(value);
dispatch(changeComponentText(color, text, value));
};
const handleChangeColor = (e: any) => {
const value = e.hex;
setColor(value);
dispatch(changeComponentText(value, text, fontSize));
};
return (
<PropertiesItem name="TEXT">
<div className={style.text_props}>
<span>Text</span>
<input value={text} onChange={handleChangeText}/>
</div>
<div className={style.text_font_size_props}>
<span>Size</span>
<input value={fontSize} onChange={handleChangeFontSize}/>
</div>
<div className={style.text_color_props}>
<span>Fill</span>
<input value={color} onClick={toggleShowPicker}/>
<div className={cls(style.text_color_picker, showPicker && style.show)} ref={pickerRef}>
<SketchPicker color={color} onChange={handleChangeColor}/>
</div>
</div>
</PropertiesItem>
);
}
Example #11
Source File: PropertiesPanel.tsx From MagicUI with Apache License 2.0 | 5 votes |
function ShadowProperties(props: IShadowPropertiesProps) {
const dispatch = useDispatch();
const [offsetX, setOffsetX] = useState(0);
const [offsetY, setOffsetY] = useState(0);
const [blur, setBlur] = useState(0);
const [color, setColor] = useState('');
const [showPicker, toggleShowPicker, pickerRef] = useShowPicker(false);
useEffect(() => setOffsetX(props.shadow.offsetX), [props.shadow.offsetX]);
useEffect(() => setOffsetY(props.shadow.offsetY), [props.shadow.offsetY]);
useEffect(() => setColor(props.shadow.fill), [props.shadow.fill]);
useEffect(() => setBlur(props.shadow.blur), [props.shadow.blur]);
const handleChangeOffsetX = (e: any) => {
const value = +e.target.value;
setOffsetX(value);
dispatch(changeComponentShadow(color, blur, value, offsetY));
};
const handleChangeOffsetY = (e: any) => {
const value = +e.target.value;
setOffsetY(value);
dispatch(changeComponentShadow(color, blur, offsetX, value));
};
const handleChangeBlur = (e: any) => {
const value = +e.target.value;
setBlur(value);
dispatch(changeComponentShadow(color, value, offsetX, offsetY));
};
const handleChangeColor = (e: any) => {
const value = e.hex;
setColor(value);
dispatch(changeComponentShadow(value, blur, offsetX, offsetY));
};
return (
<PropertiesItem name="SHADOW">
<div className={style.shadow_offset_props}>
<div>
<span>X</span>
<input value={offsetX} onChange={handleChangeOffsetX}/>
</div>
<div>
<span>Y</span>
<input value={offsetY} onChange={handleChangeOffsetY}/>
</div>
</div>
<div className={style.shadow_blur_props}>
<span>Blur</span>
<input value={blur} onChange={handleChangeBlur}/>
</div>
<div className={style.shadow_color_props}>
<span>Fill</span>
<input value={color} onClick={toggleShowPicker}/>
<div className={cls(style.shadow_color_picker, showPicker && style.show)} ref={pickerRef}>
<SketchPicker color={color} onChange={handleChangeColor}/>
</div>
</div>
</PropertiesItem>
);
}
Example #12
Source File: PropertiesPanel.tsx From MagicUI with Apache License 2.0 | 5 votes |
function BorderProperties(props: IBorderPropertiesProps) {
const dispatch = useDispatch();
const [width, setWidth] = useState(0);
const [radius, setRadius] = useState(0);
const [color, setColor] = useState('');
const [showPicker, toggleShowPicker, pickerRef] = useShowPicker(false);
useEffect(() => setWidth(props.border.width), [props.border.width]);
useEffect(() => setRadius(props.border.radius), [props.border.radius]);
useEffect(() => setColor(props.border.fill), [props.border.fill]);
const handleChangeColor = (e: any) => {
setColor(e.hex);
dispatch(changeComponentBorder(e.hex, width, radius));
};
const handleChangeWidth = (e: any) => {
setWidth(e.target.value);
dispatch(changeComponentBorder(color, +e.target.value, radius));
};
const handleChangeRadius = (e: any) => {
setRadius(e.target.value);
dispatch(changeComponentBorder(color, width, +e.target.value));
};
return (
<PropertiesItem name="BORDER">
<div className={style.border_props}>
<div>
<span>W</span>
<input value={width} onChange={handleChangeWidth}/>
</div>
<div>
<span>R</span>
<input value={radius} onChange={handleChangeRadius}/>
</div>
</div>
<div className={style.border_color_props}>
<span>Fill</span>
<input value={color} onClick={toggleShowPicker}/>
<div className={cls(style.border_color_picker, showPicker && style.show)} ref={pickerRef}>
<SketchPicker color={color} onChange={handleChangeColor}/>
</div>
</div>
</PropertiesItem>
);
}
Example #13
Source File: index.tsx From fe-v5 with Apache License 2.0 | 5 votes |
export default function index(props: IProps) {
const { value = '#000', onChange } = props;
const [visible, setVisible] = useState(false);
const eleRef = useRef<HTMLDivElement>(null);
useOnClickOutside(eleRef, () => {
setVisible(false);
});
return (
<Popover
trigger='click'
placement='left'
visible={visible}
overlayClassName='color-picker-popover'
content={
<div
ref={eleRef}
onMouseLeave={() => {
setVisible(false);
}}
>
<SketchPicker
color={value}
onChange={(val) => {
if (onChange) {
onChange(val.hex);
}
}}
/>
</div>
}
>
<div
style={{ background: value, width: 32, height: 32, borderRadius: 2, cursor: 'pointer' }}
onClick={() => {
setVisible(!visible);
}}
/>
</Popover>
);
}
Example #14
Source File: index.tsx From fe-v5 with Apache License 2.0 | 5 votes |
export default function index(props: IProps) {
const { value = '#000', onChange } = props;
const [visible, setVisible] = useState(false);
const eleRef = useRef<HTMLDivElement>(null);
useOnClickOutside(eleRef, () => {
setVisible(false);
});
return (
<Popover
trigger='click'
placement='left'
visible={visible}
overlayClassName='color-picker-popover'
content={
<div
ref={eleRef}
onMouseLeave={() => {
setVisible(false);
}}
>
<SketchPicker
color={value}
onChange={(val) => {
if (onChange) {
onChange(val.hex);
}
}}
/>
</div>
}
>
<div
style={{ background: value, width: 32, height: 32, borderRadius: 2, cursor: 'pointer' }}
onClick={() => {
setVisible(!visible);
}}
/>
</Popover>
);
}
Example #15
Source File: button-font-color.tsx From fantasy-editor with MIT License | 5 votes |
ButtonFontColor: FunctionComponent<Props> = props => {
const [visible, setVisible] = useState(false);
const editor = useSlate();
const {
editor: { removeColor },
} = useLocale();
const [color, setColor] = useState<string>('#1890ff');
const [mark, setMark] = useState<Range | null>(null);
const handleColorChange = (v: ColorResult) => {
setColor(v.hex);
setVisible(false);
if (mark) {
ReactEditor.focus(editor);
Transforms.select(editor, mark);
if (isMarkActive(editor, MARK_COLOR) && v.hex === '#000000') {
editor.removeMark(MARK_COLOR);
} else {
editor.addMark(MARK_COLOR, v.hex);
}
}
};
const cleanColor = () => {
editor.removeMark(MARK_COLOR);
setVisible(false);
};
const show = () => {
const { selection } = editor;
setMark(selection);
setVisible(true);
};
const overlay = (
<div className={classNames('fc-btn-font-content', 'ant-dropdown-menu')} onMouseDown={e => e.stopPropagation()}>
<div className="fc-btn-font-header" onClick={cleanColor}>
<IconClear />
<span>{removeColor}</span>
</div>
<SketchPicker disableAlpha={true} color={color} onChange={handleColorChange} />
</div>
);
return (
<Dropdown
trigger={['click']}
overlay={overlay}
visible={visible}
overlayClassName="fc-btn-font-overlay"
onVisibleChange={setVisible}
disabled={isBlockActive(editor, BLOCK_CODE)}
>
<DropdownButton width={45} onMouseDown={show}
disabled={isBlockActive(editor, BLOCK_CODE)}>
<IconFontColor />
</DropdownButton>
</Dropdown>
);
}
Example #16
Source File: button-bg-color.tsx From fantasy-editor with MIT License | 5 votes |
ButtonBgColor: FunctionComponent<Props> = props => {
const [visible, setVisible] = useState(false);
const editor = useSlate();
const {
editor: { removeColor },
} = useLocale();
const [color, setColor] = useState<string>('#1890ff');
const [mark, setMark] = useState<Range | null>(null);
const handleColorChange = (v: ColorResult) => {
setColor(v.hex);
setVisible(false);
if (mark) {
ReactEditor.focus(editor);
Transforms.select(editor, mark);
if (isMarkActive(editor, MARK_BG_COLOR) && v.hex === '#fff') {
editor.removeMark(MARK_BG_COLOR);
} else {
editor.addMark(MARK_BG_COLOR, v.hex);
}
}
};
const cleanColor = () => {
editor.removeMark(MARK_BG_COLOR);
setVisible(false);
};
const show = () => {
const { selection } = editor;
setMark(selection);
setVisible(true);
};
const overlay = (
<div className={classNames('fc-btn-bg-content', 'ant-dropdown-menu')} onMouseDown={e => e.stopPropagation()}>
<div className="fc-btn-bg-header" onClick={cleanColor}>
<IconClear />
<span>{removeColor}</span>
</div>
<SketchPicker disableAlpha={true} color={color} onChange={handleColorChange} />
</div>
);
return (
<Dropdown
trigger={['click']}
overlay={overlay}
visible={visible}
overlayClassName="fc-btn-bg-overlay"
onVisibleChange={setVisible}
disabled={isBlockActive(editor, BLOCK_CODE)}
>
<DropdownButton width={45} onMouseDown={show}
disabled={isBlockActive(editor, BLOCK_CODE)}>
<IconBgColor />
</DropdownButton>
</Dropdown>
);
}
Example #17
Source File: color.tsx From XFlow with MIT License | 5 votes |
ColorPicker: React.FC<IProps> = props => {
const { label, value = '', onChange } = props
const [show, setShow] = useState(false)
const colorRef = useRef<string>(value)
const { graphProvider } = useXFlowApp()
const graphConfig = useRef<IGraphConfig>()
graphProvider.getGraphOptions().then(x6GraphConfig => {
graphConfig.current = x6GraphConfig
})
const PickContainer = () => {
return (
<div className={`${PREFIX}-pick-color-container`}>
<div className={`${PREFIX}-popover`}>
<SketchPicker
onChange={color => {
colorRef.current = color.hex
}}
/>
<div className="foolter">
<Button
onClick={() => {
setShow(false)
}}
>
取消
</Button>
<Button
type="primary"
onClick={() => {
onChange?.(colorRef.current)
setShow(false)
}}
>
确认
</Button>
</div>
</div>
</div>
)
}
const createPickColorContainer = (visible: boolean) => {
const existElements = document.getElementsByClassName(`${PREFIX}-pick-color-container`)
if (existElements.length) {
Array.from(existElements).forEach(ele => {
ele.parentNode?.removeChild(ele)
})
}
if (!visible) {
return
}
const div = document.createElement('div')
render(createPortal(<PickContainer />, document.getElementsByTagName('body')[0]), div)
}
return (
<div className="group">
{label && <label>{label}</label>}
<div
className={`${PREFIX}-color-container`}
onClick={() => {
setShow(true)
}}
>
<div
className={`${PREFIX}-color`}
style={{
backgroundColor: value,
height: '100%',
}}
/>
</div>
{createPickColorContainer(show)}
</div>
)
}
Example #18
Source File: Color.tsx From yugong with MIT License | 4 votes |
Color: React.FC<Props> = ({
defaultColor,
label,
onChange,
children,
span,
...other
}) => {
const [displayColorPicker, setDisplayColorPicker] = useState(false);
const [color, setColor] = useState<RGBColor>();
const [pickWrapStyle, setPickWrapStyle] = useState({});
const picker = useRef(null);
useEffect(() => {
if (defaultColor) {
const optColor: any = {};
const temp = parse(defaultColor);
if (temp.space) {
optColor.r = temp.values[0];
optColor.g = temp.values[1];
optColor.b = temp.values[2];
optColor.a = temp.alpha;
setColor(optColor);
}
} else {
setColor(undefined);
}
}, [defaultColor]);
const handleClick = useCallback(
(e) => {
setDisplayColorPicker(!displayColorPicker);
const style: any = {
position: 'absolute',
};
const width = document.body.offsetWidth,
height = document.body.offsetHeight,
sWidth = 270,
sHeight = 350,
X = e.screenX,
Y = e.screenY;
// 1、判断拾色器的宽度小于窗口宽度
if (width > sWidth) {
if (X + sWidth > width) {
style.position = 'fixed';
style.right = `10px`;
}
}
// 2、判断拾色器的高度大于窗口高度
if (height > sHeight) {
if (Y + sHeight > height) {
style.position = 'fixed';
style.bottom = `10px`;
}
}
setPickWrapStyle(style);
},
[displayColorPicker]
);
const handleClose = useCallback(() => {
setDisplayColorPicker(false);
}, []);
/**
* 高频编辑防抖处理
*/
const refChange = useSafeCallback(onChange);
const onChangeDebounce = useMemo(
() =>
throttle((value) => {
refChange(value);
}, 500),
[refChange]
);
const handleChange = useCallback(
(color: ColorResult | 'inherit') => {
let colorResult: any = color;
if (color === 'inherit') {
colorResult = undefined;
setColor(undefined);
} else {
setColor(color.rgb);
}
onChangeDebounce({
name: 'color',
value: colorResult,
});
},
[onChangeDebounce]
);
const renderColor = () => {
return (
<>
{displayColorPicker ? (
<div className={s.popover}>
<div className={s.cover} onClick={handleClose} />
<div
className={s.wrap}
style={pickWrapStyle}
ref={picker}
onClick={(e) => e.stopPropagation()}
>
<SketchPicker
color={color || undefined}
width="250px"
onChange={handleChange}
className={s.picker}
presetColors={[
'#f44336',
'#e91e63',
'#9c27b0',
'#673ab7',
'#3f51b5',
'#2196f3',
'#03a9f4',
'#00bcd4',
'#009688',
'#4caf50',
'#8bc34a',
'#cddc39',
'#ffeb3b',
'#ffc107',
'#ff9800',
'#ff5722',
'#aaaaaa',
'#000000',
'#fff',
'transparent',
]}
/>
<div
onClick={() => handleChange('inherit')}
className={s.inherit}
>
移除
</div>
</div>
</div>
) : null}
</>
);
};
const displayColor = color && `rgba(${(color as any).r}, ${(color as any).g}, ${
(color as any).b
}, ${(color as any).a})`
return (
<>
{children ? (
<>
<span {...other} onClick={handleClick}>
{children}
</span>
{renderColor()}
</>
) : (
<Row className={s.row} gutter={4}>
<Col className={s.label} span={span?.label || 7}>
{label || ''}
</Col>
<Col span={ span?.value || 17}>
<div className={s.swatch} onClick={handleClick}>
{color ? (
<div
className={s.color}
style={{
backgroundColor: displayColor,
}}
/>
) : (
<div className={ClassNames(s.color, s.empty)}>
<BgColorsOutlined />
</div>
)}
{renderColor()}
</div>
</Col>
</Row>
)}
</>
);
}
Example #19
Source File: AdminConfigForm.tsx From binaural-meet with GNU General Public License v3.0 | 4 votes |
AdminConfigForm: React.FC<AdminConfigFormProps> = (props: AdminConfigFormProps) => {
const [clearName, setClearName] = React.useState('')
const [showFillPicker, setShowFillPicker] = React.useState(false)
const [showColorPicker, setShowColorPicker] = React.useState(false)
const [downloadLink, setDownloadLink] = React.useState('')
const fileToPlay = React.useRef<HTMLInputElement>(null)
const fillButton = React.useRef<HTMLButtonElement>(null)
const colorButton = React.useRef<HTMLButtonElement>(null)
const {roomInfo, participants} = props.stores
return <Observer>{()=>{
const textForFill = isDarkColor(roomInfo.backgroundFill) ? 'white' : 'black'
const textForColor = isDarkColor(roomInfo.backgroundColor) ? 'white' : 'black'
const btnColor = roomInfo.passMatched ? 'primary' : 'default'
return <Box m={2}>
<Box m={2}>
<RemoteTrackLimitControl key="remotelimitcontrol" {...props.stores}/>
</Box>
<Box mt={2} mb={2}>
<TextField autoFocus label="Admin password" type="password" style={{marginTop:-12}}
value={roomInfo?.password} onChange={(ev)=>{ roomInfo.password=ev.currentTarget.value}}
onKeyPress={(ev)=>onKeyPress(ev, roomInfo)}/>
 
<Button variant="contained" color="primary" style={{textTransform:'none'}} onClick={() => {
let pass = roomInfo.roomProps.get('password')
if (!pass){ pass = '' }
roomInfo.passMatched = roomInfo?.password === pass
}}> Check </Button> 
{roomInfo.passMatched ? 'OK': 'Not matched'}
</Box>
<Box mt={2} mb={2}>
<TextField label="New password to update" type="text" style={{marginTop:-12}}
value={roomInfo?.newPassword} onChange={(ev)=>{roomInfo.newPassword=ev.currentTarget.value}}
/> 
<Button variant="contained" color={btnColor} disabled={!roomInfo.passMatched} style={{textTransform:'none'}}
onClick={() => {
if (roomInfo.passMatched){
connection.conference.setRoomProp('password', roomInfo.newPassword)
}
}}> Update password </Button> 
</Box>
<Box mt={2}>
<Button variant="contained" color={btnColor} style={{textTransform:'none'}}
disabled={!roomInfo.passMatched} onClick={() => {
if (roomInfo.passMatched) { connection.conference.sendMessage(MessageType.MUTE_VIDEO, true) }
}}> Mute all videos </Button>
<Button variant="contained" color={btnColor} style={{textTransform:'none'}}
disabled={!roomInfo.passMatched} onClick={() => {
if (roomInfo.passMatched) { connection.conference.sendMessage(MessageType.MUTE_VIDEO, false) }
}}> Show all videos </Button> 
<Button variant="contained" color={btnColor} style={{textTransform:'none'}}
disabled={!roomInfo.passMatched} onClick={() => {
if (roomInfo.passMatched) { connection.conference.sendMessage(MessageType.MUTE_AUDIO, true) }
}}> Mute all mics </Button>
<Button variant="contained" color={btnColor} style={{textTransform:'none'}}
disabled={!roomInfo.passMatched} onClick={() => {
if (roomInfo.passMatched) { connection.conference.sendMessage(MessageType.MUTE_AUDIO, false) }
}}> Switch on all mics </Button>
</Box>
<Box mt={2}>
<Button variant="contained" color={btnColor} style={{textTransform:'none'}}
disabled={!roomInfo.passMatched} onClick={() => {
if (roomInfo.passMatched) {
contents.removeAllContents()
}
}}> Remove all Contents </Button> 
<Button variant="contained" color={btnColor} style={{textTransform:'none'}}
disabled={!roomInfo.passMatched} onClick={() => {
if (roomInfo.passMatched){
const ids = new Set(contents.roomContentsInfo.keys())
contents.all.forEach(c => ids.add(c.id))
contents.all.filter(c => c.ownerName === clearName).forEach(c => contents.removeByLocal(c.id))
}
}}> Clear contents by user name </Button>  
<TextField label="name" type="text" style={{marginTop:-12}}
value={clearName} onChange={(ev)=>{setClearName(ev.currentTarget.value)}} />
</Box>
<Box mt={2}>
<Button variant="contained" color={btnColor} style={{textTransform:'none'}}
disabled={!roomInfo.passMatched} onClick={() => {
if (roomInfo.passMatched) {
connection.conference.sendMessageViaJitsi(MessageType.RELOAD_BROWSER, {})
if (connection.conference.bmRelaySocket?.readyState === WebSocket.OPEN){
connection.conference.pushOrUpdateMessageViaRelay(MessageType.RELOAD_BROWSER, {})
}
}
}}> Reload </Button> 
<Button variant="contained" disabled={!roomInfo.passMatched}
style={roomInfo.passMatched ?
{backgroundColor:rgb2Color(roomInfo.backgroundFill), color:textForFill, textTransform:'none'}
: {textTransform:'none'} }
onClick={()=>{if (roomInfo.passMatched){ setShowFillPicker(true) }}} ref={fillButton}>
Back color</Button>
<Popover open={showFillPicker}
onClose={()=>{
setShowFillPicker(false)
connection.conference.setRoomProp('backgroundFill', JSON.stringify(roomInfo.backgroundFill))
}}
anchorEl={fillButton.current} anchorOrigin={{vertical:'bottom', horizontal:'right'}}>
<SketchPicker color = {{r:roomInfo.backgroundFill[0], g:roomInfo.backgroundFill[1],
b:roomInfo.backgroundFill[2]}} disableAlpha
onChange={(color, event)=>{
event.preventDefault()
roomInfo.backgroundFill = [color.rgb.r, color.rgb.g, color.rgb.b]
}}
/>
</Popover>
<Button variant="contained" disabled={!roomInfo.passMatched}
style={roomInfo.passMatched ?
{backgroundColor:rgb2Color(roomInfo.backgroundColor), color:textForColor, textTransform:'none'}
: {textTransform:'none'} }
onClick={()=>{if (roomInfo.passMatched){ setShowColorPicker(true)} }} ref={colorButton}>
Pattern color</Button>
<Popover open={showColorPicker}
onClose={()=>{
setShowColorPicker(false)
connection.conference.setRoomProp('backgroundColor', JSON.stringify(roomInfo.backgroundColor))
}}
anchorEl={colorButton.current} anchorOrigin={{vertical:'bottom', horizontal:'right'}}>
<SketchPicker color = {{r:roomInfo.backgroundColor[0], g:roomInfo.backgroundColor[1],
b:roomInfo.backgroundColor[2]}} disableAlpha
onChange={(color, event)=>{
event.preventDefault()
roomInfo.backgroundColor = [color.rgb.r, color.rgb.g, color.rgb.b]
}}
/>
</Popover>
<Button variant="contained" color={btnColor} style={{textTransform:'none'}}
disabled={!roomInfo.passMatched} onClick={() => {
if (roomInfo.passMatched) {
roomInfo.backgroundFill = roomInfo.defaultBackgroundFill
roomInfo.backgroundColor = roomInfo.defaultBackgroundColor
connection.conference.setRoomProp('backgroundFill', JSON.stringify(roomInfo.backgroundFill))
connection.conference.setRoomProp('backgroundColor', JSON.stringify(roomInfo.backgroundColor))
}
}}> Default </Button> 
<Button variant="contained" color={btnColor} style={{textTransform:'none'}}
disabled={!roomInfo.passMatched} onClick={() => {
participants.local.recording = !participants.local.recording
if (participants.local.recording){
if (props.close) { props.close() }
recorder.start(props.stores)
}else{
recorder.stop().then((all)=>{
setDownloadLink(URL.createObjectURL(all))
if (false){
all.slice(0, 4).arrayBuffer().then(buffer => {
const view = new Int32Array(buffer)
const headerLen = view[0]
all.slice(4, 4+headerLen).text().then(text => {
const headers = JSON.parse(text) as BlobHeader[]
console.log(JSON.stringify(headers))
for (const header of headers){ console.log(`blob: ${JSON.stringify(header)}`) }
})
})
}
})
}
}}>{participants.local.recording ? 'Stop Recorder' : 'Start Recorder'}</Button>
{downloadLink ? <><a href={downloadLink} download="BMRecord.bin">Download</a> </> : undefined}
<input type="file" accept="application/octet-stream" ref={fileToPlay} style={{display:'none'}}
onChange={ (ev) => {
const files = ev.currentTarget?.files
if (files && files.length) {
if (props.close){ props.close() }
player.load(files[0]).then(()=>{
player.play()
})
}
}} />
<Button variant="contained" color='primary' style={{textTransform:'none'}}
onClick={() => {
fileToPlay.current?.click()
}}>Play</Button>
</Box>
</Box>}
}</Observer>
}
Example #20
Source File: WidgetsGroupModal.tsx From hub with Apache License 2.0 | 4 votes |
WidgetsGroupModal = (props: Props) => {
const widthInput = useRef<RefInputField>(null);
const whiteLabel = isWhiteLabel();
const [theme, setTheme] = useState<string>(DEFAULT_THEME);
const [header, setHeader] = useState<boolean>(false);
const [stars, setStars] = useState<boolean>(true);
const [loading, setLoading] = useState<boolean>(true);
const [color, setColor] = useState<string>(DEFAULT_COLOR);
const [fixedWidth, setFixedWidth] = useState<string | undefined>();
const [groupWrapperWidthOpt, setGroupWrapperWidthOpt] = useState<string>(DEFAULT_WRAPPER_OPTION);
const [isValidCode, setIsValidCode] = useState<boolean>(true);
const onFixedWidthChange = (e: ChangeEvent<HTMLInputElement>) => {
setFixedWidth(e.target.value);
widthInput.current!.checkIsValid().then((res: boolean) => {
setIsValidCode(res);
});
};
const buildWidgetsGroupCode = (): string => {
const code = `<div class="artifacthub-widget-group" data-url="${
window.location.href
}" data-theme="${theme}" data-header="${!header ? 'false' : 'true'}" data-stars="${
!stars ? 'false' : 'true'
}" data-color="${color}" data-responsive="${groupWrapperWidthOpt === 'responsive'}" ${
fixedWidth ? `data-width="${fixedWidth}"` : ''
} data-loading="${loading ? 'true' : 'false'}"></div><script async src="${
window.location.origin
}/artifacthub-widget.js"></script>`;
return code;
};
const [widgetCode, setWidgetCode] = useState<string>(buildWidgetsGroupCode());
const resetValues = () => {
setTheme(DEFAULT_THEME);
setHeader(false);
setLoading(true);
setFixedWidth(undefined);
setColor(DEFAULT_COLOR);
setGroupWrapperWidthOpt(DEFAULT_WRAPPER_OPTION);
setWidgetCode(buildWidgetsGroupCode());
};
const onCloseModal = () => {
props.setOpenStatus(false);
resetValues();
};
const handleColorChange = (color: any) => {
setColor(color.hex);
};
useEffect(() => {
setWidgetCode(buildWidgetsGroupCode());
/* eslint-disable react-hooks/exhaustive-deps */
}, [
theme,
header,
stars,
fixedWidth,
groupWrapperWidthOpt,
color,
loading,
props.visibleWidget,
]); /* eslint-enable react-hooks/exhaustive-deps */
return (
<>
{props.visibleWidget && (
<Modal
modalDialogClassName="fs-6"
header={<div className={`h3 m-2 flex-grow-1 ${styles.title}`}>Widgets group</div>}
onClose={onCloseModal}
open={props.visibleWidget}
>
<div className="w-100 position-relative">
<label className={`form-label fw-bold ${styles.label}`} htmlFor="theme">
Theme
</label>
<div className="d-flex flex-row mb-3">
{THEMES.map((themeOpt: RadioProps) => {
return (
<div className="form-check me-4" key={`radio_theme_${themeOpt.name}`}>
<input
className="form-check-input"
type="radio"
name="theme"
id={themeOpt.name}
value={themeOpt.name}
checked={theme === themeOpt.name}
onChange={() => {
setTheme(themeOpt.name);
}}
required
/>
<label className="form-label text-capitalize form-check-label" htmlFor={themeOpt.name}>
<div className="d-flex flex-row align-items-center">
{themeOpt.icon}
<span className="ms-1">{themeOpt.name}</span>
</div>
</label>
</div>
);
})}
</div>
{!whiteLabel && (
<div className="mt-4 mb-3">
<div className="form-check form-switch ps-0">
<label htmlFor="header" className={`form-check-label fw-bold ${styles.label}`}>
Header
</label>
<input
id="header"
type="checkbox"
className="form-check-input position-absolute ms-2"
value="true"
role="switch"
onChange={() => setHeader(!header)}
checked={header}
/>
</div>
<div className="form-text text-muted mt-2">Display Artifact Hub header at the top of the widget.</div>
</div>
)}
<div className="mt-4 mb-3">
<div className="form-check form-switch ps-0">
<label htmlFor="stars" className={`form-check-label fw-bold ${styles.label}`}>
Stars
</label>
<input
id="stars"
type="checkbox"
className="form-check-input position-absolute ms-2"
value="true"
role="switch"
onChange={() => setStars(!stars)}
checked={stars}
/>
</div>
<div className="form-text text-muted mt-2">Display number of stars given to the package.</div>
</div>
<div className="d-flex flex-row">
<div>
<label className={`form-label fw-bold ${styles.label}`} htmlFor="groupWrapperWidthOpt">
Container width
</label>
<div className="d-flex flex-row">
{WRAPPER_OPTIONS.map((wrapperOpt: RadioProps) => {
return (
<div className="form-check me-4" key={`radio_wrapperOpt_${wrapperOpt.name}`}>
<input
className="form-check-input"
type="radio"
name="groupWrapperWidthOpt"
id={wrapperOpt.name}
value={wrapperOpt.name}
checked={groupWrapperWidthOpt === wrapperOpt.name}
onChange={() => {
if (wrapperOpt.name === 'fixed') {
setFixedWidth((WIDGET_WIDTH * 2).toString());
} else {
setIsValidCode(true);
setFixedWidth(undefined);
}
setGroupWrapperWidthOpt(wrapperOpt.name);
}}
required
/>
<label className="text-capitalize form-check-label" htmlFor={wrapperOpt.name}>
<div className="d-flex flex-row align-items-center">
{wrapperOpt.icon}
<span className="ms-1">{wrapperOpt.name}</span>
</div>
</label>
</div>
);
})}
</div>
</div>
<div className={`position-relative ${styles.inputWrapper}`}>
{groupWrapperWidthOpt === 'fixed' && (
<div className="position-absolute d-flex flex-row">
<InputField
ref={widthInput}
type="number"
name="fixedWidth"
min={380}
className="mb-0"
inputClassName={styles.input}
invalidText={{
default: 'This field is required',
rangeUnderflow: 'The min value is 380',
}}
onChange={onFixedWidthChange}
value={fixedWidth}
validateOnBlur
required
/>
<div className="mt-1 text-muted ms-2">px</div>
</div>
)}
</div>
</div>
<div className="mt-4 mb-3">
<div className="form-check form-switch ps-0">
<label htmlFor="loading" className={`form-check-label fw-bold ${styles.label}`}>
Loading spinner
</label>
<input
id="loading"
type="checkbox"
role="switch"
className="form-check-input position-absolute ms-2"
value="true"
onChange={() => setLoading(!loading)}
checked={loading}
/>
</div>
<div className="form-text text-muted mt-2">Display loading spinner while waiting for search results.</div>
</div>
<div className="mt-4 mb-3">
<div className="d-flex flex-row align-items-center">
<label htmlFor="color" className={`form-label fw-bold mb-0 ${styles.label}`}>
Color
</label>
<div className={`btn btn-sm btn-light border p-1 ms-2 ${styles.colorInputWrapper}`}>
<div
className={styles.colorInput}
style={{
backgroundColor: color,
}}
/>
</div>
{color !== DEFAULT_COLOR && (
<button
className="btn btn-sm btn-link text-muted py-0"
onClick={() => setColor(DEFAULT_COLOR)}
aria-label="Reset to default"
>
<IoIosClose />
<small>Reset to default</small>
</button>
)}
</div>
<div className="form-text text-muted mt-3 mb-2">
Color used for widgets border, header and loading spinner.
</div>
<div className={`pb-2 ${styles.colorPickerWrapper}`}>
<SketchPicker
color={color}
presetColors={PRESET_COLORS}
onChangeComplete={handleColorChange}
disableAlpha
/>
</div>
</div>
<div className="mt-3 mb-2">
<label className={`form-label fw-bold ${styles.label}`}>Code</label>
<div data-testid="block-content" className={`flex-grow-1 me-3 user-select-none ${styles.blockWrapper}`}>
<SyntaxHighlighter
language="text"
style={docco}
customStyle={{
backgroundColor: 'var(--color-1-10)',
}}
>
{widgetCode}
</SyntaxHighlighter>
</div>
<ButtonCopyToClipboard
text={widgetCode}
tooltipClassName={`bs-tooltip-end ${styles.copyBtnTooltip}`}
arrowClassName={styles.copyBtnArrow}
visibleBtnText
contentBtn="Copy code to clipboard"
className="btn-outline-secondary px-2 py-1 text-uppercase"
disabled={!isValidCode}
label="Copy code to clipboard"
/>
</div>
</div>
</Modal>
)}
</>
);
}
Example #21
Source File: ColorPicker.tsx From easy-email with MIT License | 4 votes |
export function ColorPicker(props: ColorPickerProps) {
const { colors: presetColors, addCurrentColor } =
useContext(PresetColorsContext);
const [color, setColor] = useState('');
const { value = '', onChange, children, showInput = true } = props;
useEffect(() => {
setColor(value);
}, [value]);
const onChangeComplete = useCallback(
(color: ColorResult, event: React.ChangeEvent<HTMLInputElement>) => {
if (event.target.value && event.target.value.replace('#', '').length < 6)
return;
const newColor = color.hex;
setColor(newColor);
onChange?.(newColor);
addCurrentColor(newColor);
},
[addCurrentColor, onChange]
);
const onInputChange = useCallback(
(value: string) => {
setColor(value);
onChange?.(value);
addCurrentColor(value);
},
[addCurrentColor, onChange]
);
return (
<div style={{ flex: 1, display: 'flex' }}>
<Popover
title={props.label}
trigger='click'
{...props}
content={(
<div className={styles.colorPicker}>
<SketchPicker
presetColors={presetColors}
color={color}
disableAlpha
onChangeComplete={onChangeComplete}
/>
</div>
)}
>
{children || (
<div
style={{
display: 'inline-block',
height: 32,
width: 32,
boxSizing: 'border-box',
padding: 4,
border: '1px solid var(--color-neutral-3, rgb(229, 230, 235))',
borderRadius: showInput ? undefined : 4,
fontSize: 0,
borderRight: showInput ? 'none' : undefined,
position: 'relative',
cursor: 'pointer',
}}
>
{props.value ? (
<span
style={{
position: 'relative',
display: 'block',
border:
'1px solid var(--color-neutral-3, rgb(229, 230, 235))',
borderRadius: 2,
width: '100%',
height: '100%',
textAlign: 'center',
backgroundColor: value,
}}
/>
) : (
<img
style={{
maxWidth: '100%',
maxHeight: '100%',
filter:
'invert( 0.78 ) drop-shadow(0 0px 0 rgb(0 0 0 / 45%))',
}}
src={getImg('AttributePanel_02')}
/>
)}
</div>
)}
</Popover>
{showInput && (
<Input
value={props.value}
style={{ outline: 'none', flex: 1 }}
onChange={onInputChange}
/>
)}
</div>
);
}
Example #22
Source File: AvatarUI.tsx From avalon.ist with MIT License | 4 votes |
render() {
const fontSize = Math.min(this.props.tableWidth * 0.04, this.props.fontSize);
return (
<>
<div
id="Avatar-UI"
style={{
top: this.props.avatarPosition[0] + 'px',
left: this.props.avatarPosition[1] + 'px',
display: this.props.avatarShow ? undefined : 'none',
}}
onMouseOver={this.renderButtonsTrue}
onMouseLeave={this.renderButtonsFalse}
>
<div
id="ave-graphics"
style={{
width: this.props.avatarSize + 'px',
height: this.props.avatarSize + 'px',
maxHeight: Math.max(this.props.tableWidth * 0.08, 45) + 'px',
maxWidth: Math.max(this.props.tableWidth * 0.08, 45) + 'px',
opacity: this.props.afk ? '0.5' : '1',
}}
>
<div
id="ave-background"
className={
this.background[this.state.currentBackground] +
' ' +
((this.state.avatarSelected && this.props.isPickable) || (this.props.highlighted) ? 'picked' : '')
}
/>
<div
className={
'ave tooltip ' +
(this.props.killed ? 'killed ' : '') +
(this.props.isPickable ? 'pickable' : 'not-pickable')
}
style={{
backgroundImage:
'url(' +
(this.props.isRes ? this.props.resUrl : this.props.spyUrl) +
')',
}}
onClick={this.pickPlayer}
>
{this.props.isPickable ? (
<span className="tooltip-text">Click on this player to pick them</span>
) : null}
</div>
{this.props.hasClaimed ? (
<div className="claim">
<FontAwesomeIcon icon={faExclamationTriangle} />
</div>
) : null}
{this.props.killed ? <div className="ave-sword" /> : null}
{this.props.onMission ? (
<div className="ave-shield" ref={this.shieldLocation}>
{this.props.shieldShow ? (
<div
style={{
transform: 'scale(' + this.props.shieldScale + ')',
top: this.props.shieldPosition[0] + 'px',
left: this.props.shieldPosition[1] + 'px',
}}
className="ave-shield-display"
/>
) : null}
</div>
) : null}
{this.props.leader ? <div className="ave-flag" /> : null}
{this.props.vote > -1 ? (
<div className={'ave-vote-bubble ' + (this.props.vote === 1)} />
) : null}
{this.state.renderButtons ? (
<div className="ave-buttons">
<button onClick={this.setBackgroundColor} className="tooltip">
<span className="tooltip-text">Mark this player's allegiance</span>
<FontAwesomeIcon icon={faStamp} />
</button>
<button onClick={this.toggleHighlightChat} className="tooltip">
<span className="tooltip-text">
Highlight this player's chat messages
</span>
<FontAwesomeIcon
style={{
backgroundColor: this.state.highlightChat
? this.toHtmlHex(this.state.currentHighlight)
: '',
}}
icon={faPen}
/>
</button>
<button onClick={this.showColorPicker} className="tooltip">
<span className="tooltip-text">
Change this player's highlight color
</span>
<FontAwesomeIcon icon={faPaintBrush} />
</button>
</div>
) : null}
</div>
<p
className={'ave-username ' + (this.props.isMe ? 'me' : '')}
style={{
width: Math.max(this.props.tableWidth * 0.15, 40) + 'px',
fontSize: Math.max(fontSize, 10) + 'px',
}}
>
{this.props.card ? <FontAwesomeIcon icon={faAddressCard} /> : null}{' '}
{this.props.hammer ? <FontAwesomeIcon icon={faGavel} /> : null}{' '}
{this.props.username}
</p>
<p
className={'ave-role ' + this.props.isRes}
style={{
opacity:
this.props.role !== 'Spy?' && this.props.role !== 'Resistance?'
? '1'
: '0',
fontSize: Math.max(fontSize * 0.8, 8) + 'px',
}}
>
{this.props.role}
</p>
</div>
{this.state.renderPicker ? (
<div className="hl-picker">
<AvalonScrollbars>
<div className="hl-stuff">
<p>CHANGE HIGHLIGHT COLOR</p>
<SketchPicker
color={this.state.currentHighlight}
onChange={this.handleHighlight}
/>
<button onClick={this.hideColorPicker}>
<FontAwesomeIcon icon={faCheck} />
</button>
</div>
</AvalonScrollbars>
</div>
) : null}
</>
);
}
Example #23
Source File: ColorPicker.tsx From Cromwell with MIT License | 4 votes |
export function ColorPicker(props: {
label?: string;
value?: string;
className?: string;
style?: React.CSSProperties;
onChange?: (color: string) => void;
}) {
const colorRef = useRef<string | null>(null);
const prevValue = useRef<string | null>(null);
const inputAnchorRef = useRef<HTMLDivElement | null>(null);
const [open, setOpen] = useState(false);
const forceUpdate = useForceUpdate();
if (props.value !== prevValue.current) {
prevValue.current = props.value;
colorRef.current = props.value;
}
const handleChange = (color: { hex: string; rgb: { r: number; g: number; b: number; a: number } }) => {
const colorStr = color.rgb.a === 1 ? color.hex : `rgba(${color.rgb.r}, ${color.rgb.g}, ${color.rgb.b}, ${color.rgb.a})`;
colorRef.current = colorStr;
forceUpdate();
}
const handleClose = () => {
handleApply();
setOpen(false);
}
const handleApply = () => {
props.onChange?.(colorRef.current);
}
const handleInputChange = (event) => {
colorRef.current = event.target.value;
forceUpdate();
handleApply();
}
return (
<>
<TextField
InputProps={{
startAdornment: (
<InputAdornment position="start">
<div style={{ backgroundColor: colorRef.current, width: '20px', height: '20px', borderRadius: '100%' }}></div>
</InputAdornment>
),
}}
variant="standard"
className={props.className}
label={props.label}
fullWidth
value={colorRef.current}
ref={inputAnchorRef}
onChange={handleInputChange}
onClick={() => setOpen(true)}
style={props.style}
/>
<Popover
open={open}
anchorEl={inputAnchorRef.current}
onClose={handleClose}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'left',
}}
>
<div>
<SketchPicker
color={colorRef.current ?? '#000'}
onChangeComplete={handleChange}
/>
</div>
</Popover>
</>
)
}
Example #24
Source File: LocalParticipantForm.tsx From binaural-meet with GNU General Public License v3.0 | 4 votes |
LocalParticipantForm: React.FC<LocalParticipantFormProps> = (props: LocalParticipantFormProps) => {
const {participants, map} = props.stores
const local = participants.local
const [file, setFile] = useState<File|null>()
const [showColorPicker, setShowColorPicker] = useState(false)
const [showTextColorPicker, setShowTextColorPicker] = useState(false)
const {t} = useTranslation()
function closeConfig(ev:Object, reason:string) {
if (reason === 'enter' || reason==='backdropClick'){
local.sendInformation()
local.saveInformationToStorage(true)
}
props.close()
}
const onKeyPress = (ev:React.KeyboardEvent) => {
if (ev.key === 'Enter') {
closeConfig(ev, 'enter')
}else if (ev.key === 'Esc' || ev.key === 'Escape') {
local.loadInformationFromStorage()
}
}
function clearAvatarSrc(ev: React.FormEvent) {
ev.preventDefault()
setFile(null)
local.information.avatarSrc = ''
}
function uploadAvatarSrc(ev: React.FormEvent) {
ev.preventDefault()
if (file) {
uploadToGyazo(file).then((url) => {
local.information.avatarSrc = url
})
}
}
const colorButton = React.useRef<HTMLButtonElement>(null)
const textColorButton = React.useRef<HTMLButtonElement>(null)
const {close, ...popoverProps} = props
return <Popover {...popoverProps} onClose={closeConfig}>
<DialogTitle>
<span style={{fontSize: isSmartphone() ? '2.5em' : '1em'}}>
{t('lsTitle')}
</span>
<span style={{float:'right'}}>
<SignalQualityButton open={props.open} stats={local.quality} isLocal={true}/></span>
</DialogTitle>
<DialogContent>
<Observer>{ ()=> {
const rgb = local.getColorRGB()
const textRgb = local.getTextColorRGB()
const textColor = isDarkColor(rgb) ? 'white' : 'black'
const backColor = isDarkColor(textRgb) ? 'lightgray' : 'gray'
// console.log('render color picker', rgb)
return <>
<TextField label={t('YourName')} multiline={false} value={local.information.name} style={tfDivStyle}
inputProps={{style: tfIStyle, autoFocus:true}} InputLabelProps={{style: tfLStyle}}
onChange={event => {local.information.name = event.target.value}}
onKeyPress={onKeyPress} fullWidth={true}
/>
<Box mt={3}>
<div style={{fontSize:12}}>{t('lsColor')}</div>
<Box ml={2}>
<Button variant="contained"
style={{backgroundColor:rgb2Color(rgb), color:textColor, textTransform:'none'}}
onClick={()=>{setShowColorPicker(true)}} ref={colorButton}>
{t('lsColorAvatar')}</Button>
<Popover open={showColorPicker} onClose={()=>{setShowColorPicker(false)}}
anchorEl={colorButton.current} anchorOrigin={{vertical:'bottom', horizontal:'right'}}>
<SketchPicker color = {{r:rgb[0], g:rgb[1], b:rgb[2]}} disableAlpha
onChange={(color, event)=>{
event.preventDefault()
local.information.color = [color.rgb.r, color.rgb.g, color.rgb.b]
}}
/>
</Popover>
<Button variant="contained"
style={{color:rgb2Color(textRgb), backgroundColor:backColor, marginLeft:15, textTransform:'none'}}
onClick={()=>{setShowTextColorPicker(true)}} ref={textColorButton}>
{t('lsColorText')}</Button>
<Popover open={showTextColorPicker} anchorOrigin={{vertical:'bottom', horizontal:'right'}}
onClose={()=>{setShowTextColorPicker(false)}} anchorEl={textColorButton.current}>
<SketchPicker color = {{r:textRgb[0], g:textRgb[1], b:textRgb[2]}}
onChange={(color, event)=>{
event.preventDefault()
local.information.textColor = [color.rgb.r, color.rgb.g, color.rgb.b]
}}
/>
</Popover>
<Button variant="contained" style={{marginLeft:15, textTransform:'none'}}
onClick={()=>{local.information.color=[]; local.information.textColor=[]}} >
{t('lsAutoColor')}</Button>
</Box>
</Box>
<Box mt={3}>
<div style={{fontSize:12}}>{t('lsImage')}</div>
<Box mt={-1} ml={2}>
<form key="information" onSubmit = {uploadAvatarSrc}
style={{lineHeight:'2em', fontSize: isSmartphone() ? '2.5em' : '1em'}}>
<div style={{fontSize:12, marginTop:8}}>{t('lsImageFile')}</div>
{local.information.avatarSrc ? <>
<img src={local.information.avatarSrc} style={{height:'1.5em', verticalAlign:'middle'}} alt="avatar"/>
<input style={iStyle} type="submit" onClick={clearAvatarSrc} value="✕" />
</> : undefined}
<input style={iStyle} type="file" onChange={(ev) => {
setFile(ev.target.files?.item(0))
}} />
<input style={iStyle} type="submit" value="Upload" />
</form>
<TextField label={t('lsEmail')} multiline={false} value={local.info.email}
style={{...tfDivStyle, marginTop:8}}
inputProps={{style: tfIStyle, autoFocus:true}} InputLabelProps={{style: tfLStyle}}
onChange={event => local.info.email = event.target.value}
onKeyPress={onKeyPress} fullWidth={true}
/>
</Box>
</Box>
<Box mt={3}>
<div style={{fontSize:12}}>{t('lsNotification')}</div>
<Box mt={-1} ml={2}>
<FormControlLabel control={
<Checkbox color="primary" checked={local.information.notifyCall}
onChange={(ev)=>{local.information.notifyCall = ev.target.checked}} />
} label={t('lsNotifyCall')} />
<FormControlLabel control={
<Checkbox color="primary" checked={local.information.notifyTouch}
onChange={(ev)=>{local.information.notifyTouch = ev.target.checked}} />
} label={t('lsNotifyTouch')} />
<FormControlLabel control={
<Checkbox color="primary" checked={local.information.notifyNear}
onChange={(ev)=>{local.information.notifyNear = ev.target.checked}} />
} label={t('lsNotifyNear')} />
<FormControlLabel control={
<Checkbox color="primary" checked={local.information.notifyYarn}
onChange={(ev)=>{local.information.notifyYarn = ev.target.checked}} />
} label={t('lsNotifyYarn')} />
</Box>
</Box>
</>}}
</Observer>
<Box mt={4} mb={3}>
<Button variant="contained" color="primary" style={{textTransform:'none'}}
onClick={()=>{
closeConfig({}, 'enter')
}}>{t('btSave')}</Button>
<Button variant="contained" color="secondary" style={{marginLeft:15, textTransform:'none'}}
onClick={()=>{ local.loadInformationFromStorage()}}>{t('btCancel')}</Button>
<Button variant="contained" style={{marginLeft:15, textTransform:'none'}}
onClick={()=>{
map.focusOn(local)
}}>{t('ctFocus')}</Button>
</Box>
</DialogContent>
</Popover>
}