Framework updates
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -30,14 +30,19 @@ class Man_Command extends Command
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* Directories are listed in priority order - first match wins for same-named files.
|
||||
* Project-specific docs in rsx/resource/man override framework docs in app/RSpade/man.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
// Priority order: project-specific > user docs > framework docs
|
||||
$this->docs_dirs = [
|
||||
base_path('docs/man'),
|
||||
base_path('app/RSpade/man'),
|
||||
base_path('../rsx/resource/man'), // Project-specific (highest priority)
|
||||
base_path('docs/man'), // User docs
|
||||
base_path('app/RSpade/man'), // Framework docs (lowest priority)
|
||||
];
|
||||
}
|
||||
|
||||
@@ -100,15 +105,7 @@ class Man_Command extends Command
|
||||
*/
|
||||
protected function list_all_documentation()
|
||||
{
|
||||
$files = [];
|
||||
foreach ($this->docs_dirs as $dir) {
|
||||
if (is_dir($dir)) {
|
||||
$dir_files = glob($dir . '/*.txt');
|
||||
if ($dir_files) {
|
||||
$files = array_merge($files, $dir_files);
|
||||
}
|
||||
}
|
||||
}
|
||||
$files = $this->get_all_files_deduplicated();
|
||||
|
||||
if (empty($files)) {
|
||||
$this->warn('No documentation files found in:');
|
||||
@@ -175,6 +172,32 @@ class Man_Command extends Command
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all documentation files, deduplicated by filename.
|
||||
* Files from earlier directories in docs_dirs take precedence.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function get_all_files_deduplicated(): array
|
||||
{
|
||||
$files_by_name = [];
|
||||
foreach ($this->docs_dirs as $dir) {
|
||||
if (is_dir($dir)) {
|
||||
$dir_files = glob($dir . '/*.txt');
|
||||
if ($dir_files) {
|
||||
foreach ($dir_files as $file) {
|
||||
$name = basename($file, '.txt');
|
||||
// First occurrence wins (higher priority directory)
|
||||
if (!isset($files_by_name[$name])) {
|
||||
$files_by_name[$name] = $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return array_values($files_by_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find documentation files matching the given term.
|
||||
*
|
||||
@@ -183,15 +206,7 @@ class Man_Command extends Command
|
||||
*/
|
||||
protected function find_matching_files(string $term): array
|
||||
{
|
||||
$files = [];
|
||||
foreach ($this->docs_dirs as $dir) {
|
||||
if (is_dir($dir)) {
|
||||
$dir_files = glob($dir . '/*.txt');
|
||||
if ($dir_files) {
|
||||
$files = array_merge($files, $dir_files);
|
||||
}
|
||||
}
|
||||
}
|
||||
$files = $this->get_all_files_deduplicated();
|
||||
|
||||
$term_lower = strtolower($term);
|
||||
$matches = [];
|
||||
@@ -373,25 +388,14 @@ class Man_Command extends Command
|
||||
*/
|
||||
protected function get_all_topic_names(): array
|
||||
{
|
||||
$files = [];
|
||||
foreach ($this->docs_dirs as $dir) {
|
||||
if (is_dir($dir)) {
|
||||
$dir_files = glob($dir . '/*.txt');
|
||||
if ($dir_files) {
|
||||
$files = array_merge($files, $dir_files);
|
||||
}
|
||||
}
|
||||
}
|
||||
$files = $this->get_all_files_deduplicated();
|
||||
|
||||
$topics = [];
|
||||
foreach ($files as $file) {
|
||||
$topics[] = basename($file, '.txt');
|
||||
}
|
||||
|
||||
// Remove duplicates and sort
|
||||
$topics = array_unique($topics);
|
||||
sort($topics);
|
||||
|
||||
return $topics;
|
||||
}
|
||||
|
||||
|
||||
106
app/RSpade/Core/Js/Responsive.js
Executable file
106
app/RSpade/Core/Js/Responsive.js
Executable file
@@ -0,0 +1,106 @@
|
||||
/**
|
||||
* Responsive - JavaScript breakpoint detection for RSX two-tier responsive system
|
||||
*
|
||||
* Provides runtime detection of current viewport against CSS breakpoint values.
|
||||
* Values are read from CSS custom properties defined in rsx/theme/responsive.scss.
|
||||
*
|
||||
* Two-tier system:
|
||||
* Tier 1 (Semantic): is_mobile() / is_desktop() - broad categories
|
||||
* Tier 2 (Granular): is_phone() / is_tablet() / is_desktop_sm() / is_desktop_md() / is_desktop_lg()
|
||||
*
|
||||
* Usage:
|
||||
* if (Responsive.is_mobile()) { ... }
|
||||
* if (Responsive.is_desktop_md()) { ... }
|
||||
*/
|
||||
class Responsive {
|
||||
static _cache = {};
|
||||
|
||||
/**
|
||||
* Get breakpoint value from CSS custom property as integer
|
||||
* @param {string} name - Breakpoint name (e.g., 'desktop', 'tablet', 'desktop-md')
|
||||
* @returns {number} Breakpoint value in pixels
|
||||
* @private
|
||||
*/
|
||||
static _get_breakpoint(name) {
|
||||
if (this._cache[name] !== undefined) {
|
||||
return this._cache[name];
|
||||
}
|
||||
|
||||
const styles = getComputedStyle(document.documentElement);
|
||||
const value = styles.getPropertyValue(`--bp-${name}-min`).trim();
|
||||
const parsed = parseInt(value, 10);
|
||||
|
||||
this._cache[name] = parsed;
|
||||
return parsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current viewport width
|
||||
* @returns {number}
|
||||
* @private
|
||||
*/
|
||||
static _viewport() {
|
||||
return window.innerWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tier 1: Check if viewport is mobile (0 - 1023px)
|
||||
* Includes phone and tablet sizes
|
||||
* @returns {boolean}
|
||||
*/
|
||||
static is_mobile() {
|
||||
return !this.is_desktop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tier 1: Check if viewport is desktop (1024px+)
|
||||
* Includes desktop-sm, desktop-md, and desktop-lg sizes
|
||||
* @returns {boolean}
|
||||
*/
|
||||
static is_desktop() {
|
||||
return this._viewport() >= this._get_breakpoint('desktop');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tier 2: Check if viewport is phone (0 - 799px)
|
||||
* @returns {boolean}
|
||||
*/
|
||||
static is_phone() {
|
||||
return this._viewport() < this._get_breakpoint('tablet');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tier 2: Check if viewport is tablet (800 - 1023px)
|
||||
* @returns {boolean}
|
||||
*/
|
||||
static is_tablet() {
|
||||
const vp = this._viewport();
|
||||
return vp >= this._get_breakpoint('tablet') && vp < this._get_breakpoint('desktop');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tier 2: Check if viewport is desktop-sm (1024 - 1699px)
|
||||
* @returns {boolean}
|
||||
*/
|
||||
static is_desktop_sm() {
|
||||
const vp = this._viewport();
|
||||
return vp >= this._get_breakpoint('desktop-sm') && vp < this._get_breakpoint('desktop-md');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tier 2: Check if viewport is desktop-md (1700 - 2199px)
|
||||
* @returns {boolean}
|
||||
*/
|
||||
static is_desktop_md() {
|
||||
const vp = this._viewport();
|
||||
return vp >= this._get_breakpoint('desktop-md') && vp < this._get_breakpoint('desktop-lg');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tier 2: Check if viewport is desktop-lg (2200px+)
|
||||
* @returns {boolean}
|
||||
*/
|
||||
static is_desktop_lg() {
|
||||
return this._viewport() >= this._get_breakpoint('desktop-lg');
|
||||
}
|
||||
}
|
||||
102
app/RSpade/man/man.txt
Executable file
102
app/RSpade/man/man.txt
Executable file
@@ -0,0 +1,102 @@
|
||||
NAME
|
||||
man - RSX manual page system
|
||||
|
||||
SYNOPSIS
|
||||
php artisan rsx:man # List all available topics
|
||||
php artisan rsx:man <topic> # Display documentation for topic
|
||||
php artisan rsx:man responsive # Example: show responsive docs
|
||||
|
||||
DESCRIPTION
|
||||
The man page system provides detailed technical documentation for RSX
|
||||
framework features and project-specific implementations. These documents
|
||||
serve as immediate reference when detailed understanding of any subsystem
|
||||
is necessary.
|
||||
|
||||
Man pages are plain text files following Unix man page conventions:
|
||||
terse, complete, expert-level documentation with code examples.
|
||||
|
||||
DIRECTORY STRUCTURE
|
||||
Documentation is loaded from multiple directories in priority order:
|
||||
|
||||
/rsx/resource/man/ Project-specific docs (highest priority)
|
||||
/system/docs/man/ User docs
|
||||
/system/app/RSpade/man/ Framework docs (lowest priority)
|
||||
|
||||
When the same filename exists in multiple directories, the higher
|
||||
priority version is used. This allows projects to override framework
|
||||
documentation when customizations require different instructions.
|
||||
|
||||
PROJECT-SPECIFIC DOCUMENTATION
|
||||
The /rsx/resource/man/ directory contains documentation specific to the
|
||||
current project. Create man pages here for:
|
||||
|
||||
- Custom features built on top of the framework
|
||||
- Project-specific configuration or patterns
|
||||
- Implementation details unique to this application
|
||||
- Overrides of framework behavior
|
||||
|
||||
To override a framework man page, create a file with the same name in
|
||||
/rsx/resource/man/. The project version will be displayed instead of
|
||||
the framework version.
|
||||
|
||||
FILE FORMAT
|
||||
Man pages use plain text with these conventions:
|
||||
|
||||
- Section headers in ALL CAPS on their own line
|
||||
- Code examples indented with 4 spaces
|
||||
- No markdown, no Unicode, no box-drawing characters
|
||||
- ASCII only for maximum compatibility
|
||||
|
||||
Standard sections:
|
||||
|
||||
NAME Feature name and one-line description
|
||||
SYNOPSIS Quick usage example
|
||||
DESCRIPTION Overview and purpose
|
||||
USAGE Detailed instructions
|
||||
EXAMPLES Code samples
|
||||
SEE ALSO Related documentation
|
||||
|
||||
EXAMPLES
|
||||
List all available documentation:
|
||||
|
||||
php artisan rsx:man
|
||||
|
||||
View documentation for a specific topic:
|
||||
|
||||
php artisan rsx:man jqhtml
|
||||
php artisan rsx:man bundle_api
|
||||
php artisan rsx:man responsive
|
||||
|
||||
Partial matching works:
|
||||
|
||||
php artisan rsx:man bundle # Matches bundle_api
|
||||
php artisan rsx:man spa # Matches spa
|
||||
|
||||
CREATING MAN PAGES
|
||||
Framework man pages go in /system/app/RSpade/man/*.txt
|
||||
Project man pages go in /rsx/resource/man/*.txt
|
||||
|
||||
See /rsx/resource/man/CLAUDE.md for detailed writing guidelines.
|
||||
|
||||
Template:
|
||||
|
||||
NAME
|
||||
feature_name - brief description
|
||||
|
||||
SYNOPSIS
|
||||
Most common usage example
|
||||
|
||||
DESCRIPTION
|
||||
What the feature does, why it exists.
|
||||
|
||||
USAGE
|
||||
Step-by-step instructions.
|
||||
|
||||
EXAMPLES
|
||||
Real code examples.
|
||||
|
||||
SEE ALSO
|
||||
Related topics
|
||||
|
||||
SEE ALSO
|
||||
jqhtml, bundle_api, spa, coding_standards
|
||||
80
app/RSpade/upstream_changes/CLAUDE.md
Executable file
80
app/RSpade/upstream_changes/CLAUDE.md
Executable file
@@ -0,0 +1,80 @@
|
||||
# Upstream Changes Log
|
||||
|
||||
## Purpose
|
||||
|
||||
This directory contains migration guides for significant framework changes that affect existing RSX applications. When framework updates introduce breaking changes or new patterns that downstream projects should adopt, a detailed migration document is created here.
|
||||
|
||||
These documents serve as technical references for updating existing applications to match the current framework patterns.
|
||||
|
||||
## When to Create a Document
|
||||
|
||||
Create a migration guide when:
|
||||
- Breaking changes affect existing application code
|
||||
- New patterns replace old patterns (and old code should be updated)
|
||||
- Configuration or directory structure changes
|
||||
- New required dependencies or bundle includes
|
||||
|
||||
Do NOT create documents for:
|
||||
- Internal framework refactoring that doesn't affect applications
|
||||
- New features that don't require changes to existing code
|
||||
- Bug fixes
|
||||
|
||||
## File Naming Convention
|
||||
|
||||
```
|
||||
{feature}_{month}_{day}.txt
|
||||
```
|
||||
|
||||
Examples:
|
||||
- `responsive_12_18.txt` - Responsive system changes on December 18
|
||||
- `bundle_api_03_15.txt` - Bundle API changes on March 15
|
||||
- `auth_session_07_22.txt` - Authentication/session changes on July 22
|
||||
|
||||
Use lowercase with underscores. Date is MM_DD format (no year - files are naturally ordered by creation).
|
||||
|
||||
## Document Structure
|
||||
|
||||
Each migration guide should include:
|
||||
|
||||
```
|
||||
FEATURE NAME - MIGRATION GUIDE
|
||||
Date: YYYY-MM-DD
|
||||
|
||||
SUMMARY
|
||||
One paragraph describing what changed and why.
|
||||
|
||||
AFFECTED FILES
|
||||
List of file paths that need modification in downstream projects.
|
||||
|
||||
CHANGES REQUIRED
|
||||
|
||||
1. First Change Category
|
||||
- What to do
|
||||
- Code examples (before/after)
|
||||
|
||||
2. Second Change Category
|
||||
- What to do
|
||||
- Code examples
|
||||
|
||||
CONFIGURATION
|
||||
Any new configuration values, bundle includes, or settings.
|
||||
|
||||
VERIFICATION
|
||||
How to verify the migration was successful.
|
||||
|
||||
REFERENCE
|
||||
Links to man pages or other documentation.
|
||||
```
|
||||
|
||||
## Level of Detail
|
||||
|
||||
Migration guides should be:
|
||||
- **Complete**: Every change needed to migrate, no assumptions
|
||||
- **Actionable**: Clear steps, not just descriptions
|
||||
- **Example-driven**: Show before/after code for each change type
|
||||
- **Self-contained**: Reader shouldn't need to reference other docs to complete migration
|
||||
|
||||
Assume the reader:
|
||||
- Has an existing RSX application
|
||||
- Understands the framework basics
|
||||
- Does NOT know what changed or why
|
||||
427
app/RSpade/upstream_changes/responsive_12_18.txt
Executable file
427
app/RSpade/upstream_changes/responsive_12_18.txt
Executable file
@@ -0,0 +1,427 @@
|
||||
RESPONSIVE BREAKPOINT SYSTEM - MIGRATION GUIDE
|
||||
Date: 2024-12-18
|
||||
|
||||
SUMMARY
|
||||
RSX now uses a custom two-tier responsive breakpoint system that replaces
|
||||
Bootstrap's default breakpoints (xs/sm/md/lg/xl/xxl) with semantic device
|
||||
names. This provides clearer intent (mobile vs desktop) and finer control
|
||||
(phone/tablet/desktop-sm/desktop-md/desktop-lg). All existing media queries
|
||||
using hardcoded pixel values or Bootstrap breakpoint variables should be
|
||||
migrated to use the new SCSS mixins.
|
||||
|
||||
Bootstrap's default responsive utility classes (.col-md-*, .d-lg-*, etc.)
|
||||
no longer work. Applications must use the new breakpoint names.
|
||||
|
||||
BREAKPOINT DEFINITIONS
|
||||
|
||||
Tier 1 - Semantic (Mobile vs Desktop):
|
||||
mobile 0 - 1023px Phone + tablet combined
|
||||
desktop 1024px+ All desktop sizes
|
||||
|
||||
Tier 2 - Granular Device Classes:
|
||||
phone 0 - 799px Phones, small handhelds
|
||||
tablet 800 - 1023px Tablets portrait, large phones landscape
|
||||
desktop-sm 1024 - 1699px Laptops, small monitors
|
||||
desktop-md 1700 - 2199px Standard monitors (1080p-1440p)
|
||||
desktop-lg 2200px+ Large/ultra-wide monitors, 4K
|
||||
|
||||
The 1024px mobile/desktop boundary was chosen because tablets in landscape
|
||||
(iPad Pro at 1366px) should receive desktop layouts.
|
||||
|
||||
AFFECTED FILES
|
||||
|
||||
Framework files (already updated):
|
||||
rsx/theme/vendor/bootstrap5/scss/_variables.scss
|
||||
rsx/theme/variables.scss
|
||||
rsx/theme/responsive.scss (new file)
|
||||
All bundle definition files (*_bundle.php)
|
||||
|
||||
Application files requiring migration:
|
||||
Any *.scss file with @media queries using pixel values
|
||||
Any template using Bootstrap responsive classes (.col-md-*, .d-lg-*, etc.)
|
||||
|
||||
CHANGES REQUIRED
|
||||
|
||||
1. Bootstrap Assertion Disabled
|
||||
-------------------------------------------------------------------------
|
||||
In rsx/theme/vendor/bootstrap5/scss/_variables.scss, the ascending
|
||||
assertion for $grid-breakpoints has been commented out to allow
|
||||
semantic aliases (mobile/phone share 0, desktop/desktop-sm share 1024px):
|
||||
|
||||
Line 494-495:
|
||||
// RSX: Disabled to allow semantic breakpoint aliases
|
||||
// @include _assert-ascending($grid-breakpoints, "$grid-breakpoints");
|
||||
|
||||
If you have a custom Bootstrap checkout, apply this change.
|
||||
|
||||
2. Create responsive.scss
|
||||
-------------------------------------------------------------------------
|
||||
Create rsx/theme/responsive.scss with mixins and utility classes.
|
||||
|
||||
Full file contents:
|
||||
|
||||
// ==========================================================================
|
||||
// RSX RESPONSIVE SYSTEM
|
||||
// ==========================================================================
|
||||
//
|
||||
// Two-tier responsive breakpoint system for consistent mobile/desktop handling.
|
||||
//
|
||||
// TIER 1 - Semantic (Mobile vs Desktop):
|
||||
// Mobile: 0 - 1023px (phone + tablet combined)
|
||||
// Desktop: 1024px+ (all desktop sizes)
|
||||
//
|
||||
// TIER 2 - Granular Device Classes:
|
||||
// phone: 0 - 799px
|
||||
// tablet: 800 - 1023px
|
||||
// desktop-sm: 1024 - 1699px
|
||||
// desktop-md: 1700 - 2199px
|
||||
// desktop-lg: 2200px+
|
||||
|
||||
// ==========================================================================
|
||||
// TIER 1 MIXINS: Mobile vs Desktop
|
||||
// ==========================================================================
|
||||
|
||||
@mixin mobile {
|
||||
@media (max-width: $bp-mobile-max) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin desktop {
|
||||
@media (min-width: $bp-desktop-min) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
// TIER 2 MIXINS: Device-specific
|
||||
// ==========================================================================
|
||||
|
||||
@mixin phone {
|
||||
@media (max-width: $bp-phone-max) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin tablet {
|
||||
@media (min-width: $bp-tablet-min) and (max-width: $bp-tablet-max) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin tablet-up {
|
||||
@media (min-width: $bp-tablet-min) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin tablet-down {
|
||||
@media (max-width: $bp-tablet-max) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin desktop-sm {
|
||||
@media (min-width: $bp-desktop-sm-min) and (max-width: $bp-desktop-sm-max) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin desktop-sm-up {
|
||||
@media (min-width: $bp-desktop-sm-min) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin desktop-md {
|
||||
@media (min-width: $bp-desktop-md-min) and (max-width: $bp-desktop-md-max) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin desktop-md-up {
|
||||
@media (min-width: $bp-desktop-md-min) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin desktop-lg {
|
||||
@media (min-width: $bp-desktop-lg-min) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
// UTILITY CLASSES
|
||||
// ==========================================================================
|
||||
|
||||
.mobile-only {
|
||||
@include desktop {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.desktop-only {
|
||||
@include mobile {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.hide-mobile {
|
||||
@include mobile {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.hide-desktop {
|
||||
@include desktop {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.phone-only {
|
||||
@include tablet-up {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.tablet-only {
|
||||
@include phone {
|
||||
display: none !important;
|
||||
}
|
||||
@include desktop {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.hide-phone {
|
||||
@include phone {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.hide-tablet {
|
||||
@include tablet {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
// CSS CUSTOM PROPERTIES (for JavaScript access)
|
||||
// ==========================================================================
|
||||
|
||||
:root {
|
||||
--bp-mobile-max: #{$bp-mobile-max};
|
||||
--bp-desktop-min: #{$bp-desktop-min};
|
||||
--bp-phone-max: #{$bp-phone-max};
|
||||
--bp-tablet-min: #{$bp-tablet-min};
|
||||
--bp-tablet-max: #{$bp-tablet-max};
|
||||
--bp-desktop-sm-min: #{$bp-desktop-sm-min};
|
||||
--bp-desktop-sm-max: #{$bp-desktop-sm-max};
|
||||
--bp-desktop-md-min: #{$bp-desktop-md-min};
|
||||
--bp-desktop-md-max: #{$bp-desktop-md-max};
|
||||
--bp-desktop-lg-min: #{$bp-desktop-lg-min};
|
||||
}
|
||||
|
||||
3. Update variables.scss
|
||||
-------------------------------------------------------------------------
|
||||
Add breakpoint variables and Bootstrap $grid-breakpoints override.
|
||||
|
||||
Add to rsx/theme/variables.scss (replace any existing breakpoint vars):
|
||||
|
||||
// ==========================================================================
|
||||
// RESPONSIVE BREAKPOINTS
|
||||
// ==========================================================================
|
||||
// Two-tier system: Tier 1 (Mobile vs Desktop) and Tier 2 (Granular devices)
|
||||
// See rsx/theme/responsive.scss for mixins and utilities
|
||||
|
||||
// Tier 2: Granular device breakpoints
|
||||
$bp-phone-max: 799px;
|
||||
$bp-tablet-min: 800px;
|
||||
$bp-tablet-max: 1023px;
|
||||
$bp-desktop-sm-min: 1024px;
|
||||
$bp-desktop-sm-max: 1699px;
|
||||
$bp-desktop-md-min: 1700px;
|
||||
$bp-desktop-md-max: 2199px;
|
||||
$bp-desktop-lg-min: 2200px;
|
||||
|
||||
// Tier 1: Semantic breakpoints (mobile = phone + tablet)
|
||||
$bp-mobile-max: 1023px;
|
||||
$bp-desktop-min: 1024px;
|
||||
|
||||
// Bootstrap grid breakpoints override
|
||||
// Allows: .col-mobile-6, .col-phone-12, .col-tablet-8, .col-desktop-4, etc.
|
||||
// Note: mobile/phone share 0, desktop/desktop-sm share 1024px (assertion disabled)
|
||||
$grid-breakpoints: (
|
||||
xs: 0,
|
||||
mobile: 0,
|
||||
phone: 0,
|
||||
tablet: 800px,
|
||||
desktop: 1024px,
|
||||
desktop-sm: 1024px,
|
||||
desktop-md: 1700px,
|
||||
desktop-lg: 2200px
|
||||
);
|
||||
|
||||
Remove any old breakpoint variables like:
|
||||
$breakpoint-sm, $breakpoint-md, $breakpoint-lg, $breakpoint-xl, $breakpoint-2xl
|
||||
|
||||
4. Update Bundle Definitions
|
||||
-------------------------------------------------------------------------
|
||||
Add responsive.scss to every bundle after variables.scss but before Bootstrap.
|
||||
|
||||
Before:
|
||||
'include' => [
|
||||
'rsx/theme/variables.scss',
|
||||
'Bootstrap5_Src_Bundle',
|
||||
...
|
||||
]
|
||||
|
||||
After:
|
||||
'include' => [
|
||||
'rsx/theme/variables.scss',
|
||||
'rsx/theme/responsive.scss', // ADD THIS LINE
|
||||
'Bootstrap5_Src_Bundle',
|
||||
...
|
||||
]
|
||||
|
||||
Apply to all bundle files:
|
||||
- rsx/app/frontend/frontend_bundle.php
|
||||
- rsx/app/login/login_bundle.php
|
||||
- rsx/app/root/root_bundle.php
|
||||
- rsx/app/dev/dev_bundle.php
|
||||
- rsx/app/backend/backend_bundle.php
|
||||
- Any other *_bundle.php files
|
||||
|
||||
5. Migrate SCSS Media Queries
|
||||
-------------------------------------------------------------------------
|
||||
Replace hardcoded media queries with mixins.
|
||||
|
||||
Common patterns:
|
||||
|
||||
Before: @media (max-width: 767px) { ... }
|
||||
After: @include phone { ... }
|
||||
|
||||
Before: @media (max-width: 768px) { ... }
|
||||
After: @include mobile { ... }
|
||||
|
||||
Before: @media (max-width: 991.98px) { ... }
|
||||
After: @include mobile { ... }
|
||||
|
||||
Before: @media (max-width: 1199px) { ... }
|
||||
After: @include mobile { ... }
|
||||
|
||||
Before: @media (min-width: 768px) { ... }
|
||||
After: @include tablet-up { ... }
|
||||
|
||||
Before: @media (min-width: 992px) { ... }
|
||||
After: @include desktop { ... }
|
||||
|
||||
Before: @media (min-width: 1200px) { ... }
|
||||
After: @include desktop { ... }
|
||||
|
||||
Example file migration:
|
||||
|
||||
Before:
|
||||
.My_Component {
|
||||
padding: 1rem;
|
||||
|
||||
@media (max-width: 991.98px) {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
After:
|
||||
.My_Component {
|
||||
padding: 1rem;
|
||||
|
||||
@include mobile {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
Remove any local breakpoint variables like:
|
||||
$mobile-breakpoint: 991.98px;
|
||||
|
||||
6. Migrate Bootstrap Utility Classes in Templates
|
||||
-------------------------------------------------------------------------
|
||||
Replace Bootstrap's default breakpoint names with RSX names.
|
||||
|
||||
Grid columns:
|
||||
Before: class="col-12 col-md-6 col-lg-4"
|
||||
After: class="col-mobile-12 col-tablet-6 col-desktop-4"
|
||||
|
||||
Before: class="col-sm-6 col-xl-3"
|
||||
After: class="col-phone-6 col-desktop-md-3"
|
||||
|
||||
Display utilities:
|
||||
Before: class="d-none d-md-block"
|
||||
After: class="d-none d-tablet-block" or class="d-mobile-none d-tablet-block"
|
||||
|
||||
Before: class="d-lg-none"
|
||||
After: class="d-desktop-none"
|
||||
|
||||
Spacing:
|
||||
Before: class="p-2 p-md-4"
|
||||
After: class="p-2 p-tablet-4" or class="p-mobile-2 p-desktop-4"
|
||||
|
||||
Common mappings:
|
||||
Bootstrap RSX equivalent
|
||||
--------- --------------
|
||||
xs (use base class, no suffix)
|
||||
sm phone or mobile
|
||||
md tablet or mobile
|
||||
lg desktop
|
||||
xl desktop or desktop-md
|
||||
xxl desktop-lg
|
||||
|
||||
CONFIGURATION
|
||||
|
||||
No additional configuration required beyond the file changes above.
|
||||
|
||||
Optional: If you need JavaScript access to breakpoints:
|
||||
|
||||
const styles = getComputedStyle(document.documentElement);
|
||||
const desktopMin = styles.getPropertyValue('--bp-desktop-min');
|
||||
const isMobile = window.innerWidth <= parseInt(
|
||||
styles.getPropertyValue('--bp-mobile-max')
|
||||
);
|
||||
|
||||
VERIFICATION
|
||||
|
||||
1. Compile bundles and verify no SCSS errors:
|
||||
php artisan rsx:bundle:compile Frontend_Bundle
|
||||
|
||||
2. Check that responsive utility classes work:
|
||||
- Add class="mobile-only" to an element, verify hidden on desktop
|
||||
- Add class="col-mobile-12 col-desktop-6" to a div, verify layout changes
|
||||
|
||||
3. Search for orphaned Bootstrap classes:
|
||||
grep -r "col-sm-\|col-md-\|col-lg-\|col-xl-\|d-sm-\|d-md-\|d-lg-\|d-xl-" rsx/
|
||||
|
||||
4. Search for hardcoded media queries that should be migrated:
|
||||
grep -r "@media.*max-width.*px\|@media.*min-width.*px" rsx/app rsx/theme/components
|
||||
|
||||
DOCUMENTATION
|
||||
|
||||
Man page created: rsx/resource/man/responsive.txt
|
||||
View with: php artisan rsx:man responsive
|
||||
|
||||
CLAUDE.md and docs.dist/CLAUDE.dist.md updated with:
|
||||
- Responsive Breakpoints section under SCSS Component-First Architecture
|
||||
- Tier 1 and Tier 2 definitions
|
||||
- Mixin and class name reference
|
||||
- Warning about Bootstrap default classes not working
|
||||
|
||||
PROJECT MAN PAGES
|
||||
|
||||
The rsx:man command now also searches rsx/resource/man/ for project-specific
|
||||
documentation. Project man pages override framework man pages of the same name.
|
||||
|
||||
Created: rsx/resource/man/CLAUDE.md (guidelines for project man pages)
|
||||
|
||||
REFERENCE
|
||||
|
||||
php artisan rsx:man responsive - Full responsive system documentation
|
||||
php artisan rsx:man scss - SCSS organization conventions
|
||||
php artisan rsx:man man - Man page system documentation
|
||||
@@ -446,6 +446,29 @@ The process involves creating Action classes with @route decorators and converti
|
||||
|
||||
Details: `php artisan rsx:man scss`
|
||||
|
||||
### Responsive Breakpoints
|
||||
|
||||
RSX replaces Bootstrap's default breakpoints (xs/sm/md/lg/xl/xxl) with semantic device names.
|
||||
|
||||
**Tier 1 - Semantic**:
|
||||
- `mobile`: 0 - 1023px (phone + tablet)
|
||||
- `desktop`: 1024px+
|
||||
|
||||
**Tier 2 - Granular**:
|
||||
- `phone`: 0 - 799px | `tablet`: 800 - 1023px | `desktop-sm`: 1024 - 1699px | `desktop-md`: 1700 - 2199px | `desktop-lg`: 2200px+
|
||||
|
||||
**SCSS Mixins**: `@include mobile { }`, `@include desktop { }`, `@include phone { }`, `@include tablet { }`, `@include desktop-sm { }`, etc.
|
||||
|
||||
**Bootstrap Classes**: `.col-mobile-6`, `.col-desktop-4`, `.d-mobile-none`, `.d-tablet-block`, `.col-phone-12 .col-tablet-6 .col-desktop-sm-4`
|
||||
|
||||
**Utility Classes**: `.mobile-only`, `.desktop-only`, `.phone-only`, `.hide-mobile`, `.hide-tablet`
|
||||
|
||||
**Note**: Bootstrap's default classes like `.col-md-6` or `.d-lg-none` do NOT work - use the RSX breakpoint names instead.
|
||||
|
||||
**JS Detection**: `Responsive.is_mobile()`, `Responsive.is_desktop()` (Tier 1 - broad); `Responsive.is_phone()`, `Responsive.is_tablet()`, `Responsive.is_desktop_sm()`, `Responsive.is_desktop_md()`, `Responsive.is_desktop_lg()` (Tier 2 - specific ranges)
|
||||
|
||||
Details: `php artisan rsx:man responsive`
|
||||
|
||||
### JavaScript for Blade Pages
|
||||
|
||||
Unlike SPA actions (which use component lifecycle), Blade pages use static `on_app_ready()` with a page guard:
|
||||
@@ -1208,10 +1231,24 @@ class Main extends Main_Abstract
|
||||
## GETTING HELP
|
||||
|
||||
```bash
|
||||
php artisan rsx:man <topic> # Detailed docs
|
||||
php artisan rsx:man <topic> # Framework documentation
|
||||
php artisan list rsx # All commands
|
||||
```
|
||||
|
||||
**Topics**: bundle_api, jqhtml, routing, migrations, console_debug, model_fetch, vs_code_extension, deployment, framework_divergences
|
||||
|
||||
---
|
||||
|
||||
## PROJECT DOCUMENTATION
|
||||
|
||||
Project-specific technical documentation lives in `/rsx/resource/man/`. These are man-page-style text files documenting features specific to your application that build on or extend the framework.
|
||||
|
||||
**When to create a project man page**:
|
||||
- Feature has non-obvious implementation details
|
||||
- Multiple components interact in ways that need explanation
|
||||
- Configuration options or patterns need documentation
|
||||
- AI agents or future developers need reference material
|
||||
|
||||
**Format**: Plain text files (`.txt`) following Unix man page conventions. See `/rsx/resource/man/CLAUDE.md` for writing guidelines.
|
||||
|
||||
**Remember**: RSpade prioritizes simplicity and rapid development. When in doubt, choose the straightforward approach.
|
||||
|
||||
Reference in New Issue
Block a user