assoconnect/absolute-percent-value-bundle
Symfony bundle that adds an AbsolutePercentValue field/type to handle percentage inputs safely, normalizing values and enabling comparisons, calculations, and validation without sign/format issues. Useful for forms and domain models needing absolute percentage values.
Installation Add the package via Composer:
composer require assoconnect/absolute-percent-value-bundle
Publish the config (if needed):
php artisan vendor:publish --provider="AbsolutePercentValueBundle\AbsolutePercentValueBundle" --tag="config"
Basic Usage
The package provides a AbsolutePercentValue class to handle hybrid values (e.g., "50%", "20px", or "50% + 10px").
Import and use it directly:
use AbsolutePercentValueBundle\AbsolutePercentValue;
$value = new AbsolutePercentValue("50% + 10px");
echo $value->getValue(); // "50% + 10px"
echo $value->getAbsolute(); // 10 (px)
echo $value->getPercent(); // 50
First Use Case: Dynamic Styling Use it in Blade templates or CSS logic:
$padding = new AbsolutePercentValue("20% + 5px");
return view('dashboard', ['padding' => $padding]);
In Blade:
<div style="padding: {{ $padding->getValue() }};">
Form Input Handling Validate and parse hybrid values in forms:
use Illuminate\Support\Facades\Validator;
$validator = Validator::make($request->all(), [
'margin' => 'required|absolute_percent_value',
]);
if ($validator->fails()) {
return redirect()->back()->withErrors($validator);
}
$margin = new AbsolutePercentValue($request->input('margin'));
Dynamic CSS Generation Generate responsive styles dynamically:
function getResponsivePadding($basePercent, $basePx) {
return new AbsolutePercentValue("{$basePercent}% + {$basePx}px");
}
Database Storage
Store hybrid values in a database column (e.g., VARCHAR):
// Model
protected $casts = [
'spacing' => AbsolutePercentValue::class,
];
// Usage
$user->spacing = new AbsolutePercentValue("30% + 8px");
$user->save();
// Retrieve
$percent = $user->spacing->getPercent();
$absolute = $user->spacing->getAbsolute();
API Responses Return hybrid values in JSON:
return response()->json([
'spacing' => $spacing->getValue(),
]);
FormBuilder to handle hybrid values:
Form::absolutePercentValue('margin', $value, ['class' => 'form-control']);
$width = new AbsolutePercentValue("75% + 20px");
return view('page', ['widthClass' => "w-[{$width->getValue()}]"]);
<script>
const padding = @json($padding->getValue());
</script>
Invalid Syntax
The package expects values in the format "{percent}% + {px}" or "{px}" or "{percent}%".
Fix: Validate input with a regex or custom validator:
$validator->extend('absolute_percent_value', function ($attribute, $value, $parameters, $validator) {
return preg_match('/^(\d+%)?\s*(\+\s*\d+px)?$/', $value);
});
Unit Consistency
The package assumes px for absolute values. If using other units (e.g., rem), extend the class:
class CustomAbsolutePercentValue extends AbsolutePercentValue {
public function getAbsoluteUnit() {
return 'rem';
}
}
Floating-Point Precision
Percent/absolute calculations may have rounding issues. Use round() if needed:
$value = new AbsolutePercentValue("33.333% + 1.5px");
$percent = round($value->getPercent(), 2);
Database Serialization
Ensure the database column can store strings like "50% + 10px". Avoid INTEGER or FLOAT columns.
\Log::debug('Parsed value:', [
'raw' => $value->getValue(),
'percent' => $value->getPercent(),
'absolute' => $value->getAbsolute(),
]);
"")."50% + px", "abc")."0% + 0px").Custom Parsing Logic
Override the parse() method to handle additional formats:
class CustomAbsolutePercentValue extends AbsolutePercentValue {
protected function parse($value) {
// Custom logic here
}
}
Add Units
Extend the class to support rem, em, etc.:
class UnitAwareAbsolutePercentValue extends AbsolutePercentValue {
protected $unit = 'rem';
public function getAbsoluteUnit() {
return $this->unit;
}
}
Validation Rules Create a reusable validation rule:
use Illuminate\Validation\Rule;
Rule::macro('absolute_percent_value', function ($attribute, $value, $parameters) {
return preg_match('/^(\d+%)?\s*(\+\s*\d+px)?$/', $value);
});
Blade Directives Register a Blade directive for cleaner syntax:
Blade::directive('apv', function ($expression) {
return "<?php echo (new \\AbsolutePercentValueBundle\\AbsolutePercentValue({$expression}))->getValue(); ?>";
});
Usage:
<div style="padding: @apv($padding)">...</div>
How can I help you explore Laravel packages today?