detect_scss_id($clean_content, $metadata); } // Check if it's a partial (starts with underscore) $filename = basename($file_path); if (str_starts_with($filename, '_')) { $metadata['is_partial'] = true; } // Determine scope based on path $relative_path = str_replace(base_path() . '/', '', $file_path); $metadata['relative_path'] = $relative_path; if (str_contains($relative_path, '/pages/')) { $metadata['scope'] = 'page'; } elseif (str_contains($relative_path, '/components/')) { $metadata['scope'] = 'component'; } elseif (str_contains($relative_path, '/layouts/')) { $metadata['scope'] = 'layout'; } elseif (str_contains($relative_path, '/utilities/') || str_contains($relative_path, '/utils/')) { $metadata['scope'] = 'utility'; } elseif (str_contains($relative_path, '/base/') || str_contains($relative_path, '/foundation/')) { $metadata['scope'] = 'base'; } else { $metadata['scope'] = 'general'; } // Check for media queries if (preg_match_all('/@media\s+([^{]+)/', $content, $matches)) { $media_queries = []; foreach ($matches[1] as $query) { $query = trim($query); if (str_contains($query, 'min-width')) { $media_queries[] = 'responsive'; } if (str_contains($query, 'print')) { $media_queries[] = 'print'; } if (str_contains($query, 'prefers-color-scheme')) { $media_queries[] = 'dark-mode'; } } if (!empty($media_queries)) { $metadata['media_features'] = array_unique($media_queries); } } // Check for CSS custom properties (CSS variables) $css_vars = []; if (preg_match_all('/--([a-zA-Z][\w-]*)/', $content, $matches)) { $css_vars = $matches[1]; } if (!empty($css_vars)) { $metadata['css_variables'] = array_unique($css_vars); } // Check for Bootstrap usage if (preg_match('/\.(btn|col-|row|container|navbar|modal|card|form-control)/', $content)) { $metadata['uses_bootstrap'] = true; } // Check for Font Awesome usage if (preg_match('/\.(fa-|fas|far|fab|fal|fad)/', $content)) { $metadata['uses_fontawesome'] = true; } return $metadata; } /** * Detect if SCSS file has a single top-level class that qualifies as an ID * * The SCSS file gets an 'id' if: * 1. All rules are contained within a single top-level class selector * 2. The class name matches a Blade view ID, JS class extending Component, or jqhtml template * 3. No other SCSS file already has this ID */ protected function detect_scss_id(string $clean_content, array &$metadata): void { // Remove all whitespace and newlines for easier parsing $compact = preg_replace('/\s+/', ' ', trim($clean_content)); // Check if content starts with a single class selector and everything is inside it // Pattern: .ClassName { ... everything ... } if (!preg_match('/^\.([A-Z][a-zA-Z0-9_]+)\s*\{(.*)\}\s*$/', $compact, $matches)) { return; } $class_name = $matches[1]; $inner_content = $matches[2]; // Verify there are no other top-level rules by checking for unmatched closing braces // Count opening and closing braces in the inner content $open_braces = substr_count($inner_content, '{'); $close_braces = substr_count($inner_content, '}'); // If braces are balanced, everything is contained within the main selector if ($open_braces !== $close_braces) { return; } // Now check if this class name matches something in the manifest // During build, we need to access the in-memory manifest data // The get_all() method returns the cached data, not the in-progress build // We need a different approach - access the static data directly // Get access to the Manifest class's internal data using reflection $reflection = new \ReflectionClass(\App\RSpade\Core\Manifest\Manifest::class); $data_property = $reflection->getProperty('data'); $data_property->setAccessible(true); $manifest_state = $data_property->getValue(); if (!isset($manifest_state['data']['files'])) { return; } $manifest_data = $manifest_state['data']['files']; $found_match = false; $scss_id_already_exists = false; foreach ($manifest_data as $file_data) { // Check if another SCSS file already has this ID if (isset($file_data['id']) && $file_data['id'] === $class_name && isset($file_data['extension']) && $file_data['extension'] === 'scss') { $scss_id_already_exists = true; break; } // Check for matching ID in Blade view or jqhtml template if (isset($file_data['id']) && $file_data['id'] === $class_name) { $found_match = true; } // Check for JavaScript class extending Component if (isset($file_data['extension']) && $file_data['extension'] === 'js' && isset($file_data['class']) && $file_data['class'] === $class_name && isset($file_data['extends']) && $file_data['extends'] === 'Component') { $found_match = true; } } // Only set ID if we found a match and no other SCSS has this ID if ($found_match && !$scss_id_already_exists) { $metadata['id'] = $class_name; } } }