Skip to content

fix(panel-app): DatePicker não-nativo para data de nascimento - #457

Open
BrunaDomingues wants to merge 6 commits into
he4rt:4.xfrom
BrunaDomingues:fix/397-birthdate-datepicker
Open

fix(panel-app): DatePicker não-nativo para data de nascimento#457
BrunaDomingues wants to merge 6 commits into
he4rt:4.xfrom
BrunaDomingues:fix/397-birthdate-datepicker

Conversation

@BrunaDomingues

@BrunaDomingues BrunaDomingues commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Substitui o <input type="date"> nativo do perfil por um DatePicker do Filament (native(false)), na seção Pessoal, junto com o nickname.
  • Destaca o dia atual no calendário para melhorar o contraste, especialmente no dark mode.
  • Adiciona ícone de calendário no campo e abre o picker ao clicar nele.

Fixes #397

Test plan

  • Abrir /app/profile e confirmar que "Data de Nascimento" usa o DatePicker do Filament (não o nativo do browser)
  • Abrir o calendário e confirmar que dias de meses adjacentes não aparecem como números ambíguos
  • No dark mode, confirmar que o dia de hoje fica visualmente distinto
  • Clicar no ícone de calendário e confirmar que o painel abre
  • Salvar uma data de nascimento e confirmar que persiste após reload

Mergir o PR #401 antes e resolver conflitos!!!!

BrunaDomingues and others added 4 commits July 26, 2026 20:51
Replace the native date input with a non-native Filament DatePicker in a personal section so adjacent-month days are no longer ambiguous.

Fixes he4rt#397

Co-authored-by: Cursor <cursoragent@cursor.com>
Make the current day easier to spot in dark mode with primary text and a ring.

Co-authored-by: Cursor <cursoragent@cursor.com>
Add a calendar icon to the birthdate field and open the picker when the icon is clicked.

Co-authored-by: Cursor <cursoragent@cursor.com>
Leave the nickname input in the media header so this change stays compatible with the nickname validation flow in he4rt#401. Only birthdate moves to the DatePicker.

Co-authored-by: Cursor <cursoragent@cursor.com>
@BrunaDomingues BrunaDomingues self-assigned this Jul 27, 2026
@BrunaDomingues
BrunaDomingues requested a review from a team July 27, 2026 00:06
Keep the nickname markup aligned with 4.x and cover birthdate in a dedicated test so merges with he4rt#401 stay cleaner.

Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 23772b95-1c4d-4cc2-be67-4e1f42add448

📥 Commits

Reviewing files that changed from the base of the PR and between 3288f3e and 69b1e81.

📒 Files selected for processing (4)
  • app-modules/panel-app/resources/views/components/profile-media-header.blade.php
  • app-modules/panel-app/resources/views/pages/profile.blade.php
  • app-modules/panel-app/src/Pages/ProfilePage.php
  • app-modules/panel-app/tests/Feature/ProfilePageTest.php

📝 Walkthrough

Walkthrough

The profile page now renders birthdate through a dedicated Filament DatePicker with formats, date bounds, an inline calendar icon, and custom click handling. The media header receives and renders the form. CSS updates style the calendar’s today cell and suffix cursor. A feature test verifies submission and persistence.

