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
25 changes: 25 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"@coseeing/see-mark": "^1.5.0",
"@headlessui/react": "^1.7.17",
"@heroicons/react": "^2.0.18",
"@tabler/icons-react": "^3.40.0",
"classnames": "^2.3.2",
"codemirror": "^6.0.1",
"core-js": "^3.21.1",
Expand Down
221 changes: 98 additions & 123 deletions src/components/edit-icons-tab.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,136 +40,111 @@ const EditIconsTab = ({ insertLatex, addImageToExport }) => {
);

return (
<div className="flex h-[600px]">
<>
<Tab.Group
as="div"
selectedIndex={selectedMainTabIndex}
onChange={setSelectedMainTabIndex}
className="flex flex-col w-full"
className="flex flex-col w-full h-[600px] border-r border-border-main"
>
<div className="flex bg-cyan p-2">
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

這個檔案 change 比較多,但大部分是因為調整、移除一些應該不需要重複的 DOM node,類似這行,所以造成更往下的 code indent 改變了。

<Tab.List as="div" className="w-full flex bg-cyan">
{mainTabList.map(({ id }, index) => (
<Tab
as="button"
key={id}
className={`rounded flex-1 px-4 py-2 text-sm text-center cursor-pointer transition-colors ${
selectedMainTabIndex === index ? 'bg-white text-black' : 'bg-cyan text-white'
}`}
>
{t(`main.${id}`)}
</Tab>
))}
</Tab.List>
</div>
<div className="flex flex-1 h-full">
<Tab.Panels as="div" className="flex w-full">
<Tab.Panel className="h-full w-full">
<Tab.Group
as="div"
selectedIndex={selectedMathTabIndex}
onChange={setSelectedMathTabIndex}
className="h-full flex"
>
<div className="flex h-full w-full">
<Tab.List
as="div"
className="flex flex-col bg-cyan p-2"
style={{
maxHeight: '550px',
overflowY: 'auto',
scrollbarWidth: 'none', // hide scrollbar in Firefox
msOverflowStyle: 'none', // hide scrollbar in IE/Edge
}}
>
{mathTabList.map((tab, mathTabIndex) => (
<Tooltip key={tab.id} label={t(`categorys.${tab.id}`)} position="right">
<Tab
as="button"
key={tab.id}
aria-label={t(`categorys.${tab.id}`)}
className={`group relative rounded mb-1 category-icon h-12 w-12 flex items-center justify-center mx-0.5 bg-white cursor-pointer transition-colors ${
selectedMathTabIndex === mathTabIndex ? 'active' : ''
}`}
>
<tab.Icon width={48} height={48} />
{selectedMathTabIndex === mathTabIndex && (
// White triangle arrow pointing right to indicate selected tab
<div
className="absolute -right-2 top-1/2 -translate-y-1/2 w-0 h-0"
style={{
borderTop: '8px solid transparent',
borderBottom: '8px solid transparent',
borderLeft: '8px solid white',
}}
/>
)}
</Tab>
</Tooltip>
))}
</Tab.List>
<Tab.Panels
as="div"
className="flex-1 bg-gray-50 border border-gray-300 p-2 overflow-y-auto"
>
{mathTabList.map((mathTab) => {
return (
<Tab.Panel key={mathTab.id} className="flex flex-wrap">
{(mathTab?.subTabs || []).sort(compare('order', 'asc')).map((subTab) => (
<Tooltip
key={subTab.id}
label={t(`latexs.${subTab.id}`)}
position="top"
<Tab.List as="div" className="w-full flex items-center border-b border-border-main">
{mainTabList.map(({ id }, index) => (
<Tab
as="button"
key={id}
className={`rounded-lg flex-1 text-sm text-center leading-[1.5] py-1 focus-visible:outline focus-visible:outline-2 focus-visible:outline-primary m-1 cursor-pointer transition-colors ${
selectedMainTabIndex === index ? 'bg-blue-200 text-primary' : 'text-text-primary'
}`}
>
{t(`main.${id}`)}
</Tab>
))}
</Tab.List>
<Tab.Panels as="div" className="flex flex-1 h-full w-full">
<Tab.Panel className="h-full w-full">
<Tab.Group
as="div"
selectedIndex={selectedMathTabIndex}
onChange={setSelectedMathTabIndex}
className="h-full flex"
>
<div className="flex h-full w-full">
<Tab.List
as="div"
className="flex flex-col px-2 py-3 gap-2 border-r border-border-main"
style={{
maxHeight: '562px',
overflowY: 'auto',
scrollbarWidth: 'none', // hide scrollbar in Firefox
msOverflowStyle: 'none', // hide scrollbar in IE/Edge
}}
>
{mathTabList.map((tab, mathTabIndex) => (
<Tooltip key={tab.id} label={t(`categorys.${tab.id}`)} position="right">
<Tab
as="button"
key={tab.id}
aria-label={t(`categorys.${tab.id}`)}
className={`group relative rounded category-icon flex items-center justify-center cursor-pointer transition-colors focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary ${
selectedMathTabIndex === mathTabIndex
? 'active bg-blue-100'
: 'bg-white hover:bg-blue-100'
}`}
>
<tab.Icon width={52} height={52} />
</Tab>
</Tooltip>
))}
</Tab.List>
<Tab.Panels as="div" className="flex-1 px-2 py-3 overflow-y-auto">
{mathTabList.map((mathTab) => {
return (
<Tab.Panel key={mathTab.id} className="flex flex-wrap gap-2">
{(mathTab?.subTabs || []).sort(compare('order', 'asc')).map((subTab) => (
<Tooltip key={subTab.id} label={t(`latexs.${subTab.id}`)} position="top">
<button
aria-label={t(`latexs.${subTab.id}`)}
className="group relative bg-white rounded border border-gray-200 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary"
onClick={() => insertLatex(subTab)}
>
<button
aria-label={t(`latexs.${subTab.id}`)}
className="w-w5 h-w5 group relative m-1"
onClick={() => insertLatex(subTab)}
>
<subTab.Icon
width={50}
height={50}
className="bg-cyanLight rounded"
/>
</button>
</Tooltip>
))}
</Tab.Panel>
);
})}
</Tab.Panels>
</div>
</Tab.Group>
</Tab.Panel>
<Tab.Panel className="flex flex-wrap content-baseline bg-cyan p-1 h-full">
{markdowns.map((tab) => (
<Tooltip key={tab.id} label={t(`markdown.${tab.id}`)} position="top">
<button
aria-label={t(`markdown.${tab.id}`)}
className="group relative rounded mb-1 h-12 w-12 mx-0.5 bg-white cursor-pointer transition-colors flex items-center justify-center"
onClick={() => {
if (tab.id === 'insert_image') {
setIsImageModalOpen(true);
return;
}
insertLatex(tab);
}}
>
<tab.Icon width={48} height={48} />
</button>
</Tooltip>
))}
</Tab.Panel>
</Tab.Panels>
</div>

<ImageUploadModal
isOpen={isImageModalOpen}
onClose={() => setIsImageModalOpen(false)}
onConfirm={handleImageConfirm}
/>
<subTab.Icon width={50} height={50} className="rounded" />
</button>
</Tooltip>
))}
</Tab.Panel>
);
})}
</Tab.Panels>
</div>
</Tab.Group>
</Tab.Panel>
<Tab.Panel className="flex flex-wrap gap-2 content-baseline px-2 py-3 h-full">
{markdowns.map((tab) => (
<Tooltip key={tab.id} label={t(`markdown.${tab.id}`)} position="top">
<button
aria-label={t(`markdown.${tab.id}`)}
className="group relative rounded bg-white cursor-pointer border border-gray-200 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary flex items-center justify-center"
onClick={() => {
if (tab.id === 'insert_image') {
setIsImageModalOpen(true);
return;
}
insertLatex(tab);
}}
>
<tab.Icon width={50} height={50} />
</button>
</Tooltip>
))}
</Tab.Panel>
</Tab.Panels>
</Tab.Group>
</div>
<ImageUploadModal
isOpen={isImageModalOpen}
onClose={() => setIsImageModalOpen(false)}
onConfirm={handleImageConfirm}
/>
</>
);
};

