mirror of
https://github.com/johndoe6345789/metabuilder.git
synced 2026-04-26 14:54:55 +00:00
feat(fakemui): add email atom components (icons, buttons)
This commit is contained in:
47
fakemui/react/components/email/atoms/AttachmentIcon.tsx
Normal file
47
fakemui/react/components/email/atoms/AttachmentIcon.tsx
Normal file
@@ -0,0 +1,47 @@
|
||||
import React, { forwardRef } from 'react'
|
||||
import { useAccessible } from '@metabuilder/fakemui/hooks'
|
||||
|
||||
export interface AttachmentIconProps extends React.SVGAttributes<SVGSVGElement> {
|
||||
filename?: string
|
||||
mimeType?: string
|
||||
testId?: string
|
||||
}
|
||||
|
||||
export const AttachmentIcon = forwardRef<SVGSVGElement, AttachmentIconProps>(
|
||||
({ filename, mimeType, testId: customTestId, ...props }, ref) => {
|
||||
const accessible = useAccessible({
|
||||
feature: 'email',
|
||||
component: 'attachment-icon',
|
||||
identifier: customTestId || filename || 'attachment'
|
||||
})
|
||||
|
||||
// Determine icon based on mime type
|
||||
const getIconContent = () => {
|
||||
if (mimeType?.startsWith('image/')) return '🖼️'
|
||||
if (mimeType?.startsWith('video/')) return '🎬'
|
||||
if (mimeType?.startsWith('audio/')) return '🎵'
|
||||
if (mimeType === 'application/pdf') return '📄'
|
||||
return '📎'
|
||||
}
|
||||
|
||||
return (
|
||||
<svg
|
||||
ref={ref}
|
||||
viewBox="0 0 24 24"
|
||||
width="20"
|
||||
height="20"
|
||||
className="attachment-icon"
|
||||
role="img"
|
||||
aria-label={`Attachment: ${filename || 'document'}`}
|
||||
{...accessible}
|
||||
{...props}
|
||||
>
|
||||
<text x="50%" y="50%" dominantBaseline="middle" textAnchor="middle" fontSize="16">
|
||||
{getIconContent()}
|
||||
</text>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
AttachmentIcon.displayName = 'AttachmentIcon'
|
||||
42
fakemui/react/components/email/atoms/MarkAsReadCheckbox.tsx
Normal file
42
fakemui/react/components/email/atoms/MarkAsReadCheckbox.tsx
Normal file
@@ -0,0 +1,42 @@
|
||||
import React, { forwardRef, useState } from 'react'
|
||||
import { useAccessible } from '@metabuilder/fakemui/hooks'
|
||||
|
||||
export interface MarkAsReadCheckboxProps extends React.InputHTMLAttributes<HTMLInputElement> {
|
||||
isRead?: boolean
|
||||
onToggleRead?: (read: boolean) => void
|
||||
testId?: string
|
||||
}
|
||||
|
||||
export const MarkAsReadCheckbox = forwardRef<HTMLInputElement, MarkAsReadCheckboxProps>(
|
||||
({ isRead = false, onToggleRead, testId: customTestId, ...props }, ref) => {
|
||||
const [read, setRead] = useState(isRead)
|
||||
|
||||
const accessible = useAccessible({
|
||||
feature: 'email',
|
||||
component: 'read-checkbox',
|
||||
identifier: customTestId || 'read-status'
|
||||
})
|
||||
|
||||
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const newState = e.target.checked
|
||||
setRead(newState)
|
||||
onToggleRead?.(newState)
|
||||
props.onChange?.(e)
|
||||
}
|
||||
|
||||
return (
|
||||
<input
|
||||
ref={ref}
|
||||
type="checkbox"
|
||||
checked={read}
|
||||
className="read-checkbox"
|
||||
aria-label="Mark as read"
|
||||
{...accessible}
|
||||
{...props}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
MarkAsReadCheckbox.displayName = 'MarkAsReadCheckbox'
|
||||
43
fakemui/react/components/email/atoms/StarButton.tsx
Normal file
43
fakemui/react/components/email/atoms/StarButton.tsx
Normal file
@@ -0,0 +1,43 @@
|
||||
import React, { forwardRef, useState } from 'react'
|
||||
import { useAccessible } from '@metabuilder/fakemui/hooks'
|
||||
|
||||
export interface StarButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
isStarred?: boolean
|
||||
onToggleStar?: (starred: boolean) => void
|
||||
testId?: string
|
||||
}
|
||||
|
||||
export const StarButton = forwardRef<HTMLButtonElement, StarButtonProps>(
|
||||
({ isStarred = false, onToggleStar, testId: customTestId, ...props }, ref) => {
|
||||
const [starred, setStarred] = useState(isStarred)
|
||||
|
||||
const accessible = useAccessible({
|
||||
feature: 'email',
|
||||
component: 'star-button',
|
||||
identifier: customTestId || 'star'
|
||||
})
|
||||
|
||||
const handleClick = (e: React.MouseEvent) => {
|
||||
const newState = !starred
|
||||
setStarred(newState)
|
||||
onToggleStar?.(newState)
|
||||
props.onClick?.(e)
|
||||
}
|
||||
|
||||
return (
|
||||
<button
|
||||
ref={ref}
|
||||
className={`star-button ${starred ? 'star-button--active' : ''}`}
|
||||
aria-pressed={starred}
|
||||
title={starred ? 'Remove star' : 'Add star'}
|
||||
{...accessible}
|
||||
{...props}
|
||||
onClick={handleClick}
|
||||
>
|
||||
{starred ? '⭐' : '☆'}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
StarButton.displayName = 'StarButton'
|
||||
3
fakemui/react/components/email/atoms/index.ts
Normal file
3
fakemui/react/components/email/atoms/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export { AttachmentIcon, type AttachmentIconProps } from './AttachmentIcon'
|
||||
export { StarButton, type StarButtonProps } from './StarButton'
|
||||
export { MarkAsReadCheckbox, type MarkAsReadCheckboxProps } from './MarkAsReadCheckbox'
|
||||
Reference in New Issue
Block a user