Skip to content
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
87 changes: 87 additions & 0 deletions solidjs-tailwind/src/components/RepoFilter/FilterDropdown.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import {
createSignal,
Show,
onCleanup,
splitProps,
For,
Switch,
Match,
} from 'solid-js';
import { CaretIcon, CloseIcon, CorrectIcon } from '../icons';

function clickOutside(el, accessor) {
const onClick = (e) => {
!el.contains(e.target) && accessor()?.();
};
document.body.addEventListener('click', onClick);

onCleanup(() => document.body.removeEventListener('click', onClick));
}

const FilterDropdown = (props) => {
const [local] = splitProps(props, ['name', 'title', 'items', 'selectOption']);
const [showOptions, setShowOptions] = createSignal(false);
const toggleOption = () => setShowOptions(!showOptions());

return (
<div
class="relative inline-block text-left"
use:clickOutside={() => setShowOptions(false)}
>
<div>
<button
onClick={toggleOption}
type="button"
class="inline-flex w-full justify-center items-center gap-2 rounded-md border border-gray-300 bg-white px-4 py-1.5 text-sm font-medium text-gray-700 shadow-sm hover:bg-gray-50 focus:outline-none"
id="menu-button"
aria-expanded="true"
aria-haspopup="true"
>
{local.name}
<CaretIcon />
</button>
</div>
<Show when={showOptions()}>
<div
class="absolute right-0 z-10 mt-2 w-56 origin-top-right divide-y divide-gray-100 rounded-md bg-white shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none"
role="menu"
aria-orientation="vertical"
aria-labelledby="menu-button"
tabindex="-1"
>
<div class="flex justify-between items-center text-sm text-gray-600 px-3 py-1">
<strong class="capitalize text-xs">Select {local.name}</strong>
<button onClick={() => setShowOptions(false)}>
<CloseIcon />
</button>
</div>
<For each={local.items}>
{(item, index) => (
<div
data-index={index()}
class="py-1 transition delay-[50ms] hover:bg-gray-300 cursor-pointer"
role="none"
onClick={() => local.selectOption(item)}
>
<span
class="text-gray-700 px-4 py-2 text-sm flex items-center gap-3"
role="menuitem"
tabindex="-1"
>
<Switch fallback={<span class="mr-4" />}>
<Match when={item === 'All'}>
<CorrectIcon />
</Match>
</Switch>
{item}
</span>
</div>
)}
</For>
</div>
</Show>
</div>
);
};

export default FilterDropdown;
63 changes: 63 additions & 0 deletions solidjs-tailwind/src/components/RepoFilter/FilterText.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { Show, splitProps } from 'solid-js';
import { CloseIcon } from '../icons';

const modifyFilterTypeText = (filterText = 'test') => {
if (filterText.endsWith('s')) {
if (filterText.match(new RegExp('forks', 'i'))) {
filterText = filterText.replace('s', 'ed');
} else {
filterText = filterText.replace('s', '');
}
}
return filterText;
};

const FilterText = (props) => {
const [local] = splitProps(props, ['username']);

return (
<div class="flex justify-between items-center border-b border-b-gray-300 pb-4">
<div class="flex-grow">
<small class="text-sm lowercase flex items-baseline gap-1">
{/* <length of filtered array */}
<strong>{/**Filtered repo length */}</strong>
results for
{/* <!-- repo type --> */}
<Show when={true}>
<strong>{modifyFilterTypeText(/**filter type */)}</strong>
</Show>
repositories
{/* search text */}
<Show when={true}>
<span>
matching <strong> {/**search */} </strong>
</span>
</Show>
{/* Language */}
<Show when={true}>
<span>
written in
<strong> {/** language */} </strong>
</span>
</Show>
sorted by
{/* Sorted text */}
<strong>{/**Sort by */}</strong>
</small>
</div>
<div>
<a
href={'/' + local.username}
class="flex items-center clear-filter group hover:text-blue-600 transition-colors delay-[60ms] no-underline gap-2 text-sm"
>
<span class="text-white rounded-md bg-gray-500 group-hover:bg-blue-600 transition-colors delay-[60ms] w-4 h-4">
<CloseIcon />
</span>
Clear filter
</a>
</div>
</div>
);
};

export default FilterText;
13 changes: 13 additions & 0 deletions solidjs-tailwind/src/components/RepoFilter/RepoFIlter.stories.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import RepoFilter from './RepoFilter';

export default {
title: 'components/ Repo filter',
argTypes: {},
};

const Template = (args) => <RepoFilter {...args} />;

export const Default = Template.bind({});
Default.args = {
repoText: 'New',
};
62 changes: 62 additions & 0 deletions solidjs-tailwind/src/components/RepoFilter/RepoFilter.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { mergeProps, Show } from 'solid-js';
import { RepoBookIcon } from '../icons';
import { FILTER_TYPE_OPTIONS, SORT_OPTIONS } from './data';
import FilterDropdown from './FilterDropdown';
import FilterText from './FilterText';
import SearchInput from './SearchInput';

const RepoFilter = (props) => {
const typeOptions = Object.values(FILTER_TYPE_OPTIONS);
const sortOptions = Object.values(SORT_OPTIONS);
const languageOptions = ['All', 'HTML', 'CSS', 'PHP'];

const merged = mergeProps({ repoBtnText: 'New' }, props);

const selectLanguage = (value) => console.log(value);
const selectType = (value) => console.log(value);
const selectSort = (value) => console.log(value);
const isOnlySorted = true;

return (
<>
<div class="flex relative mb-4 space-x-4 border-b border-b-gray-300 pb-4">
<div class="flex space-x-4 flex-1">
<div class="flex-grow">
<SearchInput />
</div>
<div class="flex items-center space-x-1.5">
<FilterDropdown
name="Type"
items={typeOptions}
selectOption={selectType}
/>
<FilterDropdown
name="Language"
items={languageOptions}
selectOption={selectLanguage}
/>
<FilterDropdown
name="Sort"
items={sortOptions}
selectOption={selectSort}
/>
</div>
</div>
<div>
<a
href="https://github.com/new"
class="flex items-center text-white gap-2 bg-green-600 rounded-md px-3 py-1.5 text-sm font-semibold"
>
<RepoBookIcon />
<span> {merged.repoBtnText} </span>
</a>
</div>
</div>
<Show when={!isOnlySorted}>
<FilterText username="hdjerry" />
</Show>
</>
);
};

export default RepoFilter;
17 changes: 17 additions & 0 deletions solidjs-tailwind/src/components/RepoFilter/RepoFilter.store.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { createSignal } from 'solid-js';

const [search, setSearch] = createSignal('');
const [language, setLanguage] = createSignal('');
const [sortBy, setSortBy] = createSignal('');
const [sortType, setSortType] = createSignal('');

export {
search,
language,
sortBy,
sortType,
setSearch,
setLanguage,
setSortBy,
setSortType,
};
18 changes: 18 additions & 0 deletions solidjs-tailwind/src/components/RepoFilter/SearchInput.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { setSearch } from './RepoFilter.store';

const SearchInput = () => {
const handleChange = (e) => {
setSearch(e.target.value);
};
return (
<input
placeholder="find a repository.."
role="search"
type="search"
onKeyUp={handleChange}
class="border p-1.5 focus:ring-2 focus:ring-blue-500 focus:border-blue-500 block w-full sm:text-sm border-gray-300 rounded-md outline-none"
/>
);
};

export default SearchInput;
14 changes: 14 additions & 0 deletions solidjs-tailwind/src/components/RepoFilter/data.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export const defaultFilterType = 'All';
export const defaultLanguage = 'All';
export const defaultSortBy = 'Last updated';

export const FILTER_TYPE_OPTIONS = {
default: defaultFilterType,
forks: 'Forks',
archived: 'Archived',
};
export const SORT_OPTIONS = {
default: defaultSortBy,
name: 'Name',
stars: 'Stars',
};
1 change: 1 addition & 0 deletions solidjs-tailwind/src/components/RepoFilter/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as RepoFilter } from './RepoFilter';
15 changes: 15 additions & 0 deletions solidjs-tailwind/src/components/icons/caret.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const CaretIcon = () => (
<svg
aria-hidden="true"
height="1rem"
viewBox="0 0 16 16"
version="1.1"
width="1rem"
data-view-component="true"
fill="currentColor"
>
<path d="M4.427 7.427l3.396 3.396a.25.25 0 00.354 0l3.396-3.396A.25.25 0 0011.396 7H4.604a.25.25 0 00-.177.427z" />
</svg>
);

export default CaretIcon;
20 changes: 20 additions & 0 deletions solidjs-tailwind/src/components/icons/close.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const CloseIcon = () => (
<svg
aria-label="Close menu"
aria-hidden="false"
role="img"
height="1rem"
viewBox="0 0 16 16"
version="1.1"
width="1rem"
data-view-component="true"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M3.72 3.72a.75.75 0 011.06 0L8 6.94l3.22-3.22a.75.75 0 111.06 1.06L9.06 8l3.22 3.22a.75.75 0 11-1.06 1.06L8 9.06l-3.22 3.22a.75.75 0 01-1.06-1.06L6.94 8 3.72 4.78a.75.75 0 010-1.06z"
/>
</svg>
);

export default CloseIcon;
18 changes: 18 additions & 0 deletions solidjs-tailwind/src/components/icons/correct.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const CorrectIcon = () => (
<svg
height="1rem"
viewBox="0 0 16 16"
version="1.1"
width="1rem"
fill="none"
xmlns="http://www.w3.org/2000/svg"
id="correct"
>
<path
fill="currentColor"
d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"
/>
</svg>
);

export default CorrectIcon;
4 changes: 4 additions & 0 deletions solidjs-tailwind/src/components/icons/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export { default as CaretIcon } from './caret';
export { default as CloseIcon } from './close';
export { default as CorrectIcon } from './correct';
export { default as RepoBookIcon } from './repo-book';
19 changes: 19 additions & 0 deletions solidjs-tailwind/src/components/icons/repo-book.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const RepoBookIcon = () => (
<svg
height="1rem"
viewBox="0 0 16 16"
version="1.1"
width="1rem"
fill="none"
xmlns="http://www.w3.org/2000/svg"
id="book"
>
<path
fill="currentColor"
fill-rule="evenodd"
d="M2 2.5A2.5 2.5 0 014.5 0h8.75a.75.75 0 01.75.75v12.5a.75.75 0 01-.75.75h-2.5a.75.75 0 110-1.5h1.75v-2h-8a1 1 0 00-.714 1.7.75.75 0 01-1.072 1.05A2.495 2.495 0 012 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 011-1h8zM5 12.25v3.25a.25.25 0 00.4.2l1.45-1.087a.25.25 0 01.3 0L8.6 15.7a.25.25 0 00.4-.2v-3.25a.25.25 0 00-.25-.25h-3.5a.25.25 0 00-.25.25z"
/>
</svg>
);

export default RepoBookIcon;
1 change: 1 addition & 0 deletions solidjs-tailwind/src/components/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from './CounterExample';
export * from './FetchExample';
export * from './RepoFilter';
export * from './GistPanel';
export * from './RepoMeta';
export * from './RepoCard';
Expand Down