Suggested reviewers: danielhe4rt

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title matches the main change: replacing the birthdate field with a non-native DatePicker.
Description check ✅ Passed The description is directly related to the DatePicker replacement and its UI behavior.
Linked Issues check ✅ Passed The PR replaces the native birthdate input with a Filament DatePicker, preserves persistence, and adds the requested calendar styling/icon behavior.
Out of Scope Changes check ✅ Passed The CSS and layout updates support the birthdate DatePicker work and do not introduce unrelated changes.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app-modules/panel-app/src/Pages/ProfilePage.php`:
- Around line 103-110: Update the ProfilePage save flow to use the dehydrated
$formData['birthdate'] value when constructing the DTO, rather than
$this->data['birthdate']. Preserve the DatePicker format('Y-m-d') output and
leave the component configuration unchanged.
- Around line 108-109: Update the DatePicker minDate and maxDate calls in the
profile date field to use date-only bounds via today()->subYears(120) and
today(), replacing the current now()-based values. Leave the surrounding picker
configuration unchanged.
- Around line 110-117: Update the suffix-icon interaction in the ProfilePage
date picker so keyboard users can activate the calendar affordance. Make the
suffix action focusable and provide an accessible name, or handle relevant
keyboard events to invoke the existing date-picker trigger, while preserving the
current click behavior and action-wrapper guard.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 53f1a5b4-b570-4a90-9872-a78e18a10606

📥 Commits

Reviewing files that changed from the base of the PR and between 5c8d0bf and 3288f3e.

📒 Files selected for processing (4)
  • app-modules/panel-app/resources/views/components/profile-media-header.blade.php
  • app-modules/panel-app/src/Pages/ProfilePage.php
  • app-modules/panel-app/tests/Feature/ProfilePageTest.php
  • resources/css/filament/app/theme.css

Comment on lines +103 to +110
DatePicker::make('birthdate')
->label(__('panel-app::profile.fields.birthdate'))
->native(condition: false)
->displayFormat('d/m/Y')
->format('Y-m-d')
->minDate(now()->subYears(120))
->maxDate(now())
->suffixIcon(Heroicon::Calendar, isInline: true)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== locate files =="
git ls-files | rg 'ProfilePage\.php|\.php$' | sed -n '1,120p'

echo "== target file outline/size =="
wc -l app-modules/panel-app/src/Pages/ProfilePage.php
ast-grep outline app-modules/panel-app/src/Pages/ProfilePage.php --view expanded || true

echo "== relevant target sections =="
cat -n app-modules/panel-app/src/Pages/ProfilePage.php | sed -n '1,180p'

echo "== search save/formData/birthdate usages =="
rg -n "save|formData|data->|data\[|birthdate|Profile" app-modules/panel-app/src/Pages/ProfilePage.php app-modules/panel-app/src app-modules -g '*.php' | sed -n '1,240p'

Repository: he4rt/heartdevs.com

Length of output: 46770


🌐 Web query:

Filament 5 DateTimePicker format Y-m-d state H:i:s getInternalState save JS

💡 Result:

In Filament, the format() and displayFormat() methods serve different purposes, and understanding their distinction is key to managing how data is handled and stored [1][2]. The format() method is used to define the format of the date/time string when it is saved to the database (or processed by the application) [1][2]. This accepts standard PHP date formatting tokens [1][3]. If you specify ->format('Y-m-d H:i:s'), the internal state will be handled using that format [4]. The displayFormat() method, conversely, is used strictly for how the date is rendered to the user in the browser interface (the frontend) [2][5]. This is particularly useful when using non-native pickers (->native(false)) [1][3]. Regarding your query about "getting internal state" and saving via JavaScript: 1. Filament's DateTimePicker components typically handle state as Carbon instances internally [6]. 2. When you use format(), you are instructing Filament how to format the data when it is dehydrated (prepared for storage or database insertion) [1]. 3. If you are attempting to interact with the component via JavaScript (e.g., in a custom Livewire context), the state of the component is typically managed by Filament's Livewire integration. You should generally rely on the built-in format() method to ensure the data is formatted correctly before it reaches your model or database, rather than trying to manipulate the "internal state" manually via JavaScript, as this bypasses Filament's built-in data handling lifecycle [6]. If you need the data in a specific format for an API or custom JavaScript processing, you should use the format() method on the component definition to ensure consistency [1][2]. If the goal is strictly frontend manipulation, you can use displayFormat() to control the user experience without affecting the saved data format [1].

Citations:


🌐 Web query:

raw.githubusercontent.com filamentphp/filament v5.6.0 packages/forms resources/js/components/date-time-picker.js

💡 Result:

In the Filament PHP framework, the file located at packages/forms/resources/js/components/date-time-picker.js is a core JavaScript component that manages the custom date and time picker functionality [1]. Key details regarding this file and its context within Filament v5.6.0: 1. Functionality: This file defines the Alpine.js component (typically registered as dateTimePickerFormComponent) that powers the date-time-picker form field when it is not using the native browser input mode [1]. It relies on the Day.js library to handle date formatting, localization, and manipulation [2][1]. 2. Evolution in v5.6.0: Filament v5.6.0 was released on April 21, 2026 [3][4]. Throughout the v5.x lifecycle, this file has undergone structural improvements, including refactoring to better align with project standards [5]. For instance, recent updates have focused on moving Alpine.js x-data logic out of Blade views and directly into this JavaScript file, as well as updating event listeners (e.g., switching to x-on:invalid and x-on:blur) [5]. 3. Architecture: The component is built to be modular. While older versions of Filament (v2.x) relied on CommonJS require statements within this file to load Day.js locales—which caused compatibility issues with modern bundlers like Vite—later versions have moved toward cleaner import patterns and optimized bundling processes [6]. 4. Usage: It is internal to the framework's package structure. Developers generally do not interact with this raw file directly; instead, they use the PHP DateTimePicker component in their Laravel/Filament forms, which automatically handles the registration and loading of the necessary JavaScript assets [1].

Citations:


🌐 Web query:

github filamentphp/filament v5.6.0 date-time-picker.js getState format Y-m-d H:i:s

💡 Result:

In Filament v5.6.0, the DateTimePicker component uses 'Y-m-d H:i:s' as its default internal format when the non-native (JavaScript) date picker is enabled [1]. When using the component, you can control the storage format—the format used when the data is saved to your database—by using the format() method [2][3]. If you do not specify a format, Filament defaults to 'Y-m-d H:i:s' for non-native inputs with seconds enabled [1]. Key technical details: - Default Format: When native(false) is used, the component defaults to 'Y-m-d H:i:s' (if seconds are included) [1]. - Storage Format: You can override the default storage format by chaining the format() method to your component definition (e.g., DateTimePicker::make('field')->format('Y-m-d H:i:s')) [2][3]. - Display Format: To change how the date is shown to the user without affecting the storage format, use the displayFormat() method [2][3]. - getState: Note that $getState() retrieves the raw, unformatted value from the model [4]. If you need the formatted state (e.g., for display in a table column), you should use $column->formatState($getState()) instead of relying on $getState() alone [4]. The internal handling of the state within the component is managed by the DateTimeStateCast, which utilizes the format specified in the component definition to parse and format the date-time string [1].

Citations:


Persist the dehydrated birthdate state.

$formData['birthdate'] is dehydrated through the component’s format('Y-m-d'), but save() persists $this->data['birthdate'], which can contain the component’s internal Y-m-d H:i:s value. Use $formData['birthdate'] when building the DTO.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app-modules/panel-app/src/Pages/ProfilePage.php` around lines 103 - 110,
Update the ProfilePage save flow to use the dehydrated $formData['birthdate']
value when constructing the DTO, rather than $this->data['birthdate']. Preserve
the DatePicker format('Y-m-d') output and leave the component configuration
unchanged.

