Skip to content

Commit 16994ec

Browse files
committed
fix(ui,sdk): localize disclosure labels
1 parent 5ca334c commit 16994ec

7 files changed

Lines changed: 49 additions & 7 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@workflowbuilder/ui': minor
3+
'@workflowbuilder/sdk': patch
4+
---
5+
6+
`Modal` now accepts `closeLabel`, while `Collapsible` accepts `expandLabel` and `collapseLabel`, all with English defaults. The SDK supplies its localized labels to these controls.

packages/sdk/src/features/diagram/nodes/ai-agent-node-template/ai-agent-node-template.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Collapsible, NodeDescription, NodeIcon, NodePanel, Status } from '@work
22
import { Handle } from '@xyflow/react';
33
import clsx from 'clsx';
44
import { memo, useMemo } from 'react';
5+
import { useTranslation } from 'react-i18next';
56

67
import { Icon } from '@workflow-builder/icons';
78

@@ -47,6 +48,7 @@ export const AiAgentNodeTemplate = memo(
4748
layoutDirection = 'RIGHT',
4849
onAddTool,
4950
}: Props) => {
51+
const { t } = useTranslation();
5052
const isCanvasNode = showHandles;
5153
const handleTargetId = getHandleId({ handleType: 'target' });
5254
const handleSourceId = getHandleId({ handleType: 'source' });
@@ -59,7 +61,7 @@ export const AiAgentNodeTemplate = memo(
5961
const handlesAlignment = getHandlesAlignment({ layoutDirection });
6062

6163
return (
62-
<Collapsible>
64+
<Collapsible expandLabel={t('common.expand')} collapseLabel={t('common.collapse')}>
6365
<NodePanel.Root selected={selected}>
6466
<NodePanel.Header className={styles['header']}>
6567
<NodeIcon className={styles['icon']} icon={iconElement} />

packages/sdk/src/features/diagram/nodes/start-node-template/start-node-template.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Collapsible, NodeDescription, NodeIcon, NodePanel, Status } from '@workflowbuilder/ui';
22
import { Handle } from '@xyflow/react';
33
import { memo, useMemo } from 'react';
4+
import { useTranslation } from 'react-i18next';
45

56
import { Icon } from '@workflow-builder/icons';
67

@@ -40,6 +41,7 @@ const StartNodeTemplateComponent = memo(
4041
isValid,
4142
children,
4243
}: StartNodeTemplateProps) => {
44+
const { t } = useTranslation();
4345
const isCanvasNode = showHandles;
4446

4547
const handleSourceId = getHandleId({ handleType: 'source' });
@@ -51,7 +53,7 @@ const StartNodeTemplateComponent = memo(
5153
const handlesAlignment = getHandlesAlignment({ layoutDirection });
5254

5355
return (
54-
<Collapsible>
56+
<Collapsible expandLabel={t('common.expand')} collapseLabel={t('common.collapse')}>
5557
<NodePanel.Root selected={selected} className={styles['content']}>
5658
<NodePanel.Header>
5759
<NodeIcon icon={iconElement} />

packages/sdk/src/features/diagram/nodes/workflow-node-template/workflow-node-template.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Collapsible, NodeDescription, NodeIcon, NodePanel, Status } from '@workflowbuilder/ui';
22
import { Handle } from '@xyflow/react';
33
import { memo, useMemo } from 'react';
4+
import { useTranslation } from 'react-i18next';
45

56
import { Icon } from '@workflow-builder/icons';
67

@@ -64,6 +65,7 @@ const WorkflowNodeTemplateComponent = memo(
6465
isValid,
6566
children,
6667
}: WorkflowNodeTemplateProps) => {
68+
const { t } = useTranslation();
6769
const isCanvasNode = showHandles;
6870

6971
const handleTargetId = getHandleId({ handleType: 'target' });
@@ -77,7 +79,7 @@ const WorkflowNodeTemplateComponent = memo(
7779
const handlesAlignment = getHandlesAlignment({ layoutDirection });
7880

7981
return (
80-
<Collapsible>
82+
<Collapsible expandLabel={t('common.expand')} collapseLabel={t('common.collapse')}>
8183
<NodePanel.Root selected={selected} className={styles['content']}>
8284
<NodePanel.Header>
8385
<NodeIcon icon={iconElement} />

packages/sdk/src/features/modals/providers/modal-provider.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
import { Modal } from '@workflowbuilder/ui';
22
import { useEffect, useRef, useState } from 'react';
33
import { createPortal } from 'react-dom';
4+
import { useTranslation } from 'react-i18next';
45

56
import { closeModal, useModalStore } from '../stores/use-modal-store';
67

78
// Read by variable-text.module.css to suppress its own backdrop.
89
const MODAL_OPEN_BODY_CLASS = 'wb-modal-open';
910

1011
export function ModalProvider() {
12+
const { t } = useTranslation();
1113
const isOpen = useModalStore((state) => state.isOpen);
1214
const modal = useModalStore((state) => state.modal);
1315

@@ -46,6 +48,7 @@ export function ModalProvider() {
4648
open={isOpen && !!modal}
4749
icon={activeModal?.icon}
4850
onClose={activeModal?.isCloseButtonVisible ? closeModal : undefined}
51+
closeLabel={t('common.close')}
4952
title={activeModal?.title || ''}
5053
footer={activeModal?.footer}
5154
footerVariant={activeModal?.footerVariant}

packages/ui/src/components/collapsible/collapsible.tsx

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import { NavButton } from '../button/nav-button/nav-button';
1010
interface CollapsibleContextProps {
1111
isExpanded: boolean;
1212
toggle: () => void;
13+
expandLabel: string;
14+
collapseLabel: string;
1315
}
1416

1517
const CollapsibleContext = createContext<CollapsibleContextProps | undefined>(undefined);
@@ -28,9 +30,26 @@ export type CollapsibleProps = {
2830
isExpanded?: boolean;
2931
defaultExpanded?: boolean;
3032
onToggle?: (expanded: boolean) => void;
33+
/**
34+
* Accessible label for the button when the content is collapsed
35+
* @default 'Expand'
36+
*/
37+
expandLabel?: string;
38+
/**
39+
* Accessible label for the button when the content is expanded
40+
* @default 'Collapse'
41+
*/
42+
collapseLabel?: string;
3143
};
3244

33-
export function Collapsible({ children, isExpanded, defaultExpanded = false, onToggle }: CollapsibleProps) {
45+
export function Collapsible({
46+
children,
47+
isExpanded,
48+
defaultExpanded = false,
49+
onToggle,
50+
expandLabel = 'Expand',
51+
collapseLabel = 'Collapse',
52+
}: CollapsibleProps) {
3453
const isControlled = isExpanded !== undefined;
3554
const [internalExpanded, setInternalExpanded] = useState(defaultExpanded);
3655

@@ -45,7 +64,9 @@ export function Collapsible({ children, isExpanded, defaultExpanded = false, onT
4564
}, [actualExpanded, isControlled, onToggle]);
4665

4766
return (
48-
<CollapsibleContext.Provider value={{ isExpanded: actualExpanded, toggle }}>{children}</CollapsibleContext.Provider>
67+
<CollapsibleContext.Provider value={{ isExpanded: actualExpanded, toggle, expandLabel, collapseLabel }}>
68+
{children}
69+
</CollapsibleContext.Provider>
4970
);
5071
}
5172

@@ -54,7 +75,7 @@ Collapsible.Button = function CollapsibleButton() {
5475

5576
return (
5677
<NavButton
57-
aria-label={context?.isExpanded ? 'Collapse' : 'Expand'}
78+
aria-label={context?.isExpanded ? context.collapseLabel : context?.expandLabel}
5879
className={clsx(styles['expand-button'], {
5980
[styles['expanded']]: context?.isExpanded,
6081
})}

packages/ui/src/components/modal/modal.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ export type ModalProps = React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivEle
4848
* Callback function called when the modal is closed
4949
*/
5050
onClose?: () => void;
51+
/**
52+
* Accessible label for the close button
53+
* @default 'Close'
54+
*/
55+
closeLabel?: string;
5156
};
5257

5358
/**
@@ -65,6 +70,7 @@ export const Modal = forwardRef<HTMLDivElement, ModalProps>(
6570
footerVariant = 'integrated',
6671
open,
6772
onClose,
73+
closeLabel = 'Close',
6874
className,
6975
...rest
7076
},
@@ -99,7 +105,7 @@ export const Modal = forwardRef<HTMLDivElement, ModalProps>(
99105
)}
100106
</div>
101107
</div>
102-
{onClose && <NavButton aria-label="Close" onClick={onClose} prefixIcon={<X />} />}
108+
{onClose && <NavButton aria-label={closeLabel} onClick={onClose} prefixIcon={<X />} />}
103109
</div>
104110

105111
{children && <div className={styles['content']}>{children}</div>}

0 commit comments

Comments
 (0)