Skip to content

Commit

Permalink
add relative-time component (#1650)
Browse files Browse the repository at this point in the history
  • Loading branch information
keithamus committed Dec 6, 2022
1 parent a6c5bb5 commit 2941ba2
Show file tree
Hide file tree
Showing 23 changed files with 534 additions and 32 deletions.
5 changes: 5 additions & 0 deletions .changeset/bright-cows-live.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@primer/view-components': minor
---

Add RelativeTime component
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
160 changes: 160 additions & 0 deletions app/components/primer/beta/relative_time.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
# frozen_string_literal: true

module Primer
module Beta
# Formats a timestamp as a localized string or as relative text that auto-updates in the user's browser.
class RelativeTime < Primer::Component
status :beta

TENSE_DEFAULT = :auto
TENSE_OPTIONS = [TENSE_DEFAULT, :past, :future].freeze

FORMAT_DEFAULT = :auto
FORMAT_OPTIONS = [FORMAT_DEFAULT, :micro, :elapsed].freeze

SECOND_DEFAULT = nil
SECOND_MAPPINGS = {
SECOND_DEFAULT => nil,
:numeric => "numeric",
:two_digit => "2-digit"
}.freeze
SECOND_OPTIONS = SECOND_MAPPINGS.keys

MINUTE_DEFAULT = nil
MINUTE_MAPPINGS = {
MINUTE_DEFAULT => nil,
:numeric => "numeric",
:two_digit => "2-digit"
}.freeze
MINUTE_OPTIONS = MINUTE_MAPPINGS.keys

HOUR_DEFAULT = nil
HOUR_MAPPINGS = {
HOUR_DEFAULT => nil,
:numeric => "numeric",
:two_digit => "2-digit"
}.freeze
HOUR_OPTIONS = HOUR_MAPPINGS.keys

WEEKDAY_DEFAULT = nil
WEEKDAY_OPTIONS = [WEEKDAY_DEFAULT, :long, :short, :narrow].freeze

DAY_DEFAULT = nil
DAY_MAPPINGS = {
DAY_DEFAULT => nil,
:numeric => "numeric",
:two_digit => "2-digit"
}.freeze
DAY_OPTIONS = DAY_MAPPINGS.keys

MONTH_DEFAULT = nil
MONTH_MAPPINGS = {
DAY_DEFAULT => nil,
:numeric => "numeric",
:two_digit => "2-digit",
:short => "short",
:long => "long",
:narrow => "narrow"
}.freeze
MONTH_OPTIONS = MONTH_MAPPINGS.keys

YEAR_DEFAULT = nil
YEAR_MAPPINGS = {
DAY_DEFAULT => nil,
:numeric => "numeric",
:two_digit => "2-digit"
}.freeze
YEAR_OPTIONS = YEAR_MAPPINGS.keys

TIMEZONENAME_DEFAULT = nil
TIMEZONE_MAPPINGS = {
DAY_DEFAULT => nil,
:long => "long",
:short => "short",
:short_offset => "shortOffset",
:long_offset => "longOffset",
:short_generic => "shortGeneric",
:long_generic => "longGeneric"
}.freeze
TIMEZONENAME_OPTIONS = TIMEZONE_MAPPINGS.keys

PRECISION_DEFAULT = nil
PRECISION_OPTIONS = [PRECISION_DEFAULT, :second, :minute, :hour, :day, :month, :year].freeze

# @example Default
# <%= render(Primer::Beta::RelativeTime.new(datetime: Time.at(628232400))) %>
#
# @example Past Time
# <%= render(Primer::Beta::RelativeTime.new(datetime: Time.at(628232400), tense: :past)) %>
#
# @example Elapsed Time
# <%= render(Primer::Beta::RelativeTime.new(datetime: Time.at(628232400), format: :elapsed)) %>
#
# @param datetime [Time] The time to be formatted.
# @param tense [Symbol] Which tense to use. <%= one_of(Primer::Beta::RelativeTime::TENSE_OPTIONS) %>
# @param prefix [sring] What to prefix the relative ime display with.
# @param second [Symbol] What format seconds should take. <%= one_of(Primer::Beta::RelativeTime::SECOND_OPTIONS) %>
# @param minute [Symbol] What format minues should take. <%= one_of(Primer::Beta::RelativeTime::MINUTE_OPTIONS) %>
# @param hour [Symbol] What format hours should take. <%= one_of(Primer::Beta::RelativeTime::HOUR_OPTIONS) %>
# @param weekday [Symbol] What format weekdays should take. <%= one_of(Primer::Beta::RelativeTime::WEEKDAY_OPTIONS) %>
# @param day [Symbol] What format days should take. <%= one_of(Primer::Beta::RelativeTime::DAY_OPTIONS) %>
# @param month [Symbol] What format months should take. <%= one_of(Primer::Beta::RelativeTime::MONTH_OPTIONS) %>
# @param year [Symbol] What format years should take. <%= one_of(Primer::Beta::RelativeTime::YEAR_OPTIONS) %>
# @param time_zone_name [Symbol] What format the time zone should take. <%= one_of(Primer::Beta::RelativeTime::TIMEZONENAME_OPTIONS) %>
# @param threshold [string] The threshold at which relative time displays become absolute.
# @param precision [Symbol] The precision elapsed time should display. <%= one_of(Primer::Beta::RelativeTime::PRECISION_OPTIONS) %>
# @param format [Symbol] The format the display should take. <%= one_of(Primer::Beta::RelativeTime::FORMAT_OPTIONS) %>
# @param lang [string] The language to use.
# @param title [string] Provide a custom title to the element.
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
def initialize(
datetime:,
tense: TENSE_DEFAULT,
prefix: nil,
second: SECOND_DEFAULT,
minute: MINUTE_DEFAULT,
hour: HOUR_DEFAULT,
weekday: WEEKDAY_DEFAULT,
day: DAY_DEFAULT,
month: MONTH_DEFAULT,
year: YEAR_DEFAULT,
time_zone_name: TIMEZONENAME_DEFAULT,
threshold: nil,
precision: PRECISION_DEFAULT,
format: nil,
lang: nil,
title: nil,
**system_arguments
)
@system_arguments = deny_tag_argument(**system_arguments)
@system_arguments[:tag] = "relative-time"
@system_arguments[:tense] = tense if tense.present?
@system_arguments[:prefix] = prefix if prefix.present?
@system_arguments[:second] = fetch_or_fallback(SECOND_OPTIONS, second, SECOND_DEFAULT) if second.present?
@system_arguments[:minute] = fetch_or_fallback(MINUTE_OPTIONS, minute, MINUTE_DEFAULT) if minute.present?
@system_arguments[:hour] = fetch_or_fallback(HOUR_OPTIONS, hour, HOUR_DEFAULT) if hour.present?
@system_arguments[:weekday] = fetch_or_fallback(WEEKDAY_OPTIONS, weekday, WEEKDAY_DEFAULT) if weekday.present?
@system_arguments[:day] = fetch_or_fallback(DAY_OPTIONS, day, DAY_DEFAULT) if day.present?
@system_arguments[:month] = fetch_or_fallback(MONTH_DEFAULT, month, MONTH_DEFAULT) if month.present?
@system_arguments[:year] = fetch_or_fallback(YEAR_OPTIONS, year, YEAR_DEFAULT) if year.present?
@system_arguments[:"time-zone-name"] = fetch_or_fallback(TIMEZONENAME_OPTIONS, time_zone_name, TIMEZONENAME_DEFAULT) if time_zone_name.present?
@system_arguments[:threshold] = threshold if threshold.present?
@system_arguments[:precision] = precision if precision.present?
@system_arguments[:title] = title if title.present?
@system_arguments[:lang] = lang if lang.present?
@system_arguments[:format] = fetch_or_fallback(FORMAT_OPTIONS, format, FORMAT_DEFAULT) if format.present?
if datetime.present? && datetime.respond_to?(:iso8601)
@datetime = datetime
@system_arguments[:datetime] = datetime.iso8601
elsif datetime.present?
@datetime = Time.iso8601 datetime
@system_arguments[:datetime] = @datetime
end
end

def call
render(Primer::BaseComponent.new(**@system_arguments).with_content(@datetime.strftime("%B %-d, %Y %H:%M")))
end
end
end
end
4 changes: 3 additions & 1 deletion app/components/primer/local_time.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ def initialize(datetime:, initial_text: nil, weekday: DEFAULT_TEXT_TYPE, year: D

@datetime = datetime

@system_arguments[:tag] = "local-time"
@system_arguments[:tag] = "relative-time"
@system_arguments[:threshold] = "PT0S"
@system_arguments[:prefix] = ""
@system_arguments[:datetime] = datetime

@initial_text = initial_text
Expand Down
2 changes: 1 addition & 1 deletion app/components/primer/local_time.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
import '@github/time-elements'
import '@github/relative-time-element'
3 changes: 2 additions & 1 deletion app/components/primer/time_ago_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ def initialize(time:, micro: false, **system_arguments)
@system_arguments = deny_tag_argument(**system_arguments)
@system_arguments[:datetime] = time.utc.iso8601
@system_arguments[:classes] = class_names("no-wrap", @system_arguments[:classes])
@system_arguments[:tag] = "time-ago"
@system_arguments[:tag] = "relative-time"
@system_arguments[:tense] = "past"
@system_arguments[:format] = "micro" if micro
@time = time
@micro = micro
Expand Down
2 changes: 1 addition & 1 deletion app/components/primer/time_ago_component.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
import '@github/time-elements'
import '@github/relative-time-element'
2 changes: 2 additions & 0 deletions docs/src/@primer/gatsby-theme-doctocat/nav.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@
url: "/components/beta/popover"
- title: ProgressBar
url: "/components/beta/progressbar"
- title: RelativeTime
url: "/components/beta/relativetime"
- title: SegmentedControl
url: "/components/alpha/segmentedcontrol"
- title: Spinner
Expand Down
1 change: 1 addition & 0 deletions lib/tasks/docs.rake
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ namespace :docs do
# Rails controller for rendering arbitrary ERB
view_context = ApplicationController.new.tap { |c| c.request = ActionDispatch::TestRequest.create }.view_context
components = [
Primer::Beta::RelativeTime,
Primer::Beta::IconButton,
Primer::Beta::Button,
Primer::Alpha::SegmentedControl,
Expand Down
22 changes: 11 additions & 11 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@
"@github/details-menu-element": "^1.0.12",
"@github/image-crop-element": "^5.0.0",
"@github/mini-throttle": "^2.1.0",
"@github/relative-time-element": "^4.0.0",
"@github/tab-container-element": "^3.1.2",
"@github/time-elements": "^3.1.2",
"@primer/behaviors": "^1.2.0"
},
"devDependencies": {
Expand Down
Loading

0 comments on commit 2941ba2

Please sign in to comment.