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
32 changes: 0 additions & 32 deletions apps/react/src/components/Button.tsx

This file was deleted.

2 changes: 1 addition & 1 deletion apps/react/src/components/CardOptionsMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { EllipsisVerticalIcon } from '@heroicons/react/24/outline';
import React from 'react';
import { Menu, MenuButton } from '@headlessui/react';
import { DropdownMenu, DropdownItem } from './DropdownMenu';
import { CircleHover } from './CircleHover';
import { CircleHover } from './ui/CircleHover';
import { InputModal } from './modals/InputModal';
import { ConfirmModal } from './modals/ConfirmModal';
import { VisibilityModal } from './modals/VisibilityModal';
Expand Down
2 changes: 1 addition & 1 deletion apps/react/src/components/ConsoleErrorsButton.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { ExclamationTriangleIcon } from '@heroicons/react/24/outline';
import { CircleHover } from './CircleHover';
import { CircleHover } from './ui/CircleHover';
import { Modal } from './modals/Modal';
import { useConsoleErrors } from '../utils/useConsoleErrors';
import { isIOSDebug } from '../utils/isIOSDebug';
Expand Down
2 changes: 1 addition & 1 deletion apps/react/src/components/FlashCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import React, { forwardRef } from 'react';
import { IS_TEST_ENV } from '../utils/constants';
import { FlashCardOptionsMenu } from './FlashCardOptionsMenu';
import { MultiSheetCardQuestion } from './FlashCards/MultiSheetCardQuestion';
import { Pill } from './Pill';
import { Pill } from './ui/Pill';

type Placement = 'cur' | 'scheduled' | 'answered';

Expand Down
2 changes: 1 addition & 1 deletion apps/react/src/components/FlashCardDeleteButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { deleteCard } from 'MemoryFlashCore/src/redux/actions/delete-card-action
import { CardWithAttempts } from 'MemoryFlashCore/src/redux/selectors/currDeckCardsWithAttempts';
import { useAppDispatch } from 'MemoryFlashCore/src/redux/store';
import { useIsCardOwner } from '../utils/useIsCardOwner';
import { CircleHover } from './CircleHover';
import { CircleHover } from './ui/CircleHover';
import { ConfirmModal } from './modals/ConfirmModal';

