Skip to content

Commit

Permalink
Add useCharacterCount to create controlled components (#369)
Browse files Browse the repository at this point in the history
* Skip themekit and pronouns story for lostpixel
  • Loading branch information
juliewongbandue authored Oct 10, 2023
1 parent c2333cd commit 1921d41
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 2 deletions.
9 changes: 8 additions & 1 deletion src/_labs/Pronouns/Pronouns.story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,14 @@ import { AutoplayList } from './AutoplayList';

import { Header } from '../../typography';

export default { title: 'labs/Pronouns' };
export default {
title: 'labs/Pronouns',
parameters: {
lostpixel: {
disable: true,
},
},
};

const componentName = 'Comment';

Expand Down
9 changes: 8 additions & 1 deletion src/_labs/ThemeKit/ThemeKit.story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,14 @@ import { Header as H, Paragraph as P } from '../../typography';
import { LoaderCircular as LC } from '../../motion';
import { Gear } from '../../icons';

export default { title: 'Labs/Themekit' };
export default {
title: 'Labs/Themekit',
parameters: {
lostpixel: {
disable: true,
},
},
};

export function Common() {
return <ThemeKit />;
Expand Down
42 changes: 42 additions & 0 deletions src/utils/hooks/useCharacterCount/useCharacterCount.state.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
export interface CharacterCountState {
error?: boolean;
warning?: boolean;
remainingCharacters?: number;
}

export type UserAction =
| { type: 'SET_ERROR'; payload?: undefined }
| { type: 'SET_WARNING'; payload?: undefined }
| { type: 'RESET_STATUS'; payload?: undefined }
| { type: 'SET_REMAINING_CHARACTERS'; payload: number };

export function reducer(
state: CharacterCountState,
{ type, payload }: UserAction
): CharacterCountState {
switch (type) {
case 'SET_ERROR':
return {
...state,
error: true,
warning: false,
};
case 'SET_WARNING':
return {
...state,
warning: true,
error: false,
};
case 'RESET_STATUS':
return {
...state,
warning: false,
error: false,
};
case 'SET_REMAINING_CHARACTERS':
return {
...state,
remainingCharacters: payload,
};
}
}
77 changes: 77 additions & 0 deletions src/utils/hooks/useCharacterCount/useCharacterCount.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { useReducer, useCallback } from 'react';

import {
reducer,
CharacterCountState,
UserAction,
} from './useCharacterCount.state';

export interface UseCharacterCountInit {
value?: string;
/** Max number of characters allowed */
maxCharacters?: number;
/** Shows warning color when threshold is met */
warningThreshold?: number;
}

export interface UseCharacterCount {
state: CharacterCountState;
dispatch: React.Dispatch<UserAction>;
handleChange: (value: string) => void;
clean: () => void;
}

/**
* Based on withCharacterCount, this provides handlers for a character count message to create a controlled component.
* Helpful to use in conjuction with custom inputs that need more control of input messages
*/

export function useCharacterCount({
maxCharacters = 10,
warningThreshold = 5,
}: UseCharacterCountInit): UseCharacterCount {
const [state, dispatch] = useReducer(reducer, {
remainingCharacters: maxCharacters,
});

function handleError() {
dispatch({
type: 'SET_ERROR',
});
}

function handleWarn() {
dispatch({
type: 'SET_WARNING',
});
}

const clean = useCallback(() => {
dispatch({
type: 'RESET_STATUS',
});
}, []);

const handleChange = useCallback(
(value: string) => {
const remaining = maxCharacters - value.length;
if (remaining <= warningThreshold && remaining > 0)
handleWarn();
else if (remaining <= 0) handleError();
else clean();

dispatch({
type: 'SET_REMAINING_CHARACTERS',
payload: remaining,
});
},
[clean, maxCharacters, warningThreshold]
);

return {
state,
dispatch,
handleChange,
clean,
};
}
1 change: 1 addition & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export { usePortal_DEPRECATED, validate, ANCHOR_POINTS } from './hooks/usePortal
export { useStateTransmorphic } from './hooks/useStateTransmorphic';
export { useStyleVars } from './hooks/useStyleVars';
export { withIris } from './HOCs/withIris';
export { useCharacterCount } from './hooks/useCharacterCount/useCharacterCount';

export type { Attach, AttachAlias, SimpleAnimation } from './hooks/usePortal_DEPRECATED';
export type { onClose } from './events/onClose';
Expand Down

0 comments on commit 1921d41

Please sign in to comment.