Comment on lines +108 to +109
->minDate(now()->subYears(120))
->maxDate(now())

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Locate file =="
git ls-files | rg '(^|/)ProfilePage\.php$' || true

echo "== Relevant source around date bounds =="
if [ -f "app-modules/panel-app/src/Pages/ProfilePage.php" ]; then
  nl -ba app-modules/panel-app/src/Pages/ProfilePage.php | sed -n '80,120p'
fi

echo "== Search for similar dateTimePicker bounds in repo =="
rg -n "dateTimePicker|->date\(|minDate|maxDate|subYears\(120\)|subYears\(" app-modules/panel-app/src -S || true

echo "== Check local composer/config for Filament version if present =="
for f in composer.json composer.lock app-modules/panel-app/composer.json app-modules/panel-app/composer.lock; do
  [ -f "$f" ] && { echo "-- $f"; rg -n '"filament/php"|"filament.forms"|"filament"' "$f" -A2 -B2 || true; }
done

Repository: he4rt/heartdevs.com

Length of output: 304


🌐 Web query:

Filament v5 dateTimePicker client submits date as UTC midnight minDate maxDate server validation full timestamp

💡 Result:

In Filament v5, the DateTimePicker component handles date and time values by respecting the configured timezone. By default, Filament uses the application's configured timezone (defined in your app config) [1][2]. When a timezone is specified using the timezone() method, the component automatically converts the input to that timezone for display and converts it back to the application's default timezone (usually UTC) upon saving [1][2]. Regarding your specific concerns: Client Submission and UTC: When the form is submitted, Filament handles the data transformation based on the component's timezone() configuration. If a timezone is set (e.g., 'America/New_York'), the picker manages the conversion so that the value saved to the database remains in the application's default timezone (typically UTC) [1][2]. To ensure consistency and avoid "shifting" issues, it is essential to use appropriate Eloquent model casts (e.g., datetime, immutable_datetime) on your model attributes [3]. Without proper casting, or if accessors/mutators conflict, the date values may shift incorrectly during load and save cycles [3]. Midnight and Date-Only Fields: Filament treats DatePicker (date-only) differently than DateTimePicker. For date-only fields, the timezone() method is generally not intended to be used, as this can lead to unexpected date shifts (e.g., saving the day before due to timezone offsets from midnight) [1][2][4]. If you are using a DatePicker, avoid applying a timezone to prevent these issues [1][4]. Server Validation (minDate/maxDate): The minDate() and maxDate() methods perform server-side validation using Laravel's validation rules (after_or_equal and before_or_equal) [5][6]. - These methods accept DateTime instances (such as Carbon) or strings [6][7]. - Filament internally evaluates these values to generate the required validation rules [5]. - When performing validation, ensure that the comparison values passed to minDate() and maxDate() are normalized to the same timezone as your application's stored format (typically UTC) to ensure the validation logic is accurate against the timestamp being saved [6][7]. To troubleshoot unexpected shifts: 1. Ensure your model attributes are properly cast to datetime or immutable_datetime [3]. 2. If using DatePicker (date-only), remove any timezone() calls [1][4]. 3. For DateTimePicker, verify that the timezone() matches the expected user or application context and that you are not performing manual mutations that conflict with Filament's internal handling [1][2][3].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Relevant source around date bounds =="
python3 - <<'PY'
from pathlib import Path
p = Path('app-modules/panel-app/src/Pages/ProfilePage.php')
lines = p.read_text().splitlines()
for i in range(80, 125):
    if i <= len(lines):
        print(f"{i:4d}\t{lines[i-1]}")
