Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/develop' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
itsu-dev committed Jan 26, 2024
2 parents f12be2a + dab56ea commit f7bb807
Show file tree
Hide file tree
Showing 8 changed files with 305 additions and 112 deletions.
190 changes: 153 additions & 37 deletions src/components/tabitems/template/CreateTemplateByCss.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import styled from 'styled-components';
import React, { useContext, useEffect, useState } from 'react';
import { Button, Input, Modal, Select } from 'antd';
import { Button, Input, List, Modal, Select, Typography, message } from 'antd';
import { EditOutlined, DeleteOutlined } from '@ant-design/icons';

import Section from '../common/Section';
import SubTitle from '../common/SubTitle';
import { saveUserTemplates } from '../../../features/userTemplates';
import {
deleteUserTemplates,
saveUserTemplates,
templateStyleToCssText,
} from '../../../features/userTemplates';
import { PropsContext } from '../../../contexts/PropsContext';
import type { SelectProps } from 'antd';
import t from '../../../features/translator';
import { Template } from '../../../types/Template';
export const CreateTemplateByCss = () => {
const Description = styled.p`
font-size: 10pt;
Expand All @@ -33,48 +40,135 @@ export const CreateTemplateByCss = () => {
{ value: 'h3', label: 'h3' },
];

const [isModalOpen, setIsModalOpen] = useState<boolean>(false);
const [messageApi, contextHolder] = message.useMessage();

const [isCreateModalOpen, setIsCreateModalOpen] = useState<boolean>(false);
const [isEditModalOpen, setIsEditModalOpen] = useState<boolean>(false);

// テンプレートの作成
const onCreateOk = async () => {
if (css === '') {
alert('CSSを入力してください');
return;
}
if (templateName === '') {
alert('テンプレート名を入力してください');
return;
}
const templates = prop.userTemplates;
if (templates.findIndex((t) => t.name === templateName) > -1) {
const ok = confirm(
'同じ名前のテンプレートが存在します。上書きしますか?',
);
if (!ok) {
return;
}
}
if (templateName) {
try {
await saveUserTemplates(css, templateName, tags, prop);
setIsCreateModalOpen(false);
messageApi.open({
type: 'success',
content: 'テンプレートを作成しました',
duration: 5,
});
} catch (e) {
alert(e);
}
}
};

// テンプレートの編集
const edit = (template: Template) => {
setTemplateName(template.name);
setTags(template.tags);
setCss(templateStyleToCssText(template.styles));
setIsEditModalOpen(true);
};

const onEditOk = async () => {
try {
await saveUserTemplates(css, templateName, tags, prop);
setIsEditModalOpen(false);
messageApi.open({
type: 'success',
content: 'テンプレートを作成しました',
duration: 5,
});
} catch (e) {
alert(e);
}
};

// テンプレートの削除
const deleteTemplate = async (template: Template) => {
const ok = confirm('テンプレートを削除しますか?');
if (ok) {
await deleteUserTemplates(template.name, prop);
}
};

const onCancel = () => {
setTemplateName('');
setCss('');
setTags([]);
setIsCreateModalOpen(false);
setIsEditModalOpen(false);
};

useEffect(() => {
setCss('');
setTemplateName('');
setTags([]);
}, [isModalOpen]);
}, [isCreateModalOpen]);

return (
<Section>
<SubTitle text={'テンプレートの作成'} />
<Description>{'CSSを入力してテンプレートを作成します'}</Description>
<Button
block
type="default"
onClick={async () => {
setIsModalOpen(true);
}}
>
開く
</Button>
<>
{contextHolder}
<Section>
<SubTitle text="テンプレートの作成" />
<Description>CSSを入力してテンプレートを作成します</Description>
<Button
block
type="default"
onClick={() => {
setIsCreateModalOpen(true);
}}
>
テンプレートを作成
</Button>
</Section>
<Section>
<SubTitle text="作成したテンプレート一覧" />
<List
dataSource={prop.userTemplates}
renderItem={(item) => (
<List.Item>
<Typography.Text>{item.name}</Typography.Text>
<div>
<Button
type="text"
size="small"
icon={<EditOutlined />}
onClick={() => edit(item)}
/>
<Button
type="text"
size="small"
icon={<DeleteOutlined />}
onClick={() => deleteTemplate(item)}
/>
</div>
</List.Item>
)}
/>
</Section>
<Modal
title="テンプレートの作成"
open={isModalOpen}
onOk={() => {
if (css === '') {
alert('CSSを入力してください');
return;
}
if (templateName === '') {
alert('テンプレート名を入力してください');
return;
}
saveUserTemplates(css, templateName, tags, prop)
.then(() => {
setIsModalOpen(false);
})
.catch((e) => {
alert(e);
});
}}
onCancel={() => setIsModalOpen(false)}
open={isCreateModalOpen}
onOk={onCreateOk}
onCancel={onCancel}
zIndex={99999}
>
<Section>
Expand All @@ -87,7 +181,7 @@ export const CreateTemplateByCss = () => {
/>
</Section>
<Section>
対象とする要素のタグ名(入力しない場合は全ての要素に適用されます)
対象とする要素のタグ名入力しない場合は全ての要素に適用されます
<Select
mode="tags"
style={{ width: '100%' }}
Expand All @@ -109,6 +203,28 @@ export const CreateTemplateByCss = () => {
/>
</Section>
</Modal>
</Section>
<Modal
title="テンプレートの編集"
open={isEditModalOpen}
onOk={onEditOk}
onCancel={onCancel}
zIndex={99999}
>
<Section>
テンプレート名:
{templateName}
</Section>
<Section>
CSS
<TextArea
defaultValue={css}
value={css}
onChange={(e) => setCss(e.target.value)}
contentEditable={true}
autoSize={{ minRows: 5, maxRows: 20 }}
/>
</Section>
</Modal>
</>
);
};
41 changes: 27 additions & 14 deletions src/components/tabitems/template/TemplateCard.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Template } from '../../../types/Template';
import React, { useContext, useEffect, useRef } from 'react';
import React, { useContext, useEffect, useRef, useState } from 'react';
import {
getAbsoluteCSSSelector,
getCssSelector,
Expand All @@ -22,6 +22,7 @@ const TemplateCard = (
const ref = useRef<any>(null);
const elementSelection = useContext(ElementSelectionContext);
const props = useContext(PropsContext);
const [indices, setIndices] = useState<number[]>([]);

const onUseClick = () => {
if (elementSelection.selectedElement) {
Expand All @@ -43,24 +44,36 @@ const TemplateCard = (
}
};

const insertCSS = () => {
template.styles.forEach((style) => {
getStyleSheet()?.insertRule(
`${getAbsoluteCSSSelector(ref.current!)}[id='${template.name}']${
style.pseudoClass ? `:${style.pseudoClass}` : ''
} {\n` +
`${Object.entries(style.css)
.map(([key, value]) => `${key}: ${value}`)
.join(';\n')};\n` +
'width: 100%;' +
const resetCss = () => {
const styleSheet = getStyleSheet();
// 既存のスタイルを削除
for (const index of indices) {
styleSheet.deleteRule(index);
}

const newIndices = [];
for (const style of template.styles) {
const selector = `${getAbsoluteCSSSelector(ref.current!)}[id='${
template.name
}']${style.pseudoClass ? `:${style.pseudoClass}` : ''}`;
const css = { ...style.css };
css.width = '100%';

const newIndex = styleSheet.insertRule(
`${selector} {\n` +
`${Object.entries(css)
.map(([key, value]) => `${key}: ${value};`)
.join('\n')}\n` +
'}',
);
});
newIndices.push(newIndex);
}
setIndices(newIndices);
};

