Add useColorScheme hook to twenty-sdk (#21595)
Ability to update front compoonent design according to the dark or white theme of the UI <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/21595?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. -->
This commit is contained in:
@@ -344,6 +344,7 @@ Available hooks:
|
||||
| `useSelectedRecordIds()` | `string[]` | All selected record IDs (empty array if none selected) |
|
||||
| `useRecordId()` | `string` or `null` | **Deprecated.** Use `useSelectedRecordIds()` instead |
|
||||
| `useFrontComponentId()` | `string` | This component instance's ID |
|
||||
| `useColorScheme()` | `'light'` or `'dark'` | The host UI's active color scheme (`System` is already resolved) |
|
||||
| `useFrontComponentExecutionContext(selector)` | varies | Access the full execution context with a selector function |
|
||||
|
||||
## Application variables
|
||||
|
||||
+2
@@ -20,6 +20,7 @@ const meta: Meta<typeof FrontComponentRenderer> = {
|
||||
userId: null,
|
||||
recordId: null,
|
||||
selectedRecordIds: [],
|
||||
colorScheme: 'light',
|
||||
},
|
||||
},
|
||||
beforeEach: () => {
|
||||
@@ -123,6 +124,7 @@ export const SdkContext: Story = {
|
||||
userId: 'test-user-abc-123',
|
||||
recordId: null,
|
||||
selectedRecordIds: [],
|
||||
colorScheme: 'light',
|
||||
},
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
|
||||
@@ -20,6 +20,7 @@ const meta: Meta<typeof FrontComponentRenderer> = {
|
||||
userId: null,
|
||||
recordId: null,
|
||||
selectedRecordIds: [],
|
||||
colorScheme: 'light',
|
||||
},
|
||||
},
|
||||
beforeEach: () => {
|
||||
|
||||
+1
@@ -27,6 +27,7 @@ export const FRONT_COMPONENT_STORY_DEFAULT_ARGS: NonNullable<
|
||||
userId: null,
|
||||
recordId: null,
|
||||
selectedRecordIds: [],
|
||||
colorScheme: 'light',
|
||||
},
|
||||
colorScheme: 'light',
|
||||
frontComponentHostCommunicationApi: hostApiMocks,
|
||||
|
||||
+1
@@ -23,6 +23,7 @@ export const runFrontComponentStory = ({
|
||||
userId: null,
|
||||
recordId: null,
|
||||
selectedRecordIds: [],
|
||||
colorScheme: 'light',
|
||||
},
|
||||
},
|
||||
play,
|
||||
|
||||
@@ -7,4 +7,6 @@ export type FrontComponentExecutionContext = {
|
||||
recordId: string | null;
|
||||
/** All selected record IDs */
|
||||
selectedRecordIds: string[];
|
||||
/** Resolved color scheme of the host UI ('System' is already resolved) */
|
||||
colorScheme: 'light' | 'dark';
|
||||
};
|
||||
|
||||
+1
@@ -39,6 +39,7 @@ export const FrontComponentRenderer = ({
|
||||
frontComponentId,
|
||||
commandMenuItemId,
|
||||
selectedRecordIds,
|
||||
colorScheme,
|
||||
});
|
||||
|
||||
const handleError = useCallback(
|
||||
|
||||
+22
-4
@@ -93,11 +93,18 @@ jest.mock('~/hooks/useCopyToClipboard', () => ({
|
||||
}));
|
||||
|
||||
const renderUseFrontComponentExecutionContext = (
|
||||
params: Parameters<typeof useFrontComponentExecutionContext>[0],
|
||||
params: Omit<
|
||||
Parameters<typeof useFrontComponentExecutionContext>[0],
|
||||
'colorScheme'
|
||||
> & { colorScheme?: 'light' | 'dark' },
|
||||
) =>
|
||||
renderHook(() => useFrontComponentExecutionContext(params), {
|
||||
wrapper: ({ children }) => I18nProvider({ i18n, children }),
|
||||
});
|
||||
renderHook(
|
||||
() =>
|
||||
useFrontComponentExecutionContext({ colorScheme: 'light', ...params }),
|
||||
{
|
||||
wrapper: ({ children }) => I18nProvider({ i18n, children }),
|
||||
},
|
||||
);
|
||||
|
||||
const FRONT_COMPONENT_ID = 'fc-test-id';
|
||||
const COMMAND_MENU_ITEM_ID = 'cmd-item-1';
|
||||
@@ -120,6 +127,7 @@ describe('useFrontComponentExecutionContext', () => {
|
||||
userId: 'user-123',
|
||||
recordId: 'record-456',
|
||||
selectedRecordIds: ['record-456'],
|
||||
colorScheme: 'light',
|
||||
});
|
||||
});
|
||||
|
||||
@@ -134,6 +142,7 @@ describe('useFrontComponentExecutionContext', () => {
|
||||
userId: 'user-123',
|
||||
recordId: null,
|
||||
selectedRecordIds: ['record-1', 'record-2', 'record-3'],
|
||||
colorScheme: 'light',
|
||||
});
|
||||
});
|
||||
|
||||
@@ -165,6 +174,15 @@ describe('useFrontComponentExecutionContext', () => {
|
||||
expect(result.current.executionContext.recordId).toBeNull();
|
||||
expect(result.current.executionContext.selectedRecordIds).toEqual([]);
|
||||
});
|
||||
|
||||
it('should expose the provided colorScheme', () => {
|
||||
const { result } = renderUseFrontComponentExecutionContext({
|
||||
frontComponentId: FRONT_COMPONENT_ID,
|
||||
colorScheme: 'dark',
|
||||
});
|
||||
|
||||
expect(result.current.executionContext.colorScheme).toBe('dark');
|
||||
});
|
||||
});
|
||||
|
||||
describe('navigate', () => {
|
||||
|
||||
+3
@@ -32,10 +32,12 @@ export const useFrontComponentExecutionContext = ({
|
||||
frontComponentId,
|
||||
commandMenuItemId,
|
||||
selectedRecordIds,
|
||||
colorScheme,
|
||||
}: {
|
||||
frontComponentId: string;
|
||||
commandMenuItemId?: string;
|
||||
selectedRecordIds?: string[];
|
||||
colorScheme: 'light' | 'dark';
|
||||
}): {
|
||||
executionContext: FrontComponentExecutionContext;
|
||||
frontComponentHostCommunicationApi: FrontComponentHostCommunicationApi;
|
||||
@@ -141,6 +143,7 @@ export const useFrontComponentExecutionContext = ({
|
||||
userId: currentUser?.id ?? null,
|
||||
recordId: selectedRecordIds?.length === 1 ? selectedRecordIds[0] : null,
|
||||
selectedRecordIds: selectedRecordIds ?? [],
|
||||
colorScheme,
|
||||
};
|
||||
|
||||
const unmountFrontComponent: FrontComponentHostCommunicationApi['unmountFrontComponent'] =
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
import { type FrontComponentExecutionContext } from '../types/FrontComponentExecutionContext';
|
||||
import { useFrontComponentExecutionContext } from './useFrontComponentExecutionContext';
|
||||
|
||||
const selectColorScheme = (
|
||||
context: FrontComponentExecutionContext,
|
||||
): 'light' | 'dark' => context.colorScheme;
|
||||
|
||||
export const useColorScheme = (): 'light' | 'dark' => {
|
||||
return useFrontComponentExecutionContext(selectColorScheme);
|
||||
};
|
||||
@@ -7,6 +7,7 @@ export { openCommandConfirmationModal } from './functions/openCommandConfirmatio
|
||||
export { openSidePanelPage } from './functions/openSidePanelPage';
|
||||
export { unmountFrontComponent } from './functions/unmountFrontComponent';
|
||||
export { updateProgress } from './functions/updateProgress';
|
||||
export { useColorScheme } from './hooks/useColorScheme';
|
||||
export { useFrontComponentExecutionContext } from './hooks/useFrontComponentExecutionContext';
|
||||
export { useFrontComponentId } from './hooks/useFrontComponentId';
|
||||
export { useRecordId } from './hooks/useRecordId';
|
||||
|
||||
@@ -7,4 +7,6 @@ export type FrontComponentExecutionContext = {
|
||||
recordId: string | null;
|
||||
/** All selected record IDs */
|
||||
selectedRecordIds: string[];
|
||||
/** Resolved color scheme of the host UI ('System' is already resolved) */
|
||||
colorScheme: 'light' | 'dark';
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user