ps: только дизайн, имплементация отдельно
самый первый набросок:
import React from "react";
import "./styles.css";
function Dialog(props) {
return (
<div class="Dialog">
<div class="Dialog_header">
<h1 class="Dialog_header_title">{props.dialog.title}</h1>
</div>
<div class="Dialog_body">
How are you?
</div>
<div class="Dialog_footer">
<button class="Dialog_footer_button_cancel">Cancel</button>
<button class="Dialog_footer_button_ok">Ok</button>
</div>
</div>
);
}
// Вместо диввов и баттонов будут использовать другие готовые компоненты либо html элементы
// Классы можно сгененрировать автоматически
// Для переопределения всего и вся нужно использовать похожий синтакис на бемовские шаблонизаторы
function Dialog(props) {
return (
<Card>
<Card.Header>
<Text.Title>Welcome<Text.Title />
</Card.Header>
<Card.Body>How are you?</Card.Body>
<Card.Footer>
<Button>Cancel</Button>
<Button>Ok</Button>
</Card.Footer>
</Card>
);
}
// На чем сошелся
function Dialog(props) {
defineHelper(Dialog); // или декоратор.
// Суть в том, что я описываю семантику обращаясь к свойствам этого же компонента
return (
<Dialog.Header as={Card.Header}>
<Dialog.Header.Title as={Text.Title}>Welcome</Dialog.Header.Title>
</Dialog.Header>
<Dialog.Body>How are you?</Dialog.Body>
<Dialog.Footer>
<Dialog.Footer.Button.Cancel>Cancel</Dialog.Footer.Button.Cancel>
<Dialog.Footer.Button.Ok>Ok</Dialog.Footer.Button.Ok>
</Dialog.Footer>
);
}
// Пока на этом варианте остановился
function Dialog(props) {
const Dialog = useAdequateComponent(Dialog);
return (
<Dialog as={Card}>
<Dialog.Header as={Card.Header}>
<Dialog.Title as={Text.Title}>Welcome</Dialog.Title>
</Dialog.Header>
<Dialog.Body as={Card.Body}>How are you?</Dialog.Body>
<Dialog.Footer as={Card.Footer}>
<Dialog.Button> // если не передали as={} никакого элемента не будет отрендерено. Это что бы не писать Dialog.Button.Cancel, Dialog.Button.Ok
<Dialog.Cancel as={Button}>Cancel</Dialog.Cancel>
<Dialog.Ok as={Button}>Ok</Dialog.Ok>
</Dialog.Button>
</Dialog.Footer>
</Dialog>
);
}
const WelcomeDialog = Dialog.adequateExtend({
footer_button_cancel: {
$append: WelcomeIcon, // глянть бемовские шаблонизаторы и домовские методы
}
});
export default function App() {
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<Dialog
header={{ title: 'ops' }}
footer={{ button: { cancel: { children: 'Stop', onClick: () => alert('ops') } } }}
footer={{ 'button.cancel': { chidlren: 'Strop', onClick: () => alert('ops') } }}
footer_button_cancel_sub="Stop"
footer_button_cancel_onClick={() => alert('ops')}
footer_button_cancel={{ sub: 'Stop', onClick: () => alert('ops') }}
footer_button_Cancel={<span>Click to OK!!!!#$</span>}
/>
</div>
);
}
upd: Расширение
/*
инструкция расширения состоит из двух частей: селектор и тело
селектор:
селектор по структуре
select(dialog_header).append(<Loader loading={props.isLoading} />)
по блоку
select(Card.Header).replace(null)
манипуляция узлам:
append, prepend, before, after, replace, remove, wrap, removeWrapper
ps: глянь что умеет jquery
перенаправление:
(например dialog_header_title перенести в dialog_body)
манипуляция пропсами:
например, было:
<Dialog>
<Dialog_Header>...
<Dialog_Body>
...
стало
<Dialog>
<Dialog_Header>{props.headerContent}</Dialog_Header>
<Dialog_Body className={`type_${props.type}`}>
...и эти пропсы должны попасть в проп тайпсы компонента
Надо осмыслить стоит ли полностью подражать бем или нет, кажется что это самый гибкий способ
навешивать стили
надо поразбираться в xslt возможно будет полезным
*/
Dialog0.adequateExtend((ext, props) => {
})
ps: только дизайн, имплементация отдельно
самый первый набросок:
upd: Расширение