useEffect(() => insertCSS(), []);
useEffect(() => resetCss(), [template]);

let card;
let card: JSX.Element;

if (userTemplate && template.name) {
card = (
Expand Down
1 change: 1 addition & 0 deletions src/components/tabitems/template/TemplateList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const CardsWrapper = styled.div`
background-color: rgba(255, 255, 255, 0.5);
border: lightgray solid 1px;
border-radius: 24px;
box-sizing: border-box;
`;

interface CardsProps {
Expand Down
3 changes: 2 additions & 1 deletion src/features/style_layer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { IPropsContext } from '../contexts/PropsContext';
import { StyleLayer, StyleLayerValue } from '../types/StyleLayer';
import * as resta_console from './resta_console';
import { matchCSSSelector } from '../utils/CSSUtils';
export const getStyleLayer = (
cssSelector: string,
prop: IPropsContext,
Expand All @@ -11,7 +12,7 @@ export const getStyleLayer = (
const styleLayerValue: StyleLayerValue[] = [];
for (const format of prop.formatsArray.reverse()) {
const formatChange = format.formats.find((format) => {
return format.cssSelector === cssSelector;
return matchCSSSelector(format.cssSelector, cssSelector);
});
if (!formatChange) continue;
resta_console.log('formatChange:', formatChange);
Expand Down
6 changes: 3 additions & 3 deletions src/features/style_sheet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ let styleSheet: CSSStyleSheet | null = null;
* シングルトンのような構造になっている
*/
export const getStyleSheet = () => {
if (styleSheet == null) {
if (styleSheet === null) {
const styleSheetElement = document.createElement('style');
document.head.appendChild(styleSheetElement);
styleSheet = styleSheetElement.sheet;
styleSheet = styleSheetElement.sheet as CSSStyleSheet;
}
return styleSheet as CSSStyleSheet;
return styleSheet;
};

/**
Expand Down
Loading

0 comments on commit f7bb807

Please sign in to comment.