diff options
Diffstat (limited to 'public/projects/js-small-apps/css-border-previewer')
4 files changed, 1666 insertions, 0 deletions
diff --git a/public/projects/js-small-apps/css-border-previewer/README.md b/public/projects/js-small-apps/css-border-previewer/README.md new file mode 100644 index 0000000..24a4566 --- /dev/null +++ b/public/projects/js-small-apps/css-border-previewer/README.md @@ -0,0 +1,13 @@ +# CSS Border Previewer + +An app to preview how a shapes looks when you change CSS border properties. + +You can find more details about the implementation here: https://github.com/florinpop17/app-ideas/blob/master/Projects/1-Beginner/Border-Radius-Previewer.md but I have decided to not limit myself to border-radius. + +## Preview + +You can see a live preview here: https://demo.armandphilippot.com/#css-border-previewer + +## License + +This project is open-source and available under the [MIT License](../LICENSE). diff --git a/public/projects/js-small-apps/css-border-previewer/app.js b/public/projects/js-small-apps/css-border-previewer/app.js new file mode 100644 index 0000000..583703d --- /dev/null +++ b/public/projects/js-small-apps/css-border-previewer/app.js @@ -0,0 +1,847 @@ +/** + * Retrieve the border color property name depending on direction. + * @param {String} direction - Either `top`, `right`, `left` or `bottom`. + * @returns {String} The CSS property name. + */ +function getBorderColorProperty(direction) { + let borderColorProperty; + + switch (direction) { + case "top": + borderColorProperty = "borderTopColor"; + break; + case "right": + borderColorProperty = "borderRightColor"; + break; + case "bottom": + borderColorProperty = "borderBottomColor"; + break; + case "left": + borderColorProperty = "borderLeftColor"; + break; + default: + borderColorProperty = "borderColor"; + break; + } + + return borderColorProperty; +} + +/** + * Retrieve the border style property name depending on direction. + * @param {String} direction - Either `top`, `right`, `bottom` or `left`. + * @returns {String} The CSS property name. + */ +function getBorderStyleProperty(direction) { + let borderStyleProperty; + + switch (direction) { + case "top": + borderStyleProperty = "borderTopStyle"; + break; + case "right": + borderStyleProperty = "borderRightStyle"; + break; + case "bottom": + borderStyleProperty = "borderBottomStyle"; + break; + case "left": + borderStyleProperty = "borderLeftStyle"; + break; + default: + borderStyleProperty = "borderStyle"; + break; + } + + return borderStyleProperty; +} + +/** + * Retrieve the border width property name depending on direction. + * @param {String} direction - Either `top`, `right`, `left` or `bottom`. + * @returns {String} The CSS property name. + */ +function getBorderWidthProperty(direction) { + let borderWidthProperty; + + switch (direction) { + case "top": + borderWidthProperty = "borderTopWidth"; + break; + case "right": + borderWidthProperty = "borderRightWidth"; + break; + case "bottom": + borderWidthProperty = "borderBottomWidth"; + break; + case "left": + borderWidthProperty = "borderLeftWidth"; + break; + default: + borderWidthProperty = "borderWidth"; + break; + } + + return borderWidthProperty; +} + +/** + * Apply the custom border to an element. + * @param {HTMLElement} el - Apply border to this element. + * @param {String} property - Either `color`, `style` or `width`. + * @param {String} value - The value to apply. + * @param {String} [direction] - Either `top`, `right`, `bottom` or `left`. + */ +function setBorder(el, property, value, direction = null) { + let borderProperty; + + switch (property) { + case "color": + borderProperty = getBorderColorProperty(direction); + break; + case "style": + borderProperty = getBorderStyleProperty(direction); + break; + case "width": + borderProperty = getBorderWidthProperty(direction); + default: + break; + } + + el.style[borderProperty] = value; +} + +/** + * Apply the custom border radius to an element. + * @param {HTMLElement} el - Apply border radius to this element. + * @param {String} firstRadius - The first radius value. + * @param {String} [secondRadius] - The second radius value. + * @param {String} [x] - The horizontal direction: either `right` or `left`. + * @param {String} [y] - The vertical direction: either `top` or `bottom`. + */ +function setBorderRadius(el, firstRadius, secondRadius, x = null, y = null) { + const direction = `${x}-${y}`; + const value = `${firstRadius}${secondRadius ? ` / ${secondRadius}` : ""}`; + let borderRadiusProperty; + + switch (direction) { + case "left-top": + borderRadiusProperty = "borderTopLeftRadius"; + break; + case "right-top": + borderRadiusProperty = "borderTopRightRadius"; + break; + case "left-bottom": + borderRadiusProperty = "borderBottomLeftRadius"; + break; + case "right-bottom": + borderRadiusProperty = "borderBottomRightRadius"; + break; + default: + borderRadiusProperty = "borderRadius"; + break; + } + + el.style[borderRadiusProperty] = value; +} + +/** + * Display the corresponding border settings. + * @param {String} string - Either `common` or `individual`. + */ +function toggleBorderSettingsDisplay(string) { + const allBordersFieldset = document.getElementById("fieldset-borders"); + const topBorderFieldset = document.getElementById("fieldset-border-top"); + const rightBorderFieldset = document.getElementById("fieldset-border-right"); + const bottomBorderFieldset = document.getElementById( + "fieldset-border-bottom" + ); + const leftBorderFieldset = document.getElementById("fieldset-border-left"); + + if (string === "common") { + allBordersFieldset.style.display = ""; + topBorderFieldset.style.display = "none"; + rightBorderFieldset.style.display = "none"; + bottomBorderFieldset.style.display = "none"; + leftBorderFieldset.style.display = "none"; + } else { + allBordersFieldset.style.display = "none"; + topBorderFieldset.style.display = ""; + rightBorderFieldset.style.display = ""; + bottomBorderFieldset.style.display = ""; + leftBorderFieldset.style.display = ""; + } +} + +/** + * Display the corresponding border-radius settings. + * @param {String} string - Either `common` or `individual`. + */ +function toggleBorderRadiusSettingsDisplay(string) { + const allBordersRadiusFieldset = document.getElementById( + "fieldset-borders-radius" + ); + const topLeftBorderRadiusFieldset = document.getElementById( + "fieldset-border-top-left-radius" + ); + const topRightBorderRadiusFieldset = document.getElementById( + "fieldset-border-top-right-radius" + ); + const bottomLeftBorderRadiusFieldset = document.getElementById( + "fieldset-border-bottom-left-radius" + ); + const bottomRightBorderRadiusFieldset = document.getElementById( + "fieldset-border-bottom-right-radius" + ); + + if (string === "common") { + allBordersRadiusFieldset.style.display = ""; + topLeftBorderRadiusFieldset.style.display = "none"; + topRightBorderRadiusFieldset.style.display = "none"; + bottomLeftBorderRadiusFieldset.style.display = "none"; + bottomRightBorderRadiusFieldset.style.display = "none"; + } else { + allBordersRadiusFieldset.style.display = "none"; + topLeftBorderRadiusFieldset.style.display = ""; + topRightBorderRadiusFieldset.style.display = ""; + bottomLeftBorderRadiusFieldset.style.display = ""; + bottomRightBorderRadiusFieldset.style.display = ""; + } +} + +/** + * Print the generated code into the given element. + * @param {HTMLElement} el - The element where to print generated code. + */ +function printCode(el) { + const code = document.querySelector(".result__code"); + let codeOutput = ` +.box {\n`; + + for (const property of el.style) { + codeOutput += `\t${property}: ${el.style[property]};\n`; + } + + codeOutput += "}"; + code.textContent = codeOutput; +} + +/** + * Check which type of settings is checked. + * @param {String} radioValue - The input radio value. + * @returns {Boolean} True if is individual; false if is common. + */ +function isIndividualSettings(radioValue) { + return radioValue === "true" ? true : false; +} + +/** + * Set all borders to a given element. + * @param {HTMLElement} el - Apply border to this element. + */ +function setCommonBorder(el) { + const allBordersColorInput = document.getElementById("borders-color"); + const allBordersStyleSelect = document.getElementById("borders-style"); + const allBordersUnitSelect = document.getElementById("borders-unit"); + const allBordersWidthInput = document.getElementById("borders-width"); + + setBorder(el, "color", allBordersColorInput.value); + setBorder(el, "style", allBordersStyleSelect.value); + setBorder( + el, + "width", + `${allBordersWidthInput.value}${allBordersUnitSelect.value}` + ); + + allBordersColorInput.addEventListener("input", () => { + setBorder(el, "color", allBordersColorInput.value); + printCode(el); + }); + + allBordersStyleSelect.addEventListener("input", () => { + setBorder(el, "style", allBordersStyleSelect.value); + printCode(el); + }); + + allBordersUnitSelect.addEventListener("input", () => { + setBorder( + el, + "width", + `${allBordersWidthInput.value}${allBordersUnitSelect.value}` + ); + printCode(el); + }); + + allBordersWidthInput.addEventListener("input", () => { + setBorder( + el, + "width", + `${allBordersWidthInput.value}${allBordersUnitSelect.value}` + ); + printCode(el); + }); +} + +/** + * Set the top border to the given element. + * @param {HTMLElement} el - Apply the top border to this element. + */ +function setTopBorder(el) { + const topBorderColorInput = document.getElementById("border-top-color"); + const topBorderStyleSelect = document.getElementById("border-top-style"); + const topBorderUnitSelect = document.getElementById("border-top-unit"); + const topBorderWidthInput = document.getElementById("border-top-width"); + + setBorder(el, "color", topBorderColorInput.value, "top"); + setBorder(el, "style", topBorderStyleSelect.value, "top"); + setBorder( + el, + "width", + `${topBorderWidthInput.value}${topBorderUnitSelect.value}`, + "top" + ); + + topBorderColorInput.addEventListener("input", () => { + setBorder(el, "color", topBorderColorInput.value, "top"); + printCode(el); + }); + + topBorderStyleSelect.addEventListener("input", () => { + setBorder(el, "style", topBorderStyleSelect.value, "top"); + printCode(el); + }); + + topBorderUnitSelect.addEventListener("input", () => { + setBorder( + el, + "width", + `${topBorderWidthInput.value}${topBorderUnitSelect.value}`, + "top" + ); + printCode(el); + }); + + topBorderWidthInput.addEventListener("input", () => { + setBorder( + el, + "width", + `${topBorderWidthInput.value}${topBorderUnitSelect.value}`, + "top" + ); + printCode(el); + }); +} + +/** + * Set the right border to the given element. + * @param {HTMLElement} el - Apply the right border to this element. + */ +function setRightBorder(el) { + const rightBorderWidthInput = document.getElementById("border-right-width"); + const rightBorderUnitSelect = document.getElementById("border-right-unit"); + const rightBorderStyleSelect = document.getElementById("border-right-style"); + const rightBorderColorInput = document.getElementById("border-right-color"); + + setBorder(el, "color", rightBorderColorInput.value, "right"); + setBorder(el, "style", rightBorderStyleSelect.value, "right"); + setBorder( + el, + "width", + `${rightBorderWidthInput.value}${rightBorderUnitSelect.value}`, + "right" + ); + + rightBorderColorInput.addEventListener("input", () => { + setBorder(el, "color", rightBorderColorInput.value, "right"); + printCode(el); + }); + + rightBorderStyleSelect.addEventListener("input", () => { + setBorder(el, "style", rightBorderStyleSelect.value, "right"); + printCode(el); + }); + + rightBorderUnitSelect.addEventListener("input", () => { + setBorder( + el, + "width", + `${rightBorderWidthInput.value}${rightBorderUnitSelect.value}`, + "right" + ); + printCode(el); + }); + + rightBorderWidthInput.addEventListener("input", () => { + setBorder( + el, + "width", + `${rightBorderWidthInput.value}${rightBorderUnitSelect.value}`, + "right" + ); + printCode(el); + }); +} + +/** + * Set the bottom border to the given element. + * @param {HTMLElement} el - Apply the bottom border to this element. + */ +function setBottomBorder(el) { + const bottomBorderWidthInput = document.getElementById("border-bottom-width"); + const bottomBorderUnitSelect = document.getElementById("border-bottom-unit"); + const bottomBorderStyleSelect = document.getElementById( + "border-bottom-style" + ); + const bottomBorderColorInput = document.getElementById("border-bottom-color"); + + setBorder(el, "color", bottomBorderColorInput.value, "bottom"); + setBorder(el, "style", bottomBorderStyleSelect.value, "bottom"); + setBorder( + el, + "width", + `${bottomBorderWidthInput.value}${bottomBorderUnitSelect.value}`, + "bottom" + ); + + bottomBorderColorInput.addEventListener("input", () => { + setBorder(el, "color", bottomBorderColorInput.value, "bottom"); + printCode(el); + }); + + bottomBorderStyleSelect.addEventListener("input", () => { + setBorder(el, "style", bottomBorderStyleSelect.value, "bottom"); + printCode(el); + }); + + bottomBorderUnitSelect.addEventListener("input", () => { + setBorder( + el, + "width", + `${bottomBorderWidthInput.value}${bottomBorderUnitSelect.value}`, + "bottom" + ); + printCode(el); + }); + + bottomBorderWidthInput.addEventListener("input", () => { + setBorder( + el, + "width", + `${bottomBorderWidthInput.value}${bottomBorderUnitSelect.value}`, + "bottom" + ); + printCode(el); + }); +} + +/** + * Set the left border to the given element. + * @param {HTMLElement} el - Apply the left border to this element. + */ +function setLeftBorder(el) { + const leftBorderWidthInput = document.getElementById("border-left-width"); + const leftBorderUnitSelect = document.getElementById("border-left-unit"); + const leftBorderStyleSelect = document.getElementById("border-left-style"); + const leftBorderColorInput = document.getElementById("border-left-color"); + + setBorder(el, "color", leftBorderColorInput.value, "left"); + setBorder(el, "style", leftBorderStyleSelect.value, "left"); + setBorder( + el, + "width", + `${leftBorderWidthInput.value}${leftBorderUnitSelect.value}`, + "left" + ); + + leftBorderColorInput.addEventListener("input", () => { + setBorder(el, "color", leftBorderColorInput.value, "left"); + printCode(el); + }); + + leftBorderStyleSelect.addEventListener("input", () => { + setBorder(el, "style", leftBorderStyleSelect.value, "left"); + printCode(el); + }); + + leftBorderUnitSelect.addEventListener("input", () => { + setBorder( + el, + "width", + `${leftBorderWidthInput.value}${leftBorderUnitSelect.value}`, + "left" + ); + printCode(el); + }); + + leftBorderWidthInput.addEventListener("input", () => { + setBorder( + el, + "width", + `${leftBorderWidthInput.value}${leftBorderUnitSelect.value}`, + "left" + ); + printCode(el); + }); +} + +/** + * Set all borders radius to the given element. + * @param {HTMLElement} el - Apply the border radius to this element. + */ +function setCommonBorderRadius(el) { + const borderCommonFirstRadius = document.getElementById( + "borders-first-radius" + ); + const borderCommonFirstRadiusUnit = document.getElementById( + "borders-first-radius-unit" + ); + const borderCommonSecondRadius = document.getElementById( + "borders-second-radius" + ); + const borderCommonSecondRadiusUnit = document.getElementById( + "borders-second-radius-unit" + ); + let firstRadius = `${borderCommonFirstRadius.value}${borderCommonFirstRadiusUnit.value}`; + let secondRadius = borderCommonSecondRadius.value + ? `${borderCommonSecondRadius.value}${borderCommonSecondRadiusUnit.value}` + : null; + + setBorderRadius(el, firstRadius, secondRadius); + + borderCommonFirstRadius.addEventListener("input", () => { + firstRadius = `${borderCommonFirstRadius.value}${borderCommonFirstRadiusUnit.value}`; + setBorderRadius(el, firstRadius, secondRadius); + printCode(el); + }); + + borderCommonFirstRadiusUnit.addEventListener("input", () => { + firstRadius = `${borderCommonFirstRadius.value}${borderCommonFirstRadiusUnit.value}`; + setBorderRadius(el, firstRadius, secondRadius); + printCode(el); + }); + + borderCommonSecondRadius.addEventListener("input", () => { + secondRadius = borderCommonSecondRadius.value + ? `${borderCommonSecondRadius.value}${borderCommonSecondRadiusUnit.value}` + : null; + setBorderRadius(el, firstRadius, secondRadius); + printCode(el); + }); + + borderCommonSecondRadiusUnit.addEventListener("input", () => { + secondRadius = borderCommonSecondRadius.value + ? `${borderCommonSecondRadius.value}${borderCommonSecondRadiusUnit.value}` + : null; + setBorderRadius(el, firstRadius, secondRadius); + printCode(el); + }); +} + +/** + * Set the top left border-radius to the given element. + * @param {HTMLElement} el - Apply the top left border-radius to this element. + */ +function setTopLeftBorderRadius(el) { + const borderTopLeftFirstRadius = document.getElementById( + "border-top-left-first-radius" + ); + const borderTopLeftFirstRadiusUnit = document.getElementById( + "border-top-left-first-radius-unit" + ); + const borderTopLeftSecondRadius = document.getElementById( + "border-top-left-second-radius" + ); + const borderTopLeftSecondRadiusUnit = document.getElementById( + "border-top-left-second-radius-unit" + ); + let firstRadius = `${borderTopLeftFirstRadius.value}${borderTopLeftFirstRadiusUnit.value}`; + let secondRadius = borderTopLeftSecondRadius.value + ? `${borderTopLeftSecondRadius.value}${borderTopLeftSecondRadiusUnit.value}` + : null; + + setBorderRadius(el, firstRadius, secondRadius, "left", "top"); + + borderTopLeftFirstRadius.addEventListener("input", () => { + firstRadius = `${borderTopLeftFirstRadius.value}${borderTopLeftFirstRadiusUnit.value}`; + setBorderRadius(el, firstRadius, secondRadius, "left", "top"); + printCode(el); + }); + + borderTopLeftFirstRadiusUnit.addEventListener("input", () => { + firstRadius = `${borderTopLeftFirstRadius.value}${borderTopLeftFirstRadiusUnit.value}`; + setBorderRadius(el, firstRadius, secondRadius, "left", "top"); + printCode(el); + }); + + borderTopLeftSecondRadius.addEventListener("input", () => { + secondRadius = borderTopLeftSecondRadius.value + ? `${borderTopLeftSecondRadius.value}${borderTopLeftSecondRadiusUnit.value}` + : null; + setBorderRadius(el, firstRadius, secondRadius, "left", "top"); + printCode(el); + }); + + borderTopLeftSecondRadiusUnit.addEventListener("input", () => { + secondRadius = borderTopLeftSecondRadius.value + ? `${borderTopLeftSecondRadius.value}${borderTopLeftSecondRadiusUnit.value}` + : null; + setBorderRadius(el, firstRadius, secondRadius, "left", "top"); + printCode(el); + }); +} + +/** + * Set the top right border-radius to the given element. + * @param {HTMLElement} el - Apply the top right border-radius to this element. + */ +function setTopRightBorderRadius(el) { + const borderTopRightFirstRadius = document.getElementById( + "border-top-right-first-radius" + ); + const borderTopRightFirstRadiusUnit = document.getElementById( + "border-top-right-first-radius-unit" + ); + const borderTopRightSecondRadius = document.getElementById( + "border-top-right-second-radius" + ); + const borderTopRightSecondRadiusUnit = document.getElementById( + "border-top-right-second-radius-unit" + ); + const firstRadius = `${borderTopRightFirstRadius.value}${borderTopRightFirstRadiusUnit.value}`; + const secondRadius = borderTopRightSecondRadius.value + ? `${borderTopRightSecondRadius.value}${borderTopRightSecondRadiusUnit.value}` + : null; + + setBorderRadius(el, firstRadius, secondRadius, "right", "top"); + + borderTopRightFirstRadius.addEventListener("input", () => { + firstRadius = `${borderTopRightFirstRadius.value}${borderTopRightFirstRadiusUnit.value}`; + setBorderRadius(el, firstRadius, secondRadius, "right", "top"); + printCode(el); + }); + + borderTopRightFirstRadiusUnit.addEventListener("input", () => { + firstRadius = `${borderTopRightFirstRadius.value}${borderTopRightFirstRadiusUnit.value}`; + setBorderRadius(el, firstRadius, secondRadius, "right", "top"); + printCode(el); + }); + + borderTopRightSecondRadius.addEventListener("input", () => { + secondRadius = borderTopRightSecondRadius.value + ? `${borderTopRightSecondRadius.value}${borderTopRightSecondRadiusUnit.value}` + : null; + setBorderRadius(el, firstRadius, secondRadius, "right", "top"); + printCode(el); + }); + + borderTopRightSecondRadiusUnit.addEventListener("input", () => { + secondRadius = borderTopRightSecondRadius.value + ? `${borderTopRightSecondRadius.value}${borderTopRightSecondRadiusUnit.value}` + : null; + setBorderRadius(el, firstRadius, secondRadius, "right", "top"); + printCode(el); + }); +} + +/** + * Set the bottom left border-radius to the given element. + * @param {HTMLElement} el - Apply bottom left border-radius to this element. + */ +function setBottomLeftBorderRadius(el) { + const borderBottomLeftFirstRadius = document.getElementById( + "border-bottom-left-first-radius" + ); + const borderBottomLeftFirstRadiusUnit = document.getElementById( + "border-bottom-left-first-radius-unit" + ); + const borderBottomLeftSecondRadius = document.getElementById( + "border-bottom-left-second-radius" + ); + const borderBottomLeftSecondRadiusUnit = document.getElementById( + "border-bottom-left-second-radius-unit" + ); + const firstRadius = `${borderBottomLeftFirstRadius.value}${borderBottomLeftFirstRadiusUnit.value}`; + const secondRadius = borderBottomLeftSecondRadius.value + ? `${borderBottomLeftSecondRadius.value}${borderBottomLeftSecondRadiusUnit.value}` + : null; + + setBorderRadius(el, firstRadius, secondRadius, "left", "bottom"); + + borderBottomLeftFirstRadius.addEventListener("input", () => { + firstRadius = `${borderBottomLeftFirstRadius.value}${borderBottomLeftFirstRadiusUnit.value}`; + setBorderRadius(el, firstRadius, secondRadius, "left", "bottom"); + printCode(el); + }); + + borderBottomLeftFirstRadiusUnit.addEventListener("input", () => { + firstRadius = `${borderBottomLeftFirstRadius.value}${borderBottomLeftFirstRadiusUnit.value}`; + setBorderRadius(el, firstRadius, secondRadius, "left", "bottom"); + printCode(el); + }); + + borderBottomLeftSecondRadius.addEventListener("input", () => { + secondRadius = borderBottomLeftSecondRadius.value + ? `${borderBottomLeftSecondRadius.value}${borderBottomLeftSecondRadiusUnit.value}` + : null; + setBorderRadius(el, firstRadius, secondRadius, "left", "bottom"); + printCode(el); + }); + + borderBottomLeftSecondRadiusUnit.addEventListener("input", () => { + secondRadius = borderBottomLeftSecondRadius.value + ? `${borderBottomLeftSecondRadius.value}${borderBottomLeftSecondRadiusUnit.value}` + : null; + setBorderRadius(el, firstRadius, secondRadius, "left", "bottom"); + printCode(el); + }); +} + +/** + * Set the bottom right border-radius to the given element. + * @param {HTMLElement} el - Apply bottom right border-radius to this element. + */ +function setBottomRightBorderRadius(el) { + const borderBottomRightFirstRadius = document.getElementById( + "border-bottom-right-first-radius" + ); + const borderBottomRightFirstRadiusUnit = document.getElementById( + "border-bottom-right-first-radius-unit" + ); + const borderBottomRightSecondRadius = document.getElementById( + "border-bottom-right-second-radius" + ); + const borderBottomRightSecondRadiusUnit = document.getElementById( + "border-bottom-right-second-radius-unit" + ); + const firstRadius = `${borderBottomRightFirstRadius.value}${borderBottomRightFirstRadiusUnit.value}`; + const secondRadius = borderBottomRightSecondRadius.value + ? `${borderBottomRightSecondRadius.value}${borderBottomRightSecondRadiusUnit.value}` + : null; + + setBorderRadius(el, firstRadius, secondRadius, "right", "bottom"); + + borderBottomRightFirstRadius.addEventListener("input", () => { + firstRadius = `${borderBottomRightFirstRadius.value}${borderBottomRightFirstRadiusUnit.value}`; + setBorderRadius(el, firstRadius, secondRadius, "right", "bottom"); + printCode(el); + }); + + borderBottomRightFirstRadiusUnit.addEventListener("input", () => { + firstRadius = `${borderBottomRightFirstRadius.value}${borderBottomRightFirstRadiusUnit.value}`; + setBorderRadius(el, firstRadius, secondRadius, "right", "bottom"); + printCode(el); + }); + + borderBottomRightSecondRadius.addEventListener("input", () => { + secondRadius = borderBottomRightSecondRadius.value + ? `${borderBottomRightSecondRadius.value}${borderBottomRightSecondRadiusUnit.value}` + : null; + setBorderRadius(el, firstRadius, secondRadius, "right", "bottom"); + printCode(el); + }); + + borderBottomRightSecondRadiusUnit.addEventListener("input", () => { + secondRadius = borderBottomRightSecondRadius.value + ? `${borderBottomRightSecondRadius.value}${borderBottomRightSecondRadiusUnit.value}` + : null; + setBorderRadius(el, firstRadius, secondRadius, "right", "bottom"); + printCode(el); + }); +} + +/** + * Display a message inside the given element. + * @param {HTMLElement} el - The element where to print the message. + * @param {String} msg - The message to display. + * @param {Number} [duration] - The message duration. + */ +function printMessage(el, msg, duration = 1000) { + const backupContent = el.textContent; + + el.textContent = msg; + setTimeout(() => (el.textContent = backupContent), duration); +} + +/** + * Copy code to the clipboard. + */ +function copyCode() { + const code = document.querySelector(".result__code"); + navigator.clipboard.writeText(code.textContent); +} + +/** + * Listen the button copy to clipboard. + */ +function listenCopyCodeBtn() { + const btn = document.getElementById("copy-code"); + + btn.addEventListener("click", () => { + copyCode(); + printMessage(btn, "Copied to clipboard!"); + }); +} + +/** + * Initialize borders settings and borders. + * @param {String} radioValue - The input radio value. + * @param {HTMLElement} el - The element where to apply borders. + */ +function initBorders(radioValue, el) { + if (isIndividualSettings(radioValue)) { + toggleBorderSettingsDisplay("individual"); + setTopBorder(el); + setRightBorder(el); + setBottomBorder(el); + setLeftBorder(el); + } else { + toggleBorderSettingsDisplay("common"); + setCommonBorder(el); + } +} + +/** + * Initialize border-radius settings and border-radius. + * @param {String} radioValue - The input radio value. + * @param {HTMLElement} el - The element where to apply border-radius. + */ +function initBordersRadius(radioValue, el) { + if (isIndividualSettings(radioValue)) { + toggleBorderRadiusSettingsDisplay("individual"); + setTopLeftBorderRadius(el); + setTopRightBorderRadius(el); + setBottomLeftBorderRadius(el); + setBottomRightBorderRadius(el); + } else { + toggleBorderRadiusSettingsDisplay("common"); + setCommonBorderRadius(el); + } +} + +/** + * Initialize the app. + */ +function init() { + const box = document.querySelector(".box"); + const borderPropertyRadio = document.querySelectorAll( + 'input[name="border-property"]' + ); + const borderRadiusPropertyRadio = document.querySelectorAll( + 'input[name="border-radius-property"]' + ); + + for (const radio of borderPropertyRadio) { + if (radio.checked) initBorders(radio.value, box); + radio.addEventListener("change", () => initBorders(radio.value, box)); + } + + for (const radio of borderRadiusPropertyRadio) { + if (radio.checked) initBordersRadius(radio.value, box); + radio.addEventListener("change", () => initBordersRadius(radio.value, box)); + } + + printCode(box); + listenCopyCodeBtn(); +} + +init(); diff --git a/public/projects/js-small-apps/css-border-previewer/index.html b/public/projects/js-small-apps/css-border-previewer/index.html new file mode 100644 index 0000000..bf16fa5 --- /dev/null +++ b/public/projects/js-small-apps/css-border-previewer/index.html @@ -0,0 +1,625 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="UTF-8" /> + <meta http-equiv="X-UA-Compatible" content="IE=edge" /> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <title>CSS Border Previewer</title> + <link rel="stylesheet" href="style.css" /> + </head> + <body> + <header class="header"> + <h1 class="branding">CSS Border Previewer</h1> + </header> + <main class="main"> + <div class="preview"> + <div class="box"></div> + </div> + <form action="#" method="POST" class="settings form"> + <fieldset class="form__fieldset"> + <legend class="form__legend">Global settings</legend> + <div class="form__item"> + Control border property separately? + <input + type="radio" + name="border-property" + id="border-property-no" + value="false" + checked + /> + <label for="border-property-no">No</label> + <input + type="radio" + name="border-property" + id="border-property-yes" + value="true" + /> + <label for="border-property-yes">Yes</label> + </div> + <div class="form__item"> + Control border radius property separately? + <input + type="radio" + name="border-radius-property" + id="border-radius-property-no" + value="false" + checked + /> + <label for="border-radius-property-no">No</label> + <input + type="radio" + name="border-radius-property" + id="border-radius-property-yes" + value="true" + /> + <label for="border-radius-property-yes">Yes</label> + </div> + </fieldset> + <fieldset + id="fieldset-borders" + class="form__fieldset form__fieldset--flex" + > + <legend class="form__legend">Borders settings</legend> + <div class="form__item form__item--flex"> + <label for="borders-width">Width</label> + <input + type="number" + name="borders-width" + id="borders-width" + size="3" + value="1" + class="form__input" + /> + </div> + <div class="form__item form__item--flex"> + <label for="borders-unit" class="form__label">Unit</label> + <select name="borders-unit" id="borders-unit" class="form__select"> + <option value="px" selected>px</option> + <option value="cm">cm</option> + <option value="em">em</option> + <option value="rem">rem</option> + </select> + </div> + <div class="form__item form__item--flex"> + <label for="borders-style">Style</label> + <select + name="borders-style" + id="borders-style" + class="form__select" + > + <option value="none">None</option> + <option value="dashed">Dashed</option> + <option value="dotted">Dotted</option> + <option value="double">Double</option> + <option value="groove">Groove</option> + <option value="hidden">Hidden</option> + <option value="inset">Inset</option> + <option value="outset">Outset</option> + <option value="ridge">Ridge</option> + <option value="solid" selected>Solid</option> + </select> + </div> + <div class="form__item form__item--flex"> + <label for="borders-color">Color</label> + <input + type="color" + name="borders-color" + id="borders-color" + value="#000000" + class="form__input form__input--color" + /> + </div> + </fieldset> + <fieldset + id="fieldset-border-top" + class="form__fieldset form__fieldset--flex" + > + <legend class="form__legend">Border-top settings</legend> + <div class="form__item form__item--flex"> + <label for="border-top-width">Width</label> + <input + type="number" + name="border-top-width" + id="border-top-width" + size="3" + value="1" + class="form__input" + /> + </div> + <div class="form__item form__item--flex"> + <label for="border-top-unit" class="form__label">Unit</label> + <select + name="border-top-unit" + id="border-top-unit" + class="form__select" + > + <option value="px" selected>px</option> + <option value="cm">cm</option> + <option value="em">em</option> + <option value="rem">rem</option> + </select> + </div> + <div class="form__item form__item--flex"> + <label for="border-top-style">Style</label> + <select + name="border-top-style" + id="border-top-style" + class="form__select" + > + <option value="none">None</option> + <option value="dashed">Dashed</option> + <option value="dotted">Dotted</option> + <option value="double">Double</option> + <option value="groove">Groove</option> + <option value="hidden">Hidden</option> + <option value="inset">Inset</option> + <option value="outset">Outset</option> + <option value="ridge">Ridge</option> + <option value="solid" selected>Solid</option> + </select> + </div> + <div class="form__item form__item--flex"> + <label for="border-top-color">Color</label> + <input + type="color" + name="border-top-color" + id="border-top-color" + value="#000000" + class="form__input form__input--color" + /> + </div> + </fieldset> + <fieldset + id="fieldset-border-right" + class="form__fieldset form__fieldset--flex" + > + <legend class="form__legend">Border-right settings</legend> + <div class="form__item form__item--flex"> + <label for="border-right-width">Width</label> + <input + type="number" + name="border-right-width" + id="border-right-width" + size="3" + value="1" + class="form__input" + /> + </div> + <div class="form__item form__item--flex"> + <label for="border-right-unit" class="form__label">Unit</label> + <select + name="border-right-unit" + id="border-right-unit" + class="form__select" + > + <option value="px" selected>px</option> + <option value="cm">cm</option> + <option value="em">em</option> + <option value="rem">rem</option> + </select> + </div> + <div class="form__item form__item--flex"> + <label for="border-right-style">Style</label> + <select + name="border-right-style" + id="border-right-style" + class="form__select" + > + <option value="none">None</option> + <option value="dashed">Dashed</option> + <option value="dotted">Dotted</option> + <option value="double">Double</option> + <option value="groove">Groove</option> + <option value="hidden">Hidden</option> + <option value="inset">Inset</option> + <option value="outset">Outset</option> + <option value="ridge">Ridge</option> + <option value="solid" selected>Solid</option> + </select> + </div> + <div class="form__item form__item--flex"> + <label for="border-right-color">Color</label> + <input + type="color" + name="border-right-color" + id="border-right-color" + value="#000000" + class="form__input form__input--color" + /> + </div> + </fieldset> + <fieldset + id="fieldset-border-bottom" + class="form__fieldset form__fieldset--flex" + > + <legend class="form__legend">Border-bottom settings</legend> + <div class="form__item form__item--flex"> + <label for="border-bottom-width">Width</label> + <input + type="number" + name="border-bottom-width" + id="border-bottom-width" + size="3" + value="1" + class="form__input" + /> + </div> + <div class="form__item form__item--flex"> + <label for="border-bottom-unit" class="form__label">Unit</label> + <select + name="border-bottom-unit" + id="border-bottom-unit" + class="form__select" + > + <option value="px" selected>px</option> + <option value="cm">cm</option> + <option value="em">em</option> + <option value="rem">rem</option> + </select> + </div> + <div class="form__item form__item--flex"> + <label for="border-bottom-style">Style</label> + <select + name="border-bottom-style" + id="border-bottom-style" + class="form__select" + > + <option value="none">None</option> + <option value="dashed">Dashed</option> + <option value="dotted">Dotted</option> + <option value="double">Double</option> + <option value="groove">Groove</option> + <option value="hidden">Hidden</option> + <option value="inset">Inset</option> + <option value="outset">Outset</option> + <option value="ridge">Ridge</option> + <option value="solid" selected>Solid</option> + </select> + </div> + <div class="form__item form__item--flex"> + <label for="border-bottom-color">Color</label> + <input + type="color" + name="border-bottom-color" + id="border-bottom-color" + value="#000000" + class="form__input form__input--color" + /> + </div> + </fieldset> + <fieldset + id="fieldset-border-left" + class="form__fieldset form__fieldset--flex" + > + <legend class="form__legend">Border-left settings</legend> + <div class="form__item form__item--flex"> + <label for="border-left-width">Width</label> + <input + type="number" + name="border-left-width" + id="border-left-width" + size="3" + value="1" + class="form__input" + /> + </div> + <div class="form__item form__item--flex"> + <label for="border-left-unit" class="form__label">Unit</label> + <select + name="border-left-unit" + id="border-left-unit" + class="form__select" + > + <option value="px" selected>px</option> + <option value="cm">cm</option> + <option value="em">em</option> + <option value="rem">rem</option> + </select> + </div> + <div class="form__item form__item--flex"> + <label for="border-left-style">Style</label> + <select + name="border-left-style" + id="border-left-style" + class="form__select" + > + <option value="none">None</option> + <option value="dashed">Dashed</option> + <option value="dotted">Dotted</option> + <option value="double">Double</option> + <option value="groove">Groove</option> + <option value="hidden">Hidden</option> + <option value="inset">Inset</option> + <option value="outset">Outset</option> + <option value="ridge">Ridge</option> + <option value="solid" selected>Solid</option> + </select> + </div> + <div class="form__item form__item--flex"> + <label for="border-left-color">Color</label> + <input + type="color" + name="border-left-color" + id="border-left-color" + value="#000000" + class="form__input form__input--color" + /> + </div> + </fieldset> + <fieldset id="fieldset-borders-radius" class="form__fieldset"> + <legend class="form__legend">Border-radius settings</legend> + <div class="form__item"> + <p>First radius:</p> + <label for="borders-first-radius">Value</label> + <input + type="number" + name="borders-first-radius" + id="borders-first-radius" + class="form__input" + /> + <label for="borders-first-radius-unit" class="form__label" + >Unit</label + > + <select + name="borders-first-radius-unit" + id="borders-first-radius-unit" + class="form__select" + > + <option value="px" selected>px</option> + <option value="%">%</option> + <option value="em">em</option> + <option value="rem">rem</option> + </select> + </div> + <div class="form__item"> + <p>Second radius:</p> + <label for="borders-second-radius">Value</label> + <input + type="number" + name="borders-second-radius" + id="borders-second-radius" + class="form__input" + /> + <label for="borders-second-radius-unit" class="form__label" + >Unit</label + > + <select + name="borders-second-radius-unit" + id="borders-second-radius-unit" + class="form__select" + > + <option value="px" selected>px</option> + <option value="%">%</option> + <option value="em">em</option> + <option value="rem">rem</option> + </select> + </div> + </fieldset> + <fieldset id="fieldset-border-top-left-radius" class="form__fieldset"> + <legend class="form__legend">Border-top-left-radius settings</legend> + <div class="form__item"> + <p>First radius:</p> + <label for="border-top-left-first-radius">Value</label> + <input + type="number" + name="border-top-left-first-radius" + id="border-top-left-first-radius" + class="form__input" + /> + <label for="border-top-left-first-radius-unit" class="form__label" + >Unit</label + > + <select + name="border-top-left-first-radius-unit" + id="border-top-left-first-radius-unit" + class="form__select" + > + <option value="px" selected>px</option> + <option value="%">%</option> + <option value="em">em</option> + <option value="rem">rem</option> + </select> + </div> + <div class="form__item"> + <p>Second radius:</p> + <label for="border-top-left-second-radius">Value</label> + <input + type="number" + name="border-top-left-second-radius" + id="border-top-left-second-radius" + class="form__input" + /> + <label for="border-top-left-second-radius-unit" class="form__label" + >Unit</label + > + <select + name="border-top-left-second-radius-unit" + id="border-top-left-second-radius-unit" + class="form__select" + > + <option value="px" selected>px</option> + <option value="%">%</option> + <option value="em">em</option> + <option value="rem">rem</option> + </select> + </div> + </fieldset> + <fieldset id="fieldset-border-top-right-radius" class="form__fieldset"> + <legend class="form__legend">Border-top-right-radius settings</legend> + <div class="form__item"> + <p>First radius:</p> + <label for="border-top-right-first-radius">Value</label> + <input + type="number" + name="border-top-right-first-radius" + id="border-top-right-first-radius" + class="form__input" + /> + <label for="border-top-right-first-radius-unit" class="form__label" + >Unit</label + > + <select + name="border-top-right-first-radius-unit" + id="border-top-right-first-radius-unit" + class="form__select" + > + <option value="px" selected>px</option> + <option value="%">%</option> + <option value="em">em</option> + <option value="rem">rem</option> + </select> + </div> + <div class="form__item"> + <p>Second radius:</p> + <label for="border-top-right-second-radius">Value</label> + <input + type="number" + name="border-top-right-second-radius" + id="border-top-right-second-radius" + class="form__input" + /> + <label for="border-top-right-second-radius-unit" class="form__label" + >Unit</label + > + <select + name="border-top-right-second-radius-unit" + id="border-top-right-second-radius-unit" + class="form__select" + > + <option value="px" selected>px</option> + <option value="%">%</option> + <option value="em">em</option> + <option value="rem">rem</option> + </select> + </div> + </fieldset> + <fieldset + id="fieldset-border-bottom-left-radius" + class="form__fieldset" + > + <legend class="form__legend"> + Border-bottom-left-radius settings + </legend> + <div class="form__item"> + <p>First radius:</p> + <label for="border-bottom-left-first-radius">Value</label> + <input + type="number" + name="border-bottom-left-first-radius" + id="border-bottom-left-first-radius" + class="form__input" + /> + <label + for="border-bottom-left-first-radius-unit" + class="form__label" + >Unit</label + > + <select + name="border-bottom-left-first-radius-unit" + id="border-bottom-left-first-radius-unit" + class="form__select" + > + <option value="px" selected>px</option> + <option value="%">%</option> + <option value="em">em</option> + <option value="rem">rem</option> + </select> + </div> + <div class="form__item"> + <p>Second radius:</p> + <label for="border-bottom-left-second-radius">Value</label> + <input + type="number" + name="border-bottom-left-second-radius" + id="border-bottom-left-second-radius" + class="form__input" + /> + <label + for="border-bottom-left-second-radius-unit" + class="form__label" + >Unit</label + > + <select + name="border-bottom-left-second-radius-unit" + id="border-bottom-left-second-radius-unit" + class="form__select" + > + <option value="px" selected>px</option> + <option value="%">%</option> + <option value="em">em</option> + <option value="rem">rem</option> + </select> + </div> + </fieldset> + <fieldset + id="fieldset-border-bottom-right-radius" + class="form__fieldset" + > + <legend class="form__legend"> + Border-bottom-right-radius settings + </legend> + <div class="form__item"> + <p>First radius:</p> + <label for="border-bottom-right-first-radius">Value</label> + <input + type="number" + name="border-bottom-right-first-radius" + id="border-bottom-right-first-radius" + class="form__input" + /> + <label + for="border-bottom-right-first-radius-unit" + class="form__label" + >Unit</label + > + <select + name="border-bottom-right-first-radius-unit" + id="border-bottom-right-first-radius-unit" + class="form__select" + > + <option value="px" selected>px</option> + <option value="%">%</option> + <option value="em">em</option> + <option value="rem">rem</option> + </select> + </div> + <div class="form__item"> + <p>Second radius:</p> + <label for="border-bottom-right-second-radius">Value</label> + <input + type="number" + name="border-bottom-right-second-radius" + id="border-bottom-right-second-radius" + class="form__input" + /> + <label + for="border-bottom-right-second-radius-unit" + class="form__label" + >Unit</label + > + <select + name="border-bottom-right-second-radius-unit" + id="border-bottom-right-second-radius-unit" + class="form__select" + > + <option value="px" selected>px</option> + <option value="%">%</option> + <option value="em">em</option> + <option value="rem">rem</option> + </select> + </div> + </fieldset> + </form> + <div class="result"> + <pre class="result__pre"> + <code class="result__code"></code> + </pre> + <button id="copy-code" class="btn">Copy to the clipboard</button> + </div> + </main> + <footer class="footer"> + <p class="copyright">CSS Border Previewer. MIT 2021. Armand Philippot.</p> + </footer> + <script src="app.js"></script> + </body> +</html> diff --git a/public/projects/js-small-apps/css-border-previewer/style.css b/public/projects/js-small-apps/css-border-previewer/style.css new file mode 100644 index 0000000..458d31c --- /dev/null +++ b/public/projects/js-small-apps/css-border-previewer/style.css @@ -0,0 +1,181 @@ +*, +*::after, +*::before { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +body { + background: #fff; + color: #000; + font-family: Arial, Helvetica, sans-serif; + font-size: 1rem; + line-height: 1.618; + display: flex; + flex-flow: column nowrap; + min-height: 100vh; +} + +.header, +.footer, +.result { + width: min(calc(100vw - 2rem), calc(1200px - 2rem)); + margin-left: auto; + margin-right: auto; +} + +.preview, +.settings { + width: min(calc(100vw - 2rem), calc(1200px / 2 - 2rem)); + margin-left: auto; + margin-right: auto; +} + +@media screen and (min-width: 1200px) { + .preview { + margin-right: 0; + } + + .settings { + margin-left: 0; + } +} + +.header { + padding: 2rem 0 3rem; + text-align: center; +} + +.branding { + color: hsl(219, 64%, 35%); +} + +.main { + flex: 1; + display: flex; + flex-flow: row wrap; + gap: 1rem; + margin: auto; +} + +.preview { + border: 1px solid #ccc; + padding: 3rem; + position: relative; +} + +.box { + border: 1px solid #000; + width: 100%; + height: 20vh; + position: sticky; + top: 3rem; +} + +.result { + max-width: 100%; +} + +.result__pre { + background: #333; + color: #fff; + min-height: 20rem; + margin: 1rem auto; + padding: 0 1rem; + overflow-x: auto; + tab-size: 4; +} + +.result .btn { + margin: auto; +} + +@media screen and (min-width: 1440px) { + .result__pre { + margin: 1rem 0; + } +} + +.footer { + margin-top: 2rem; + padding: 1rem 0; +} + +.copyright { + font-size: 0.9rem; + text-align: center; +} + +.form p { + font-weight: 600; +} + +.form__fieldset { + border-color: hsl(219, 64%, 35%); + margin-bottom: 1rem; + padding: 0.5rem 1rem 1rem; +} + +.form__fieldset--flex { + display: flex; + flex-flow: row wrap; + gap: 1rem; +} + +.form__legend { + color: hsl(219, 64%, 35%); + font-size: 0.9rem; + font-weight: 600; + text-transform: uppercase; + padding: 0 0.5rem; +} + +.form__item--flex { + display: flex; + flex-flow: column wrap; +} + +.form__item:not(.form__item--flex) + * { + margin-top: 1rem; +} + +.form__input, +.form__select { + font-family: inherit; + font-size: inherit; + line-height: inherit; +} + +.form__input { + padding: 0.2rem 0.5rem; +} + +.form__select { + padding: 0.4rem 0.5rem; +} + +.btn { + background: #fff; + border: 2px solid hsl(219, 64%, 35%); + box-shadow: 1px 1px 2px hsl(219, 64%, 15%), 0 0 2px 1px hsl(219, 64%, 15%); + color: hsl(219, 64%, 35%); + font-family: inherit; + font-size: inherit; + font-weight: 600; + line-height: inherit; + display: block; + padding: 0.5rem; + cursor: pointer; + transition: all 0.15s ease-in-out 0s; +} + +.btn:hover, +.btn:focus { + background: hsl(219, 64%, 35%); + color: #fff; +} + +.btn:active { + transform: translateX(1px) translateY(1px); +} |
