diff --git a/assets/css/settings.css b/assets/css/settings.css new file mode 100644 index 0000000..8a8714d --- /dev/null +++ b/assets/css/settings.css @@ -0,0 +1,306 @@ +/** + * Anything Shortcodes — Admin Styles + * Provides layout and visuals for the plugin settings page. + * + * Table of Contents: + * 1. Base / Global + * 2. Header + * 3. Tabs + * 4. Sidebar / Card / Links + * 5. Main / Form + * 6. Mobile FAB & Sheet + * 7. Responsive (≤782px) + * + * @since NEXT + */ + +/* ====================================== + 1. Base / Global + ====================================== */ +#wpcontent { padding-left: 0; } + +.anys-settings-grid { + display: grid; + grid-template-columns: 1fr 300px; + gap: 24px; + align-items: start; + margin-top: 20px; + padding-inline: 2rem; +} + +/* ====================================== + 2. Header + ====================================== */ +.anys-page-header { + display: flex; + justify-content: space-between; + align-items: center; + background: #fff; + padding: 1rem 2rem; +} + +.anys-title { + margin: 0; + font-size: 24px; + font-weight: 600; +} + +.anys-pro-cta { + background: #DAFFD9; + border: 1px solid transparent; + color: #1D2327; + font-weight: 500; + padding: 16px; + border-radius: 3px; + text-decoration: none; + font-size: 13px; + transition: all .2s ease; +} + +.anys-pro-cta:hover { + background: #d8f3e3d6; + color: #1D2327; + border-color: #b8e0c3; +} + +/* ====================================== + 3. Tabs + ====================================== */ +.anys-tabs { + padding-inline: 2rem; + padding-top: 0; + background: #fff; + border-block: 1px solid #e5e5e5; +} + +.anys-tabs .anys-tab { + background: transparent; + border: none; + box-shadow: none; + margin-right: 18px; + padding: 10px 0; + color: #7E7E7F; + border-bottom: 3px solid transparent; + transition: border-color .2s ease, color .2s ease; +} + +.anys-tabs .anys-tab:hover { + color: #0a0a0a; + border-bottom-color: #0a0a0a; +} + +.anys-tabs .anys-tab.nav-tab-active { + background: transparent; + border: none; + border-bottom: 3px solid #1d2327; + color: #1d2327; + font-weight: 600; +} + +.anys-tabs .anys-tab:focus { + outline: none; + box-shadow: none; +} + +/* ====================================== + 4. Sidebar / Card / Links + ====================================== */ +.anys-sidebar { + background: #fff; + border: 1px solid #e0e0e0; + border-radius: 6px; + align-self: start; +} + +.anys-card { + border-top: 2px solid #f0f0f0; + padding: 1rem; +} + +.anys-sidebar h3 { + margin: 0; + font-size: 14px; + font-weight: 600; + padding: .8rem 1rem; +} + +.anys-links { list-style: none; margin: 0; padding: 0; } +.anys-links li { margin: 8px 0; } + +.anys-links a { + color: #000; + text-decoration: none; + font-size: 13px; +} + +.anys-links a:hover { font-weight: 600; } +.anys-links a:focus { outline: none; box-shadow: none; } + +/* ====================================== + 5. Main / Form + ====================================== */ +.anys-main { border-radius: 6px; } + +.form-table th { + width: 200px; + padding: 12px 10px; + vertical-align: top; +} + +.form-table td { padding: 12px 10px; } + +.form-table input[type="text"], +.form-table input[type="number"], +.form-table select, +.form-table textarea { + width: 100%; + max-width: 100%; + border: 1px solid #ccc; + border-radius: 3px; + padding: 6px 8px; + font-size: 13px; + background: #fff; + box-sizing: border-box; +} + +.form-table .description { + color: #666; + font-size: 12px; + margin-top: 4px; +} + +input[type="checkbox"], +input[type="radio"] { vertical-align: middle; } + +.anys-field-group { + display: flex; + flex-direction: column; + gap: 16px; + padding: 12px 0; + border-bottom: 1px solid #f1f1f1; +} + +.anys-field-group:last-child { border-bottom: 0; } + +.anys-field-label { + font-weight: 500; + font-size: 13px; + line-height: 16px; + color: #000; +} + +.anys-field-label label { font-weight: 600; } + +.anys-field-control { + flex: 1 1 auto; + min-width: 0; +} + +.anys-field-control .regular-text, +.anys-field-control input[type="text"], +.anys-field-control input[type="number"], +.anys-field-control select, +.anys-field-control textarea { + width: 100%; + max-width: 640px; + box-sizing: border-box; + padding: 2px 8px; +} + +.anys-field-control .description { + color: #666; + font-size: 12px; +} + +/* ====================================== + 6. Mobile FAB & Sheet + ====================================== */ +.anys-fab { + position: fixed; + right: 16px; + bottom: 16px; + width: 56px; + height: 56px; + border-radius: 50%; + border: none; + background: #2271b1; + color: #fff; + box-shadow: 0 6px 16px rgba(0,0,0,.2); + cursor: pointer; + display: none; + z-index: 1000; +} + +.anys-fab span { + font-size: 24px; + line-height: 28px; + margin-top: -2px; +} + +.anys-mobile-sheet[hidden] { display: none; } + +.anys-mobile-sheet { + position: fixed; + inset: 0; + z-index: 999; + display: none; +} + +.anys-mobile-sheet.is-open { display: block; } + +.anys-mobile-sheet__backdrop { + position: absolute; + inset: 0; +} + +.anys-mobile-sheet__content { + position: absolute; + right: 12px; + bottom: 76px; + min-width: 260px; + max-width: 90vw; + background: #fff; + border-radius: 12px; + box-shadow: 0 10px 24px rgba(0,0,0,.25); + padding: 12px 14px 14px; + z-index: 50; +} + +.anys-mobile-sheet__content h3 { margin-top: 0; } + +.anys-mobile-sheet__close { + position: absolute; + top: 8px; + right: 8px; + border: none; + background: transparent; + font-size: 18px; + cursor: pointer; +} + +/* ====================================== + 7. Responsive (≤ 782px) + ====================================== */ +@media (max-width: 782px) { + .anys-settings-grid { grid-template-columns: 1fr; } + .anys-sidebar { display: none; } + .anys-main { order: 2; } + .anys-sidebar { order: 1; } + + .anys-page-header { + flex-direction: column; + align-items: flex-start; + gap: 12px; + } + + .anys-field-group { gap: 8px; } + .anys-field-label { padding-top: 0; } + + #wpcontent { padding-left: 0 !important; } + + .anys-fab { + display: inline-flex; + align-items: center; + justify-content: center; + } +} diff --git a/assets/js/admin-mobile-sidebar.js b/assets/js/admin-mobile-sidebar.js new file mode 100644 index 0000000..7c640b1 --- /dev/null +++ b/assets/js/admin-mobile-sidebar.js @@ -0,0 +1,38 @@ +(function(){ + // Elements + var fab = document.querySelector('.anys-fab'); + var sheet = document.getElementById('anys-mobile-menu'); + var closeBtn = sheet ? sheet.querySelector('.anys-mobile-sheet__close') : null; + var backdrop = sheet ? sheet.querySelector('.anys-mobile-sheet__backdrop') : null; + + if(!fab || !sheet) return; + + // Open/close helpers + function openSheet(){ + sheet.hidden = false; + sheet.classList.add('is-open'); + fab.setAttribute('aria-expanded', 'true'); + // Focus first link for accessibility + var firstLink = sheet.querySelector('a,button,[tabindex]:not([tabindex="-1"])'); + if(firstLink) firstLink.focus(); + } + function closeSheet(){ + sheet.classList.remove('is-open'); + fab.setAttribute('aria-expanded', 'false'); + // Use a microtask so CSS can apply before hiding + setTimeout(function(){ sheet.hidden = true; }, 0); + } + + // Toggle + fab.addEventListener('click', function(){ + var expanded = fab.getAttribute('aria-expanded') === 'true'; + if(expanded) { closeSheet(); } else { openSheet(); } + }); + + // Close handlers + if(closeBtn) closeBtn.addEventListener('click', closeSheet); + if(backdrop) backdrop.addEventListener('click', closeSheet); + document.addEventListener('keydown', function(e){ + if(e.key === 'Escape') closeSheet(); + }); +})(); diff --git a/includes/modules/settings-page/settings-page.php b/includes/modules/settings-page/settings-page.php index 83c0d38..797d9d3 100644 --- a/includes/modules/settings-page/settings-page.php +++ b/includes/modules/settings-page/settings-page.php @@ -1,186 +1,230 @@ %s', - esc_html__( 'Adjust plugin functions.', 'anys' ) - ); - } - - /** - * Renders the Whitelisted Functions textarea field. - * - * @since 1.1.0 - */ - public function whitelisted_functions_callback() { - $options = get_option( 'anys_settings' ); - $whitelisted_functions = isset( $options['anys_whitelisted_functions'] ) && is_array( $options['anys_whitelisted_functions'] ) - ? $options['anys_whitelisted_functions'] - : []; - - // Gets the default whitelisted functions list as an array. - $default_whitelisted_functions = anys_get_default_whitelisted_functions(); - - // Converts array to a comma-separated string for display. - $default_whitelisted_functions_list = implode( ', ', $default_whitelisted_functions ); - ?> - -
- -
- -' . esc_html__( 'The requested settings tab could not be found.', 'anys' ) . '
'; + } + + echo '+ +
++ +
++ +
++ +
++ +
++ +
++ +
++ +
++ +
++ +
++ +
+