feat: add :date-range property type with year/month/day precision + ranges#12643
feat: add :date-range property type with year/month/day precision + ranges#12643ricardo37 wants to merge 11 commits into
Conversation
|
@ricardo37 :date-range looks great, can you add tests and maybe record a video on this feature? |
|
I see that you can add not only a range but also individual dates, like select the year "2021" or the month "January 2021". This is awesome. |
|
I'm glad the proposed change would prove useful for other purposes too. I hadn't actually compiled the code to see if it works; I just wanted to get the basic idea out there. But I see now the existing code falls at the very first hurdle. In any case, I've started working on the video and tests and will make them available as soon as I can. |
|
Here is a short video demonstrating some of the main features of the PR. daterange-demo.mp4 |
… range support
A new :date-range property type lets users attach temporal metadata at
varying granularities — a full year ("2026"), a month ("May 2026"), or a
specific day ("May 13, 2026") — and optionally pair any two of those into
a start/end range.
Storage
-------
Each value is a lightweight DataScript entity (no :block/uuid) with three
new schema attributes:
:logseq.property.date/precision — keyword :year | :month | :day
:logseq.property.date/start — YYYYMMDD integer
:logseq.property.date/end — YYYYMMDD integer (absent for single-point dates)
The entity type is identified in malli_schema/entity-dispatch-key by the
presence of :logseq.property.date/precision, and validated by the new
date-range-value malli schema.
Type system changes
-------------------
• :date-range added to user-built-in-property-types (after :date in UI order)
• :date-range added to cardinality-property-types (supports :many)
• :date-range added to user-ref-property-types (value stored as DB ref)
• date-range? predicate added to built-in-validation-schemas
• :date-range added to property-types-with-db (validation needs DB)
• "logseq.property.date" added to logseq-property-namespaces
UI
--
• New frontend.components.date-range-picker namespace with:
- format-label — human-readable display string
- year-picker — ‹ year › navigation
- month-grid — 4×3 month grid with year navigation
- day-calendar — delegates to existing ui/nlp-calendar
- endpoint-picker — single-date picker (switches on precision)
- date-range-picker-inner — full popup with precision chips and
"Add end" / "Single date" toggle
• date-range-picker-trigger wired into property-value-date-picker
• <find-or-create-date-range-entity! handles entity dedup/creation
• property.cljs and value.css updated to treat :date-range like :date
(inline layout, cursor-pointer, calendar-range icon)
• en.edn: :property/type-date-range "Date range"
• property/config.cljs: property-type-label case for :date-range
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add :daterange to property type system (malli schema, type sets, view sorting) - New date-range picker component: year/month/day precision, optional end date, free-text input with multi-format parser, space-hyphen trigger for range mode - Tests: type-set membership, DB validation, value-entity validation, sort behaviour (year/month/day precision, range values, nil handling)
fdca492 to
00e2c73
Compare
Year-precision start values were stored as yyyy0101 and month-precision as yyyymm01, requiring the sort code to compensate. Store them directly in the canonical form (yyyy0000, yyyymm00) so sort keys equal stored values, and simplify view.cljs sort-val accordingly. Update all tests to match the new storage format.
|
Cool proof of concept but from a UX perspective (imagining a non technical user) i would like to see Date, DateTime and DateRange unified in one date picker UI… 🤔 |
I entirely agree. I've proposed this approach only because I thought it might get a quicker implementation than one that involved altering the two existing date-related types. |
Makes a lot of sense! From a design perspective i have another suggestion: it would be great if the different states of the picker wouldn't change width (so switching between Year | Month | Day). Height changes i think are tolerable, but a consistent width makes it more easy on the eyes. |
|
@scheinriese Good advice; I'll work on implementing that change. |
- Add precision-from-int helper; derive display format from the integer encoding (yyyy0000/yyyymm00/yyyymmdd) so :precision key is no longer required by format-label - Replace single ::precision atom with ::start-precision / ::end-precision so start and end dates can have independent Year/Month/Day precision; each endpoint column now has its own precision-button row - set-start-precision! / set-end-precision! adjust the draft integer to the new precision and update the text box immediately (fix for month switch from year: use (max m 1) to avoid collapsing to yyyy0000 format) - endpoint-picker uses fixed height: 330px (not min-height) so the pop-over never resizes when switching precision or toggling range mode - Start label kept in DOM via visibility:hidden when not in range mode, preventing height drop on "Remove end" - Live-parse on-change: fix prev-text sentinel so clearing the box when the picker opens onto an existing range correctly collapses range mode; restore " -" → show end calendar behaviour (blank p2 no longer hides it) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
727b6af to
8c6847b
Compare
|
I've modified the code to ensure that both width and height of the datepicker remain constant as the precision level varies. In the process I also added the possibility for start and end dates to be of different precision levels. The attached video illustrates these changes. datepicker-test.mp4 |
|
Hi, just checking in on this PR. Happy to address any feedback. Could you approve the CI workflows when you get a chance? |
Summary
Adds a new :date-range property type that lets users specify dates at a range of granularities and optionally with an end date for the chosen level of granularity.
The existing :date and :datetime types are unchanged (though there is no reason the proposed new property couldn't eventually just replace the existing :date property).
Storage
Each value is a lightweight DataScript entity (no :block/uuid) with three new schema attributes:
:logseq.property.date/precision:year|:month|:day:logseq.property.date/start:logseq.property.date/endThe entity type is identified in malli_schema/entity-dispatch-key by the presence of :logseq.property.date/precision, and validated by the new date-range-value malli schema.
Files changed
deps/db/.../schema.cljsdeps/db/.../property.cljs"logseq.property.date"namespace registereddeps/db/.../property/type.cljs:date-rangein 6 sets/mapsdeps/db/.../malli_schema.cljsdate-range-valueschema + dispatch keysrc/.../date_range_picker.cljssrc/.../property/value.cljs:date-rangedisplay + entity creationsrc/.../property/value.csssrc/.../property.cljssrc/.../property/config.cljsproperty-type-labelcasesrc/resources/dicts/en.edn"Date range"i18n stringUI
The new picker (date-range-picker-inner) provides:
Test plan
🤖 Generated with Claude Code