interface FlashCardDeleteButtonProps {
Expand Down
2 changes: 1 addition & 1 deletion apps/react/src/components/FlashCardEditButton.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { PencilSquareIcon } from '@heroicons/react/24/outline';
import { CardWithAttempts } from 'MemoryFlashCore/src/redux/selectors/currDeckCardsWithAttempts';
import { useIsCardOwner } from '../utils/useIsCardOwner';
import { CircleHover } from './CircleHover';
import { CircleHover } from './ui/CircleHover';

interface FlashCardEditButtonProps {
card: CardWithAttempts;
Expand Down
2 changes: 1 addition & 1 deletion apps/react/src/components/FlashCardOptionsMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { EllipsisVerticalIcon } from '@heroicons/react/24/outline';
import React from 'react';
import { Menu, MenuButton } from '@headlessui/react';
import { DropdownMenu, DropdownItem } from './DropdownMenu';
import { CircleHover } from './CircleHover';
import { CircleHover } from './ui/CircleHover';
import { ConfirmModal } from './modals/ConfirmModal';
import { useNavigate } from 'react-router-dom';
import { useIsCardOwner } from '../utils/useIsCardOwner';
Expand Down
2 changes: 1 addition & 1 deletion apps/react/src/components/FlashCards/RevealAnswerModal.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import { Modal } from '../modals/Modal';
import { MusicNotation } from '../MusicNotation';
import { Button } from '../Button';
import { Button } from '../ui/Button';
import { AnswerType, Card, CardTypeEnum, ChordMemoryAnswer } from 'MemoryFlashCore/src/types/Cards';

export const canRevealAnswer = (card: Card): boolean => {
Expand Down
2 changes: 1 addition & 1 deletion apps/react/src/components/OpenSettingsButton.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { Cog6ToothIcon } from '@heroicons/react/24/outline';
import { CircleHover } from './CircleHover';
import { CircleHover } from './ui/CircleHover';
import { isIOSDebug } from '../utils/isIOSDebug';

export const OpenSettingsButton: React.FC = () => {
Expand Down
34 changes: 27 additions & 7 deletions apps/react/src/components/SegmentButton.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,40 @@
import clsx from 'clsx';

interface SegmentedButtonProps {
text: string;
Icon?: (props: { color: string }) => JSX.Element;
active: boolean;
onClick: () => void;
variant?: 'default' | 'compact';
}

export const SegmentButton: React.FC<SegmentedButtonProps> = ({ text, Icon, active, onClick }) => {
export const SegmentButton: React.FC<SegmentedButtonProps> = ({
text,
Icon,
active,
onClick,
variant = 'default',
}) => {
return (
<div
<button
type="button"
onClick={onClick}
className={`cursor-pointer p-2 flex flex-1 justify-center items-center rounded-lg text-base font-medium ${
active ? 'text-white bg-blue-600' : 'text-black bg-transparent'
} space-x-0.5`}
className={clsx(
'cursor-pointer flex flex-1 justify-center items-center rounded-md font-medium',
variant === 'default' && 'p-2 text-base space-x-0.5',
variant === 'compact' && 'px-3 py-1 text-xs',
variant === 'default' && active && 'text-white bg-blue-600',
variant === 'default' && !active && 'text-black dark:text-white bg-transparent',
variant === 'compact' &&
active &&
'bg-gray-900 text-white dark:bg-gray-100 dark:text-gray-900',
variant === 'compact' &&
!active &&
'text-gray-800 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700',
)}
>
{Icon && <Icon color={active ? '#fff' : ''} />}
<div>{text}</div>
</div>
<span>{text}</span>
</button>
);
};
15 changes: 15 additions & 0 deletions apps/react/src/components/feedback/EmptyState.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react';
import clsx from 'clsx';

interface EmptyStateProps {
message: string;
className?: string;
}

export const EmptyState: React.FC<EmptyStateProps> = ({ message, className }) => {
return (
<p className={clsx('text-center text-gray-500 dark:text-gray-400 py-8', className)}>
{message}
</p>
);
};
4 changes: 4 additions & 0 deletions apps/react/src/components/feedback/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export * from './Spinner';
export * from './Toast';
export * from './ErrorCard';
export * from './EmptyState';
27 changes: 16 additions & 11 deletions apps/react/src/components/index.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
export * from './Layout';
// UI Components
export * from './ui';

// Layout Components
export * from './layout';

// Feedback Components
export * from './feedback';

// Form Inputs
export * from './inputs';

// Modals
export * from './modals';

// Other Components
export * from './FlashCard';
export * from '../screens/StudyScreen/StudyScreen';
export * from './SectionCard';
export * from './SectionData';
export * from './SectionHeader';
export * from './SegmentHeader';
export * from './graphics';
export * from './AuthForm';
export * from './inputs';
export * from './Button';
export * from './modals/Modal';
export * from './modals/InputModal';
export * from './modals/ConfirmModal';
export * from './modals/VisibilityModal';
export * from './CardOptionsMenu';
export * from './ConsoleErrorsButton';
export * from './TranspositionSelector';
Expand Down
11 changes: 11 additions & 0 deletions apps/react/src/components/inputs/SearchInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react';
import { BaseInput, BaseInputProps } from './BaseInput';

export type SearchInputProps = Omit<BaseInputProps, 'type'>;

export const SearchInput = React.forwardRef<HTMLInputElement, SearchInputProps>(
({ className = '', ...props }, ref) => (
<BaseInput ref={ref} type="text" className={`py-2 px-3 ${className}`} {...props} />
),
);
SearchInput.displayName = 'SearchInput';
1 change: 1 addition & 0 deletions apps/react/src/components/inputs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ export * from './Select';
export * from './Checkbox';
export * from './DurationSelect';
export * from './NumberInput';
export * from './SearchInput';
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import { ChevronLeftIcon, ArrowPathIcon, GlobeAltIcon } from '@heroicons/react/2
import clsx from 'clsx';
import React from 'react';
import { Link, useLocation, useNavigate } from 'react-router-dom';
import { CircleHover } from './CircleHover';
import { MidiInputsDropdown } from './MidiInputsDropdown';
import { AccountNavButton } from './navigation/AccountNavButton';
import { isIOSDebug } from '../utils/isIOSDebug';
import { ConsoleErrorsButton } from './ConsoleErrorsButton';
import { StreakChip } from './StreakChip';
import { CircleHover } from '../ui/CircleHover';
import { MidiInputsDropdown } from '../MidiInputsDropdown';
import { AccountNavButton } from '../navigation/AccountNavButton';
import { isIOSDebug } from '../../utils/isIOSDebug';
import { ConsoleErrorsButton } from '../ConsoleErrorsButton';
import { StreakChip } from '../StreakChip';

interface LayoutProps {
children: React.ReactNode;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useCallback } from 'react';
import { Card } from './Card';
import { Card } from '../ui/Card';
import { useNavigate } from 'react-router-dom';

interface SectionCardProps {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { ChevronDownIcon } from '@heroicons/react/24/solid';
import { CircleHover } from './CircleHover';
import { CircleHover } from '../ui/CircleHover';

interface SectionHeaderProps {
title: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { iconDisplay } from '../mocks/icon';
import { SegmentButton } from './SegmentButton';
import { iconDisplay } from '../../mocks/icon';
import { SegmentButton } from '../ui/SegmentButton';

interface SegmentHeaderProps {
segments: string[];
Expand Down
5 changes: 5 additions & 0 deletions apps/react/src/components/layout/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export * from './Layout';
export * from './SectionCard';
export * from './SectionData';
export * from './SectionHeader';
export * from './SegmentHeader';
30 changes: 10 additions & 20 deletions apps/react/src/components/modals/ConfirmModal.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react';
import { Modal, ModalProps } from './Modal';
import { ModalButtons } from './ModalButtons';

export interface ConfirmModalProps extends Omit<ModalProps, 'children' | 'title'> {
message: string;
Expand All @@ -20,25 +21,14 @@ export const ConfirmModal: React.FC<ConfirmModalProps> = ({
<div className="px-6">
<div className="mt-3 mb-6 text-center sm:mt-0 sm:text-left">{message}</div>
</div>
<div className="mt-8 sm:flex sm:pl-4 gap-3 justify-end bg-gray-50 px-6 pt-3 pb-4 border-t border-gray-100">
<button
type="button"
data-autofocus
onClick={onClose}
className="mt-3 inline-flex w-full justify-center rounded-md bg-white px-3 py-2 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50 sm:mt-0 sm:w-auto mb-3 sm:mb-0"
>
Cancel
</button>
<button
type="button"
onClick={() => {
onConfirm();
onClose();
}}
className="inline-flex w-full justify-center rounded-md bg-red-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-red-500 sm:w-auto"
>
{confirmText}
</button>
</div>
<ModalButtons
onCancel={onClose}
onConfirm={() => {
onConfirm();
onClose();
}}
confirmText={confirmText}
confirmVariant="danger"
/>
</Modal>
);
18 changes: 2 additions & 16 deletions apps/react/src/components/modals/InputModal.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useEffect, useState } from 'react';
import { Modal, ModalProps } from './Modal';
import { InputField } from '../inputs';
import { ModalButtons } from './ModalButtons';

export interface InputModalProps extends Omit<ModalProps, 'children' | 'title'> {
label: string;
Expand Down Expand Up @@ -43,22 +44,7 @@ export const InputModal: React.FC<InputModalProps> = ({
/>
</div>
</div>
<div className="mt-8 sm:flex sm:pl-4 gap-3 justify-end bg-gray-50 px-6 pt-3 pb-4 border-t border-gray-100">
<button
type="button"
onClick={onClose}
className="mt-3 inline-flex w-full justify-center rounded-md bg-white px-3 py-2 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50 sm:mt-0 sm:w-auto mb-3 sm:mb-0"
>
Cancel
</button>
<button
type="button"
onClick={handle}
className="inline-flex w-full justify-center rounded-md bg-blue-500 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-blue-400 sm:w-auto"
>
{saveText}
</button>
</div>
<ModalButtons onCancel={onClose} onConfirm={handle} confirmText={saveText} />
</Modal>
);
};
40 changes: 40 additions & 0 deletions apps/react/src/components/modals/ModalButtons.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React from 'react';
import { Button, ButtonVariant } from '../ui/Button';

export interface ModalButtonsProps {
onCancel: () => void;
onConfirm: () => void;
cancelText?: string;
confirmText?: string;
confirmVariant?: ButtonVariant;
confirmDisabled?: boolean;
}

export const ModalButtons: React.FC<ModalButtonsProps> = ({
onCancel,
onConfirm,
cancelText = 'Cancel',
confirmText = 'Confirm',
confirmVariant = 'primary',
confirmDisabled = false,
}) => {
return (
<div className="mt-8 sm:flex sm:pl-4 gap-3 justify-end bg-gray-50 px-6 pt-3 pb-4 border-t border-gray-100 dark:bg-gray-900 dark:border-gray-700">
<Button
variant="outline"
onClick={onCancel}
className="mt-3 w-full sm:mt-0 sm:w-auto mb-3 sm:mb-0"
>
{cancelText}
</Button>
<Button
variant={confirmVariant}
onClick={onConfirm}
disabled={confirmDisabled}
className="w-full sm:w-auto"
>
{confirmText}
</Button>
</div>
);
};
Loading