Expand Down
55 changes: 40 additions & 15 deletions src/components/header/index.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,61 @@
import React, { useState } from 'react';
import PropTypes from 'prop-types';

import { ReactComponent as A8mLogo } from '@/components/svg/a8m-logo.svg';
import Menu from './menu';
import LanguageMenu from './language-menu';
import TipModal from '@/components/home/tip-modal';
import { ReactComponent as QuestionCircleComponent } from '@/components/svg/question-circle.svg';
import { IconBulb } from '@tabler/icons-react';
import { useTranslation } from '@/lib/i18n';
import Button from '@/components/core/button';

const Header = () => {
const Header = ({ onImportClick, onExportClick, title, onTitleChange }) => {
const t = useTranslation('home');
const [showTipModal, setShowTipModal] = useState(false);

return (
<header className="px-8 md:px-20 fixed h-20 flex justify-between items-center bg-white text-md md:text-2xl font-bold inset-x-0 z-10">
<div className="flex">
<h1 className="m-0">Access8Math</h1>
<button
className="hover:scale-110 transition-scale ml-2"
<header className="px-6 fixed h-[72px] flex items-center gap-2 bg-white inset-x-0 z-10 shadow-shadow2">
<div className="flex items-center gap-3 grow">
<h1 className="sr-only">Access8Math</h1>
<A8mLogo aria-hidden="true" />
<input
value={title}
type="text"
style={{ outline: 'none' }}
className="grow max-w-[280px] text-text-primary placeholder-text-placeholder text-xl font-medium leading-[1.4] pb-2 border-b-2 border-primary"
placeholder={t('pleaseInputTitle')}
aria-label={t('pleaseInputTitle')}
onChange={(e) => onTitleChange(e.target.value)}
/>
</div>
<div className="flex items-center gap-3">
<Button
variant="tertiary"
className="min-w-[88px] flex items-center gap-1"
onClick={() => setShowTipModal(true)}
aria-label={t('descript')}
>
<QuestionCircleComponent className="w-5 h-5" />
</button>
</div>
<div className="flex items-center">
<div className="md:mr-12 mr-8">
<LanguageMenu />
</div>
<IconBulb size={16} aria-hidden="true" />
<span>{t('instructions')}</span>
</Button>
<Menu />
<LanguageMenu />
<Button variant="secondary" className="min-w-[88px]" onClick={onImportClick}>
{t('import')}
</Button>
<Button variant="primary" className="min-w-[88px]" onClick={onExportClick}>
{t('export')}
</Button>
</div>
<TipModal isOpen={showTipModal} onClose={() => setShowTipModal(false)} />
</header>
);
};

Header.propTypes = {
onImportClick: PropTypes.func.isRequired,
onExportClick: PropTypes.func.isRequired,
title: PropTypes.string.isRequired,
onTitleChange: PropTypes.func.isRequired,
};

export default Header;
Loading
Loading