Skip to content
Draft
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
1 change: 1 addition & 0 deletions public/locales/en/upload-image-modal.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"removeImage": "Remove Image",
"optional": "(Optional)",
"altTextRequired": "Alt text is required",
"imageSourceRequired": "Please upload an image or enter a URL",
"dropTitle": "Drag & drop to upload",
"dropMeta": "Max size: {{maxSize}}MB Recommended: 1200 x 800 px Formats: jpg/jpeg, png",
"uploadFailed": "Image upload failed",
Expand Down
1 change: 1 addition & 0 deletions public/locales/zh-TW/upload-image-modal.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"removeImage": "移除圖片",
"optional": "(選填)",
"altTextRequired": "請輸入替代文字",
"imageSourceRequired": "請填寫圖片 URL 或上傳圖片",
"dropTitle": "拖曳檔案上傳",
"dropMeta": "大小限制:{{maxSize}}MB 建議尺寸:1200 x 800 px 支援格式:jpg/jpeg, png",
"uploadFailed": "圖片上傳失敗",
Expand Down
41 changes: 22 additions & 19 deletions src/components/core/button/primary-button.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,33 @@ const sizeClasses = {
l: 'px-4 py-3 text-base leading-[1.5] disabled:px-[15px] disabled:py-[11px]',
};

const PrimaryButton = React.forwardRef(({ size = 'sm', className, children, ...props }, ref) => {
return (
<button
ref={ref}
type="button"
className={cn(
'flex items-center justify-center bg-primary text-white rounded-lg',
'hover:bg-blue-800',
'focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary',
'disabled:bg-bg-disabled disabled:text-text-disabled disabled:border disabled:border-text-secondary disabled:cursor-not-allowed',
sizeClasses[size],
className
)}
{...props}
>
{children}
</button>
);
});
const PrimaryButton = React.forwardRef(
({ size = 'sm', type = 'button', className, children, ...props }, ref) => {
return (
<button
ref={ref}
type={type}
className={cn(
'flex items-center justify-center bg-primary text-white rounded-lg',
'hover:bg-blue-800',
'focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary',
'disabled:bg-bg-disabled disabled:text-text-disabled disabled:border disabled:border-text-secondary disabled:cursor-not-allowed',
sizeClasses[size],
className
)}
{...props}
>
{children}
</button>
);
}
);

PrimaryButton.displayName = 'PrimaryButton';

PrimaryButton.propTypes = {
size: PropTypes.oneOf(['sm', 'l']),
type: PropTypes.string,
className: PropTypes.string,
children: PropTypes.node,
};
Expand Down
41 changes: 22 additions & 19 deletions src/components/core/button/secondary-button.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,33 @@ const sizeClasses = {
l: 'px-[15px] py-[11px] text-base leading-[1.5]',
};

const SecondaryButton = React.forwardRef(({ size = 'sm', className, children, ...props }, ref) => {
return (
<button
ref={ref}
type="button"
className={cn(
'flex items-center justify-center bg-white text-text-primary border border-border-main rounded-lg',
'hover:bg-gray-50',
'focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary',
'disabled:bg-bg-disabled disabled:text-text-disabled disabled:border disabled:border-text-secondary disabled:cursor-not-allowed',
sizeClasses[size],
className
)}
{...props}
>
{children}
</button>
);
});
const SecondaryButton = React.forwardRef(
({ size = 'sm', type = 'button', className, children, ...props }, ref) => {
return (
<button
ref={ref}
type={type}
className={cn(
'flex items-center justify-center bg-white text-text-primary border border-border-main rounded-lg',
'hover:bg-gray-50',
'focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary',
'disabled:bg-bg-disabled disabled:text-text-disabled disabled:border disabled:border-text-secondary disabled:cursor-not-allowed',
sizeClasses[size],
className
)}
{...props}
>
{children}
</button>
);
}
);

SecondaryButton.displayName = 'SecondaryButton';

