UNPKG

itmar-block-packages

Version:

Common React components for WordPress custom blocks, now fully TypeScript-ready.

207 lines (204 loc) 13.7 kB
import { jsxs, Fragment, jsx } from 'react/jsx-runtime'; import { __ } from '@wordpress/i18n'; import { PanelColorSettings } from '@wordpress/block-editor'; import { PanelBody, RadioControl, RangeControl, PanelRow, ToggleControl } from '@wordpress/components'; import { useState, useEffect } from '@wordpress/element'; import { dispatch } from '@wordpress/data'; import { rgb16ToHsl, hslToRgb16, HexToRGB } from './hslToRgb.js'; /** * 方向と距離に基づいて、各頂点の数値を算出する */ const dirctionDigit = (direction, distance) => { // 初期値(デフォルト)を設定しておくことで、switch 漏れを防ぐ let destTopLeft = 0; let destTopRight = 0; let destBottomLeft = 0; let destBottomRight = 0; switch (direction) { case "top_left": destTopLeft = distance; destTopRight = distance; destBottomLeft = distance * -1; destBottomRight = distance * -1; break; case "top_right": destTopLeft = distance * -1; destTopRight = distance; destBottomLeft = distance; destBottomRight = distance * -1; break; case "bottom_left": destTopLeft = distance; destTopRight = distance * -1; destBottomLeft = distance * -1; destBottomRight = distance; break; case "bottom_right": destTopLeft = distance * -1; destTopRight = distance * -1; destBottomLeft = distance; destBottomRight = distance; break; case "right_bottom": destTopLeft = distance; destTopRight = distance * -1; destBottomLeft = distance * -1; destBottomRight = distance; break; case "top": destTopLeft = 0; destTopRight = 0; destBottomLeft = distance * -1; destBottomRight = distance; break; } return { topLeft: destTopLeft, topRight: destTopRight, bottomLeft: destBottomLeft, bottomRight: destBottomRight, }; }; // グラデーションの色値は通常'linear-gradient'または'radial-gradient'で始まるので、 // これらのキーワードを探すことでグラデーションかどうかを判断します。 function isGradient(colorValue) { // 1. 値が存在しない、または文字列でない場合は false if (typeof colorValue !== "string") { return false; } return (colorValue.includes("linear-gradient") || colorValue.includes("radial-gradient")); } const ShadowElm = (shadowState) => { //let baseColor; const { shadowType, spread, lateral, longitude, nomalBlur, shadowColor, blur, intensity, distance, newDirection, clayDirection, embos, opacity, depth, bdBlur, expand, glassblur, glassopa, hasOutline, baseColor, } = shadowState; //ノーマル if (shadowType === "nomal") { //boxshadowの生成 const ShadowStyle = embos === "dent" ? { style: { boxShadow: `${lateral}px ${longitude}px ${nomalBlur}px ${spread}px transparent, inset ${lateral}px ${longitude}px ${nomalBlur}px ${spread}px ${shadowColor}`, }, } : { style: { boxShadow: `${lateral}px ${longitude}px ${nomalBlur}px ${spread}px ${shadowColor}, inset ${lateral}px ${longitude}px ${nomalBlur}px ${spread}px transparent`, }, }; //Shadowのスタイルを返す return ShadowStyle; } //ニューモフィズム // --- ニューモフィズム --- else if (shadowType === "newmor") { if (isGradient(baseColor)) { dispatch("core/notices").createNotice("error", __("Neumorphism cannot be set when the background color is a gradient.", "itmar_guest_contact_block"), { type: "snackbar", isDismissible: true }); return null; } const hslValue = rgb16ToHsl(baseColor); if (!hslValue) return null; // カラー変換失敗時のガード const lightVal = Math.min(hslValue.lightness + intensity, 100); const darkVal = Math.max(hslValue.lightness - intensity, 0); const lightValue = hslToRgb16(hslValue.hue, hslValue.saturation, lightVal); const darkValue = hslToRgb16(hslValue.hue, hslValue.saturation, darkVal); const dircObj = dirctionDigit(newDirection, distance); const baseBoxShadow = embos === "swell" ? `${dircObj.topLeft}px ${dircObj.topRight}px ${blur}px ${darkValue}, ${dircObj.bottomLeft}px ${dircObj.bottomRight}px ${blur}px ${lightValue}, inset ${dircObj.topLeft}px ${dircObj.topRight}px ${blur}px transparent, inset ${dircObj.bottomLeft}px ${dircObj.bottomRight}px ${blur}px transparent` : `${dircObj.topLeft}px ${dircObj.topRight}px ${blur}px transparent, ${dircObj.bottomLeft}px ${dircObj.bottomRight}px ${blur}px transparent, inset ${dircObj.topLeft}px ${dircObj.topRight}px ${blur}px ${darkValue}, inset ${dircObj.bottomLeft}px ${dircObj.bottomRight}px ${blur}px ${lightValue}`; return { style: { border: "none", background: baseColor, boxShadow: baseBoxShadow, }, }; } // --- クレイモーフィズム --- else if (shadowType === "claymor") { if (isGradient(baseColor)) { dispatch("core/notices").createNotice("error", __("claymorphism cannot be set when the background color is a gradient.", "itmar_guest_contact_block"), { type: "snackbar", isDismissible: true }); return null; } const rgbValue = HexToRGB(baseColor); if (!rgbValue) return null; const outsetObj = dirctionDigit(clayDirection, expand); const insetObj = dirctionDigit(clayDirection, depth); return { style: { background: `rgba(255, 255, 255, ${opacity})`, backdropFilter: `blur(${bdBlur}px)`, border: "none", boxShadow: `${outsetObj.topLeft}px ${outsetObj.bottomRight}px ${expand * 2}px 0px rgba(${rgbValue.red}, ${rgbValue.green}, ${rgbValue.blue}, 0.5), inset ${insetObj.topRight}px ${insetObj.bottomLeft}px 16px 0px rgba(${rgbValue.red}, ${rgbValue.green}, ${rgbValue.blue}, 0.6), inset 0px 11px 28px 0px rgb(255, 255, 255)`, }, }; } // --- グラスモーフィズム --- else if (shadowType === "glassmor") { const glassBoxShadow = embos === "swell" ? `0 8px 12px 0 rgba( 31, 38, 135, 0.37 ), inset 0 8px 12px 0 transparent` : `0 8px 12px 0 transparent, inset 0 8px 12px 0 rgba( 31, 38, 135, 0.37 )`; return { style: { backgroundColor: `rgba(255, 255, 255, ${glassopa})`, ...(hasOutline ? { border: `1px solid rgba(255, 255, 255, 0.4)` } : {}), borderRightColor: `rgba(255, 255, 255, 0.2)`, borderBottomColor: `rgba(255, 255, 255, 0.2)`, backdropFilter: `blur(${glassblur}px)`, boxShadow: glassBoxShadow, }, }; } return null; }; const ShadowStyle = ({ shadowStyle, onChange }) => { const [shadowState, setShadowState] = useState(shadowStyle); const { shadowType, spread, lateral, longitude, nomalBlur, shadowColor, blur, intensity, distance, newDirection, clayDirection, embos, opacity, depth, bdBlur, expand, glassblur, glassopa, hasOutline, } = shadowState; //シャドーのスタイル変更と背景色変更に伴う親コンポーネントの変更 useEffect(() => { const shadowElm = ShadowElm(shadowState); if (shadowElm) onChange(shadowElm, shadowState); }, [shadowState]); // ヘルパー: ステートの一部を更新 const updateState = (partial) => { setShadowState((prev) => ({ ...prev, ...partial })); }; return (jsxs(Fragment, { children: [jsxs(PanelBody, { title: __("Shadow Type", "block-collections"), initialOpen: true, children: [jsx("div", { className: "itmar_shadow_type", children: jsx(RadioControl, { selected: shadowType, options: [ { label: __("Normal", "block-collections"), value: "nomal" }, { label: __("Neumorphism", "block-collections"), value: "newmor", }, { label: __("Claymorphism", "block-collections"), value: "claymor", }, { label: __("Glassmorphism", "block-collections"), value: "glassmor", }, ], onChange: (val) => updateState({ shadowType: val }) }) }), shadowType !== "claymor" && (jsx("div", { className: "embos", children: jsx(RadioControl, { label: __("unevenness", "block-collections"), selected: embos, options: [ { label: "Swell", value: "swell" }, { label: "Dent", value: "dent" }, ], onChange: (val) => updateState({ embos: val }) }) }))] }), shadowType === "nomal" && (jsxs(PanelBody, { title: __("Normal settings", "block-collections"), initialOpen: false, children: [jsx(RangeControl, { value: spread, label: __("Spread", "block-collections"), max: 50, min: 0, onChange: (val) => updateState({ spread: val ?? 0 }) }), jsx(RangeControl, { value: lateral, label: __("Lateral direction", "block-collections"), max: 50, min: 0, onChange: (val) => updateState({ lateral: val ?? 0 }) }), jsx(RangeControl, { value: longitude, label: __("Longitudinal direction", "block-collections"), max: 50, min: 0, onChange: (val) => updateState({ longitude: val ?? 0 }) }), jsx(RangeControl, { value: nomalBlur, label: __("Blur", "block-collections"), max: 20, min: 0, onChange: (val) => updateState({ nomalBlur: val ?? 0 }) }), jsx(PanelColorSettings, { title: __("Shadow Color Setting", "block-collections"), colorSettings: [ { value: shadowColor, label: __("Choose Shadow color", "block-collections"), onChange: (val) => updateState({ shadowColor: val || "" }), }, ] })] })), shadowType === "newmor" && (jsxs(PanelBody, { title: __("Neumorphism settings", "block-collections"), initialOpen: false, children: [jsx(RangeControl, { value: distance, label: __("Distance", "block-collections"), max: 50, min: 0, onChange: (val) => updateState({ distance: val ?? 0 }) }), jsx(RangeControl, { value: intensity, label: __("Intensity", "block-collections"), max: 100, min: 0, onChange: (val) => updateState({ intensity: val ?? 0 }) }), jsx(RangeControl, { value: blur, label: __("Blur", "block-collections"), max: 20, min: 0, onChange: (val) => updateState({ blur: val ?? 0 }) }), jsx(PanelRow, { children: jsx("div", { className: "light_direction", children: jsx(RadioControl, { selected: newDirection, options: [ { label: "Top Left", value: "top_left" }, { label: "Top Right", value: "top_right" }, { label: "Bottom Left", value: "bottom_left" }, { label: "Bottom Right", value: "bottom_right" }, ], onChange: (val) => updateState({ newDirection: val }) }) }) })] })), shadowType === "claymor" && (jsxs(PanelBody, { title: __("Claymorphism settings", "block-collections"), initialOpen: false, children: [jsx(RangeControl, { value: opacity, label: __("Opacity", "block-collections"), max: 1, min: 0, step: 0.1, onChange: (val) => updateState({ opacity: val ?? 1 }) }), jsx(RangeControl, { value: depth, label: "Depth", max: 20, min: 0, onChange: (val) => updateState({ depth: val ?? 0 }) }), jsx(RangeControl, { value: expand, label: "Expand", max: 50, min: 0, onChange: (val) => updateState({ expand: val ?? 0 }) }), jsx(RangeControl, { value: bdBlur, label: "Background Blur", max: 10, min: 0, onChange: (val) => updateState({ bdBlur: val ?? 0 }) }), jsx("div", { className: "light_direction claymor", children: jsx(RadioControl, { selected: clayDirection, options: [ { label: "Right Bottom", value: "right_bottom" }, { label: "Top Right", value: "top_right" }, { label: "Top", value: "top" }, ], onChange: (val) => updateState({ clayDirection: val }) }) })] })), shadowType === "glassmor" && (jsxs(PanelBody, { title: __("Grassmophism settings", "block-collections"), initialOpen: false, children: [jsx(RangeControl, { value: glassblur, label: __("Glass blur", "block-collections"), max: 20, min: 0, onChange: (val) => updateState({ glassblur: val ?? 0 }) }), jsx(RangeControl, { value: glassopa, label: __("Glass Opacity", "block-collections"), max: 1, min: 0, step: 0.1, onChange: (val) => updateState({ glassopa: val ?? 0.5 }) }), jsx(ToggleControl, { label: __("Show outline", "block-collections"), checked: hasOutline, onChange: (val) => updateState({ hasOutline: val }) })] }))] })); }; export { ShadowElm, ShadowStyle as default }; //# sourceMappingURL=ShadowStyle.js.map