@ -1,22 +1,14 @@
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
import { IconPhone } from '@tabler/icons-react';
|
||||
|
||||
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
|
||||
import { ComponentWithRouterDecorator } from '~/testing/decorators/ComponentWithRouterDecorator';
|
||||
|
||||
import { PhoneEditableField } from '../PhoneEditableField';
|
||||
|
||||
const meta: Meta<typeof PhoneEditableField> = {
|
||||
title: 'UI/EditableField/PhoneEditableField',
|
||||
component: PhoneEditableField,
|
||||
decorators: [
|
||||
(Story) => (
|
||||
<BrowserRouter>
|
||||
<Story />
|
||||
</BrowserRouter>
|
||||
),
|
||||
ComponentDecorator,
|
||||
],
|
||||
decorators: [ComponentWithRouterDecorator],
|
||||
argTypes: {
|
||||
icon: {
|
||||
type: 'boolean',
|
||||
|
||||
@ -1,25 +1,13 @@
|
||||
import React from 'react';
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
import styled from '@emotion/styled';
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
|
||||
import { ComponentWithRouterDecorator } from '~/testing/decorators/ComponentWithRouterDecorator';
|
||||
|
||||
import { EmailInputDisplay } from '../EmailInputDisplay';
|
||||
|
||||
const meta: Meta = {
|
||||
title: 'Modules/People/EmailInputDisplay',
|
||||
title: 'UI/Input/EmailInputDisplay',
|
||||
component: EmailInputDisplay,
|
||||
decorators: [
|
||||
(Story) => (
|
||||
<StyledTestEmailContainer>
|
||||
<BrowserRouter>
|
||||
<Story />
|
||||
</BrowserRouter>
|
||||
</StyledTestEmailContainer>
|
||||
),
|
||||
ComponentDecorator,
|
||||
],
|
||||
decorators: [ComponentWithRouterDecorator],
|
||||
args: {
|
||||
value: 'mustajab.ikram@google.com',
|
||||
},
|
||||
@ -29,9 +17,4 @@ export default meta;
|
||||
|
||||
type Story = StoryObj<typeof EmailInputDisplay>;
|
||||
|
||||
const StyledTestEmailContainer = styled.div`
|
||||
align-items: center;
|
||||
color: ${({ theme }) => theme.font.color.primary};
|
||||
display: flex;
|
||||
`;
|
||||
export const Default: Story = {};
|
||||
|
||||
@ -1,25 +1,13 @@
|
||||
import React from 'react';
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
import styled from '@emotion/styled';
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
|
||||
import { ComponentWithRouterDecorator } from '~/testing/decorators/ComponentWithRouterDecorator';
|
||||
|
||||
import { PhoneInputDisplay } from '../PhoneInputDisplay'; // Adjust the import path as needed
|
||||
|
||||
const meta: Meta = {
|
||||
title: 'Modules/People/PhoneInputDisplay',
|
||||
title: 'UI/Input/PhoneInputDisplay',
|
||||
component: PhoneInputDisplay,
|
||||
decorators: [
|
||||
(Story) => (
|
||||
<StyledTestPhoneContainer>
|
||||
<BrowserRouter>
|
||||
<Story />
|
||||
</BrowserRouter>
|
||||
</StyledTestPhoneContainer>
|
||||
),
|
||||
ComponentDecorator,
|
||||
],
|
||||
decorators: [ComponentWithRouterDecorator],
|
||||
args: {
|
||||
value: '+33788901234',
|
||||
},
|
||||
@ -29,10 +17,4 @@ export default meta;
|
||||
|
||||
type Story = StoryObj<typeof PhoneInputDisplay>;
|
||||
|
||||
const StyledTestPhoneContainer = styled.div`
|
||||
align-items: center;
|
||||
color: ${({ theme }) => theme.font.color.primary};
|
||||
display: flex;
|
||||
`;
|
||||
|
||||
export const Default: Story = {};
|
||||
|
||||
@ -1,13 +1,10 @@
|
||||
import { ChangeEvent, useEffect, useRef, useState } from 'react';
|
||||
import { useRef, useState } from 'react';
|
||||
import PhoneInput, { isPossiblePhoneNumber } from 'react-phone-number-input';
|
||||
import styled from '@emotion/styled';
|
||||
import intlTelInput from 'intl-tel-input';
|
||||
|
||||
import { hoverBackground } from '@/ui/theme/constants/effects';
|
||||
|
||||
import countries from '../../../constants/countries.json';
|
||||
import { useRegisterCloseCellHandlers } from '../../hooks/useRegisterCloseCellHandlers';
|
||||
|
||||
import 'intl-tel-input/build/css/intlTelInput.css';
|
||||
import 'react-phone-number-input/style.css';
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
align-items: center;
|
||||
@ -17,113 +14,91 @@ const StyledContainer = styled.div`
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
.iti__country-list {
|
||||
background: ${({ theme }) => theme.background.secondary};
|
||||
border: 1px solid ${({ theme }) => theme.border.color.medium};
|
||||
border-radius: ${({ theme }) => theme.border.radius.md};
|
||||
box-shadow: ${({ theme }) => theme.boxShadow.strong};
|
||||
|
||||
.iti__country {
|
||||
--horizontal-padding: ${({ theme }) => theme.spacing(1)};
|
||||
--vertical-padding: ${({ theme }) => theme.spacing(3)};
|
||||
|
||||
border-radius: ${({ theme }) => theme.border.radius.sm};
|
||||
color: ${({ theme }) => theme.font.color.secondary};
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
font-size: ${({ theme }) => theme.font.size.sm};
|
||||
|
||||
gap: ${({ theme }) => theme.spacing(1)};
|
||||
|
||||
height: calc(32px - 2 * var(--vertical-padding));
|
||||
|
||||
padding: var(--vertical-padding) var(--horizontal-padding);
|
||||
|
||||
${hoverBackground};
|
||||
|
||||
width: calc(100% - 2 * var(--horizontal-padding));
|
||||
}
|
||||
}
|
||||
|
||||
.iti__flag {
|
||||
background-color: ${({ theme }) => theme.background.secondary};
|
||||
}
|
||||
|
||||
.iti__arrow {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledInput = styled.input`
|
||||
background: ${({ theme }) => theme.background.primary};
|
||||
border: none;
|
||||
border-radius: ${({ theme }) => theme.border.radius.md};
|
||||
color: ${({ theme }) => theme.font.color.primary};
|
||||
|
||||
margin: 0;
|
||||
|
||||
outline: none;
|
||||
padding: ${({ theme }) => theme.spacing(2)};
|
||||
|
||||
width: ${({ theme }) => theme.spacing(48)};
|
||||
`;
|
||||
|
||||
type OwnProps = {
|
||||
export type PhoneCellEditProps = {
|
||||
placeholder?: string;
|
||||
autoFocus?: boolean;
|
||||
value: string;
|
||||
onSubmit: (newText: string) => void;
|
||||
};
|
||||
|
||||
export function PhoneCellEdit({ autoFocus, value, onSubmit }: OwnProps) {
|
||||
const [internalText, setInternalText] = useState(value);
|
||||
const phoneInputRef = useRef<HTMLInputElement | null>(null);
|
||||
const StyledCustomPhoneInput = styled(PhoneInput)`
|
||||
--PhoneInput-color--focus: transparent;
|
||||
--PhoneInputCountryFlag-borderColor--focus: transparent;
|
||||
--PhoneInputCountrySelect-marginRight: ${({ theme }) => theme.spacing(2)};
|
||||
--PhoneInputCountrySelectArrow-color: ${({ theme }) =>
|
||||
theme.font.color.tertiary};
|
||||
--PhoneInputCountrySelectArrow-opacity: 1;
|
||||
font-family: ${({ theme }) => theme.font.family};
|
||||
height: 32px;
|
||||
|
||||
.PhoneInputCountry {
|
||||
--PhoneInputCountryFlag-height: 12px;
|
||||
--PhoneInputCountryFlag-width: 16px;
|
||||
border-right: 1px solid ${({ theme }) => theme.border.color.light};
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-left: ${({ theme }) => theme.spacing(2)};
|
||||
}
|
||||
|
||||
.PhoneInputCountryIcon {
|
||||
background: none;
|
||||
border-radius: ${({ theme }) => theme.border.radius.xs};
|
||||
box-shadow: none;
|
||||
margin-right: 1px;
|
||||
overflow: hidden;
|
||||
&:focus {
|
||||
box-shadow: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.PhoneInputCountrySelectArrow {
|
||||
margin-right: ${({ theme }) => theme.spacing(2)};
|
||||
}
|
||||
|
||||
.PhoneInputInput {
|
||||
background: ${({ theme }) => theme.background.transparent.secondary};
|
||||
border: none;
|
||||
color: ${({ theme }) => theme.font.color.primary};
|
||||
|
||||
&::placeholder,
|
||||
&::-webkit-input-placeholder {
|
||||
color: ${({ theme }) => theme.font.color.light};
|
||||
font-family: ${({ theme }) => theme.font.family};
|
||||
font-weight: ${({ theme }) => theme.font.weight.medium};
|
||||
}
|
||||
|
||||
:focus {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export function PhoneCellEdit({
|
||||
autoFocus,
|
||||
value,
|
||||
onSubmit,
|
||||
}: PhoneCellEditProps) {
|
||||
const [internalValue, setInternalValue] = useState<string | undefined>(value);
|
||||
|
||||
const wrapperRef = useRef<HTMLDivElement | null>(null);
|
||||
|
||||
function handleSubmit() {
|
||||
onSubmit(internalText);
|
||||
}
|
||||
|
||||
function handleCancel() {
|
||||
setInternalText(value);
|
||||
}
|
||||
|
||||
function handleChange(event: ChangeEvent<HTMLInputElement>) {
|
||||
setInternalText(event.target.value);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
setInternalText(value);
|
||||
}, [value]);
|
||||
|
||||
useEffect(() => {
|
||||
if (phoneInputRef.current) {
|
||||
intlTelInput(phoneInputRef.current, {
|
||||
utilsScript:
|
||||
'https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/8.4.6/js/utils.js',
|
||||
initialCountry: 'auto',
|
||||
formatOnDisplay: true,
|
||||
localizedCountries: countries,
|
||||
onlyCountries: Object.keys(countries),
|
||||
preferredCountries: [],
|
||||
});
|
||||
if (isPossiblePhoneNumber(internalValue ?? '')) {
|
||||
onSubmit(internalValue ?? '');
|
||||
}
|
||||
}, [value]);
|
||||
}
|
||||
|
||||
useRegisterCloseCellHandlers(wrapperRef, handleSubmit, handleCancel);
|
||||
useRegisterCloseCellHandlers(wrapperRef, handleSubmit);
|
||||
|
||||
return (
|
||||
<StyledContainer ref={wrapperRef}>
|
||||
<StyledInput
|
||||
type="tel"
|
||||
<StyledCustomPhoneInput
|
||||
autoFocus={autoFocus}
|
||||
ref={phoneInputRef}
|
||||
onChange={handleChange}
|
||||
value={internalText}
|
||||
placeholder="Phone number"
|
||||
value={value}
|
||||
onChange={setInternalValue}
|
||||
/>
|
||||
</StyledContainer>
|
||||
);
|
||||
|
||||
@ -0,0 +1,23 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import { PhoneCellEdit } from '@/ui/table/editable-cell/type/components/PhoneCellEdit';
|
||||
import { TableRecoilScopeContext } from '@/ui/table/states/recoil-scope-contexts/TableRecoilScopeContext';
|
||||
import { ComponentWithRecoilScopeDecorator } from '~/testing/decorators/ComponentWithRecoilScopeDecorator';
|
||||
|
||||
const meta: Meta<typeof PhoneCellEdit> = {
|
||||
title: 'UI/Table/EditableCell/PhoneCellEdit',
|
||||
component: PhoneCellEdit,
|
||||
decorators: [ComponentWithRecoilScopeDecorator],
|
||||
args: {
|
||||
value: '+33714446494',
|
||||
autoFocus: true,
|
||||
},
|
||||
parameters: {
|
||||
recoilScopeContext: TableRecoilScopeContext,
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof PhoneCellEdit>;
|
||||
|
||||
export const Default: Story = {};
|
||||
Reference in New Issue
Block a user