add basic layout for Pattern Library.
This commit is contained in:
parent
add11be2b7
commit
d0c1ee2adb
|
@ -1,7 +1,7 @@
|
|||
import { invoke } from '@tauri-apps/api/core';
|
||||
import dayjs from 'dayjs';
|
||||
import { atom } from 'jotai';
|
||||
import { atomFamily } from 'jotai/utils';
|
||||
import { atomFamily, atomWithRefresh } from 'jotai/utils';
|
||||
import { get, reduce } from 'lodash-es';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
|
@ -121,7 +121,7 @@ export function totalDuration(pattern: Pattern): number {
|
|||
}
|
||||
|
||||
export const PatternsAtom = atomFamily((keyword: string) =>
|
||||
atom(async () => {
|
||||
atomWithRefresh(async () => {
|
||||
try {
|
||||
const patterns = await invoke<Pattern[]>('list_patterns', { keyword });
|
||||
return patterns;
|
||||
|
|
|
@ -1,10 +1,27 @@
|
|||
@layer pages {
|
||||
.pattern_list {
|
||||
.patterns {
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
flex: 1;
|
||||
border-radius: calc(var(--border-radius) * 2);
|
||||
background-color: var(--color-surface-container);
|
||||
padding: calc(var(--spacing) * 2);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
gap: calc(var(--spacing) * 2);
|
||||
.search_row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: calc(var(--spacing));
|
||||
}
|
||||
}
|
||||
.pattern_list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
gap: calc(var(--spacing) * 2);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,51 @@
|
|||
import { FC } from 'react';
|
||||
import { Icon } from '@iconify/react/dist/iconify.js';
|
||||
import cx from 'clsx';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import { FC, useState } from 'react';
|
||||
import { useDebounce } from 'react-use';
|
||||
import { ScrollArea } from '../../components/ScrollArea';
|
||||
import { PatternsAtom } from '../../context/Patterns';
|
||||
import styles from './Patterns.module.css';
|
||||
|
||||
const Patterns: FC = () => {
|
||||
const [rawKeyword, setRawKeyword] = useState<string>('');
|
||||
const [keyword, setKeyword] = useState<string | null>(null);
|
||||
const patterns = useAtomValue(PatternsAtom(keyword));
|
||||
|
||||
useDebounce(
|
||||
() => {
|
||||
if (rawKeyword.trim().length > 0) {
|
||||
setKeyword(rawKeyword.trim());
|
||||
} else {
|
||||
setKeyword(null);
|
||||
}
|
||||
},
|
||||
1500,
|
||||
[rawKeyword],
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={styles.pattern_list}>
|
||||
<ScrollArea enableY></ScrollArea>
|
||||
<div className={styles.patterns}>
|
||||
<div className={styles.search_row}>
|
||||
<div className={cx('input_wrapper', 'extendable')}>
|
||||
<Icon icon="material-symbols-light:search" />
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Search patterns..."
|
||||
value={rawKeyword}
|
||||
onChange={(evt) => setRawKeyword(evt.currentTarget.value)}
|
||||
/>
|
||||
</div>
|
||||
<button className="tonal secondary">
|
||||
<Icon icon="material-symbols-light:add" />
|
||||
New Pattern
|
||||
</button>
|
||||
</div>
|
||||
<ScrollArea enableY>
|
||||
<div className={styles.pattern_list}>
|
||||
{patterns.length === 0 && <div className="empty_prompt">No pattern found.</div>}
|
||||
</div>
|
||||
</ScrollArea>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue
Block a user