From 51150bf0dd702d2f62265d86bdd722f9d799a9b3 Mon Sep 17 00:00:00 2001
From: Henriette Darge <h.darge@openproject.com>
Date: Mon, 18 Sep 2023 13:21:28 +0200
Subject: [PATCH] Add DragHandlerComponent

---
 .changeset/unlucky-buses-knock.md             |  7 +++++
 .../primer/open_project/drag_handler.html.erb |  6 ++++
 .../primer/open_project/drag_handler.pcss     |  6 ++++
 .../primer/open_project/drag_handler.rb       | 28 +++++++++++++++++++
 app/components/primer/primer.pcss             |  1 +
 .../open_project/drag_handler_preview.rb      | 23 +++++++++++++++
 static/classes.json                           |  3 ++
 test/components/component_test.rb             |  1 +
 .../primer/open_project/drag_handler_test.rb  | 19 +++++++++++++
 test/system/open_project/drag_handler_test.rb | 11 ++++++++
 10 files changed, 105 insertions(+)
 create mode 100644 .changeset/unlucky-buses-knock.md
 create mode 100644 app/components/primer/open_project/drag_handler.html.erb
 create mode 100644 app/components/primer/open_project/drag_handler.pcss
 create mode 100644 app/components/primer/open_project/drag_handler.rb
 create mode 100644 previews/primer/open_project/drag_handler_preview.rb
 create mode 100644 test/components/primer/open_project/drag_handler_test.rb
 create mode 100644 test/system/open_project/drag_handler_test.rb

diff --git a/.changeset/unlucky-buses-knock.md b/.changeset/unlucky-buses-knock.md
new file mode 100644
index 0000000000..4d20935a56
--- /dev/null
+++ b/.changeset/unlucky-buses-knock.md
@@ -0,0 +1,7 @@
+---
+'@openproject/primer-view-components': minor
+---
+
+Add DragHandler component
+
+<!-- Changed components: Primer::OpenProject::DragHandler -->
diff --git a/app/components/primer/open_project/drag_handler.html.erb b/app/components/primer/open_project/drag_handler.html.erb
new file mode 100644
index 0000000000..2a6ff52534
--- /dev/null
+++ b/app/components/primer/open_project/drag_handler.html.erb
@@ -0,0 +1,6 @@
+<%= render Primer::BaseComponent.new(**@system_arguments) do %>
+  <%= render(Primer::Beta::Octicon.new(
+    icon: :grabber,
+    size: @size
+    )) %>
+<% end %>
diff --git a/app/components/primer/open_project/drag_handler.pcss b/app/components/primer/open_project/drag_handler.pcss
new file mode 100644
index 0000000000..63c6bb6b8f
--- /dev/null
+++ b/app/components/primer/open_project/drag_handler.pcss
@@ -0,0 +1,6 @@
+/* CSS for DragHandler  */
+
+.DragHandler {
+    cursor: move;
+    color: var(--fgColor-muted);
+}
diff --git a/app/components/primer/open_project/drag_handler.rb b/app/components/primer/open_project/drag_handler.rb
new file mode 100644
index 0000000000..2027555c31
--- /dev/null
+++ b/app/components/primer/open_project/drag_handler.rb
@@ -0,0 +1,28 @@
+# 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 DragHandler < Primer::Component
+      status :open_project
+
+      DEFAULT_SIZE = Primer::Beta::Octicon::SIZE_DEFAULT
+      SIZE_OPTIONS = Primer::Beta::Octicon::SIZE_OPTIONS
+
+      # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
+      def initialize(size: Primer::OpenProject::DragHandler::DEFAULT_SIZE, **system_arguments)
+        @system_arguments = system_arguments
+        @system_arguments[:tag] = "div"
+        @system_arguments[:classes] =
+          class_names(
+            @system_arguments[:classes],
+            "DragHandler"
+          )
+
+        @size = fetch_or_fallback(Primer::OpenProject::DragHandler::SIZE_OPTIONS, size, Primer::OpenProject::DragHandler::DEFAULT_SIZE)
+      end
+    end
+  end
+end
diff --git a/app/components/primer/primer.pcss b/app/components/primer/primer.pcss
index fd1cc6b4e1..b5f7ac3a9c 100644
--- a/app/components/primer/primer.pcss
+++ b/app/components/primer/primer.pcss
@@ -43,3 +43,4 @@
 
 /* OP specifics */
 @import "./open_project/page_header.pcss";
+@import "./open_project/drag_handler.pcss";
diff --git a/previews/primer/open_project/drag_handler_preview.rb b/previews/primer/open_project/drag_handler_preview.rb
new file mode 100644
index 0000000000..729b4bfcff
--- /dev/null
+++ b/previews/primer/open_project/drag_handler_preview.rb
@@ -0,0 +1,23 @@
+# 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 DragHandler
+    class DragHandlerPreview < ViewComponent::Preview
+      # @label Default
+      # @snapshot
+      def default(size: :small)
+        render(Primer::OpenProject::DragHandler.new(size: size))
+      end
+
+      # @label Playground
+      # @param size [Symbol] select [xsmall, small, medium]
+      def playground(size: :small)
+        render(Primer::OpenProject::DragHandler.new(size: size))
+      end
+    end
+  end
+end
diff --git a/static/classes.json b/static/classes.json
index 03a680a0fe..70634acf2e 100644
--- a/static/classes.json
+++ b/static/classes.json
@@ -233,6 +233,9 @@
   "Counter--secondary": [
     "Primer::Beta::Counter"
   ],
+  "DragHandler": [
+    "Primer::OpenProject::DragHandler"
+  ],
   "FormControl": [
     "Primer::Alpha::TextField"
   ],
diff --git a/test/components/component_test.rb b/test/components/component_test.rb
index 9bc3f3f786..39af22d107 100644
--- a/test/components/component_test.rb
+++ b/test/components/component_test.rb
@@ -8,6 +8,7 @@ class PrimerComponentTest < Minitest::Test
 
   # Components with any arguments necessary to make them render
   COMPONENTS_WITH_ARGS = [
+    [Primer::OpenProject::DragHandler, {}],
     [Primer::OpenProject::PageHeader, {}, proc { |component|
       component.with_title { "Foo" }
     }],
diff --git a/test/components/primer/open_project/drag_handler_test.rb b/test/components/primer/open_project/drag_handler_test.rb
new file mode 100644
index 0000000000..efcc1a7c13
--- /dev/null
+++ b/test/components/primer/open_project/drag_handler_test.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+require "components/test_helper"
+
+class PrimerOpenProjectDragHandlerTest < Minitest::Test
+  include Primer::ComponentTestHelpers
+
+  def test_renders
+    render_inline(Primer::OpenProject::DragHandler.new)
+
+    assert_selector(".DragHandler .octicon")
+  end
+
+  def test_renders_larger_icon
+    render_inline(Primer::OpenProject::DragHandler.new(size: :medium))
+
+    assert_selector(".DragHandler .octicon", width: "24")
+  end
+end
diff --git a/test/system/open_project/drag_handler_test.rb b/test/system/open_project/drag_handler_test.rb
new file mode 100644
index 0000000000..51fd9f2470
--- /dev/null
+++ b/test/system/open_project/drag_handler_test.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+require "system/test_case"
+
+class IntegrationOpenProjectDragHandlerTest < System::TestCase
+  def test_renders_component
+    visit_preview(:default)
+
+    assert_selector(".DragHandler")
+  end
+end