feat: implement preferences pane
This commit is contained in:
22
app/assets/javascripts/components/preferences/index.tsx
Normal file
22
app/assets/javascripts/components/preferences/index.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { FunctionComponent } from 'preact';
|
||||
|
||||
import { toDirective } from '../utils';
|
||||
import { PreferencesView } from './view';
|
||||
|
||||
interface WrapperProps {
|
||||
appState: { preferences: { isOpen: boolean; closePreferences: () => void } };
|
||||
}
|
||||
|
||||
const PreferencesViewWrapper: FunctionComponent<WrapperProps> = observer(
|
||||
({ appState }) => {
|
||||
if (!appState.preferences.isOpen) return null;
|
||||
return (
|
||||
<PreferencesView close={() => appState.preferences.closePreferences()} />
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export const PreferencesDirective = toDirective<WrapperProps>(
|
||||
PreferencesViewWrapper
|
||||
);
|
||||
50
app/assets/javascripts/components/preferences/mock-state.ts
Normal file
50
app/assets/javascripts/components/preferences/mock-state.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import { IconType } from '@/components/Icon';
|
||||
import { action, computed, makeObservable, observable } from 'mobx';
|
||||
|
||||
interface PreferenceItem {
|
||||
icon: IconType;
|
||||
label: string;
|
||||
}
|
||||
|
||||
interface PreferenceListItem extends PreferenceItem {
|
||||
id: number;
|
||||
}
|
||||
|
||||
const predefinedItems: PreferenceItem[] = [
|
||||
{ label: 'General', icon: 'settings-filled' },
|
||||
{ label: 'Account', icon: 'user' },
|
||||
{ label: 'Appearance', icon: 'themes' },
|
||||
{ label: 'Security', icon: 'security' },
|
||||
{ label: 'Listed', icon: 'listed' },
|
||||
{ label: 'Shortcuts', icon: 'keyboard' },
|
||||
{ label: 'Accessibility', icon: 'accessibility' },
|
||||
{ label: 'Get a free month', icon: 'star' },
|
||||
{ label: 'Help & feedback', icon: 'help' },
|
||||
];
|
||||
|
||||
export class MockState {
|
||||
private readonly _items: PreferenceListItem[];
|
||||
private _selectedId = 0;
|
||||
|
||||
constructor(items: PreferenceItem[] = predefinedItems) {
|
||||
makeObservable<MockState, '_selectedId'>(this, {
|
||||
_selectedId: observable,
|
||||
items: computed,
|
||||
select: action,
|
||||
});
|
||||
|
||||
this._items = items.map((p, idx) => ({ ...p, id: idx }));
|
||||
this._selectedId = this._items[0].id;
|
||||
}
|
||||
|
||||
select(id: number) {
|
||||
this._selectedId = id;
|
||||
}
|
||||
|
||||
get items(): (PreferenceListItem & { selected: boolean })[] {
|
||||
return this._items.map((p) => ({
|
||||
...p,
|
||||
selected: p.id === this._selectedId,
|
||||
}));
|
||||
}
|
||||
}
|
||||
33
app/assets/javascripts/components/preferences/pane.tsx
Normal file
33
app/assets/javascripts/components/preferences/pane.tsx
Normal file
@@ -0,0 +1,33 @@
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { FunctionComponent } from 'preact';
|
||||
import { PreferencesMenuItem } from '../PreferencesMenuItem';
|
||||
import { MockState } from './mock-state';
|
||||
|
||||
interface PreferencesMenuProps {
|
||||
store: MockState;
|
||||
}
|
||||
|
||||
const PreferencesMenu: FunctionComponent<PreferencesMenuProps> = observer(
|
||||
({ store }) => (
|
||||
<div className="h-full w-auto flex flex-col px-3 py-6">
|
||||
{store.items.map((pref) => (
|
||||
<PreferencesMenuItem
|
||||
key={pref.id}
|
||||
iconType={pref.icon}
|
||||
label={pref.label}
|
||||
selected={pref.selected}
|
||||
onClick={() => store.select(pref.id)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
);
|
||||
|
||||
export const PreferencesPane: FunctionComponent = () => {
|
||||
const store = new MockState();
|
||||
return (
|
||||
<div className="h-full w-full flex flex-row">
|
||||
<PreferencesMenu store={store}></PreferencesMenu>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
28
app/assets/javascripts/components/preferences/view.tsx
Normal file
28
app/assets/javascripts/components/preferences/view.tsx
Normal file
@@ -0,0 +1,28 @@
|
||||
import { IconButton } from '@/components/IconButton';
|
||||
import { TitleBar, Title } from '@/components/TitleBar';
|
||||
import { FunctionComponent } from 'preact';
|
||||
import { PreferencesPane } from './pane';
|
||||
|
||||
interface PreferencesViewProps {
|
||||
close: () => void;
|
||||
}
|
||||
|
||||
export const PreferencesView: FunctionComponent<PreferencesViewProps> = ({
|
||||
close,
|
||||
}) => (
|
||||
<div className="sn-full-screen flex flex-col bg-contrast z-index-preferences">
|
||||
<TitleBar className="items-center justify-between">
|
||||
{/* div is added so flex justify-between can center the title */}
|
||||
<div className="h-8 w-8" />
|
||||
<Title className="text-lg">Your preferences for Standard Notes</Title>
|
||||
<IconButton
|
||||
onClick={() => {
|
||||
close();
|
||||
}}
|
||||
type="normal"
|
||||
iconType="close"
|
||||
/>
|
||||
</TitleBar>
|
||||
<PreferencesPane />
|
||||
</div>
|
||||
);
|
||||
Reference in New Issue
Block a user