PY

echo "== Relevant JavaScript validation snippets from vendor/local repo if available =="
rg -n "minDate|maxDate|DateTimePicker|date\\.toISOString|utcToSystemOffset|systemToUtc" . -S --glob '!vendor/**' --glob '!node_modules/**' || true

echo "== Check for field type and imports =="
python3 - <<'PY'
from pathlib import Path
p = Path('app-modules/panel-app/src/Pages/ProfilePage.php')
text = p.read_text()
for needle in ['DateTimePicker', 'DatePicker', 'now()->subYears', 'today()->subYears']:
    print(f"{needle}: {text.count(needle)}")
PY

Repository: he4rt/heartdevs.com

Length of output: 4743


🌐 Web query:

Filament DateTimePicker minDate maxDate server validation code after_or_equal before_or_equal

💡 Result:

In Filament, you should use the built-in minDate and maxDate methods on the DateTimePicker component to handle both frontend constraints and server-side validation [1][2][3]. When you use these methods, Filament automatically applies the corresponding Laravel validation rules (after_or_equal and before_or_equal) to your form component [4]. Implementation: use Filament\Forms\Components\DateTimePicker; DateTimePicker::make('start_date') ->minDate(now) ->maxDate(now->addDays(7)) How it works: 1. Native Validation: The minDate and maxDate methods internally call the ->rule method on the component [4]. 2. Server Validation: Specifically, minDate adds the after_or_equal rule, and maxDate adds the before_or_equal rule [4]. 3. Dynamic Values: You can pass static dates (like Carbon instances or strings) or closures to these methods to calculate the limits dynamically at runtime [1][3]. If a closure returns null, the validation rule is not applied [1][3]. If you need to perform additional validation against other fields in your form, you should use the dedicated validation methods provided by Filament rather than writing raw strings in a rule method [5][6][7]. For example, to ensure an end_date is after or equal to a start_date, you can use: DateTimePicker::make('end_date') ->afterOrEqual('start_date')

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Check local Filament source/date-time-picker validation if vendor present =="
if [ -d vendor/filamentphp/forms ]; then
  rg -n "Function:minDate|maxDate|Function:validate|\$rules|after_or_equal|before_or_equal|utc_to_datetime|cast" vendor/filamentphp/forms/src -S || true
  python3 - <<'PY'
