Files
site-builder/craft/src/components/basic/Footer.tsx
T
shadowdao 65a10a1ef9 refactor(builder): remove dead component settings UI
Each component defined a .craft.related.settings panel that was never
rendered -- the right panel renders only GuidedStyles (per-type
*StylePanel components), never .related.settings. Removed all dead
settings components across every component, their settings-only helpers
(including the dead uploadToWhp/showBrowser/handleBrowse asset-browse
blocks in Logo/Navbar/VideoBlock/FeaturesGrid, and CtasEditor in
_cta-helpers), and dropped the now-empty related keys. Render output,
.craft props/rules, and toHtml statics are unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 13:16:53 -07:00

90 lines
2.2 KiB
TypeScript

import React, { CSSProperties, useCallback, useRef, useEffect } from 'react';
import { useNode, UserComponent } from '@craftjs/core';
import { cssPropsToString } from '../../utils/style-helpers';
interface FooterProps {
text?: string;
style?: CSSProperties;
}
export const Footer: UserComponent<FooterProps> = ({
text = '© 2026 MySite. All rights reserved.',
style = {},
}) => {
const {
connectors: { connect, drag },
selected,
actions: { setProp },
} = useNode((node) => ({
selected: node.events.selected,
}));
const elRef = useRef<HTMLElement | null>(null);
const handleBlur = useCallback(() => {
if (elRef.current) {
const newText = elRef.current.innerText;
setProp((p: FooterProps) => { p.text = newText; }, 500);
}
}, [setProp]);
useEffect(() => {
if (elRef.current && !selected) {
elRef.current.innerText = text || '';
}
}, [text, selected]);
return (
<footer
ref={(ref: HTMLElement | null): void => {
elRef.current = ref;
if (ref) connect(drag(ref));
}}
contentEditable={selected}
suppressContentEditableWarning
onBlur={handleBlur}
style={{
padding: '24px 20px',
textAlign: 'center',
outline: 'none',
cursor: selected ? 'text' : 'pointer',
...style,
}}
>
{selected ? undefined : (text || '')}
</footer>
);
};
/* ---------- Craft config ---------- */
Footer.craft = {
displayName: 'Footer',
props: {
text: '© 2026 MySite. All rights reserved.',
style: {
backgroundColor: '#18181b',
color: '#a1a1aa',
fontSize: '14px',
padding: '24px 20px',
},
},
rules: {
canDrag: () => true,
canMoveIn: () => false,
canMoveOut: () => true,
},
};
/* ---------- HTML export ---------- */
(Footer as any).toHtml = (props: FooterProps, _childrenHtml: string) => {
const styleStr = cssPropsToString({
padding: '24px 20px',
textAlign: 'center',
...props.style,
});
const escapedText = (props.text || '').replace(/</g, '&lt;').replace(/>/g, '&gt;');
return { html: `<footer${styleStr ? ` style="${styleStr}"` : ''}>${escapedText}</footer>` };
};