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

Can't find Card component, Autocomplete etc #1737

Open
samad-kanton opened this issue May 24, 2023 · 2 comments
Open

Can't find Card component, Autocomplete etc #1737

samad-kanton opened this issue May 24, 2023 · 2 comments

Comments

@samad-kanton
Copy link

I wish the team could add most used components such as Cards, Autocomplete, Swipeouts and the like

@brunnerh
Copy link
Contributor

brunnerh commented May 24, 2023

There are no such components in the design system, so they will not be here either.

(For containers there would be Tile and an input with multiple options would be ComboBox.)

@dsm-72
Copy link

dsm-72 commented Jun 9, 2023

@brunnerh that is half true. HeaderSearch even has a demo with it.

Here is some of that code (that I modified a bit for myself

<script>
    import { browser } from '$app/environment';

    /**
     * @typedef {{ href: string; text: string; description?: string; }} HeaderSearchResult
     * @event {null} active
     * @event {null} inactive
     * @event {null} clear
     * @event {{ value: string; selectedResultIndex: number; selectedResult: HeaderSearchResult }} select
     * @slot {{ result: HeaderSearchResult; index: number }}
     */
  
    /** Specify the search input value */
    export let value = "";
  
    /** Set to `true` to activate and focus the search bar */
    export let active = false;
  
    /** Obtain a reference to the input HTML element */
    export let ref = null;
  
    /**
     * Render a list of search results
     * @type {ReadonlyArray<HeaderSearchResult>}
     */
    export let results = [];
  
    /** Specify the selected result index */
    export let selectedResultIndex = 0;
  
    import { createEventDispatcher, tick } from "svelte";
    
    import Close from "carbon-icons-svelte/lib/Close.svelte";
    import Query from "carbon-icons-svelte/lib/Query.svelte";

    // import Close from "../icons/Close.svelte";
    // import IconSearch from "../icons/IconSearch.svelte";
  
    const dispatch = createEventDispatcher();
  
    let refSearch = null;
  
    function reset() {
      active = false;
      value = "";      
      selectedResultIndex = 0;
      ref.blur()
    }
  
    function selectResult() {
      dispatch("select", { value, selectedResultIndex, selectedResult });
      reset();
    }
  
    $: if (browser && active && ref) ref.focus();
    $: dispatch(active ? "active" : "inactive");
    $: selectedResult = results[selectedResultIndex];
    $: selectedId = selectedResult
      ? `search-menuitem-${selectedResultIndex}`
      : undefined;
  </script>
  
<svelte:window
    on:mouseup="{({ target }) => {
        if (active && !refSearch.contains(target)) active = false;
    }}"
/>

{#if browser}
<button on:click="{() => { active = true;}}" type="button" class:wrapper="{true}" class:bx--header__action="{true}">
    <div bind:this="{refSearch}" role="search" class:active class="wrapper">
        <label for="search-input" id="search-label">Search</label>
        <div aria-owns="search-menu" aria-haspopup="menu">
            <button
                class:bx--header__action="{true}"                
                class:disabled="{active}"
                type="button"
                class="query"
                on:click="{() => {
                    active = true;
                }}"
            >
                <Query size="{20}" title="Search"  />
            </button>

            <input
                bind:this="{ref}"
                type="text"
                autocomplete="off"
                placeholder="Search..."
                tabindex="{active ? '0' : '-1'}"
                class:active
                {...$$restProps}
                id="search-input"
                aria-autocomplete="list"
                aria-controls="search-menu"
                aria-activedescendant="{selectedId}"
                bind:value
                on:change
                on:input
                on:focus
                on:blur
                on:keydown
                on:keydown="{(e) => {
                switch (e.key) {
                    case 'Enter':
                    selectResult();
                    break;
                    case 'ArrowDown':
                    e.preventDefault();
                    if (selectedResultIndex === results.length - 1) {
                        selectedResultIndex = 0;
                    } else {
                        selectedResultIndex += 1;
                    }
                    break;
                    case 'ArrowUp':
                    e.preventDefault();
                    if (selectedResultIndex === 0) {
                        selectedResultIndex = results.length - 1;
                    } else {
                        selectedResultIndex -= 1;
                    }
                    break;
                }
                }}"
                on:paste
            />

            {#if active && results.length > 0}
            <div class="result-wrapper">
                <div class="ul-wrap">
                    <ul aria-labelledby="search-label" role="menu" id="search-menu">
                        {#each results as result, i}
                        <li role="none">
                            <a
                            tabindex="-1"
                            id="search-menuitem-{i}"
                            role="menuitem"
                            href="{result.href}"
                            class:selected="{selectedId === `search-menuitem-${i}`}"
                            on:click|preventDefault="{async () => {
                                selectedResultIndex = i;
                                await tick();
                                selectResult();
                            }}"
                            >
                            <slot result="{result}" index="{i}">
                                {result.text}
                                {#if result.description}<span>– {result.description}</span>{/if}
                            </slot>
                            </a>
                        </li>
                        {/each}
                    </ul>
                </div> 
            </div>  
            {/if}

            <button
                type="button"
                aria-label="Clear search"
                tabindex="{active ? '0' : '-1'}"
                class:bx--header__action="{true}"
                class:hidden="{!active}"
                on:click="{() => {
                    reset();
                    dispatch('clear');
                }}"
            >
                <Close size="{20}" title="Close" />
            </button>
        </div>
    </div>
