Radish alpha
r
Radicle web interface
Radicle
Git (anonymous pull)
Log in to clone via SSH
Make search bar more interactive
Rūdolfs Ošiņš committed 3 years ago
commit 5cbf8b97dabdcfe5eb8497d5a262a797f33282f9
parent b8b203514b60bae526c55356f71e070116553107
7 files changed +77 -26
modified src/App/Header.svelte
@@ -29,19 +29,12 @@
    display: flex;
    height: var(--button-regular-height);
    align-items: center;
-
    margin-right: 0.5rem;
-
  }
-
  .search {
-
    width: 16rem;
  }

  @media (max-width: 720px) {
    header .right {
      gap: 1rem;
    }
-
    .search {
-
      display: none;
-
    }
  }

  .toggle {
@@ -65,9 +58,7 @@
<header>
  <div class="left">
    <Link route={{ resource: "home" }}><span class="logo"><Logo /></span></Link>
-
    <div class="search">
-
      <Search />
-
    </div>
+
    <Search />
  </div>

  <div class="right">
modified src/App/Header/Search.svelte
@@ -1,25 +1,30 @@
<script lang="ts" strictEvents>
  import debounce from "lodash/debounce";
  import { createEventDispatcher } from "svelte";
-
  import * as router from "@app/lib/router";

  import * as Search from "@app/lib/search";
  import * as modal from "@app/lib/modal";
+
  import * as router from "@app/lib/router";
+
  import { unreachable } from "@app/lib/utils";
+

+
  import Icon from "@app/components/Icon.svelte";
  import SearchResultsModal from "@app/App/Header/SearchResultsModal.svelte";
  import TextInput from "@app/components/TextInput.svelte";
-
  import { unreachable } from "@app/lib/utils";

  const dispatch = createEventDispatcher<{
    finished: never;
  }>();

-
  let input = "";
+
  export let input = "";
  let loading = false;
  let shaking = false;

  // Clears search input on user navigation.
  router.historyStore.subscribe(() => (input = ""));

+
  const collapsedWidth = 13;
+
  const expandedWidth = 20;
+

  function shake() {
    shaking = true;
    debounce(() => (shaking = false), 500)();
@@ -64,6 +69,7 @@
        });
      }
      dispatch("finished");
+
      searchBarWidth = collapsedWidth;
    } else {
      unreachable(searchResult);
    }
@@ -71,6 +77,7 @@
  }

  $: valid = input !== "";
+
  $: searchBarWidth = collapsedWidth;
</script>

<style>
@@ -97,15 +104,31 @@
      transform: translateX(0);
    }
  }
+
  .search {
+
    transition: all 0.2s;
+
  }
+
  @media (max-width: 720px) {
+
    .search {
+
      display: none;
+
    }
+
  }
</style>

-
<div class="search-bar" class:shaking>
-
  <TextInput
-
    variant="dashed"
-
    valid={input !== ""}
-
    {loading}
-
    disabled={loading}
-
    bind:value={input}
-
    on:submit={search}
-
    placeholder="Search a name or address…" />
+
<div class="search" style:width={`${searchBarWidth}rem`}>
+
  <div class="search-bar" class:shaking>
+
    <TextInput
+
      valid={input !== ""}
+
      {loading}
+
      disabled={loading}
+
      bind:value={input}
+
      on:focus={() => (searchBarWidth = expandedWidth)}
+
      on:blur={() =>
+
        input === "" ? (searchBarWidth = collapsedWidth) : undefined}
+
      on:submit={search}
+
      placeholder="Search a name…">
+
      <div slot="left">
+
        <Icon name="magnifying-glass" />
+
      </div>
+
    </TextInput>
+
  </div>
