Last active
October 31, 2024 07:25
-
-
Save Briscoooe/ce13faf5c02a7ae69b9cddfa654786af to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { useCallback, useState } from "react"; | |
const EnvironmentVariables = () => { | |
const [variables, setVariables] = useState([{ key: '', value: '' }]); | |
const handleInputChange = useCallback((index, field, value) => { | |
setVariables((prevVariables) => { | |
const newVariables = [...prevVariables]; | |
newVariables[index][field] = value; | |
return newVariables; | |
}); | |
}, []); | |
const removeVariable = useCallback((index) => { | |
setVariables((prevVariables) => { | |
if (prevVariables.length === 1) { | |
return [{ key: '', value: '' }]; | |
} | |
const newVariables = [...prevVariables]; | |
newVariables.splice(index, 1); | |
return newVariables; | |
}); | |
}, []); | |
const addVariable = useCallback(() => { | |
setVariables((prevVariables) => [...prevVariables, { key: '', value: '' }]); | |
}, []); | |
const isEnvFormat = useCallback((content) => { | |
return /^\s*\w+\s*=.*$/m.test(content); | |
}, []); | |
const parseEnvContent = useCallback((content) => { | |
return content | |
.split("\n") | |
.map((line) => line.trim()) | |
.filter((line) => line && !line.startsWith("#")) | |
.map((line) => { | |
const [key, ...valueParts] = line.split("="); | |
let value = valueParts.join("=").trim(); | |
if ( | |
(value.startsWith('"') && value.endsWith('"')) || | |
(value.startsWith("'") && value.endsWith("'")) | |
) { | |
value = value.slice(1, -1); | |
} | |
return { key: key.trim(), value }; | |
}); | |
}, []); | |
const handlePaste = useCallback((e, index, field) => { | |
const pastedText = e.clipboardData.getData('text'); | |
if (isEnvFormat(pastedText)) { | |
e.preventDefault(); | |
const parsedVariables = parseEnvContent(pastedText); | |
setVariables(prevVariables => { | |
let newVariables = [...prevVariables]; | |
if (index < newVariables.length) { | |
const currentVar = newVariables[index]; | |
if (currentVar.key === '' && currentVar.value === '') { | |
newVariables[index] = parsedVariables[0]; | |
parsedVariables.shift(); | |
} | |
} | |
const existingKeys = new Set(newVariables.map(v => v.key)); | |
const additionalVariables = parsedVariables.filter(v => !existingKeys.has(v.key)); | |
return [...newVariables, ...additionalVariables]; | |
}); | |
} else { | |
setVariables(prevVariables => { | |
const newVariables = [...prevVariables]; | |
newVariables[index][field] = e.target.value; | |
return newVariables; | |
}); | |
} | |
}, [isEnvFormat, parseEnvContent]); | |
return ( | |
<div> | |
<div> | |
{variables.map((variable, index) => ( | |
<div key={index}> | |
<input | |
type="text" | |
placeholder="e.g. API_KEY" | |
value={variable.key} | |
onChange={(e) => handleInputChange(index, 'key', e.target.value)} | |
data-field="key" | |
data-index={index} | |
onPaste={(e) => handlePaste(e, index, 'key')} | |
/> | |
<input | |
type="text" | |
placeholder="Value" | |
value={variable.value} | |
onChange={(e) => handleInputChange(index, 'value', e.target.value)} | |
data-field="value" | |
data-index={index} | |
/> | |
<button onClick={() => removeVariable(index)}> | |
Remove | |
</button> | |
</div> | |
))} | |
<button onClick={addVariable}> | |
Add new | |
</button> | |
</div> | |
</div> | |
); | |
}; | |
export default EnvironmentVariables; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment