mirror of
https://github.com/LukeHagar/sveltesociety.dev.git
synced 2025-12-10 04:21:49 +00:00
Refactor clipboard copy + extration of data
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import Tag from '../Tag.svelte';
|
import Tag from '../Tag.svelte';
|
||||||
|
import { copyToClipboard } from '$lib/utils/clipboard';
|
||||||
|
|
||||||
export let active = false;
|
export let active = false;
|
||||||
export let title = '';
|
export let title = '';
|
||||||
export let description = '';
|
export let description = '';
|
||||||
@@ -11,14 +13,12 @@
|
|||||||
export let manager = 'npm';
|
export let manager = 'npm';
|
||||||
|
|
||||||
let clipboardCopy = false;
|
let clipboardCopy = false;
|
||||||
const copyToClipboard = (text) => {
|
|
||||||
navigator.clipboard
|
const copy = () => {
|
||||||
.writeText(text)
|
copyToClipboard(`${packageManagers[manager]}l ${cleanupNpm(npm)}`).then(
|
||||||
.then(() => {
|
() => (clipboardCopy = false)
|
||||||
|
);
|
||||||
clipboardCopy = true;
|
clipboardCopy = true;
|
||||||
setTimeout(() => (clipboardCopy = false), 1000);
|
|
||||||
})
|
|
||||||
.catch(() => alert('Clipboard copy Permission denied'));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const packageManagers = {
|
const packageManagers = {
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
<h3>
|
<h3>
|
||||||
<a href="#component-{encodeURI(title)}">#</a> <a href={url}>{title}</a>
|
<a href="#component-{encodeURI(title)}">#</a> <a href={url}>{title}</a>
|
||||||
{#if npm}<Tag
|
{#if npm}<Tag
|
||||||
click={() => copyToClipboard(`${packageManagers[manager]}l ${cleanupNpm(npm)}`)}
|
click={() => copy()}
|
||||||
variant="copy"
|
variant="copy"
|
||||||
title={clipboardCopy ? 'copied!' : `${packageManagers[manager]} ${cleanupNpm(npm)}`}
|
title={clipboardCopy ? 'copied!' : `${packageManagers[manager]} ${cleanupNpm(npm)}`}
|
||||||
/>{/if}
|
/>{/if}
|
||||||
|
|||||||
7
src/lib/utils/clipboard.ts
Normal file
7
src/lib/utils/clipboard.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
export const copyToClipboard = (text: string): Promise<boolean> =>
|
||||||
|
new Promise<boolean>((resolve) =>
|
||||||
|
navigator.clipboard
|
||||||
|
.writeText(text)
|
||||||
|
.then(() => setTimeout(() => resolve(true), 1000))
|
||||||
|
.catch(() => alert('Clipboard copy Permission denied'))
|
||||||
|
);
|
||||||
17
src/lib/utils/extractUnique.ts
Normal file
17
src/lib/utils/extractUnique.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
export const extractUnique = (
|
||||||
|
source: Array<Record<string, unknown>>,
|
||||||
|
field: string
|
||||||
|
): Array<Record<'label' | 'value', unknown>> => {
|
||||||
|
const extracted = Array.from(new Set(source.map((item) => item[field]).flat()));
|
||||||
|
return extracted
|
||||||
|
.map((value) => ({ label: value, value }))
|
||||||
|
.sort((a, b) => {
|
||||||
|
if (typeof a.value === 'string' && typeof b.value === 'string') {
|
||||||
|
return a.value.toLowerCase().localeCompare(b.value.toLowerCase());
|
||||||
|
}
|
||||||
|
if (typeof a.value === 'number' && typeof b.value === 'number') {
|
||||||
|
return a.value - b.value;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
import '$styles/highlight.css';
|
import '$styles/highlight.css';
|
||||||
import { HighlightSvelte } from 'svelte-highlight';
|
import { HighlightSvelte } from 'svelte-highlight';
|
||||||
import { fly } from 'svelte/transition';
|
import { fly } from 'svelte/transition';
|
||||||
|
import { copyToClipboard } from '$lib/utils/clipboard';
|
||||||
|
|
||||||
export let title = '';
|
export let title = '';
|
||||||
export let content = '';
|
export let content = '';
|
||||||
@@ -9,12 +10,8 @@
|
|||||||
export let repl = '';
|
export let repl = '';
|
||||||
let isCopied = false;
|
let isCopied = false;
|
||||||
function copy() {
|
function copy() {
|
||||||
const element = document.getElementById(title).firstChild;
|
copyToClipboard(content).then(() => (isCopied = false));
|
||||||
if (navigator.clipboard) {
|
|
||||||
navigator.clipboard.writeText(element.innerText);
|
|
||||||
isCopied = true;
|
isCopied = true;
|
||||||
setTimeout(() => (isCopied = false), 1500);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -7,16 +7,15 @@
|
|||||||
import Button from '$components/ComponentIndex/ArrowButton.svelte';
|
import Button from '$components/ComponentIndex/ArrowButton.svelte';
|
||||||
import components from './components.json';
|
import components from './components.json';
|
||||||
import { compare, selectSortItems } from '$lib/utils/sort';
|
import { compare, selectSortItems } from '$lib/utils/sort';
|
||||||
|
import { extractUnique } from '$lib/utils/extractUnique';
|
||||||
import Select from '$components/Select.svelte';
|
import Select from '$components/Select.svelte';
|
||||||
let searchValue;
|
let searchValue;
|
||||||
const tags = Array.from(new Set(components.map((item) => item.tags).flat()));
|
const tagItems = extractUnique(components, 'tags');
|
||||||
const tagItems = tags.map((t) => ({ label: t, value: t }));
|
|
||||||
let filterTag = [];
|
let filterTag = [];
|
||||||
let selectedTags = null;
|
let selectedTags = null;
|
||||||
const allCategories = Array.from(new Set(components.map((item) => item.category).flat()));
|
|
||||||
const categoryItems = [
|
const categoryItems = [
|
||||||
{ label: 'All', value: null },
|
{ label: 'All', value: null },
|
||||||
...allCategories.filter((cat) => cat !== '').map((cat) => ({ label: cat, value: cat }))
|
...extractUnique(components, 'category').filter((cat) => cat.value !== '')
|
||||||
];
|
];
|
||||||
let selectedCategory = null;
|
let selectedCategory = null;
|
||||||
let filterCategory = null;
|
let filterCategory = null;
|
||||||
@@ -45,7 +44,7 @@
|
|||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
.sort(compare(sorting));
|
.sort(compare(sorting));
|
||||||
$: categories = Array.from(new Set(dataToDisplay.map((item) => item.category)));
|
$: categories = extractUnique(dataToDisplay, 'category');
|
||||||
$: filterTag = selectedTags?.map((obj) => obj.value) || [];
|
$: filterTag = selectedTags?.map((obj) => obj.value) || [];
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -101,8 +100,8 @@
|
|||||||
</section>
|
</section>
|
||||||
<section slot="items">
|
<section slot="items">
|
||||||
{#each categories as category}
|
{#each categories as category}
|
||||||
<List title={category || 'Unclassified'}>
|
<List title={category.label || 'Unclassified'}>
|
||||||
{#each dataToDisplay.filter((d) => d.category === category) as data}
|
{#each dataToDisplay.filter((d) => d.category === category.value) as data}
|
||||||
<ComponentCard {...data} manager={$packageManager} />
|
<ComponentCard {...data} manager={$packageManager} />
|
||||||
{/each}
|
{/each}
|
||||||
</List>
|
</List>
|
||||||
|
|||||||
@@ -3,21 +3,17 @@
|
|||||||
import List from '$lib/components/ComponentIndex/CardList.svelte';
|
import List from '$lib/components/ComponentIndex/CardList.svelte';
|
||||||
import components from './templates.json';
|
import components from './templates.json';
|
||||||
import { compare, selectSortItems } from '$lib/utils/sort';
|
import { compare, selectSortItems } from '$lib/utils/sort';
|
||||||
|
import { extractUnique } from '$lib/utils/extractUnique';
|
||||||
import Select from '$lib/components/Select.svelte';
|
import Select from '$lib/components/Select.svelte';
|
||||||
import SearchLayout from '$lib/layouts/SearchLayout.svelte';
|
import SearchLayout from '$lib/layouts/SearchLayout.svelte';
|
||||||
|
|
||||||
let searchValue;
|
let searchValue;
|
||||||
|
|
||||||
const tags = Array.from(new Set(components.map((item) => item.tags).flat()));
|
const tagItems = extractUnique(components, 'tags');
|
||||||
const tagItems = tags.map((t) => ({ label: t, value: t }));
|
|
||||||
let filterTag = [];
|
let filterTag = [];
|
||||||
let selectedTags = null;
|
let selectedTags = null;
|
||||||
|
|
||||||
const allCategories = Array.from(new Set(components.map((item) => item.category).flat()));
|
const categoryItems = [{ label: 'all', value: null }, ...extractUnique(components, 'category')];
|
||||||
const categoryItems = [
|
|
||||||
{ label: 'all', value: null },
|
|
||||||
...allCategories.map((cat) => ({ label: cat, value: cat }))
|
|
||||||
];
|
|
||||||
let selectedCategory = null;
|
let selectedCategory = null;
|
||||||
let filterCategory = null;
|
let filterCategory = null;
|
||||||
|
|
||||||
@@ -49,7 +45,7 @@
|
|||||||
})
|
})
|
||||||
.sort(compare(sorting));
|
.sort(compare(sorting));
|
||||||
|
|
||||||
$: categories = Array.from(new Set(dataToDisplay.map((item) => item.category)));
|
$: categories = extractUnique(dataToDisplay, 'category');
|
||||||
$: filterTag = selectedTags?.map((obj) => obj.value) || [];
|
$: filterTag = selectedTags?.map((obj) => obj.value) || [];
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -92,8 +88,8 @@
|
|||||||
</section>
|
</section>
|
||||||
<section slot="items">
|
<section slot="items">
|
||||||
{#each categories as category}
|
{#each categories as category}
|
||||||
<List title={category || 'Unclassified'}>
|
<List title={category.label || 'Unclassified'}>
|
||||||
{#each dataToDisplay.filter((d) => d.category === category) as data}
|
{#each dataToDisplay.filter((d) => d.category === category.value) as data}
|
||||||
<ComponentCard {...data} />
|
<ComponentCard {...data} />
|
||||||
{/each}
|
{/each}
|
||||||
</List>
|
</List>
|
||||||
|
|||||||
@@ -4,20 +4,17 @@
|
|||||||
import SearchLayout from '$layouts/SearchLayout.svelte';
|
import SearchLayout from '$layouts/SearchLayout.svelte';
|
||||||
import tools from './tools.json';
|
import tools from './tools.json';
|
||||||
import Select from '$lib/components/Select.svelte';
|
import Select from '$lib/components/Select.svelte';
|
||||||
|
import { extractUnique } from '$lib/utils/extractUnique';
|
||||||
import { compare, selectSortItems } from '$lib/utils/sort';
|
import { compare, selectSortItems } from '$lib/utils/sort';
|
||||||
|
import components from '../templates/templates.json';
|
||||||
|
|
||||||
let searchValue;
|
let searchValue;
|
||||||
|
|
||||||
const tags = Array.from(new Set(tools.map((item) => item.tags).flat()));
|
const tagItems = extractUnique(tools, 'tags');
|
||||||
const tagItems = tags.map((t) => ({ label: t, value: t }));
|
|
||||||
let filterTag = [];
|
let filterTag = [];
|
||||||
let selectedTags = null;
|
let selectedTags = null;
|
||||||
|
|
||||||
const allCategories = Array.from(new Set(tools.map((item) => item.category).flat()));
|
const categoryItems = [{ label: 'all', value: null }, ...extractUnique(components, 'category')];
|
||||||
const categoryItems = [
|
|
||||||
{ label: 'all', value: null },
|
|
||||||
...allCategories.map((cat) => ({ label: cat, value: cat }))
|
|
||||||
];
|
|
||||||
let selectedCategory = null;
|
let selectedCategory = null;
|
||||||
let filterCategory = null;
|
let filterCategory = null;
|
||||||
|
|
||||||
@@ -48,7 +45,7 @@
|
|||||||
})
|
})
|
||||||
.sort(compare(sorting));
|
.sort(compare(sorting));
|
||||||
|
|
||||||
$: categories = Array.from(new Set(dataToDisplay.map((item) => item.category)));
|
$: categories = extractUnique(dataToDisplay, 'category');
|
||||||
$: filterTag = selectedTags?.map((obj) => obj.value) || [];
|
$: filterTag = selectedTags?.map((obj) => obj.value) || [];
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -90,8 +87,8 @@
|
|||||||
</section>
|
</section>
|
||||||
<section slot="items">
|
<section slot="items">
|
||||||
{#each categories as category}
|
{#each categories as category}
|
||||||
<List title={category || 'Unclassified'}>
|
<List title={category.label || 'Unclassified'}>
|
||||||
{#each dataToDisplay.filter((d) => d.category === category) as data}
|
{#each dataToDisplay.filter((d) => d.category === category.value) as data}
|
||||||
<ComponentCard {...data} />
|
<ComponentCard {...data} />
|
||||||
{/each}
|
{/each}
|
||||||
</List>
|
</List>
|
||||||
|
|||||||
Reference in New Issue
Block a user