diff --git a/src/hooks/useColorGenerator/__tests__/randomIndex.test.ts b/src/components/utils/common.tests.ts similarity index 86% rename from src/hooks/useColorGenerator/__tests__/randomIndex.test.ts rename to src/components/utils/common.tests.ts index 6f1d25e98d..1d6f323bd0 100644 --- a/src/hooks/useColorGenerator/__tests__/randomIndex.test.ts +++ b/src/components/utils/common.tests.ts @@ -1,6 +1,4 @@ -import {randomIndex} from '../utils'; - -import {randomString} from './utils/randomString'; +import {randomIndex, randomString} from './common'; describe('randomIndex', () => { test('returns numbers within the range [0, max)', () => { diff --git a/src/components/utils/common.ts b/src/components/utils/common.ts index 0a394d0ddc..69e64a6da2 100644 --- a/src/components/utils/common.ts +++ b/src/components/utils/common.ts @@ -10,3 +10,38 @@ export function getUniqId() { } export const isIcon = isOfType(Icon); + +const getHash = (seed: string) => { + let hash = 0; + + for (let index = 0; index < seed.length; index++) { + // eslint-disable-next-line no-bitwise + hash = seed.charCodeAt(index) + ((hash << 5) - hash); + } + + return hash; +}; + +export const randomIndex = (seed: string, max: number) => { + if (max === 0) { + return 0; + } + + const hash = getHash(seed); + + const number = Math.abs(hash) % max; + + return number; +}; + +const MASK = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; + +export const randomString = (length: number) => { + let result = ''; + + for (let index = length; index >= 0; index--) { + result += MASK[Math.round(Math.random() * (MASK.length - 1))]; + } + + return result; +}; diff --git a/src/hooks/useColorGenerator/__stories__/ColorGenerator.scss b/src/hooks/useColorGenerator/__stories__/ColorGenerator.scss index 100143912f..07eb5cfb10 100644 --- a/src/hooks/useColorGenerator/__stories__/ColorGenerator.scss +++ b/src/hooks/useColorGenerator/__stories__/ColorGenerator.scss @@ -7,6 +7,22 @@ $block: '.#{variables.$ns}color-generator'; display: flex; flex-wrap: wrap; gap: 10px; - margin-block-start: 20px; + padding: 12px 8px; + } + + &__grid { + display: inline-grid; + grid-template-columns: repeat(2, auto); + place-items: center center; + margin-block-end: 20px; + + &-cell { + padding: 12px 16px; + + &_head_left { + white-space: nowrap; + justify-self: end; + } + } } } diff --git a/src/hooks/useColorGenerator/__stories__/ColoredAvatar.tsx b/src/hooks/useColorGenerator/__stories__/ColoredAvatar.tsx index c40c81ff0b..447e935189 100644 --- a/src/hooks/useColorGenerator/__stories__/ColoredAvatar.tsx +++ b/src/hooks/useColorGenerator/__stories__/ColoredAvatar.tsx @@ -7,27 +7,27 @@ import {useColorGenerator} from '../useColorGenerator'; type ColoredAvatarProps = AvatarProps & { withText: boolean; - mode: UseColorGeneratorProps['mode']; - token: UseColorGeneratorProps['token']; + intensity: UseColorGeneratorProps['intensity']; + seed: UseColorGeneratorProps['seed']; }; export const ColoredAvatar = ({ - mode, + intensity, theme, - token, + seed, withText, ...avatarProps }: ColoredAvatarProps) => { const {color, textColor} = useColorGenerator({ - token, - mode, + seed, + intensity, }); return ( ; -const initValues = () => { - const result = Array.from({length: 10}, () => randomString(16)); - - return result; -}; +const views = ['-', 'light', 'medium', 'heavy'] as const; +const states = ['view', 'colors'] as const; const Template = (args: React.ComponentProps) => { - const {mode, withText} = args; - const [tokens, setTokens] = React.useState(initValues); + const items = []; + const tokens = Array.from({length: 10}, () => randomString(16)); + + for (const view of views) { + for (const state of states) { + const key = `${view}_${state}`; + + if (view === '-' && state === 'view') { + items.push( +
+ view\state +
, + ); + } else if (state === 'view') { + items.push( +
+ {view} +
, + ); + } else if (view === '-') { + items.push( +
+ {state} +
, + ); + } else { + const props = { + ...args, + intensity: view, + }; - const onClick = React.useCallback(() => { - const newToken = randomString(16); - setTokens((prev) => [newToken, ...prev]); - }, []); + items.push( +
+ {tokens.map((token) => ( + + ))} +
, + ); + } + } + } return ( - - -
- {tokens.map((token) => ( - - ))} -
-
+
+
{items}
+
); }; -export const Default: Story = { +export const View: Story = { render: (args) => { return