from pathlib import Path
p = Path('vendor/filamentphp/forms/src/Components/DatePicker.php')
if p.exists():
    for i, line in enumerate(p.read_text().splitlines(), 1):
        if 'minDate' in line or 'maxDate' in line or 'after_or_equal' in line or 'before_or_equal' in line:
            print(f"{p}:{i}:{line}")
PY
else
  echo "vendor/filamentphp/forms not present"
fi

echo "== Check provider DateTimePicker configuration =="
python3 - <<'PY'
from pathlib import Path
for p in [Path('app/Providers/FilamentServiceProvider.php')]:
    if p.exists():
        lines = p.read_text().splitlines()
        for i in range(130, 160):
            if i <= len(lines):
                print(f"{i:4d}\t{lines[i-1]}")
PY

echo "== Locale-specific now behavior probe =="
python3 - <<'PY'
from datetime import datetime
now = datetime.now()
today = now.replace(hour=0, minute=0, second=0, microsecond=0)
lower = today.year - 120
for nd in ["2005-06-01", "2005-06-02"]:
    submitted = datetime.strptime(nd, "%Y-%m-%d")
    print({"now_sub_year_120": lower <= submitted < now, "today_sub_year_120": lower <= submitted < today, "submitted": nd, "now_sub_year_120_boundary": lower, "submitted_date": submitted.date()})
PY

Repository: he4rt/heartdevs.com

Length of output: 1950


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Check GitHub Filament v5.6 DatePicker minDate/maxDate behavior =="
python3 - <<'PY'
from urllib.request import urlopen
for path in [
  "https://raw.githubusercontent.com/filamentphp/filament/v5.6.0/packages/forms/src/Components/DatePicker.php",
  "https://raw.githubusercontent.com/filamentphp/filament/v5.6.0/packages/forms/resources/js/components/date-time-picker.js",
  "https://raw.githubusercontent.com/filamentphp/filament/v5.6.0/packages/forms/src/Components/DateTimePicker.php",
]:
    try:
        text = urlopen(path, timeout=20).read().decode()
    except Exception as e:
        print(f"-- {path}: ERROR {e}")
        continue
    print(f"\n## {path}")
    for needle in ["minDate", "maxDate", "after_or_equal", "before_or_equal", "toISOString", "min-date", "max-date"]:
        idx = text.find(needle)
        if idx != -1:
            start = max(0, idx - 500)
            end = min(len(text), idx + 700)
            print(f"\n>>> {needle}")
            print(text[start:end])
            break
    else:
        print("no date bounds matches")
PY

echo "== Read-only behavioral timestamp boundary illustration =="
python3 - <<'PY'
from datetime import datetime, timedelta
now = datetime.now()
today = now.replace(hour=0, minute=0, second=0, microsecond=0)
today_sub_120 = today - timedelta(days=365*120)
same_day_now_sub_120 = datetime(now.year-120, now.month, now.day, now.hour, now.minute, now.second, now.microsecond)
for submitted in [today_sub_120, now]:
    print(submitted.strftime("%Y-%m-%d %H:%M:%S"))
    print("  after_or_equal(nownow minus 120y):", submitted >= same_day_now_sub_120, " before_or_equal(now):", submitted <= now)
    print("  after_or_equal(today minus 120y):", submitted >= today_sub_120, " before_or_equal(today):", submitted <= today)
PY

Repository: he4rt/heartdevs.com

Length of output: 1379


🌐 Web query:

GitHub raw.githubusercontent.com filamentphp filament v5.6.0 packages forms src Components DatePicker.php minDate

💡 Result:

