diff --git a/packages/component/src/atom/SettingsAtom.test.ts b/packages/component/src/atom/SettingsAtom.test.ts deleted file mode 100644 index 670d3b1..0000000 --- a/packages/component/src/atom/SettingsAtom.test.ts +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Test for SettingsAtom - * - * Created by sunvisor on 2024/02/09. - * Copyright (C) Sunvisor Lab. 2024. - */ -import { SettingsAtom, UpdateSettingsAtom } from "./SettingsAtom"; -import { renderHook, act } from '@testing-library/react'; -import { useAtomValue, useSetAtom } from 'jotai'; - -describe('Tests for SettingsAtom', () => { - - const getSettings = () => { - const { result } = renderHook( - () => useAtomValue(SettingsAtom) - ); - return result.current; - }; - - test('Updates a part of the settings using UpdateSettingsAtom', () => { - // Arrange - const { result } = renderHook( - () => useSetAtom(UpdateSettingsAtom) - ); - // Act - act(() => { - result.current({ boundingBox: { handleSize: 10 } }); - }); - // Assert - const newSettings = getSettings(); - expect(newSettings.boundingBox.handleSize).toBe(10); - }); -}); diff --git a/packages/component/src/atom/SettingsAtom.ts b/packages/component/src/atom/SettingsAtom.ts deleted file mode 100644 index b6ef7a2..0000000 --- a/packages/component/src/atom/SettingsAtom.ts +++ /dev/null @@ -1,61 +0,0 @@ -/** - * SettingsAtom - * - * Created by sunvisor on 2024/02/09. - * Copyright (C) Sunvisor Lab. 2024. - */ -import { atom } from 'jotai'; -import { BoundingBoxOptions, defaultSettings, DefaultShapeSize, RubberBandOptions, SettingData } from '../settings'; -import { LineSelectOptions } from '@sunvisor/super-leopard-core'; - - -class DesignModeOptions { -} - -type UpdateSettingData = { - boundingBox?: Partial; - rubberBand?: Partial; - lineSelect?: Partial; - /** - * default shape size by point - */ - defaultShapeSize?: Partial; - designMode?: Partial; -} - -export const SettingsAtom = atom(defaultSettings); - -export const UpdateSettingsAtom = atom(null, (get, set, settings: UpdateSettingData) => { - const original = get(SettingsAtom); - if (settings.boundingBox) { - original.boundingBox = { - ...original.boundingBox, - ...settings.boundingBox - } - } - if (settings.rubberBand) { - original.rubberBand = { - ...original.rubberBand, - ...settings.rubberBand - } - } - if (settings.lineSelect) { - original.lineSelect = { - ...original.lineSelect, - ...settings.lineSelect - } - } - if (settings.defaultShapeSize) { - original.defaultShapeSize = { - ...original.defaultShapeSize, - ...settings.defaultShapeSize - } - } - if (settings.designMode) { - original.designMode = { - ...original.designMode, - ...settings.designMode - } - } - set(SettingsAtom, original); -}); diff --git a/packages/component/src/captions/CaptionsType.ts b/packages/component/src/captions/CaptionsType.ts deleted file mode 100644 index a0c8678..0000000 --- a/packages/component/src/captions/CaptionsType.ts +++ /dev/null @@ -1,248 +0,0 @@ -export type Captions = { - operation: Operation; - reportObject: ReportObject; - pageProperty: PageProperty; - staticShapeType: StaticShapeTypeName; - shapeType: ShapeTypeName; - editTool: EditTool; - editModeTool: EditModeTool; - positionProperty: PositionProperty; - sizeProperty: SizeProperty; - fillColorProperty: FillColorProperty; - borderProperty: BorderProperty; - capTool: CapTool; - joinTool: JoinTool; - colorPickerField: ColorPickerField; - circleProperty: CircleProperty; - textProperty: TextProperty; - alignTool: AlignTool; - fontProperty: FontProperty; - imageProperty: ImageProperty; - barcodeProperty: BarcodeProperty; - barcodeRotateName: BarcodeRotateName; - fieldProperty: FieldProperty; - groupProperty: GroupProperty; - listProperty: ListProperty; - objectManipulation: ObjectManipulation; - groupOperation: GroupOperation; - layerOperation: LayerOperation; - numberErrorMessage: NumberErrorMessage; -} - -export type Operation = { - undo: string; - redo: string; - transform: string; - copy: string; - paste: string; - cut: string; - delete: string; -} - -export type ReportObject = { - property: string; - layer: string; - page: string; - report: string; - shape: string; - object: string; - editProperty: string; -} - -export type PageProperty = { - title: string; - paperSize: string; - custom: string; - width: string; - height: string; - orientation: string; - portrait: string; - landscape: string; - margin: string; - left: string; - top: string; - unit: string; - mm: string; - in: string; - pt: string; -} - -export type StaticShapeTypeName = { - rect: string; - circle: string; - ellipse: string; - line: string; - image: string; - text: string; - barcode: string; -} - -export type ShapeTypeName = StaticShapeTypeName & { - group: string; - list: string; - field: string; -} - -export type EditTool = { - save: string; - rename: string; - property: string; -} - -export type EditModeTool = StaticShapeTypeName & { - edit: string; - field: string; -} - -export type PositionProperty = { - x: string; - y: string; - startPosition: string; - endPosition: string; -} -export type SizeProperty = { - width: string; - height: string; -} -export type FillColorProperty = { - fillColor: string; -} - -export type CircleProperty = { - diameter: string; -} - -export type BorderProperty = { - border: string; - color: string; - width: string; - style: string; - cap: string; - join: string; -} - -export type CapTool = { - butt: string; - round: string; - square: string; -} - -export type JoinTool = { - miter: string; - round: string; - bevel: string; -} - -export type TextProperty = { - text: string; - align: string; - color: string; - valign: string; - multiLine: string; - linePitch: string; - fitCell: string; -} - -export type AlignTool = { - left: string; - center: string; - right: string; - justify: string; - justifyAll: string; - top: string; - middle: string; - bottom: string; -} - -export type FontProperty = { - fontFamily: string; - fontSize: string; - fontStyle: string; - bold: string; - italic: string; - underline: string; - strikethrough: string; -} - -export type ImageProperty = { - upload: string; - select: string; - selectMessage: string; - decide: string; - close: string; -} - -export type BarcodeProperty = { - format: string; - value: string; - rotate: string; - includeText: string; -} - -export type BarcodeRotateName = { - N: string; - R: string; - L: string; - I: string; -} - -export type FieldProperty = { - name: string; - shapeType: string; -} - -export type ColorPickerField = { - invalidColor: string; -} - -export type GroupProperty = { - repeatCount: string; - direction: string; - vertical: string; - horizontal: string; - times: string; -} - -export type ListProperty = { - rows: string; - direction: string; - columns: string; -} - -export type ObjectManipulation = { - toFront: string; - toBack: string; - toForward: string; - toBackward: string; - bringToFront: string; - sendToBack: string; - bringToForward: string; - sendToBackward: string; - alignToTop: string; - alignToBottom: string; - alignToLeft: string; - alignToRight: string; - alignToCenter: string; - alignToMiddle: string; - distributeHorizontally: string; - distributeVertically: string; -} - -export type GroupOperation = { - group: string; - ungroup: string; - shapesToList: string; - listToShapes: string; -} - -export type NumberErrorMessage = { - minValue: (value: number) => string; - maxValue: (value: number) => string; - invalidValue: string; -} - -export type LayerOperation = { - addLayer: string; - removeLayer: string; - renameLayer: string; -} diff --git a/packages/component/src/captions/captions.ts b/packages/component/src/captions/captions.ts deleted file mode 100644 index 5934bed..0000000 --- a/packages/component/src/captions/captions.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './ja/captions'; diff --git a/packages/component/src/captions/getCaptions.ts b/packages/component/src/captions/getCaptions.ts deleted file mode 100644 index 114cac5..0000000 --- a/packages/component/src/captions/getCaptions.ts +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Captions - * - * Created by sunvisor on 2024/02/14. - * Copyright (C) Sunvisor Lab. 2024. - */ -import { captions as ja } from './ja/captions'; -import { captions as en } from './en/captions'; - -export type Language = 'ja' | 'en'; - -class Captions { - #language: Language = 'ja'; - - public setLanguage(lang: Language) { - this.#language = lang; - } - - public getCaptions() { - if (this.#language === 'ja') { - return ja; - } else { - return en; - } - } -} - -const captions = new Captions(); - -export default function getCaptions() { - return captions.getCaptions() -} - -export function setLanguage(lang: string) { - captions.setLanguage(lang === 'en' ? 'en' : 'ja'); -} diff --git a/packages/component/src/component/objectList/ObjectListItem.tsx b/packages/component/src/component/objectList/ObjectListItem.tsx index f6ecb06..34ed875 100644 --- a/packages/component/src/component/objectList/ObjectListItem.tsx +++ b/packages/component/src/component/objectList/ObjectListItem.tsx @@ -37,7 +37,7 @@ import { Text, TextShape, } from '@sunvisor/super-leopard-core'; -import getCaptions from '../../captions/getCaptions'; +import translation from '../../translations/translation'; import EllipseIcon from '../toolbar/EllipseIcon'; import LineIcon from '../toolbar/LineIcon'; @@ -57,7 +57,7 @@ type ObjectListItemProps = { } function ObjectListItemItem({ title, icon, indent, onItemClick, onSettingClick }: ObjectListItemProps) { - const captions = getCaptions().reportObject; + const t = translation().reportObject; return ( @@ -70,8 +70,8 @@ function ObjectListItemItem({ title, icon, indent, onItemClick, onSettingClick } - - + + @@ -105,7 +105,7 @@ function getIcon(shape: Shape) { } export default function ObjectListItem({ shape, indent, onClick, onSettingClick }: Props) { - const shapeTypes = getCaptions().shapeType; + const shapeTypes = translation().shapeType; const title = shape.type === TextShape ? (shape as Text).text : shape.type === FieldShape diff --git a/packages/component/src/component/property/field/AlignButtons.tsx b/packages/component/src/component/property/field/AlignButtons.tsx index a39eb24..c4925cf 100644 --- a/packages/component/src/component/property/field/AlignButtons.tsx +++ b/packages/component/src/component/property/field/AlignButtons.tsx @@ -11,7 +11,7 @@ import FormatAlignCenterIcon from '@mui/icons-material/FormatAlignCenter'; import FormatAlignRightIcon from '@mui/icons-material/FormatAlignRight'; import FormatAlignJustifyIcon from '@mui/icons-material/FormatAlignJustify'; import { AlignType, AlignValue } from '@sunvisor/super-leopard-core'; -import getCaptions from '../../../captions/getCaptions'; +import translation from '../../../translations/translation'; import ToggleTools, { ToggleToolButton } from '../ToggleTools'; import { ChangeValueHandler } from '../usePropertyStates'; @@ -31,7 +31,7 @@ function AlignJustifyIcon() { export default function AlignButtons(props: Props) { const { name, value, onChangeValue } = props; - const captions = getCaptions().alignTool; + const t = translation().alignTool; const handleChange = (_: React.MouseEvent, newAlign: AlignValue) => { if (newAlign === null) return; @@ -39,12 +39,12 @@ export default function AlignButtons(props: Props) { }; const buttons: ToggleToolButton[] = useMemo(() => [ - { value: AlignType.LEFT, icon: , title: captions.left }, - { value: AlignType.CENTER, icon: , title: captions.center }, - { value: AlignType.RIGHT, icon: , title: captions.right }, - { value: AlignType.JUSTIFY, icon: , title: captions.justify }, - { value: AlignType.JUSTIFY_ALL, icon: , title: captions.justifyAll }, - ], [captions.left, captions.center, captions.right, captions.justify]); + { value: AlignType.LEFT, icon: , title: t.left }, + { value: AlignType.CENTER, icon: , title: t.center }, + { value: AlignType.RIGHT, icon: , title: t.right }, + { value: AlignType.JUSTIFY, icon: , title: t.justify }, + { value: AlignType.JUSTIFY_ALL, icon: , title: t.justifyAll }, + ], [t.left, t.center, t.right, t.justify]); return ( @@ -27,7 +27,7 @@ export const Normal: Story = { label: 'Rotate', name: 'rotate', value: 'N', - rotateTypeList: getCaptions().barcodeRotateName, + rotateTypeList: translation().barcodeRotateName, } }; diff --git a/packages/component/src/component/property/field/CapButtons.tsx b/packages/component/src/component/property/field/CapButtons.tsx index 35c7f24..e5762a7 100644 --- a/packages/component/src/component/property/field/CapButtons.tsx +++ b/packages/component/src/component/property/field/CapButtons.tsx @@ -9,7 +9,7 @@ import CapButtIcon from '../field/icon/CapButtIcon'; import { CapValue } from '@sunvisor/super-leopard-core'; import CapRoundIcon from '../field/icon/CapRoundIcon'; import CapSquareIcon from '../field/icon/CapSquareIcon'; -import getCaptions from '../../../captions/getCaptions'; +import translation from '../../../translations/translation'; import ToggleTools, { ToggleToolButton } from '../ToggleTools'; import { ChangeValueHandler } from '../usePropertyStates'; @@ -22,13 +22,13 @@ type Props = { export default function CapButtons(props: Props) { const { name, value, onChangeValue } = props; - const captions = getCaptions().capTool; + const t = translation().capTool; const buttons: ToggleToolButton[] = useMemo(() => [ - { icon: , value: 'butt', title: captions.butt }, - { icon: , value: 'round', title: captions.round }, - { icon: , value: 'square', title: captions.square } - ], [captions.butt, captions.round, captions.square]); + { icon: , value: 'butt', title: t.butt }, + { icon: , value: 'round', title: t.round }, + { icon: , value: 'square', title: t.square } + ], [t.butt, t.round, t.square]); const handleChange = useCallback((_: React.MouseEvent, newCap: CapValue) => { if (newCap === null) return; diff --git a/packages/component/src/component/property/field/ClipboardButtons.tsx b/packages/component/src/component/property/field/ClipboardButtons.tsx index 923eb4c..1e4f4ad 100644 --- a/packages/component/src/component/property/field/ClipboardButtons.tsx +++ b/packages/component/src/component/property/field/ClipboardButtons.tsx @@ -9,7 +9,7 @@ import ContentCopyIcon from '@mui/icons-material/ContentCopy'; import ContentCutIcon from '@mui/icons-material/ContentCut'; import ContentPasteIcon from '@mui/icons-material/ContentPaste'; import DeleteIcon from '@mui/icons-material/Delete'; -import getCaptions from '../../../captions/getCaptions'; +import translation from '../../../translations/translation'; import GroupBox from '../fieldGroup/GroupBox'; type Props = { @@ -23,19 +23,19 @@ type Props = { export default function ClipboardButtons(props: Props) { const { canCopy, canPaste, onCopy, onCut, onPaste, onRemove } = props; - const captions = getCaptions().operation; + const t = translation().operation; return ( ); diff --git a/packages/component/src/component/property/field/ColorPickerField.tsx b/packages/component/src/component/property/field/ColorPickerField.tsx index 2a417c7..bd6950f 100644 --- a/packages/component/src/component/property/field/ColorPickerField.tsx +++ b/packages/component/src/component/property/field/ColorPickerField.tsx @@ -6,7 +6,7 @@ */ import React, { useCallback, useMemo, useState } from "react"; import { SxProps, TextField, TextFieldProps } from '@mui/material'; -import getCaptions from '../../../captions/getCaptions'; +import translation from '../../../translations/translation'; import { ChangeValueHandler } from '../usePropertyStates'; import GroupBox from '../fieldGroup/GroupBox'; @@ -31,12 +31,12 @@ export default function ColorPickerField(props: Props) { colorFieldProps, onChangeValue, } = props; - const captions = getCaptions().colorPickerField; + const t = translation().colorPickerField; const [color, setColor] = useState(value); const [error, message] = useMemo( - () => isValidColor(color) ? [false, ''] : [true, captions.invalidColor], - [captions.invalidColor, color] + () => isValidColor(color) ? [false, ''] : [true, t.invalidColor], + [t.invalidColor, color] ); const handleChangeColor = useCallback( diff --git a/packages/component/src/component/property/field/DirectionButtons.tsx b/packages/component/src/component/property/field/DirectionButtons.tsx index f467fb3..14059b7 100644 --- a/packages/component/src/component/property/field/DirectionButtons.tsx +++ b/packages/component/src/component/property/field/DirectionButtons.tsx @@ -9,7 +9,7 @@ import EastIcon from '@mui/icons-material/East'; import SouthIcon from '@mui/icons-material/South'; import ToggleTools, { ToggleToolButton } from '../ToggleTools'; import { DirectionType, DirectionValue } from '@sunvisor/super-leopard-core'; -import getCaptions from '../../../captions/getCaptions'; +import translation from '../../../translations/translation'; import { ChangeValueHandler } from '../usePropertyStates'; @@ -21,12 +21,12 @@ type Props = { export default function DirectionButtons(props: Props) { const { name, value, onChangeValue } = props; - const captions = getCaptions().groupProperty; + const t = translation().groupProperty; const buttons: ToggleToolButton[] = useMemo(() => [ - { icon: , value: DirectionType.HORIZONTAL, title: captions.horizontal }, - { icon: , value: DirectionType.VERTICAL, title: captions.vertical } - ], [captions.horizontal, captions.vertical]) + { icon: , value: DirectionType.HORIZONTAL, title: t.horizontal }, + { icon: , value: DirectionType.VERTICAL, title: t.vertical } + ], [t.horizontal, t.vertical]) const handleChange = useCallback( (_: React.MouseEvent, newDirection: DirectionValue) => { diff --git a/packages/component/src/component/property/field/FillColorField.tsx b/packages/component/src/component/property/field/FillColorField.tsx index a34fa7b..2b16fa6 100644 --- a/packages/component/src/component/property/field/FillColorField.tsx +++ b/packages/component/src/component/property/field/FillColorField.tsx @@ -7,7 +7,7 @@ import { Checkbox, FormControlLabel } from '@mui/material'; import ColorPickerField from '../field/ColorPickerField'; import React, { useCallback } from 'react'; -import getCaptions from '../../../captions/getCaptions'; +import translation from '../../../translations/translation'; import { ChangeValueHandler } from '../usePropertyStates'; import Caption from '../Caption'; import GroupBox from '../fieldGroup/GroupBox'; @@ -22,7 +22,7 @@ export default function FillColorField(props: Props) { const { onChangeValue, } = props; - const captions = getCaptions().fillColorProperty; + const t = translation().fillColorProperty; const [fillColor, setFillColor] = React.useState(props.fillColor); const [useFillColor, setUseFillColor] = React.useState(fillColor !== undefined); @@ -46,13 +46,13 @@ export default function FillColorField(props: Props) { /> } label={ - {!fillColor && captions.fillColor} + {!fillColor && t.fillColor} }/> { fillColor && , newStyle: FontStyleValue[]) => { @@ -38,29 +38,29 @@ export default function FontStyleButtons(props: Props) { { icon: , value: FontStyleType.BOLD, - title: captions.bold, + title: t.bold, disabled: !enabledStyles.includes('bold'), }, { icon: , value: FontStyleType.ITALIC, - title: captions.italic, + title: t.italic, disabled: !enabledStyles.includes('italic'), }, { icon: , value: FontStyleType.UNDERLINE, - title: captions.underline, + title: t.underline, disabled: !enabledStyles.includes('underline') || multiLine, }, { icon: , value: FontStyleType.STRIKE, - title: captions.strikethrough, + title: t.strikethrough, disabled: !enabledStyles.includes('strike') || multiLine, } ], - [captions.bold, captions.italic, captions.underline, enabledStyles, captions.strikethrough, multiLine] + [t.bold, t.italic, t.underline, enabledStyles, t.strikethrough, multiLine] ); return ( diff --git a/packages/component/src/component/property/field/JoinButtons.tsx b/packages/component/src/component/property/field/JoinButtons.tsx index 7af9e79..db418c6 100644 --- a/packages/component/src/component/property/field/JoinButtons.tsx +++ b/packages/component/src/component/property/field/JoinButtons.tsx @@ -9,7 +9,7 @@ import JoinMiterIcon from '../field/icon/JoinMiterIcon'; import JoinRoundIcon from '../field/icon/JoinRoundIcon'; import JoinBevelIcon from '../field/icon/JoinBevelIcon'; import { JoinValue } from '@sunvisor/super-leopard-core'; -import getCaptions from '../../../captions/getCaptions'; +import translation from '../../../translations/translation'; import ToggleTools, { ToggleToolButton } from '../ToggleTools'; import { ChangeValueHandler } from '../usePropertyStates'; @@ -22,13 +22,13 @@ export type JoinButtonsProps = Props; export default function JoinButtons(props: Props) { const { name, value, onChangeValue } = props; - const captions = getCaptions().joinTool; + const t = translation().joinTool; const buttons: ToggleToolButton[] = useMemo(() => [ - { icon: , value: 'miter', title: captions.miter }, - { icon: , value: 'round', title: captions.round }, - { icon: , value: 'bevel', title: captions.bevel } - ], [captions.miter, captions.round, captions.bevel]); + { icon: , value: 'miter', title: t.miter }, + { icon: , value: 'round', title: t.round }, + { icon: , value: 'bevel', title: t.bevel } + ], [t.miter, t.round, t.bevel]); const handleChange = useCallback( (_: React.MouseEvent, newJoin: JoinValue) => { if (newJoin === null) return; diff --git a/packages/component/src/component/property/field/ObjectsAlignButtons.tsx b/packages/component/src/component/property/field/ObjectsAlignButtons.tsx index 501c1a1..0f9862d 100644 --- a/packages/component/src/component/property/field/ObjectsAlignButtons.tsx +++ b/packages/component/src/component/property/field/ObjectsAlignButtons.tsx @@ -11,7 +11,7 @@ import AlignVerticalBottomIcon from '@mui/icons-material/AlignVerticalBottom'; import AlignVerticalCenterIcon from '@mui/icons-material/AlignVerticalCenter'; import AlignVerticalTopIcon from '@mui/icons-material/AlignVerticalTop'; import { Box, Button, ButtonGroup, Tooltip } from '@mui/material'; -import getCaptions from '../../../captions/getCaptions'; +import translation from '../../../translations/translation'; import DistributeHorizontallyIcon from '../field/icon/DistributeHorizontallyIcon'; import DistributeVerticallyIcon from '../field/icon/DistributeVerticallyIcon'; import React from 'react'; @@ -42,36 +42,36 @@ type Props = { export default function ObjectsAlignButtons(props: Props) { const { onClick } = props; - const captions = getCaptions().objectManipulation; + const t = translation().objectManipulation; return ( - onClick('left')}> + onClick('left')}> - onClick('center')}> + onClick('center')}> - onClick('right')}> + onClick('right')}> - onClick('top')}> + onClick('top')}> - onClick('middle')}> + onClick('middle')}> - onClick('bottom')}> + onClick('bottom')}> - onClick('distributeHorizontally')}> + onClick('distributeHorizontally')}> - onClick('distributeVertically')}> + onClick('distributeVertically')}> diff --git a/packages/component/src/component/property/field/OrientationField.tsx b/packages/component/src/component/property/field/OrientationField.tsx index 0d35fea..b297c28 100644 --- a/packages/component/src/component/property/field/OrientationField.tsx +++ b/packages/component/src/component/property/field/OrientationField.tsx @@ -9,7 +9,7 @@ import CropPortraitIcon from '@mui/icons-material/CropPortrait'; import { SxProps } from '@mui/material'; import { OrientationValue } from '@sunvisor/super-leopard-core'; import React, { useCallback, useMemo } from "react"; -import getCaptions from '../../../captions/getCaptions'; +import translation from '../../../translations/translation'; import ToggleTools, { ToggleToolButton } from '../ToggleTools'; import { ChangeValueHandler } from '../usePropertyStates'; @@ -23,12 +23,12 @@ type Props = { export default function OrientationField(props: Props) { const { name, value, onChangeValue , sx } = props; - const captions = getCaptions().pageProperty; + const t = translation().pageProperty; const button: ToggleToolButton[] = useMemo(() => [ - { icon: , value: 'portrait', caption: captions.portrait, sx: { flex: 1 } }, - { icon: , value: 'landscape', caption: captions.landscape, sx: { flex: 1 } }, - ], [captions.portrait, captions.landscape]); + { icon: , value: 'portrait', caption: t.portrait, sx: { flex: 1 } }, + { icon: , value: 'landscape', caption: t.landscape, sx: { flex: 1 } }, + ], [t.portrait, t.landscape]); const handleChange = useCallback((_: React.MouseEvent, newOrientation: OrientationValue) => { if (newOrientation === null) return; diff --git a/packages/component/src/component/property/field/PageUnitField.tsx b/packages/component/src/component/property/field/PageUnitField.tsx index 9400bed..3fa9011 100644 --- a/packages/component/src/component/property/field/PageUnitField.tsx +++ b/packages/component/src/component/property/field/PageUnitField.tsx @@ -8,14 +8,14 @@ import { SxProps, TextField } from '@mui/material'; import MenuItem from '@mui/material/MenuItem'; import { UnitType } from '@sunvisor/super-leopard-core'; import { ChangeEvent, useCallback } from "react"; -import getCaptions from '../../../captions/getCaptions'; +import translation from '../../../translations/translation'; import { ChangeValueHandler } from '../usePropertyStates'; function getUnitList() { - const captions = getCaptions().pageProperty; + const t = translation().pageProperty; return Object.entries(UnitType).map(([, value]) => ({ key: value, - value: captions[value as keyof typeof captions], + value: t[value as keyof typeof t], })) } diff --git a/packages/component/src/component/property/field/PaperSizeField.tsx b/packages/component/src/component/property/field/PaperSizeField.tsx index 5f7152e..7a83b97 100644 --- a/packages/component/src/component/property/field/PaperSizeField.tsx +++ b/packages/component/src/component/property/field/PaperSizeField.tsx @@ -8,7 +8,7 @@ import { SxProps, TextField } from '@mui/material'; import MenuItem from '@mui/material/MenuItem'; import { PaperSize } from '@sunvisor/super-leopard-core'; import { ChangeEvent, useCallback } from "react"; -import getCaptions from '../../../captions/getCaptions'; +import translation from '../../../translations/translation'; import { ChangeValueHandler } from '../usePropertyStates'; type Props = { @@ -34,8 +34,8 @@ function getPaperSizeList(customCaption: string) { export default function PaperSizeField(props: Props) { const { label, name, value, onChangeValue, sx } = props; - const captions = getCaptions().pageProperty; - const paperSizeList = getPaperSizeList(captions.custom); + const t = translation().pageProperty; + const paperSizeList = getPaperSizeList(t.custom); const handleChange = useCallback((event: ChangeEvent) => { const { value } = event.target; diff --git a/packages/component/src/component/property/field/ShapeTypeField.tsx b/packages/component/src/component/property/field/ShapeTypeField.tsx index d8ad2c8..d6a5d44 100644 --- a/packages/component/src/component/property/field/ShapeTypeField.tsx +++ b/packages/component/src/component/property/field/ShapeTypeField.tsx @@ -7,7 +7,7 @@ import { SxProps, TextField } from '@mui/material'; import MenuItem from '@mui/material/MenuItem'; import { ChangeEvent, useCallback } from "react"; -import getCaptions from '../../../captions/getCaptions'; +import translation from '../../../translations/translation'; import { ChangeValueHandler } from '../usePropertyStates'; type Props = { @@ -20,7 +20,7 @@ type Props = { export default function ShapeTypeField(props: Props) { const { label, name, value, onChangeValue, sx } = props; - const captions = getCaptions().staticShapeType; + const t = translation().staticShapeType; const handleChange = useCallback((event: ChangeEvent) => { onChangeValue(name, event.target.value); @@ -37,7 +37,7 @@ export default function ShapeTypeField(props: Props) { select > { - Object.entries(captions).map(([key, value]) => ( + Object.entries(t).map(([key, value]) => ( , newValign: AlignValue) => { if (newValign === null) return; @@ -51,10 +51,10 @@ export default function ValignButtons(props: Props) { }; const buttons: ToggleToolButton[] = useMemo(() => [ - { value: ValignType.TOP, icon: , title: captions.top }, - { value: ValignType.MIDDLE, icon: , title: captions.middle }, - { value: ValignType.BOTTOM, icon: , title: captions.bottom }, - ], [captions.top, captions.middle, captions.bottom]); + { value: ValignType.TOP, icon: , title: t.top }, + { value: ValignType.MIDDLE, icon: , title: t.middle }, + { value: ValignType.BOTTOM, icon: , title: t.bottom }, + ], [t.top, t.middle, t.bottom]); return ( - + - + - + - + diff --git a/packages/component/src/component/property/field/useValidateNumber.ts b/packages/component/src/component/property/field/useValidateNumber.ts index 8e45625..f63591a 100644 --- a/packages/component/src/component/property/field/useValidateNumber.ts +++ b/packages/component/src/component/property/field/useValidateNumber.ts @@ -5,7 +5,7 @@ * Copyright (C) Sunvisor Lab. 2024. */ import { useState } from 'react'; -import getCaptions from '../../../captions/getCaptions'; +import translation from '../../../translations/translation'; type Props = { minValue?: number, @@ -17,23 +17,23 @@ export default function useValidateNumber(props: Props) { const { minValue, maxValue } = props; const [error, setError] = useState(false); const [message, setMessage] = useState(''); - const captions = getCaptions().numberErrorMessage; + const t = translation().numberErrorMessage; const validate = (value: string) => { const numValue = Number(value); if (isNaN(numValue)) { setError(true); - setMessage(captions.invalidValue); + setMessage(t.invalidValue); return false; } if (minValue !== undefined && numValue < minValue) { setError(true); - setMessage(captions.minValue(minValue)); + setMessage(t.minValue(minValue)); return false; } if (maxValue !== undefined && numValue > maxValue) { setError(true); - setMessage(captions.maxValue(maxValue)); + setMessage(t.maxValue(maxValue)); return false; } setError(false); diff --git a/packages/component/src/component/property/fieldGroup/BarcodeOptionFields.stories.tsx b/packages/component/src/component/property/fieldGroup/BarcodeOptionFields.stories.tsx index 756916c..d74a97b 100644 --- a/packages/component/src/component/property/fieldGroup/BarcodeOptionFields.stories.tsx +++ b/packages/component/src/component/property/fieldGroup/BarcodeOptionFields.stories.tsx @@ -10,7 +10,7 @@ import BarcodeOptionFields from "./BarcodeOptionFields"; import { Meta, StoryObj } from '@storybook/react'; import { fn } from '@storybook/test'; import { Box } from '@mui/material'; -import getCaptions from '../../../captions/getCaptions'; +import translation from '../../../translations/translation'; type Story = StoryObj @@ -34,7 +34,7 @@ export const Normal: Story = { rotate: 'N', includeText: false, }, - captions: getCaptions().barcodeProperty + captions: translation().barcodeProperty } }; diff --git a/packages/component/src/component/property/fieldGroup/BarcodeOptionFields.tsx b/packages/component/src/component/property/fieldGroup/BarcodeOptionFields.tsx index a0bfbf6..65beee3 100644 --- a/packages/component/src/component/property/fieldGroup/BarcodeOptionFields.tsx +++ b/packages/component/src/component/property/fieldGroup/BarcodeOptionFields.tsx @@ -9,7 +9,7 @@ import { ChangeValueHandler } from '../usePropertyStates'; import GroupBox from './GroupBox'; import BarcodeRotateField from '../field/BarcodeRotateField'; import SvCheckboxField from '../field/SvCheckboxField'; -import getCaptions from '../../../captions/getCaptions'; +import translation from '../../../translations/translation'; import { useCallback } from 'react'; type Props = { @@ -20,7 +20,7 @@ type Props = { export default function BarcodeOptionFields(props :Props) { const { values, captions, onChangeValue } = props; const { rotate = 'N', includeText = false } = values; - const rotateTypeList = getCaptions().barcodeRotateName; + const rotateTypeList = translation().barcodeRotateName; const handleChange = useCallback((key: string, value: string | boolean, update?: boolean) => { const newValue = { ...values, [key]: value }; diff --git a/packages/component/src/component/property/fieldGroup/BorderFields.tsx b/packages/component/src/component/property/fieldGroup/BorderFields.tsx index dcc510d..77f4173 100644 --- a/packages/component/src/component/property/fieldGroup/BorderFields.tsx +++ b/packages/component/src/component/property/fieldGroup/BorderFields.tsx @@ -6,7 +6,7 @@ import CapButtons from '../field/CapButtons'; import JoinButtons from '../field/JoinButtons'; import { ChangeValueHandler } from '../usePropertyStates'; import BorderStyleField from '../field/BorderStyleField'; -import getCaptions from '../../../captions/getCaptions'; +import translation from '../../../translations/translation'; import Caption from '../Caption'; import SvCheckboxField from '../field/SvCheckboxField'; import GroupBox from '../fieldGroup/GroupBox'; @@ -26,7 +26,7 @@ type Props = { */ export default function BorderFields(props: Props) { const { onChangeValue } = props; - const captions = getCaptions().borderProperty; + const t = translation().borderProperty; const [border, setBorder] = useState(props.border); const [useStroke, setUseStroke] = useState(border !== undefined); @@ -54,7 +54,7 @@ export default function BorderFields(props: Props) { @@ -62,7 +62,7 @@ export default function BorderFields(props: Props) { border && <> - {captions.cap} + {t.cap} - {captions.join} + {t.join} @@ -29,12 +29,12 @@ export default function FieldNameFields(props: Props) { size="small" sx={{ flex: 2}} name="fieldName" - label={captions.name} + label={t.name} value={fieldName} onChangeValue={props.onChangeName} /> ([]); const adjustFont = useCallback((font: FontValueType) => { @@ -86,7 +86,7 @@ export default function FontFields(props: Props) { - {captions.direction} + {t.direction} diff --git a/packages/component/src/component/property/fieldGroup/ListFields.tsx b/packages/component/src/component/property/fieldGroup/ListFields.tsx index 852d46b..3de1c0e 100644 --- a/packages/component/src/component/property/fieldGroup/ListFields.tsx +++ b/packages/component/src/component/property/fieldGroup/ListFields.tsx @@ -6,7 +6,7 @@ */ import { DirectionValue } from '@sunvisor/super-leopard-core'; import { ChangeValueHandler } from '../usePropertyStates'; -import getCaptions from '../../../captions/getCaptions'; +import translation from '../../../translations/translation'; import { Box } from '@mui/material'; import Caption from '../Caption'; import DirectionButtons from '../field/DirectionButtons'; @@ -26,13 +26,13 @@ type Props = { export default function ListFields(props: Props) { const { direction, rows, columns, onChangeValue } = props; - const captions = getCaptions().listProperty; + const t = translation().listProperty; return ( - {captions.direction} + {t.direction} { multiLine && (props.margin); - const captions = getCaptions().pageProperty; + const t = translation().pageProperty; useEffect(() => { setMargin(props.margin); @@ -36,7 +36,7 @@ export default function PageMarginFields(props: Props) { return ( { @@ -101,7 +101,7 @@ export default function PaperSizeFields(props: Props) { - {captions.startPosition} + {t.startPosition} - {captions.endPosition} + {t.endPosition} @@ -33,7 +33,7 @@ export default function TextColorFields(props: Props) { diff --git a/packages/component/src/component/property/object/BarcodeProperty.tsx b/packages/component/src/component/property/object/BarcodeProperty.tsx index 44a0a89..008d958 100644 --- a/packages/component/src/component/property/object/BarcodeProperty.tsx +++ b/packages/component/src/component/property/object/BarcodeProperty.tsx @@ -16,7 +16,7 @@ import { Box } from '@mui/material'; import SvTextField from '../field/SvTextField'; import BarcodePanel from '../panel/BarcodePanel'; import BarcodeField from '../field/BarcodeField'; -import getCaptions from '../../../captions/getCaptions'; +import translation from '../../../translations/translation'; type Props = { @@ -31,7 +31,7 @@ export default function BarcodeProperty(props: Props) { const barcodeProperty = useMemo( () => serializeBarcode(shape), [shape] ); - const captions = getCaptions().barcodeProperty; + const captions = translation().barcodeProperty; const doUpdate = useCallback( (values: BarcodeData) => { diff --git a/packages/component/src/component/property/object/TextProperty.tsx b/packages/component/src/component/property/object/TextProperty.tsx index 7635e2e..a043ccb 100644 --- a/packages/component/src/component/property/object/TextProperty.tsx +++ b/packages/component/src/component/property/object/TextProperty.tsx @@ -9,7 +9,7 @@ import { createText, serializeText, Text, TextData, UnitValue } from '@sunvisor/ import usePropertyStates from '../usePropertyStates'; import { FontList } from '../../../font'; import { Box } from '@mui/material'; -import getCaptions from '../../../captions/getCaptions'; +import translation from '../../../translations/translation'; import TextPanel from '../panel/TextPanel'; import SvTextField from '../field/SvTextField'; import { UpdateHandler } from './ShapeProperty'; @@ -41,7 +41,7 @@ export default function TextProperty(props: Props) { textValue, values => doUpdate(values) ); - const captions = getCaptions().textProperty; + const t = translation().textProperty; useEffect(() => { setValues(textValue); @@ -56,7 +56,7 @@ export default function TextProperty(props: Props) { name="text" size="small" fullWidth - label={captions.text} + label={t.text} value={values.text} multiline={values.multiLine} maxRows={5} diff --git a/packages/component/src/component/property/page/PageProperty.tsx b/packages/component/src/component/property/page/PageProperty.tsx index 525710f..14308cc 100644 --- a/packages/component/src/component/property/page/PageProperty.tsx +++ b/packages/component/src/component/property/page/PageProperty.tsx @@ -10,7 +10,7 @@ import PageUnitField from '../field/PageUnitField'; import PaperSizeFields, { PaperSizeFieldType } from '../fieldGroup/PaperSizeFields'; import GroupBox from '../fieldGroup/GroupBox'; import PageMarginFields from '../fieldGroup/PageMarginFields'; -import getCaptions from '../../../captions/getCaptions'; +import translation from '../../../translations/translation'; import PropertyBox from '../object/PropertyBox'; import Caption from '../Caption'; import useReport from '../../../hooks/useReport'; @@ -21,7 +21,7 @@ type Props = { } export default function PageProperty(props: Props) { - const captions = getCaptions().pageProperty; + const t = translation().pageProperty; const [page, setPage] = useState(props.page); const [unit, setUnit] = React.useState(page.unit); const { report, setReport } = useReport(); @@ -66,11 +66,11 @@ export default function PageProperty(props: Props) { - {captions.title} + {t.title} diff --git a/packages/component/src/component/property/panel/CirclePanel.tsx b/packages/component/src/component/property/panel/CirclePanel.tsx index 7b991d7..6c5f13f 100644 --- a/packages/component/src/component/property/panel/CirclePanel.tsx +++ b/packages/component/src/component/property/panel/CirclePanel.tsx @@ -11,7 +11,7 @@ import FillColorField from '../field/FillColorField'; import BorderFields from '../fieldGroup/BorderFields'; import { BorderData, CircleData, UnitValue } from '@sunvisor/super-leopard-core'; import { ChangeValueHandler } from '../usePropertyStates'; -import getCaptions from '../../../captions/getCaptions'; +import translation from '../../../translations/translation'; import GroupBox from '../fieldGroup/GroupBox'; import { MAX_SCALE_VALUE } from '@sunvisor/super-leopard-core'; @@ -24,7 +24,7 @@ type Props = { export default function CirclePanel(props: Props) { const { unit, values, onChangeValue } = props; - const captions = getCaptions().circleProperty; + const t = translation().circleProperty; return ( <> @@ -37,7 +37,7 @@ export default function CirclePanel(props: Props) { (); - const captions = getCaptions().imageProperty; + const t = translation().imageProperty; const handleClick = useCallback( (image: ImageListData) => { @@ -51,9 +51,9 @@ export default function ImageListPanel(props: Props) { - {captions.selectMessage} + {t.selectMessage} - + @@ -112,8 +112,8 @@ export default function ImageListPanel(props: Props) { - {selected ? selected.name : captions.selectMessage} - + {selected ? selected.name : t.selectMessage} + ); diff --git a/packages/component/src/component/property/panel/ImagePanel.tsx b/packages/component/src/component/property/panel/ImagePanel.tsx index 4ab0fa2..b0b8f72 100644 --- a/packages/component/src/component/property/panel/ImagePanel.tsx +++ b/packages/component/src/component/property/panel/ImagePanel.tsx @@ -10,7 +10,7 @@ import SizeFields from '../fieldGroup/SizeFields'; import { Box, Button } from '@mui/material'; import { UnitValue, ImageData } from '@sunvisor/super-leopard-core'; import { ChangeValueHandler } from '../usePropertyStates'; -import getCaptions from '../../../captions/getCaptions'; +import translation from '../../../translations/translation'; import SvImage from '../field/SvImage'; import CollectionsIcon from '@mui/icons-material/Collections'; import { ImageListData } from '../../index'; @@ -28,7 +28,7 @@ type Props = { export default function ImagePanel(props: Props) { const { imageOptions, unit, values, onChangeValue } = props; const { getImageList, getImageUrl, noImageUrl } = imageOptions; - const captions = getCaptions().imageProperty; + const t = translation().imageProperty; const [openSelect, setOpenSelect] = useState(false); const [imageList, setImageList] = useState([]); const srcUrl = values.src.length ? getImageUrl(values.src) : noImageUrl; @@ -79,7 +79,7 @@ export default function ImagePanel(props: Props) { disabled={imageList.length === 0} startIcon={} > - {captions.select} + {t.select} diff --git a/packages/component/src/component/property/panel/TextPanel.tsx b/packages/component/src/component/property/panel/TextPanel.tsx index 3940629..8ee7bd7 100644 --- a/packages/component/src/component/property/panel/TextPanel.tsx +++ b/packages/component/src/component/property/panel/TextPanel.tsx @@ -14,7 +14,7 @@ import { ChangeValueHandler } from '../usePropertyStates'; import { AlignType, FontData, TextData, UnitValue, ValignType } from '@sunvisor/super-leopard-core'; import { FontList } from '../../../font'; import SvCheckboxField from '../field/SvCheckboxField'; -import getCaptions from '../../../captions/getCaptions'; +import translation from '../../../translations/translation'; export type TextPanelValueType = number @@ -32,7 +32,7 @@ type Props = { export default function TextPanel(props: Props) { const { unit, values, fontList, onChangeValue } = props; - const captions = getCaptions().textProperty; + const t = translation().textProperty; return ( <> @@ -72,7 +72,7 @@ export default function TextPanel(props: Props) { /> diff --git a/packages/component/src/component/property/tool/GroupTool.tsx b/packages/component/src/component/property/tool/GroupTool.tsx index 8a4cbdd..38268e6 100644 --- a/packages/component/src/component/property/tool/GroupTool.tsx +++ b/packages/component/src/component/property/tool/GroupTool.tsx @@ -7,7 +7,7 @@ import { useCallback } from "react"; import PropertyBox from '../object/PropertyBox'; import { Button, ButtonGroup } from '@mui/material'; -import getCaptions from '../../../captions/getCaptions'; +import translation from '../../../translations/translation'; import useShapes from '../../reportEditor/hooks/useShapes'; import { Field, Group, grouping, List, listToShapes, @@ -23,7 +23,7 @@ export default function GroupTool() { const { selection, setSelection } = useSelection(); const { hasList } = useReport(); const reportHasList = hasList(); - const captions = getCaptions().groupOperation; + const t = translation().groupOperation; const handleGroup = useCallback(() => { const { shapes: newShapes, group } = grouping(shapes, selection); @@ -73,13 +73,13 @@ export default function GroupTool() { @@ -87,13 +87,13 @@ export default function GroupTool() { size="small" onClick={handleShapesToList} disabled={!canList()} > - {captions.shapesToList} + {t.shapesToList} diff --git a/packages/component/src/component/reportEditor/ReportEditor.tsx b/packages/component/src/component/reportEditor/ReportEditor.tsx index 38b2598..1cf80db 100644 --- a/packages/component/src/component/reportEditor/ReportEditor.tsx +++ b/packages/component/src/component/reportEditor/ReportEditor.tsx @@ -13,7 +13,7 @@ import FooterToolbar from '../toolbar/FooterToolbar'; import { ReportData } from '@sunvisor/super-leopard-core'; import DrawToolbar from '../toolbar/DrawToolbar'; import SidePanel from './side/SidePanel'; -import { setLanguage } from '../../captions/getCaptions'; +import { setLanguage } from '../../translations/translation'; import { setSettings, SettingData } from '../../settings'; import useReport from '../../hooks/useReport'; import useSelection from '../../hooks/useSelection'; diff --git a/packages/component/src/component/reportEditor/side/LayerListItem.tsx b/packages/component/src/component/reportEditor/side/LayerListItem.tsx index a7a0417..ff236a5 100644 --- a/packages/component/src/component/reportEditor/side/LayerListItem.tsx +++ b/packages/component/src/component/reportEditor/side/LayerListItem.tsx @@ -14,7 +14,7 @@ import DeleteIcon from '@mui/icons-material/Delete'; import EditIcon from '@mui/icons-material/Edit'; import ListItemButton from '@mui/material/ListItemButton'; import { LayerItem } from './LayerList'; -import getCaptions from '../../../captions/getCaptions'; +import translation from '../../../translations/translation'; type Props = { item: LayerItem; @@ -25,7 +25,7 @@ type Props = { export default function LayerListItem(props: Props) { const { item, onSelect, onRemove, onRename } = props; - const captions = getCaptions().layerOperation; + const t = translation().layerOperation; const [editMode, setEditMode] = useState(false); const [layerName, setLayerName] = useState(item.name); const { @@ -85,12 +85,12 @@ export default function LayerListItem(props: Props) {
- + - + diff --git a/packages/component/src/component/reportEditor/side/LayerToolbar.tsx b/packages/component/src/component/reportEditor/side/LayerToolbar.tsx index 24a754a..f87ea3e 100644 --- a/packages/component/src/component/reportEditor/side/LayerToolbar.tsx +++ b/packages/component/src/component/reportEditor/side/LayerToolbar.tsx @@ -7,14 +7,14 @@ import { Button, Toolbar } from "@mui/material"; import AddCircleIcon from '@mui/icons-material/AddCircle'; import { useCallback } from "react"; -import getCaptions from '../../../captions/getCaptions'; +import translation from '../../../translations/translation'; type Props = { onAddLayer: () => void; } export default function LayerToolbar({ onAddLayer }: Props) { - const captions = getCaptions().layerOperation; + const t = translation().layerOperation; const handleClick = useCallback(() => { onAddLayer(); @@ -26,7 +26,7 @@ export default function LayerToolbar({ onAddLayer }: Props) { startIcon={} onClick={handleClick} > - {captions.addLayer} + {t.addLayer} ); diff --git a/packages/component/src/component/reportEditor/side/SidePanel.tsx b/packages/component/src/component/reportEditor/side/SidePanel.tsx index 781f1ec..4e0d7e5 100644 --- a/packages/component/src/component/reportEditor/side/SidePanel.tsx +++ b/packages/component/src/component/reportEditor/side/SidePanel.tsx @@ -9,7 +9,7 @@ import { Box, Drawer, IconButton, Tab, Tabs, Toolbar } from '@mui/material'; import { EditMode } from '../ReportWorkArea'; import ChevronRightIcon from '@mui/icons-material/ChevronRight'; import { Shapes } from '@sunvisor/super-leopard-core'; -import getCaptions from '../../../captions/getCaptions'; +import translation from '../../../translations/translation'; import PropertyTab from './PropertyTab'; import LayerPanel from './LayerPanel'; import ObjectListPanel from '../../objectList/ObjectListPanel'; @@ -25,14 +25,12 @@ type Props = { } function getAddModeTitle(mode: EditMode): string { - const captions = getCaptions().editModeTool; - return captions[mode]; + const t = translation().editModeTool; + return t[mode]; } function getEditModeTitle(selection: Shapes): string { - const captions = getCaptions(); - const shapeType = captions.shapeType; - const { transform } = captions.operation; + const { shapeType, operation: { transform } } = translation(); if (selection.count === 1) { return shapeType[selection.get(0).type]; } @@ -55,7 +53,7 @@ export default function SidePanel(props: Props) { const { selection } = useSelection(); const settings = getSettings(); const [tabIndex, setTabIndex] = React.useState(0); - const captions = getCaptions().reportObject; + const t = translation().reportObject; const { image: imageOptions, barcode: barcodeOptions } = settings; const fontList = getFontList(settings.fontMap); @@ -86,9 +84,9 @@ export default function SidePanel(props: Props) { - - - + + + { diff --git a/packages/component/src/component/toolbar/EditModeButtons.tsx b/packages/component/src/component/toolbar/EditModeButtons.tsx index 93697b1..f7a0fcf 100644 --- a/packages/component/src/component/toolbar/EditModeButtons.tsx +++ b/packages/component/src/component/toolbar/EditModeButtons.tsx @@ -15,7 +15,7 @@ import QrCodeIcon from '@mui/icons-material/QrCode'; import { EditMode } from '../reportEditor/ReportWorkArea'; import EllipseIcon from '../toolbar/EllipseIcon'; import LineIcon from '../toolbar/LineIcon'; -import getCaptions from '../../captions/getCaptions'; +import translation from '../../translations/translation'; import ToggleTools, { ToggleToolButton } from '../property/ToggleTools'; type OnChangeHandler = (event: React.MouseEvent, newMode: EditMode) => void; @@ -29,7 +29,7 @@ export type EditModeButtonsProps = Props; export default function EditModeButtons(props: Props) { const { onChange, orientation } = props; const [mode, setMode] = React.useState(props.mode || "edit"); - const captions = getCaptions().editModeTool; + const t = translation().editModeTool; const handleChange = useCallback((event: React.MouseEvent, value: string) => { if (value !== null) { @@ -40,16 +40,16 @@ export default function EditModeButtons(props: Props) { }, [onChange, setMode]); const buttons: ToggleToolButton[] = useMemo(() => [ - { value: "edit", icon: , title: captions.edit }, - { value: "rect", icon: , title: captions.rect }, - { value: "circle", icon: , title: captions.circle }, - { value: "ellipse", icon: , title: captions.ellipse }, - { value: "line", icon: , title: captions.line }, - { value: "image", icon: , title: captions.image }, - { value: "text", icon: , title: captions.text }, - { value: "field", icon: , title: captions.field }, - { value: "barcode", icon: , title: captions.barcode }, - ], [captions.edit, captions.rect, captions.circle, captions.ellipse, captions.line, captions.image, captions.text, captions.field, captions.barcode]); + { value: "edit", icon: , title: t.edit }, + { value: "rect", icon: , title: t.rect }, + { value: "circle", icon: , title: t.circle }, + { value: "ellipse", icon: , title: t.ellipse }, + { value: "line", icon: , title: t.line }, + { value: "image", icon: , title: t.image }, + { value: "text", icon: , title: t.text }, + { value: "field", icon: , title: t.field }, + { value: "barcode", icon: , title: t.barcode }, + ], [t.edit, t.rect, t.circle, t.ellipse, t.line, t.image, t.text, t.field, t.barcode]); return ( (props.title); const showSaveButton = props.showSaveButton !== undefined ? props.showSaveButton : true; - const captions = getCaptions().editTool; + const t = translation().editTool; const [editTitle, setEditTitle] = React.useState(false); @@ -60,8 +60,8 @@ export default function EditToolbar(props: Props) { props.additionalTools?.before && props.additionalTools.before } { - showSaveButton && - + showSaveButton && + @@ -72,8 +72,8 @@ export default function EditToolbar(props: Props) { { (showSaveButton || props.additionalTools) && } - - + + @@ -94,8 +94,8 @@ export default function EditToolbar(props: Props) { setEditTitle(true)} style={{ color: 'white' }}>{title} } - - + + diff --git a/packages/component/src/index.ts b/packages/component/src/index.ts index 1470e1c..7942844 100644 --- a/packages/component/src/index.ts +++ b/packages/component/src/index.ts @@ -2,3 +2,4 @@ export * from './svg'; export * from './component'; export * from './settings'; export * from './font'; +export * from './translations/translation'; diff --git a/packages/component/src/captions/en/captions.ts b/packages/component/src/translations/languages/en.ts similarity index 67% rename from packages/component/src/captions/en/captions.ts rename to packages/component/src/translations/languages/en.ts index 216c0fa..0d97614 100644 --- a/packages/component/src/captions/en/captions.ts +++ b/packages/component/src/translations/languages/en.ts @@ -1,45 +1,13 @@ -// noinspection JSUnusedGlobalSymbols - /** * English Captions * * Created by sunvisor on 2024/02/15. * Copyright (C) Sunvisor Lab. 2024. */ -import { - AlignTool, - BarcodeProperty, - BarcodeRotateName, - BorderProperty, - Captions, - CapTool, - CircleProperty, - ColorPickerField, - EditModeTool, - EditTool, - FieldProperty, - FillColorProperty, - FontProperty, - GroupOperation, - GroupProperty, - ImageProperty, - JoinTool, - LayerOperation, - ListProperty, - NumberErrorMessage, - ObjectManipulation, - Operation, - PageProperty, - PositionProperty, - ReportObject, - ShapeTypeName, - SizeProperty, - StaticShapeTypeName, - TextProperty -} from '../CaptionsType'; +import { Translation } from './ja'; -const operation: Operation = { +const operation = { undo: "Undo", redo: "Redo", cut: "Cut", @@ -49,7 +17,7 @@ const operation: Operation = { delete: "Delete", } -const reportObject: ReportObject = { +const reportObject= { report: "Report", layer: "Layer", shape: "Shape", @@ -59,7 +27,7 @@ const reportObject: ReportObject = { editProperty: "Edit Property", } -const pageProperty: PageProperty = { +const pageProperty= { title: 'Page Settings', paperSize: 'Paper Size', custom: 'custom...', @@ -77,7 +45,7 @@ const pageProperty: PageProperty = { pt: 'Point (pt)', } -const staticShapeType: StaticShapeTypeName = { +const staticShapeType= { rect: "Rectangle", circle: "Circle", ellipse: "Ellipse", @@ -87,41 +55,41 @@ const staticShapeType: StaticShapeTypeName = { barcode: "Barcode", } -const shapeType: ShapeTypeName = { +const shapeType= { ...staticShapeType, group: "Group", list: "List", field: "Field", } -const editTool: EditTool = { +const editTool= { save: 'Save', rename: 'Rename', property: 'Property', } -const editModeTool: EditModeTool = { +const editModeTool= { edit: "Edit", field: "Field", ...staticShapeType, } -const positionProperty: PositionProperty = { +const positionProperty= { x: "X", y: "Y", startPosition: "Start", endPosition: "End", } -const sizeProperty: SizeProperty = { +const sizeProperty= { width: "Width", height: "Height", } -const fillColorProperty: FillColorProperty = { +const fillColorProperty= { fillColor: "Fill Color", } -const borderProperty: BorderProperty = { +const borderProperty= { border: "Border", color: "Border Color", width: "Border Width", @@ -130,28 +98,28 @@ const borderProperty: BorderProperty = { join: "Join", } -const capTool: CapTool = { +const capTool= { butt: "Butt", round: "Round", square: "Square", } -const joinTool: JoinTool = { +const joinTool= { miter: "Miter", round: "Round", bevel: "Bevel", } -export const colorPickerField: ColorPickerField = { +export const colorPickerField= { invalidColor: 'Invalid color code', } -const circleProperty: CircleProperty = { +const circleProperty= { diameter: "直径", } -const textProperty: TextProperty = { +const textProperty= { text: 'Text', align: 'Align', valign: 'Vertical Align', @@ -161,7 +129,7 @@ const textProperty: TextProperty = { fitCell: 'Fit to Cell', } -const alignTool: AlignTool = { +const alignTool= { left: 'Left', center: 'Center', right: 'Right', @@ -172,7 +140,7 @@ const alignTool: AlignTool = { bottom: 'Bottom', } -const fontProperty: FontProperty = { +const fontProperty= { fontFamily: "Font", fontSize: "Size", fontStyle: "Style", @@ -182,7 +150,7 @@ const fontProperty: FontProperty = { strikethrough: "Strikethrough", } -const imageProperty: ImageProperty = { +const imageProperty= { upload: "Upload Image", select: "Select Image", selectMessage: "Please Select image", @@ -190,26 +158,26 @@ const imageProperty: ImageProperty = { close: 'Close', } -const barcodeProperty: BarcodeProperty = { +const barcodeProperty= { format: "Format", value: "Value", rotate: 'Rotate', includeText: 'Include Text', } -const barcodeRotateName: BarcodeRotateName = { +const barcodeRotateName= { N: 'None', L: 'Clockwise', R: 'Anti-Clockwise', I: 'Invert', } -const fieldProperty: FieldProperty = { +const fieldProperty= { name: 'Field Name', shapeType: 'Shape Type', } -const groupProperty: GroupProperty = { +const groupProperty= { repeatCount: 'Repeat Count', direction: 'Repeat Direction', horizontal: 'Horizontal', @@ -217,13 +185,13 @@ const groupProperty: GroupProperty = { times: 'Times', } -const listProperty: ListProperty = { +const listProperty= { direction: 'Direction', rows: 'Rows', columns: 'Columns', } -const objectManipulation: ObjectManipulation = { +const objectManipulation= { toFront: 'Front', toBack: 'Back', toForward: 'Forward', @@ -242,26 +210,26 @@ const objectManipulation: ObjectManipulation = { distributeVertically: 'Distribute Vertically', } -const groupOperation: GroupOperation = { +const groupOperation= { group: 'Group', ungroup: 'Ungroup', shapesToList: 'Shapes to List', listToShapes: 'List to Shapes', } -const layerOperation: LayerOperation = { +const layerOperation= { addLayer: 'Add Layer', removeLayer: 'Remove Layer', renameLayer: 'Rename Layer', } -const numberErrorMessage: NumberErrorMessage = { - minValue: value => `The value must be greater than or equal to ${value}.`, - maxValue: value => `The value must be less than or equal to ${value}.`, +const numberErrorMessage= { + minValue: (value: number) => `The value must be greater than or equal to ${value}.`, + maxValue: (value: number) => `The value must be less than or equal to ${value}.`, invalidValue: 'Invalid number.', } -export const captions: Captions = { +export const en: Translation = { operation, reportObject, pageProperty, diff --git a/packages/component/src/captions/ja/captions.ts b/packages/component/src/translations/languages/ja.ts similarity index 70% rename from packages/component/src/captions/ja/captions.ts rename to packages/component/src/translations/languages/ja.ts index 2cd5529..b7d1346 100644 --- a/packages/component/src/captions/ja/captions.ts +++ b/packages/component/src/translations/languages/ja.ts @@ -1,42 +1,10 @@ -// noinspection JSUnusedGlobalSymbols - /** * Japanese Captions * * Created by sunvisor on 2024/02/15. * Copyright (C) Sunvisor Lab. 2024. */ -import { - AlignTool, - BarcodeProperty, BarcodeRotateName, - BorderProperty, - Captions, - CapTool, - CircleProperty, - ColorPickerField, - EditModeTool, - EditTool, - FieldProperty, - FillColorProperty, - FontProperty, - GroupOperation, - GroupProperty, - ImageProperty, - JoinTool, - LayerOperation, - ListProperty, - NumberErrorMessage, - ObjectManipulation, - Operation, - PageProperty, - PositionProperty, - ReportObject, - ShapeTypeName, - SizeProperty, - TextProperty -} from '../CaptionsType'; - -const operation: Operation = { +const operation = { undo: '元に戻す', redo: 'やり直す', delete: '削除', @@ -46,8 +14,8 @@ const operation: Operation = { transform: '変形', } -const reportObject: ReportObject = { - report: 'レポート' , +const reportObject = { + report: 'レポート', page: 'ページ', layer: 'レイヤー', property: 'プロパティ', @@ -56,7 +24,7 @@ const reportObject: ReportObject = { editProperty: 'プロパティを編集する', } -const pageProperty: PageProperty = { +const pageProperty = { title: 'ページ情報', paperSize: '用紙サイズ', custom: 'カスタム...', @@ -84,42 +52,42 @@ const staticShapeType = { barcode: 'バーコード', } -const shapeType: ShapeTypeName = { +const shapeType = { ...staticShapeType, group: 'グループ', list: 'リスト', field: 'フィールド', } -const editTool: EditTool = { +const editTool = { save: '保存', rename: '名前を変更', property: 'プロパティ', } -const editModeTool: EditModeTool = { +const editModeTool = { edit: '編集', field: 'フィールド', ...staticShapeType, } -const positionProperty: PositionProperty = { +const positionProperty = { x: "X位置", y: "Y位置", startPosition: "開始", endPosition: "終了", } -const sizeProperty: SizeProperty = { +const sizeProperty = { width: "幅", height: "高さ", } -const fillColorProperty: FillColorProperty = { +const fillColorProperty = { fillColor: "塗り色", } -const borderProperty: BorderProperty = { +const borderProperty = { border: "線", color: "線色", width: "線幅", @@ -128,27 +96,27 @@ const borderProperty: BorderProperty = { join: "角", } -const capTool: CapTool = { +const capTool = { butt: "直線", round: "丸", square: "四角", } -const joinTool: JoinTool = { +const joinTool = { miter: "角結合", round: "丸結合", bevel: "斜結合", } -const colorPickerField: ColorPickerField = { +const colorPickerField = { invalidColor: '不正な色コード', } -const circleProperty: CircleProperty = { +const circleProperty = { diameter: "直径", } -const textProperty: TextProperty = { +const textProperty = { text: '文字', align: '揃え', valign: '縦揃え', @@ -158,7 +126,7 @@ const textProperty: TextProperty = { fitCell: '範囲に合わせる', } -const alignTool: AlignTool = { +const alignTool = { left: '左揃え', center: '中央揃え', right: '右揃え', @@ -169,7 +137,7 @@ const alignTool: AlignTool = { bottom: '下揃え', } -const fontProperty: FontProperty = { +const fontProperty = { fontFamily: "フォント", fontSize: "サイズ", fontStyle: "スタイル", @@ -179,7 +147,7 @@ const fontProperty: FontProperty = { strikethrough: "打ち消し線", } -const imageProperty: ImageProperty = { +const imageProperty = { upload: '画像をアップロードする', select: '画像を選択する', selectMessage: '使用する画像を選択してください', @@ -187,26 +155,26 @@ const imageProperty: ImageProperty = { close: '閉じる', } -const barcodeProperty: BarcodeProperty = { +const barcodeProperty = { format: '形式', value: '値', rotate: '回転', includeText: '文字を表示', } -const barcodeRotateName: BarcodeRotateName = { +const barcodeRotateName = { N: 'なし', L: '時計回り', R: '反時計回り', I: '180度回転', } -const fieldProperty: FieldProperty = { +const fieldProperty = { name: 'フィールド名', shapeType: '図形タイプ', } -const groupProperty: GroupProperty = { +const groupProperty = { direction: '繰り返す方向', repeatCount: '繰り返し回数', vertical: '縦方向', @@ -214,13 +182,13 @@ const groupProperty: GroupProperty = { times: '回', } -const listProperty: ListProperty = { +const listProperty = { direction: '方向', rows: '行数', columns: '列数', } -const objectManipulation: ObjectManipulation = { +const objectManipulation = { toFront: '最前面へ', toBack: '最背面へ', toForward: '前へ', @@ -239,26 +207,26 @@ const objectManipulation: ObjectManipulation = { distributeVertically: '縦方向に分布', } -const groupOperation: GroupOperation = { +const groupOperation = { group: 'グループ化', ungroup: 'グループ解除', shapesToList: 'リスト化', listToShapes: 'リスト解除', } -const layerOperation: LayerOperation = { +const layerOperation = { addLayer: 'レイヤーを追加', removeLayer: 'レイヤーを削除', renameLayer: 'レイヤー名を変更', } -const numberErrorMessage: NumberErrorMessage = { - minValue: value => `値は${value}以上でなければなりません`, - maxValue: value => `値は${value}以下でなければなりません`, +const numberErrorMessage = { + minValue: (value: number) => `値は${value}以上でなければなりません`, + maxValue: (value: number) => `値は${value}以下でなければなりません`, invalidValue: '不正な値です', } -export const captions: Captions = { +export const ja = { operation, reportObject, pageProperty, @@ -289,3 +257,4 @@ export const captions: Captions = { numberErrorMessage, } +export type Translation = typeof ja diff --git a/packages/component/src/translations/translation.test.ts b/packages/component/src/translations/translation.test.ts new file mode 100644 index 0000000..ad060e5 --- /dev/null +++ b/packages/component/src/translations/translation.test.ts @@ -0,0 +1,96 @@ +/** + * Test for Translation + * + * Created by sunvisor on 2025/03/08. + * Copyright (C) Sunvisor Lab. 2025. + */ +import translation, { addLanguage, mergeLanguage, setLanguage } from "./translation"; +import { ja } from './languages/ja'; +import { en } from './languages/en'; + +describe('Tests for translation', () => { + + it('should return ja when currentLanguage is ja', () => { + setLanguage('ja'); + expect(translation()).toEqual(ja); + }); + + it('should return en when currentLanguage is en', () => { + setLanguage('en'); + expect(translation()).toEqual(en); + }); + + it('should throw error when currentLanguage is unknown', () => { + expect(() => setLanguage('unknown')).toThrowError('Unknown language: unknown'); + }); + + describe("Tests for addLanguage", () => { + + it('should add new language', () => { + // Arrange + const lang = 'custom'; + const newTranslation = { + ...ja, + operation: { + ...ja.operation, + undo: "Undo" + } + }; + // Act + addLanguage(lang, newTranslation); + // Assert + setLanguage(lang); + expect(translation().operation.undo).toBe('Undo'); + }); + + it('should throw error when language already exists', () => { + // Arrange + const lang = 'en'; + const newTranslation = { + ...ja, + operation: { + ...ja.operation, + undo: "Undo" + } + }; + // Act & Assert + expect(() => addLanguage(lang, newTranslation)).toThrowError('Language already exists: en'); + }); + + }); + + describe("Tests for mergeLanguage", () => { + + it("should override value", () => { + const updated = mergeLanguage("en", { + operation: { undo: "元に戻す" }, + }); + + expect(updated.operation.undo).toBe("元に戻す"); + expect(updated.operation.redo).toBe("Redo"); // should not change + }); + + it("should throw error when unknown language is specified", () => { + expect(() => mergeLanguage("fr", { operation: { undo: "Annuler" } })) + .toThrow("Unknown language: fr"); + }); + + it("can update multiple sections at once", () => { + const updated = mergeLanguage("en", { + operation: { undo: "元に戻す", redo: "やり直し" }, + reportObject: { property: "プロパティ", layer: "レイヤー" }, + }); + + expect(updated.operation.undo).toBe("元に戻す"); + expect(updated.operation.redo).toBe("やり直し"); + expect(updated.reportObject.property).toBe("プロパティ"); + expect(updated.reportObject.layer).toBe("レイヤー"); + + // should not change + expect(updated.operation.delete).toBe("Delete"); + expect(updated.reportObject.report).toBe("Report"); + }); + + }); + +}); diff --git a/packages/component/src/translations/translation.ts b/packages/component/src/translations/translation.ts new file mode 100644 index 0000000..dcdd1f6 --- /dev/null +++ b/packages/component/src/translations/translation.ts @@ -0,0 +1,63 @@ +/** + * Translation + * + * Created by sunvisor on 2025/03/08. + * Copyright (C) Sunvisor Lab. 2025. + */ +import { ja, Translation } from './languages/ja'; +import { en } from './languages/en'; + +export type Language = string; + +let currentLanguage: Language = 'ja'; +const translations = new Map([ + ["ja", ja], + ["en", en], +]); + +export default function translation(): Translation { + return translations.get(currentLanguage) || ja; +} + +export function setLanguage(lang: string) { + if (!translations.has(lang)) { + throw new Error(`Unknown language: ${lang}`); + } + currentLanguage = lang; +} + +export function addLanguage(lang: string, translation: Translation) { + if (translations.has(lang)) { + throw new Error(`Language already exists: ${lang}`); + } + translations.set(lang, translation); +} + +type DeepPartial = { + [P in keyof T]?: Partial; +}; + +export function mergeLanguage( + lang: string, + newValues: DeepPartial +): Translation { + const target = translations.get(lang); + if (!target) { + throw new Error(`Unknown language: ${lang}`); + } + + return Object.keys(newValues).reduce((acc, key) => { + const typedKey = key as keyof Translation; + return mergeSection(acc, typedKey, newValues[typedKey]!); + }, target); +} + +function mergeSection(target: Translation, key: keyof Translation, newValues: Partial): Translation { + return { + ...target, + [key]: { + ...target[key], + ...newValues, + }, + }; +}