diff --git a/.eslintrc b/.eslintrc index 3f69276..59bbe1a 100644 --- a/.eslintrc +++ b/.eslintrc @@ -10,16 +10,6 @@ "babel", "react" ], - "settings": { - "import/resolver": { - "node": { - "paths": ["node_modules"] - }, - "webpack": { - "config": "webpack.config.js" - } - } - }, "env": { "browser": true, "node": true, @@ -62,5 +52,15 @@ "count": 1 }] }, + "settings": { + "import/resolver": { + "node": { + "paths": ["node_modules"] + }, + "webpack": { + "config": "webpack.config.js" + } + } + }, "parser": "@babel/eslint-parser" } diff --git a/modules/settings/assets/css/style.css b/modules/settings/assets/css/style.css index 8fa3d9b..724999c 100644 --- a/modules/settings/assets/css/style.css +++ b/modules/settings/assets/css/style.css @@ -15,7 +15,7 @@ html:not([dir='rtl']) #ea11y-app { html[dir='rtl'] #ea11y-app { margin-right: -20px; background: white; - height: calc(100vh - 32px); + height: calc( 100vh - 32px ); } #ea11y-app * { diff --git a/modules/settings/assets/js/app.js b/modules/settings/assets/js/app.js index 9a6cad7..502d802 100644 --- a/modules/settings/assets/js/app.js +++ b/modules/settings/assets/js/app.js @@ -8,13 +8,17 @@ import { Notifications, MenuItems, AdminTopBar, - BottomBar, } from '@ea11y/components'; -import { useNotificationSettings, useSettings } from '@ea11y/hooks'; +import { + useNotificationSettings, + useSettings, + useSavedSettings, +} from '@ea11y/hooks'; import { usePluginSettingsContext } from './contexts/plugin-settings'; import { Sidebar } from './layouts/sidebar'; const App = () => { + useSavedSettings(); const { isConnected } = usePluginSettingsContext(); const { notificationMessage, notificationType } = useNotificationSettings(); const { selectedMenu } = useSettings(); @@ -37,10 +41,7 @@ const App = () => { justifyContent="space-between" > - - {selectedChild ? selectedChild.page : selectedParent?.page} - - + {selectedChild ? selectedChild.page : selectedParent?.page} diff --git a/modules/settings/assets/js/components/admin-top-bar/index.js b/modules/settings/assets/js/components/admin-top-bar/index.js index ff92671..b92cfd8 100644 --- a/modules/settings/assets/js/components/admin-top-bar/index.js +++ b/modules/settings/assets/js/components/admin-top-bar/index.js @@ -5,7 +5,7 @@ import Toolbar from '@elementor/ui/Toolbar'; import { __ } from '@wordpress/i18n'; import { HELP_LINK } from '../../constants'; -export const AdminTopBar = () => { +const AdminTopBar = () => { const toolBarStyle = { justifyContent: 'end', alignItems: 'center', @@ -30,3 +30,5 @@ export const AdminTopBar = () => { ); }; + +export default AdminTopBar; diff --git a/modules/settings/assets/js/components/alignment-matrix-control/index.js b/modules/settings/assets/js/components/alignment-matrix-control/index.js index feecb05..7186ccf 100644 --- a/modules/settings/assets/js/components/alignment-matrix-control/index.js +++ b/modules/settings/assets/js/components/alignment-matrix-control/index.js @@ -2,68 +2,89 @@ import Box from '@elementor/ui/Box'; import FormControl from '@elementor/ui/FormControl'; import FormControlLabel from '@elementor/ui/FormControlLabel'; import FormLabel from '@elementor/ui/FormLabel'; +import Paper from '@elementor/ui/Paper'; import Radio from '@elementor/ui/Radio'; import RadioGroup from '@elementor/ui/RadioGroup'; +import Tooltip from '@elementor/ui/Tooltip'; import Typography from '@elementor/ui/Typography'; -import { useState } from '@wordpress/element'; +import { useIconPosition } from '@ea11y/hooks'; import { __ } from '@wordpress/i18n'; -const AlignmentMatrixControl = () => { - const [selectedValue, setSelectedValue] = useState('center-right'); +const AlignmentMatrixControl = ({ mode }) => { + const { iconPosition, updateIconPosition } = useIconPosition(); const handleChange = (event) => { - setSelectedValue(event.target.value); + updateIconPosition(mode, 'position', event.target.value); }; + // Define options based on the mode const options = [ { value: 'top-left', label: __('Top Left', 'pojo-accessibility') }, + ...(mode === 'desktop' + ? [{ value: 'top-center', label: __('Top Center', 'pojo-accessibility') }] + : []), { value: 'top-right', label: __('Top Right', 'pojo-accessibility') }, { value: 'center-left', label: __('Center Left', 'pojo-accessibility') }, + ...(mode === 'desktop' ? [{ value: 'empty' }] : []), { value: 'center-right', label: __('Center Right', 'pojo-accessibility') }, { value: 'bottom-left', label: __('Bottom Left', 'pojo-accessibility') }, + ...(mode === 'desktop' + ? [ + { + value: 'bottom-center', + label: __('Bottom Center', 'pojo-accessibility'), + }, + ] + : []), { value: 'bottom-right', label: __('Bottom Right', 'pojo-accessibility') }, ]; return ( - + {__('Default Position', 'pojo-accessibility')} - - - {options.map((option, i) => ( - } - /> - ))} - - + + + + + {options.map((option) => + 'empty' === option.value ? ( + + ) : ( + + } + /> + + ), + )} + + + + ); }; diff --git a/modules/settings/assets/js/components/bottom-bar/index.js b/modules/settings/assets/js/components/bottom-bar/index.js index 95cca68..02ad052 100644 --- a/modules/settings/assets/js/components/bottom-bar/index.js +++ b/modules/settings/assets/js/components/bottom-bar/index.js @@ -1,8 +1,35 @@ import Box from '@elementor/ui/Box'; import Button from '@elementor/ui/Button'; +import { useSettings, useStorage, useToastNotification } from '@ea11y/hooks'; import { __ } from '@wordpress/i18n'; -export const BottomBar = () => { +const BottomBar = () => { + const { selectedMenu, iconDesign, iconPosition, hasChanges, setHasChanges } = + useSettings(); + const { save } = useStorage(); + const { success, error } = useToastNotification(); + + const saveSettings = async () => { + if ( + selectedMenu.parent === 'widget' && + selectedMenu.child === 'iconSettings' + ) { + try { + await save({ + a11y_widget_icon_settings: { + style: iconDesign, + position: iconPosition, + }, + }); + + success('Settings saved!'); + setHasChanges(false); + } catch (e) { + error('Failed to save settings!'); + } + } + }; + return ( { width="100%" borderTop="1px solid rgba(0, 0, 0, 0.12)" > - ); }; + +export default BottomBar; diff --git a/modules/settings/assets/js/components/color-picker/index.js b/modules/settings/assets/js/components/color-picker/index.js index beecd7a..dcb502d 100644 --- a/modules/settings/assets/js/components/color-picker/index.js +++ b/modules/settings/assets/js/components/color-picker/index.js @@ -4,37 +4,36 @@ import FormLabel from '@elementor/ui/FormLabel'; import Grid from '@elementor/ui/Grid'; import Typography from '@elementor/ui/Typography'; import { HexColorPicker, HexColorInput } from 'react-colorful'; -import { useState } from '@wordpress/element'; +import { useIconDesign } from '@ea11y/hooks'; import { __ } from '@wordpress/i18n'; import './style.css'; const ColorPicker = () => { - const [color, setColor] = useState('#2563eb'); + const { iconDesign, updateIconDesign } = useIconDesign(); return ( - + - + {__('Color', 'pojo-accessibility')} updateIconDesign({ color: value })} className="widget-settings-color-picker" /> updateIconDesign({ color: value })} style={{ width: '100%', border: '1px solid rgba(0, 0, 0, 0.12)', diff --git a/modules/settings/assets/js/components/color-picker/style.css b/modules/settings/assets/js/components/color-picker/style.css index 3025ab6..05d5733 100644 --- a/modules/settings/assets/js/components/color-picker/style.css +++ b/modules/settings/assets/js/components/color-picker/style.css @@ -1,5 +1,5 @@ .widget-settings-color-picker.react-colorful { - min-width: 460px; + width: 100%; } .widget-settings-color-picker .react-colorful__saturation { border-radius: 0; diff --git a/modules/settings/assets/js/components/icon-select/index.js b/modules/settings/assets/js/components/icon-select/index.js index bf8db60..a025019 100644 --- a/modules/settings/assets/js/components/icon-select/index.js +++ b/modules/settings/assets/js/components/icon-select/index.js @@ -4,44 +4,13 @@ import Paper from '@elementor/ui/Paper'; import Radio from '@elementor/ui/Radio'; import RadioGroup from '@elementor/ui/RadioGroup'; import Typography from '@elementor/ui/Typography'; -import { - AccessibilityControlsIcon, - AccessibilityEyeIcon, - AccessibilityPersonIcon, - AccessibilityTextIcon, -} from '@ea11y/icons'; -import { useState } from '@wordpress/element'; +import { useIconDesign } from '@ea11y/hooks'; +import { cloneElement } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; +import options from '../../helpers/accessibility-options'; const IconSelect = (props) => { - const [selectedValue, setSelectedValue] = useState('person'); - const optionStyle = { - color: 'info.main', - fontSize: 44, - }; - - const options = [ - { - value: 'person', - icon: , - label: __('Accessibility Person Icon', 'pojo-accessibility'), - }, - { - value: 'eye', - icon: , - label: __('Accessibility Eye Icon', 'pojo-accessibility'), - }, - { - value: 'text', - icon: , - label: __('Accessibility Text Badge Icon', 'pojo-accessibility'), - }, - { - value: 'controls', - icon: , - label: __('Accessibility Controls Slider Icon', 'pojo-accessibility'), - }, - ]; + const { iconDesign, updateIconDesign } = useIconDesign(); return ( @@ -54,10 +23,11 @@ const IconSelect = (props) => { {...props} aria-labelledby="icon-select-radio-buttons-group-label" name="icon-select-radio-buttons-group" - value={selectedValue} + value={iconDesign.icon} sx={{ display: 'flex', flexDirection: 'row', + flexWrap: 'nowrap', gap: 2, }} > @@ -65,7 +35,7 @@ const IconSelect = (props) => { setSelectedValue(option.value)} + onClick={() => updateIconDesign({ icon: option.value })} sx={{ borderRadius: 'md', boxShadow: 'sm', @@ -76,21 +46,21 @@ const IconSelect = (props) => { justifyContent: 'center', gap: 1.5, p: 2, - minWidth: 100, + minWidth: 10, minHeight: 100, borderColor: - selectedValue === option.value ? 'info.main' : 'divider', - borderWidth: selectedValue === option.value ? 2 : 1, + iconDesign.icon === option.value ? 'info.main' : 'divider', + borderWidth: iconDesign.icon === option.value ? 2 : 1, cursor: 'pointer', }} > - {option.icon} + {option.icon && + cloneElement(option.icon, { + sx: { color: iconDesign.color, fontSize: 44 }, + })} ))} diff --git a/modules/settings/assets/js/components/icon-size/index.js b/modules/settings/assets/js/components/icon-size/index.js index b509684..b5b7709 100644 --- a/modules/settings/assets/js/components/icon-size/index.js +++ b/modules/settings/assets/js/components/icon-size/index.js @@ -4,48 +4,32 @@ import Paper from '@elementor/ui/Paper'; import Radio from '@elementor/ui/Radio'; import RadioGroup from '@elementor/ui/RadioGroup'; import Typography from '@elementor/ui/Typography'; -import { - AccessibilityEyeIcon, - AccessibilityPersonIcon, - AccessibilityTextIcon, -} from '@ea11y/icons'; -import { useState } from '@wordpress/element'; +import { useIconDesign } from '@ea11y/hooks'; +import { cloneElement } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; +import { getOptionByValue } from '../../helpers/accessibility-options'; const IconSize = (props) => { - const [selectedValue, setSelectedValue] = useState('medium'); - const optionStyle = { color: 'info.main', fontSize: 44 }; + const { iconDesign, updateIconDesign } = useIconDesign(); + const icon = getOptionByValue(iconDesign.icon); const options = [ - { - value: 'small', - icon: , - label: __('Accessibility Person Icon', 'pojo-accessibility'), - }, - { - value: 'medium', - icon: , - label: __('Accessibility Eye Icon', 'pojo-accessibility'), - }, - { - value: 'large', - icon: , - label: __('Accessibility Text Badge Icon', 'pojo-accessibility'), - }, + { value: 'large', fontSize: 64 }, + { value: 'medium', fontSize: 44 }, + { value: 'small', fontSize: 36 }, ]; - return ( - + {__('Size', 'pojo-accessibility')} { setSelectedValue(option.value)} + onClick={() => updateIconDesign({ size: option.value })} sx={{ borderRadius: 'md', boxShadow: 'sm', @@ -67,15 +51,18 @@ const IconSize = (props) => { flexGrow: 1, gap: 1.5, p: 2, - minWidth: 100, + minWidth: 10, minHeight: 100, borderColor: - selectedValue === option.value ? 'info.main' : 'divider', - borderWidth: selectedValue === option.value ? 2 : 1, + iconDesign.size === option.value ? 'info.main' : 'divider', + borderWidth: iconDesign.size === option.value ? 2 : 1, cursor: 'pointer', }} > - {option.icon} + {icon?.icon && + cloneElement(icon.icon, { + sx: { color: iconDesign.color, fontSize: option.fontSize }, + })} ({ }, })); -const PositionControl = ({ type, disabled }, props) => { +const PositionControl = ({ type, disabled, mode }) => { + const { iconPosition, updateExactPosition } = useIconPosition(); const [unitsIndex, setUnitsIndex] = useState(0); const popupState = usePopupState({ variant: 'popover', - popupId: 'textfield-inner-selection', + popupId: 'position-settings', }); const handleMenuItemClick = (index) => { setUnitsIndex(index); + updateExactPosition( + mode, + type, + iconPosition[mode].exactPosition[type].direction, + iconPosition[mode].exactPosition[type].value, + units[index], + ); popupState.close(); }; - - const [position, setPosition] = useState(10); - const handlePositionChange = (event) => setPosition(event.target.value); - + const handlePositionChange = (event) => { + updateExactPosition( + mode, + type, + iconPosition[mode].exactPosition[type].direction, + event.target.value, + iconPosition[mode].exactPosition[type].unit, + ); + }; + const handlePositionDirection = (event) => { + updateExactPosition( + mode, + type, + event.target.value, + iconPosition[mode].exactPosition[type].value, + iconPosition[mode].exactPosition[type].unit, + ); + }; return ( { color="inherit" sx={{ font: 'inherit', minWidth: 'initial' }} {...bindTrigger(popupState)} + disabled={disabled} > {units[unitsIndex]} - {units.map((unit, index) => ( { }} />