In Filament v5.6.0, the DatePicker component does not define a minDate property directly within its own class file. Instead, it extends the DateTimePicker component, which handles the minDate logic [1][2]. The DatePicker class primarily serves to restrict the picker to date-only selection by overriding the hasTime() method [1]: public function hasTime: bool { return false; } The minDate functionality is inherited from the DateTimePicker component, which includes a minDate() method to set the minimum allowed date (accepting Carbon instances, strings, or closures) and a getMinDate() method to retrieve the evaluated value [3][2]. Users have noted that when a minDate is set, the picker may default its focused date to the minDate rather than the current date [4][5]. While this has been discussed as intended behavior when the current date falls outside the allowed range, enhancements have been made to the underlying logic in various updates to improve focused date behavior [4][5].

Citations:


Align DatePicker bounds with date-only values.

DatePicker::minDate() / maxDate() are inherited from DateTimePicker and pass these values into timestamp-based validation rules (after_or_equal / before_or_equal). Since this field submits only a date, use today()->subYears(120) and today() so values on the selected day don’t fail before/after comparisons.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app-modules/panel-app/src/Pages/ProfilePage.php` around lines 108 - 109,
Update the DatePicker minDate and maxDate calls in the profile date field to use
date-only bounds via today()->subYears(120) and today(), replacing the current
now()-based values. Leave the surrounding picker configuration unchanged.

Comment on lines +110 to +117
->suffixIcon(Heroicon::Calendar, isInline: true)
->extraAttributes([
// Suffix icon sits outside the trigger button; open the panel on icon click.
'x-on:click' => <<<'JS'
if (! $event.target.closest('.fi-input-wrp-suffix')) return;
if ($event.target.closest('.fi-input-wrp-actions')) return;
$el.querySelector('button.fi-fo-date-time-picker-trigger')?.click();
JS,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== locate files =="
fd -a 'ProfilePage\.php|date-time-picker\.blade\.php' . | sed 's#^\./##' | head -200

echo "== ProfilePage relevant lines =="
file="$(fd 'ProfilePage\.php' . | head -1)"
if [ -n "${file:-}" ]; then
  wc -l "$file"
  sed -n '80,140p' "$file" | cat -n
fi

echo "== search suffix icon / click handling in repo =="
rg -n "suffixIcon|fi-input-wrp-suffix|fi-input-wrp-actions|fi-fo-date-time-picker-trigger|x-on:click|ke[ey]|enter|keydown|keypress" -S .

Repository: he4rt/heartdevs.com

Length of output: 50376


🏁 Script executed:

#!/bin/bash
set -euo pipefail

profile="$(fd -a 'ProfilePage\.php' . | head -1)"
echo "PROFILE=$profile"
if [ -n "$profile" ]; then
  wc -l "$profile"
  sed -n '1,180p' "$profile" | cat -n
fi

echo "== focused search for relevant symbols =="
rg -n "Date\.dateTimes\(|suffixIcon\(|fi-input-wrp-suffix|fi-fo-date-time-picker-trigger|tabindex|key|click\\(|date-time-picker|Calendar\.Heroicon|Heroicon::Calendar" -S app-modules/panel-app/src/Pages/ProfilePage.php || true

Repository: he4rt/heartdevs.com

Length of output: 10445


🌐 Web query:

Filament date time picker blade template suffix icon fi-input-wrp-suffix tab index trigger

💡 Result:

In Filament PHP, the DateTimePicker component handles suffix icons and trigger buttons as part of its core input wrapper [1][2]. Regarding tab index and focus behavior, historical issues involving redundant tab stops in the DateTimePicker were addressed by ensuring appropriate tabindex settings [3]. 1. Suffix Icon and Action Implementation: You can add a suffix icon to a DateTimePicker using the ->suffixIcon method [1][4]. If you need a clickable interaction (such as opening the picker or a custom action), Filament uses suffix actions [5][6]. These are implemented via the ->suffixAction or ->suffixActions methods, which wrap the action in an icon-button view by default [5][7]. 2. Tab Index and Trigger Behavior: Filament specifically manages the tab index of the DateTimePicker's trigger button to ensure seamless keyboard navigation [3]. - Historical Fix: To prevent the input and the trigger button from both stealing focus (which would cause the user to tab twice to exit the component), the trigger button is often configured with tabindex="-1" [3]. This ensures that the primary focus remains on the input field while still allowing the component to be triggered via keyboard interactions (such as the Enter key or specific focus events) [3]. - Accessibility: This design choice aims to provide a consistent focus outline and predictable tab flow across browsers like Chrome and Firefox [3]. If you are encountering unexpected tab index behavior in custom implementations or specific modals, verify if there are conflicting attributes in your custom Blade views or extra attributes [8]. The core component manages these attributes via the InputAttributeBag and internal logic to maintain standardized accessible behavior [9][10]. If you need to customize this, you can use the ->extraTriggerAttributes method on the DateTimePicker to manually override or adjust attributes on the trigger element [2][11].

Citations:


🌐 Web query:

GitHub filamentphp v5.6.0 packages/forms/resources/views/components/date-time-picker.blade.php suffix

💡 Result:

In FilamentPHP v5.6.0, the packages/forms/resources/views/components/date-time-picker.blade.php file manages the rendering of suffix elements (labels, icons, and actions) for the DateTimePicker component [1]. The DateTimePicker component supports suffixes through the HasAffixes trait [2]. You can use the following methods in your component configuration to add or modify suffixes: - suffix(string | Closure | null $suffix): Adds text after the input field [3]. - suffixIcon(string | BackedEnum | bool | null $icon): Adds an icon after the input field [2][4]. - suffixIconColor(string | Closure | null $color): Sets the color of the suffix icon [1][4]. In the Blade view, the component conditionally renders these elements by checking for the presence of a suffix label, icon, or actions, and applies appropriate CSS classes (such as fi-input-has-suffix) to style the input wrapper accordingly [1]. The implementation ensures that the suffix appears correctly alongside the date-time picker trigger [1]. For more information, you can refer to the official FilamentPHP documentation on the Date-time picker component [3].

Citations:


🌐 Web query:

raw.githubusercontent.com filamentphp filament v5.6.0 packages/forms/resources/views/components/date-time-picker.blade.php

💡 Result:

The file packages/forms/resources/views/components/date-time-picker.blade.php in the Filament PHP framework corresponds to the Blade component template for the DateTimePicker form field [1][2]. In version v5.6.0, released on April 21, 2026 [3][4], this component handles rendering the date and time picker input, including logic for configuration such as min/max dates, read-only states, and integration with Alpine.js [1][2]. As of July 27, 2026, version v5.6.0 is an older release in the 5.x series, which has since seen multiple subsequent updates (e.g., v5.6.8, v5.7.0, and v5.7.1) [5][6]. Changes to this specific file in the repository have included bug fixes for SPA mode compatibility and typo corrections (e.g., fixing variable naming such as $isReadonly to $isReadOnly) [7][8][9]. You can view the source code for this component directly on the official Filament GitHub repository for specific versions or the current branch [1][2][6].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== temp raw source =="
tmp="$(mktemp -d)"
curl -LfsS https://raw.githubusercontent.com/filamentphp/filament/v5.6.0/packages/forms/resources/views/components/date-time-picker.blade.php -o "$tmp/date-time-picker.blade.php"
curl -LfsS https://raw.githubusercontent.com/filamentphp/filament/v5.6.0/packages/forms/src/Concerns/HasAffixes.php -o "$tmp/HasAffixes.php"
curl -LfsS https://raw.githubusercontent.com/filamentphp/filament/v5.6.0/packages/forms/resources/views/components/input.blade.php -o "$tmp/input.blade.php" 2>/dev/null || true

echo "== date-time picker relevant snippets =="
grep -nE "suffix|trigger|tabindex|button|input-wrp-suffix|fi-fo-date-time-picker-trigger" "$tmp/date-time-picker.blade.php" "$tmp/HasAffixes.php" || true
sed -n '1,240p' "$tmp/date-time-picker.blade.php" | cat -n

Repository: he4rt/heartdevs.com

Length of output: 230


🌐 Web query:

Filament DateTimePicker suffixIcon interactive button suffix action date-time picker blade

💡 Result:

In Filament, the DateTimePicker component supports interactive buttons via "affix actions" [1]. These are distinct from static suffix icons (added via suffixIcon()) and allow you to add clickable buttons before or after the input field [1]. To add an interactive button to the suffix of a DateTimePicker, use the suffixAction() or suffixActions() method [1]. Example of adding a suffix action: use Filament\Forms\Components\Actions\Action; use Filament\Forms\Components\DateTimePicker; use Filament\Forms\Set; DateTimePicker::make('deadline') ->suffixAction( Action::make('clear') ->icon('heroicon-m-x-mark') ->action(fn (Set $set) => $set('deadline', null))) Key differences: - suffixIcon: Used for static or dynamic decorative icons only [2][3][4]. - suffixAction: Used for interactive buttons that trigger logic, such as updating other fields, clearing inputs, or performing custom operations [1]. You can add multiple actions by passing an array to suffixActions() [1]. All affix actions are rendered as interactive buttons [1].

Citations:


🌐 Web query:

site:raw.githubusercontent.com/filamentphp/filament packages/forms/resources/views/components date-time-picker suffixIcon isInline

💡 Result:

The requested components and methods, such as suffixIcon and isInline, are part of the Filament PHP framework's form builder package, specifically within the DateTimePicker component [1]. In Filament, the DateTimePicker component allows for extensive customization of its appearance and functionality. To utilize the suffixIcon method, you can chain it onto the DateTimePicker component definition to display an icon inside the input field's suffix area. Regarding isInline, this is typically used in form components to control whether the component's label or field structure aligns horizontally rather than the default stacked layout. The file path packages/forms/resources/views/components referenced in your query corresponds to the internal directory structure of the Filament Forms package where the Blade templates for these components reside [1]. Please note that developers generally should not modify these core view files directly, but rather use the fluent API provided by the DateTimePicker class to configure these attributes. You can find the relevant methods defined in the official Filament documentation under the Forms component section for Date Time Picker.

Citations:


🌐 Web query:

"suffixIcon" "isInline" "DateTimePicker" "HasAffixes" filament packages/forms/src/Components/DateTimePicker.php

💡 Result:

In Filament PHP, the DateTimePicker component implements the HasAffixes concern, which provides the functionality to add icons and labels as affixes [1]. The suffixIcon() method is used to define an icon that appears after the input field [2][3][4]. Its signature is defined in the HasAffixes trait as follows [5]: public function suffixIcon(string | Closure | null $icon, bool | Closure $isInline = false): static Parameters: - $icon: The icon to display (e.g., a Heroicon string) [5][4]. - $isInline: A boolean or closure (defaulting to false) that determines whether the icon should be displayed inline with the input's content [5]. When isInline is set to true, the component's underlying view retrieves this state via the isSuffixInline() method [5][6][7], which ensures the icon is rendered correctly within the input's affix container [6][7]. For example, the DateTimePicker uses this internally in its icon() method to force the calendar icon to be rendered inline [8][1]: return $this->suffixIcon($icon?? Heroicon::Calendar, isInline: true); You can use these methods to customize your DateTimePicker by chaining them in your form schema [2][3].

Citations:


Make the custom calendar icon keyboard-accessible.

DatePicker::suffixIcon() renders a non focusable suffix wrapper, and the picker trigger is tabindex="-1", so this click-only affordance is unreachable by keyboard. Use a focusable action/suffix button with an accessible name, or add keyboard handling to call the picker trigger.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app-modules/panel-app/src/Pages/ProfilePage.php` around lines 110 - 117,
Update the suffix-icon interaction in the ProfilePage date picker so keyboard
users can activate the calendar affordance. Make the suffix action focusable and
provide an accessible name, or handle relevant keyboard events to invoke the
existing date-picker trigger, while preserving the current click behavior and
action-wrapper guard.

Render the Filament birthdate picker in the media header next to nickname via a dedicated schema, preserving the original layout.

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Calendário do campo "Data de Nascimento" mistura dias de meses adjacentes sem indicar a qual mês cada um pertence

1 participant