</div>
modified src/App/Hotkeys.svelte
@@ -17,7 +17,7 @@
      case "/": {
        event.preventDefault();
        const searchInput: HTMLElement | null = document.querySelector(
-
          '*[placeholder="Search a name or address…"]',
+
          '*[placeholder="Search a name…"]',
        );
        searchInput?.focus();
        break;
modified src/components/Icon.svelte
@@ -12,6 +12,7 @@
    | "ellipsis"
    | "fork"
    | "gear"
+
    | "magnifying-glass"
    | "moon"
    | "sun"
    | "twitter";
@@ -297,6 +298,18 @@
  1.8701-0.84393 3.4204-0.22929 4.6486 0.6925 1.3838 2.004 2.4102 3.1211 3.0036
  0.15696 0.08337 0.23697 0.26295 0.19401 0.43534-0.042953 0.17246-0.19784
  0.29353-0.37557 0.29353z" />
+
  {:else if name === "magnifying-glass"}
+
    <path
+
      fill-rule="evenodd"
+
      clip-rule="evenodd"
+
      d="M11 6.5C8.51472 6.5 6.5
+
    8.51472 6.5 11C6.5 13.4853 8.51472 15.5 11 15.5C13.4853 15.5 15.5 13.4853
+
    15.5 11C15.5 8.51472 13.4853 6.5 11 6.5ZM5.5 11C5.5 7.96243 7.96243 5.5 11
+
    5.5C14.0376 5.5 16.5 7.96243 16.5 11C16.5 12.3387 16.0217 13.5658 15.2266
+
    14.5195L19.3536 18.6464C19.5488 18.8417 19.5488 19.1583 19.3536
+
    19.3536C19.1583 19.5488 18.8417 19.5488 18.6464 19.3536L14.5195
+
    15.2266C13.5658 16.0217 12.3387 16.5 11 16.5C7.96243 16.5 5.5 14.0376 5.5
+
    11Z" />
  {:else}
    {unreachable(name)}
  {/if}
modified src/components/TextInput.svelte
@@ -21,6 +21,7 @@
  }>();

  let rightContainerWidth: number;
+
  let leftContainerWidth: number;
  let inputElement: HTMLInputElement | undefined = undefined;

  onMount(() => {
@@ -84,6 +85,18 @@
  .dashed:focus {
    background: var(--color-background-1);
  }
+
  .left-container {
+
    color: var(--color-secondary);
+
    position: absolute;
+
    left: 0;
+
    top: 0;
+
    display: flex;
+
    align-items: center;
+
    height: var(--button-regular-height);
+
    padding-right: 0.5rem;
+
    padding-left: 0.5rem;
+
    gap: 0.5rem;
+
  }
  .right-container {
    color: var(--color-secondary);
    position: absolute;
@@ -120,9 +133,18 @@

<div class="wrapper">
  <div class="validation-wrapper">
+
    <div class="left-container" bind:clientWidth={leftContainerWidth}>
+
      {#if $$slots.left}
+
        <slot name="left" />
+
      {/if}
+
    </div>
+

    <input
      class:regular={variant === "regular"}
      class:dashed={variant === "dashed"}
+
      style:padding-left={leftContainerWidth
+
        ? `${leftContainerWidth}px`
+
        : "auto"}
      style:padding-right={rightContainerWidth
        ? `${rightContainerWidth}px`
        : "auto"}
@@ -133,6 +155,8 @@
      {disabled}
      bind:value
      on:input
+
      on:focus
+
      on:blur
      on:keydown|stopPropagation={handleKeydown}
      on:click
      on:change />
modified tests/e2e/hotkeys.spec.ts
@@ -1,6 +1,6 @@
import { test, expect } from "@tests/support/fixtures.js";

-
const searchPlaceholder = "Search a name or address…";
+
const searchPlaceholder = "Search a name…";

test("global hotkeys", async ({ page }) => {
  await page.goto("/");
modified tests/e2e/search.spec.ts
@@ -8,7 +8,7 @@ import {

test("navigate to existing project", async ({ page }) => {
  await page.goto("/");
-
  const searchInput = page.getByPlaceholder("Search a name or address…");
+
  const searchInput = page.getByPlaceholder("Search a name…");
  await searchInput.click();
  await searchInput.fill(`${ridPrefix}${rid}`);
  await searchInput.press("Enter");
@@ -19,7 +19,7 @@ test("navigate to existing project", async ({ page }) => {

test("navigate to a project that does not exist", async ({ page }) => {
  await page.goto("/");
-
  const searchInput = page.getByPlaceholder("Search a name or address…");
+
  const searchInput = page.getByPlaceholder("Search a name…");
  await searchInput.click();

  const nonExistantId = `${ridPrefix}:zt${rid.substring(2)}`;