SecondaryButton.propTypes = {
size: PropTypes.oneOf(['sm', 'l']),
type: PropTypes.string,
className: PropTypes.string,
children: PropTypes.node,
};
Expand Down
13 changes: 12 additions & 1 deletion src/components/core/modal/basic-modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ const BasicModal = ({
hasConfirm = true,
cancelLabel = 'Cancel',
confirmLabel = 'Confirm',
confirmType = 'button',
confirmForm,
size = 'l',
children,
}) => {
Expand Down Expand Up @@ -47,7 +49,14 @@ const BasicModal = ({
</Button>
)}
{hasConfirm && (
<Button className="w-full" variant="primary" onClick={onConfirm} size={size}>
<Button
className="w-full"
variant="primary"
size={size}
type={confirmType}
form={confirmForm}
onClick={confirmType === 'submit' ? undefined : onConfirm}
>
{confirmLabel}
</Button>
)}
Expand All @@ -66,6 +75,8 @@ BasicModal.propTypes = {
cancelLabel: PropTypes.string,
onConfirm: PropTypes.func,
confirmLabel: PropTypes.string,
confirmType: PropTypes.oneOf(['button', 'submit']),
confirmForm: PropTypes.string,
title: PropTypes.string,
children: PropTypes.node,
hasCancel: PropTypes.bool,
Expand Down
17 changes: 14 additions & 3 deletions src/components/home/setting-modal/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,29 @@ const SettingModal = ({ isOpen, onClose, onSubmit, displayConfig, exportType, se
onClose();
}, [onSubmit, onClose, localConfig, exportType, fileName]);

const handleFormSubmit = (e) => {
e.preventDefault();
onConfirm();
};

return (
<BasicModal
title={t('title')}
isOpen={isOpen}
hasCancel={true}
onClose={onClose}
onCancel={onClose}
onConfirm={onConfirm}
cancelLabel={t('cancel')}
confirmLabel={t('submit')}
confirmType="submit"
confirmForm="setting-form"
>
<div className="flex flex-col gap-6">
<form
id="setting-form"
noValidate
onSubmit={handleFormSubmit}
className="flex flex-col gap-6"
>
<TextInput
id="setting-document-title"
label={t('documentTitle')}
Expand Down Expand Up @@ -75,7 +86,7 @@ const SettingModal = ({ isOpen, onClose, onSubmit, displayConfig, exportType, se
value={localConfig.documentColor}
onChange={(val) => updateLocalConfig('documentColor', val)}
/>
</div>
</form>
</BasicModal>
);
};
Expand Down
24 changes: 19 additions & 5 deletions src/components/iframe-input-modal.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState } from 'react';
import React, { useRef, useState } from 'react';
import PropTypes from 'prop-types';
import { useTranslation } from '@/lib/i18n';
import { isValidUrl } from '@/lib/url';
Expand All @@ -10,6 +10,8 @@ const IframeInputModal = ({ isOpen, onClose, onConfirm }) => {
const [url, setUrl] = useState('');
const [titleError, setTitleError] = useState('');
const [urlError, setUrlError] = useState('');
const titleRef = useRef(null);
const urlRef = useRef(null);
const t = useTranslation('iframe-input-modal');

const resetForm = () => {
Expand All @@ -32,24 +34,35 @@ const IframeInputModal = ({ isOpen, onClose, onConfirm }) => {
if (isTitleEmpty) setTitleError(t('titleRequiredError'));
if (isUrlEmpty) setUrlError(t('urlRequiredError'));
else if (isUrlInvalid) setUrlError(t('urlInvalidError'));
if (isTitleEmpty || isUrlEmpty || isUrlInvalid) return;
if (isTitleEmpty || isUrlEmpty || isUrlInvalid) {
if (isTitleEmpty) titleRef.current?.focus();
else urlRef.current?.focus();
return;
}

onConfirm(title.trim(), url.trim());
handleClose();
};

const handleFormSubmit = (e) => {
e.preventDefault();
handleConfirm();
};

return (
<BasicModal
title={t('title')}
isOpen={isOpen}
onClose={handleClose}
onCancel={handleClose}
onConfirm={handleConfirm}
cancelLabel={t('cancel')}
confirmLabel={t('confirm')}
confirmType="submit"
confirmForm="iframe-form"
>
<div className="flex flex-col gap-6">
<form id="iframe-form" noValidate onSubmit={handleFormSubmit} className="flex flex-col gap-6">
<TextInput
ref={titleRef}
id="iframe-title"
label={t('titleLabel')}
value={title}
Expand All @@ -63,6 +76,7 @@ const IframeInputModal = ({ isOpen, onClose, onConfirm }) => {
/>

<TextInput
ref={urlRef}
id="iframe-url"
type="url"
label={t('urlLabel')}
Expand All @@ -75,7 +89,7 @@ const IframeInputModal = ({ isOpen, onClose, onConfirm }) => {
error={urlError}
required
/>
</div>
</form>
</BasicModal>
);
};
Expand Down
Loading
Loading