Skip to content

Commit

Permalink
Deprecate Primer::Dropdown moving to Primer::Alpha::Dropdown (#1625)
Browse files Browse the repository at this point in the history
Co-authored-by: jonrohan <jonrohan@users.noreply.github.com>
  • Loading branch information
jonrohan and jonrohan authored Nov 22, 2022
1 parent 61c8a7d commit 3af9bf5
Show file tree
Hide file tree
Showing 27 changed files with 564 additions and 503 deletions.
9 changes: 9 additions & 0 deletions .changeset/khaki-avocados-notice.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@primer/view-components": patch
---

Deprecate components and moving to new namespace:

- Primer::Dropdown moving to Primer::Alpha::Dropdown
- Primer::Dropdown::Menu moving to Primer::Alpha::Dropdown::Menu
- Primer::Dropdown::Menu::Item moving to Primer::Alpha::Dropdown::Menu::Item
File renamed without changes.
File renamed without changes.
154 changes: 154 additions & 0 deletions app/components/primer/alpha/dropdown.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
# frozen_string_literal: true

module Primer
module Alpha
# `Dropdown` is a lightweight context menu for housing navigation and actions.
# They're great for instances where you don't need the full power (and code) of the SelectMenu.
class Dropdown < Primer::Component
status :alpha

# Required trigger for the dropdown. Has the same arguments as <%= link_to_component(Primer::ButtonComponent) %>,
# but it is locked as a `summary` tag.
renders_one :button, lambda { |**system_arguments|
@button_arguments = system_arguments
@button_arguments[:button] = true
@button_arguments[:dropdown] = @with_caret

Primer::Content.new
}

# Required context menu for the dropdown.
#
# @param as [Symbol] When `as` is `:list`, wraps the menu in a `<ul>` with a `<li>` for each item.
# @param direction [Symbol] <%= one_of(Primer::Alpha::Dropdown::Menu::DIRECTION_OPTIONS) %>
# @param scheme [Symbol] Pass `:dark` for dark mode theming
# @param header [String] Optional string to display as the header
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
renders_one :menu, "Primer::Alpha::Dropdown::Menu"

# @example Default
# <%= render(Primer::Alpha::Dropdown.new) do |c| %>
# <% c.with_button do %>
# Dropdown
# <% end %>
#
# <% c.with_menu(header: "Options") do |menu|
# menu.item { "Item 1" }
# menu.item { "Item 2" }
# menu.item { "Item 3" }
# end %>
# <% end %>
#
# @example With dividers
#
# @description
# Dividers can be used to separate a group of items. They don't have any content.
# @code
# <%= render(Primer::Alpha::Dropdown.new) do |c| %>
# <% c.with_button do %>
# Dropdown
# <% end %>
#
# <% c.with_menu(header: "Options") do |menu|
# menu.item { "Item 1" }
# menu.item { "Item 2" }
# menu.item(divider: true)
# menu.item { "Item 3" }
# menu.item { "Item 4" }
# menu.item(divider: true)
# menu.item { "Item 5" }
# menu.item { "Item 6" }
# end %>
# <% end %>
#
# @example With direction
# <%= render(Primer::Alpha::Dropdown.new(display: :inline_block)) do |c| %>
# <% c.with_button do %>
# Dropdown
# <% end %>
#
# <% c.with_menu(header: "Options", direction: :s) do |menu|
# menu.item { "Item 1" }
# menu.item { "Item 2" }
# menu.item { "Item 3" }
# menu.item { "Item 4" }
# end %>
# <% end %>
#
# @example With caret
# <%= render(Primer::Alpha::Dropdown.new(with_caret: true)) do |c| %>
# <% c.with_button do %>
# Dropdown
# <% end %>
#
# <% c.with_menu(header: "Options") do |menu|
# menu.item { "Item 1" }
# menu.item { "Item 2" }
# menu.item { "Item 3" }
# menu.item { "Item 4" }
# end %>
# <% end %>
#
# @example Customizing the button
# <%= render(Primer::Alpha::Dropdown.new) do |c| %>
# <% c.with_button(scheme: :primary, size: :small) do %>
# Dropdown
# <% end %>
#
# <% c.with_menu(header: "Options") do |menu|
# menu.item { "Item 1" }
# menu.item { "Item 2" }
# menu.item { "Item 3" }
# menu.item { "Item 4" }
# end %>
# <% end %>
#
# @example Menu as list
# <%= render(Primer::Alpha::Dropdown.new) do |c| %>
# <% c.with_button do %>
# Dropdown
# <% end %>
#
# <% c.with_menu(as: :list, header: "Options") do |menu|
# menu.item { "Item 1" }
# menu.item { "Item 2" }
# menu.item(divider: true)
# menu.item { "Item 3" }
# menu.item { "Item 4" }
# end %>
# <% end %>
#
# @example Customizing menu items
# <%= render(Primer::Alpha::Dropdown.new) do |c| %>
# <% c.with_button do %>
# Dropdown
# <% end %>
#
# <% c.with_menu(header: "Options") do |menu|
# menu.item(tag: :button) { "Item 1" }
# menu.item(classes: "custom-class") { "Item 2" }
# menu.item { "Item 3" }
# end %>
# <% end %>
#
# @param overlay [Symbol] <%= one_of(Primer::Beta::Details::OVERLAY_MAPPINGS.keys) %>
# @param with_caret [Boolean] Whether or not a caret should be rendered in the button.
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
def initialize(overlay: :default, with_caret: false, **system_arguments)
@with_caret = with_caret

@system_arguments = system_arguments
@system_arguments[:overlay] = overlay
@system_arguments[:reset] = true
@system_arguments[:classes] = class_names(
@system_arguments[:classes],
"dropdown"
)
end

def render?
button.present? && menu.present?
end
end
end
end
File renamed without changes.
105 changes: 105 additions & 0 deletions app/components/primer/alpha/dropdown/menu.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# frozen_string_literal: true

module Primer
module Alpha
class Dropdown
# This component is part of `Dropdown` and should not be
# used as a standalone component.
class Menu < Primer::Component
status :alpha

AS_DEFAULT = :default
AS_OPTIONS = [AS_DEFAULT, :list].freeze

SCHEME_DEFAULT = :default
SCHEME_MAPPINGS = {
SCHEME_DEFAULT => "",
:dark => "dropdown-menu-dark"
}.freeze

DIRECTION_DEFAULT = :se
DIRECTION_OPTIONS = [DIRECTION_DEFAULT, :sw, :w, :e, :ne, :s].freeze

# @param tag [Symbol] <%= one_of(Primer::Alpha::Dropdown::Menu::Item::TAG_OPTIONS) %>.
# @param divider [Boolean] Whether the item is a divider without any function.
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
renders_many :items, lambda { |divider: false, **system_arguments|
Primer::Alpha::Dropdown::Menu::Item.new(as: @as, divider: divider, **system_arguments)
}

# @param as [Symbol] When `as` is `:list`, wraps the menu in a `<ul>` with a `<li>` for each item.
# @param direction [Symbol] <%= one_of(Primer::Alpha::Dropdown::Menu::DIRECTION_OPTIONS) %>.
# @param header [String] Header to be displayed above the menu.
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
def initialize(as: AS_DEFAULT, direction: DIRECTION_DEFAULT, scheme: SCHEME_DEFAULT, header: nil, **system_arguments)
@header = header
@direction = direction
@as = fetch_or_fallback(AS_OPTIONS, as, AS_DEFAULT)

@system_arguments = deny_tag_argument(**system_arguments)
@system_arguments[:tag] = "details-menu"
@system_arguments[:role] = "menu"

@system_arguments[:classes] = class_names(
@system_arguments[:classes],
"dropdown-menu",
"dropdown-menu-#{fetch_or_fallback(DIRECTION_OPTIONS, direction, DIRECTION_DEFAULT)}",
SCHEME_MAPPINGS[fetch_or_fallback(SCHEME_MAPPINGS.keys, scheme, SCHEME_DEFAULT)]
)
end

private

def list?
@as == :list
end

# Items to be rendered in the `Dropdown` menu.
class Item < Primer::Component
status :alpha

TAG_DEFAULT = :a
BUTTON_TAGS = [:button, :summary].freeze
TAG_OPTIONS = [TAG_DEFAULT, *BUTTON_TAGS].freeze

def initialize(as:, tag: TAG_DEFAULT, divider: false, **system_arguments)
@divider = divider
@as = as

@system_arguments = system_arguments
@system_arguments[:tag] = fetch_or_fallback(TAG_OPTIONS, tag, TAG_DEFAULT)
@system_arguments[:tag] = :li if list? && divider?
@system_arguments[:role] ||= :menuitem
@system_arguments[:role] = :separator if divider
@system_arguments[:classes] = class_names(
@system_arguments[:classes],
"dropdown-item" => !divider,
"dropdown-divider" => divider
)
end

def call
component = if BUTTON_TAGS.include?(@system_arguments[:tag])
Primer::ButtonComponent.new(scheme: :link, **@system_arguments)
else
Primer::BaseComponent.new(**@system_arguments)
end

# divider has no content
render(component) if divider?

render(component) { content }
end

def divider?
@divider
end

def list?
@as == :list
end
end
end
end
end
end
File renamed without changes.
Loading

0 comments on commit 3af9bf5

Please sign in to comment.