</button>
{/if}
  <style>
    .wrapper{
        display: inline-flex;
        width: 100%;
        outline: 0px solid #fff !important;;
        outline-offset: 0px !important;
        border: 0px solid #fff !important;;
        background-color: #fff;

    }

    .wrapper:not(.active):hover{
        background-color: #4c4c4c;
        opacity:1;
        transition: background 0.11s cubic-bezier(0.2, 0, 0.38, 0.9);
    }

    button, label, ul {        
        outline: 0px solid #fff !important;;
        outline-offset: 0px !important;
    }
    .query{
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }

    label {
      position: absolute;
      width: 1px;
      height: 1px;
      margin: -1px;
      padding: 0;
      overflow: hidden;
      white-space: nowrap;
      border: 0;
      visibility: inherit;
      clip: rect(0, 0, 0, 0);
    }
  
    [role="search"] {
      position: relative;
      display: flex;
      /* max-width: 28rem; */
      width: 100%;
      /* margin-left: 0.5rem; */
      height: 3rem;
      background-color: #393939;
      color: #fff;
      transition: max-width 0.11s cubic-bezier(0.2, 0, 0.38, 0.9),
        background 0.11s cubic-bezier(0.2, 0, 0.38, 0.9);
    }
  
    [role="search"]:not(.active) {
      /* max-width: 3rem; */
      background-color: #161616;
    }
  
    [role="search"].active {
      outline: 0px solid #fff !important;;
      outline-offset: 0px !important;
    }
  
    [aria-haspopup="menu"] {
      display: flex;
      flex-grow: 1;
      border-bottom: 1px solid #393939;
    }
  
    input {
      width: 100%;
      height: 3rem;
      padding: 0;
      margin-left: 0.5rem;
      font-size: 1rem;
      font-weight: 400;
      line-height: 1.375rem;
      letter-spacing: 0;
      color: #fff;
      caret-color: #fff;
      background-color: initial;
      border: none;
      outline: none;
      transition: opacity 0.11s cubic-bezier(0.2, 0, 0.38, 0.9);
    }
  
    input:not(.active) {
      opacity: 0;
      pointer-events: none;
    }
  
    button {
      width: 3rem;
      height: 100%;
      padding: 0;
      flex-shrink: 0;
      opacity: 1;
      transition: background-color 0.11s cubic-bezier(0.2, 0, 0.38, 0.9),
        opacity 0.11s cubic-bezier(0.2, 0, 0.38, 0.9);
    }
  
    .disabled {
      border: none;
      pointer-events: none;
    }
  
    [aria-label="Clear search"]:hover {
      background-color: #4c4c4c;
    }
  
    .hidden {
      opacity: 0;
      display: none;
    }
  
    ul {
      position: relative;
      z-index: 10000;
      padding: 1rem 0;
      

      max-width: fit-content;
      /* display: flex; */
      /* justify-content: center; */
      /* flex-direction: column;  */
      width:100%;
      
      
      /* left: 0;
      right: 0; */
      top: 3rem;
      background-color: #161616;
      border: px solid #393939;
      border-top: none;
      box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.5);
    }

    li {
        width:100%;
        /* max-width: fit-content; */
        /* display: inline-flex; */
        /* flex-direction: column; */
        /* justify-content: center; */
        /* justify-self: center;     */
    }

    .ul-wrap {
        display: flex;
        justify-content: space-around;
        width:100%;

        /* display: inline-flex; */
        /* width: 100%;
        justify-content: center;
        align-content: center; 
        align-self: center;
        align-items: center; */
    }

    .result-wrapper {
        position:absolute;
        display: block;
        left: 0;
        right: 0;
        width:100%;

        /* display: inline-flex; */
        /* justify-content: center */
    }
  
    [role="menuitem"] {
        
        text-align: left;
      padding: 6px 1rem;
      cursor: pointer;
      font-size: 0.875rem;
      font-weight: 600;
      line-height: 1.29;
      letter-spacing: 0.16px;
      transition: all 70ms cubic-bezier(0.2, 0, 0.38, 0.9);
      display: block;
      text-decoration: none;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
      color: #c6c6c6;
    }
  
    .selected,
    [role="menuitem"]:hover {
      background-color: #353535;
      color: #f4f4f4;
    }
  
    [role="menuitem"] span {
      font-size: 0.75rem;
      font-weight: 400;
      line-height: 1.34;
      letter-spacing: 0.32px;
      text-transform: lowercase;
      color: #c6c6c6;
    }
  </style>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants