Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Zen mode button component #69

Merged
merged 9 commits into from
Apr 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/wild-avocados-smash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@openproject/primer-view-components": minor
---

Add `Primer::OpenProject::ZenModeButton` component. By clicking on the button, screen will be in full-mode or back in normal-mode.
11 changes: 11 additions & 0 deletions app/components/primer/open_project/zen_mode_button.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<%= render(Primer::BaseComponent.new(**@system_arguments)) do %>
<%= render(
Primer::Beta::IconButton.new(
scheme: :default,
id: "zenModeButton",
icon: "screen-normal",
aria: { label: I18n.t("zen_mode") },
data: { target: "zen-mode-button.button", action: "click:zen-mode-button#performAction" }
)
) %>
<% end %>
23 changes: 23 additions & 0 deletions app/components/primer/open_project/zen_mode_button.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# frozen_string_literal: true

module Primer
module OpenProject
# Add a general description of component here
# Add additional usage considerations or best practices that may aid the user to use the component correctly.
# @accessibility Add any accessibility considerations
class ZenModeButton < Primer::Component
status :open_project

# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
def initialize(**system_arguments)
@system_arguments = system_arguments
@system_arguments[:tag] = "zen-mode-button"
@system_arguments[:classes] =
class_names(
@system_arguments[:classes],
"ZenModeButton"
)
end
end
end
end
42 changes: 42 additions & 0 deletions app/components/primer/open_project/zen_mode_button.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import {controller, target} from '@github/catalyst'

@controller
class ZenModeButtonElement extends HTMLElement {
@target button: HTMLElement
inZenMode = false

private deactivateZenMode() {
this.inZenMode = false
this.button.setAttribute('aria-pressed', 'false')
if (document.exitFullscreen) {
void document.exitFullscreen()
}
}

private activateZenMode() {
this.inZenMode = true
this.button.setAttribute('aria-pressed', 'true')
if (document.documentElement.requestFullscreen) {
void document.documentElement.requestFullscreen()
}
}

public performAction() {
if (this.inZenMode) {
this.deactivateZenMode()
} else {
this.activateZenMode()
}
}
}

declare global {
interface Window {
ZenModeButtonElement: typeof ZenModeButtonElement
}
}

if (!window.customElements.get('zen-mode-button')) {
window.ZenModeButtonElement = ZenModeButtonElement
window.customElements.define('zen-mode-button', ZenModeButtonElement)
}
1 change: 1 addition & 0 deletions app/components/primer/primer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ import '../../../lib/primer/forms/primer_text_field'
import '../../../lib/primer/forms/toggle_switch_input'
import './alpha/action_menu/action_menu_element'
import './open_project/page_header_element'
import './open_project/zen_mode_button'
22 changes: 22 additions & 0 deletions previews/primer/open_project/zen_mode_button_preview.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# frozen_string_literal: true

# Setup Playground to use all available component props
# Setup Features to use individual component props and combinations

module Primer
module OpenProject
# @label ZenModeButton
class ZenModeButtonPreview < ViewComponent::Preview
# @label Default
# @snapshot
def default
render(Primer::OpenProject::ZenModeButton.new)
end

# @label Playground
def playground
render(Primer::OpenProject::ZenModeButton.new)
end
end
end
end
1 change: 1 addition & 0 deletions test/components/component_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class PrimerComponentTest < Minitest::Test

# Components with any arguments necessary to make them render
COMPONENTS_WITH_ARGS = [
[Primer::OpenProject::ZenModeButton, {}],
[Primer::OpenProject::InputGroup, {}, proc { |component|
component.with_text_input(name: "a name", label: "My input group", value: "Copyable value")
component.with_trailing_action_clipboard_copy_button(id: "button", value: "Copyable value", aria: { label: "Copy some text" })
Expand Down
13 changes: 13 additions & 0 deletions test/components/primer/open_project/zen_mode_button_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true

require "components/test_helper"

class PrimerOpenProjectZenModeButtonTest < Minitest::Test
include Primer::ComponentTestHelpers

def test_renders
render_inline(Primer::OpenProject::ZenModeButton.new)

assert_selector(".ZenModeButton .octicon-screen-normal")
end
end
11 changes: 11 additions & 0 deletions test/system/open_project/zen_mode_button_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# frozen_string_literal: true

require "system/test_case"

class IntegrationOpenProjectZenModeButtonTest < System::TestCase
def test_renders_component
visit_preview(:default)

assert_selector(".ZenModeButton")
end
end
Loading