From ff5333db52904095767d9c50472e77e12f501c81 Mon Sep 17 00:00:00 2001 From: Daria Alekhina Date: Thu, 16 May 2024 13:40:49 +0300 Subject: [PATCH 1/2] feat(InlineTextField): add new component --- .../InlineTextField/InlineTextField.api.mdx | 37 +++++++++++ .../InlineTextField.classes.ts | 13 ++++ .../InlineTextField.stories.tsx | 42 +++++++++++++ .../InlineTextField/InlineTextField.tsx | 61 +++++++++++++++++++ .../src/components/InlineTextField/index.ts | 2 + 5 files changed, 155 insertions(+) create mode 100644 packages/react/src/components/InlineTextField/InlineTextField.api.mdx create mode 100644 packages/react/src/components/InlineTextField/InlineTextField.classes.ts create mode 100644 packages/react/src/components/InlineTextField/InlineTextField.stories.tsx create mode 100644 packages/react/src/components/InlineTextField/InlineTextField.tsx create mode 100644 packages/react/src/components/InlineTextField/index.ts diff --git a/packages/react/src/components/InlineTextField/InlineTextField.api.mdx b/packages/react/src/components/InlineTextField/InlineTextField.api.mdx new file mode 100644 index 000000000..3a953f75b --- /dev/null +++ b/packages/react/src/components/InlineTextField/InlineTextField.api.mdx @@ -0,0 +1,37 @@ +import { Meta } from '@storybook/addon-docs'; +import LinkTo from '@storybook/addon-links/react'; +import { TableInterface } from '~storybook/components/TableInterface'; + + + +# InlineTextField API + +```js +import { InlineTextField } from '@elonkit/react'; +``` + +## Component name + +The name `ESInlineTextField` can be used when providing default props or style overrides in the theme. + +## Props + + + +
+ +## CSS + + + +
+ +## Demos + +
    +
  • + + InlineTextField + +
  • +
diff --git a/packages/react/src/components/InlineTextField/InlineTextField.classes.ts b/packages/react/src/components/InlineTextField/InlineTextField.classes.ts new file mode 100644 index 000000000..7cc0890bc --- /dev/null +++ b/packages/react/src/components/InlineTextField/InlineTextField.classes.ts @@ -0,0 +1,13 @@ +import { generateUtilityClass, generateUtilityClasses } from '@mui/material'; + +export type InlineTextFieldClasses = { + /** Styles applied to the root element. */ + root: string; +}; +export type InlineTextFieldClassKey = keyof InlineTextFieldClasses; + +export function getInlineTextFieldUtilityClass(slot: string): string { + return generateUtilityClass('ESInlineTextField', slot); +} + +export const inlineTextFieldClasses: InlineTextFieldClasses = generateUtilityClasses('ESInlineTextField', ['root']); diff --git a/packages/react/src/components/InlineTextField/InlineTextField.stories.tsx b/packages/react/src/components/InlineTextField/InlineTextField.stories.tsx new file mode 100644 index 000000000..43068392c --- /dev/null +++ b/packages/react/src/components/InlineTextField/InlineTextField.stories.tsx @@ -0,0 +1,42 @@ +import { Meta, StoryObj } from '@storybook/react'; + +import { InlineTextField } from '.'; + +const meta: Meta = { + tags: ['autodocs'], + component: InlineTextField, + parameters: { + references: ['InlineTextField'] + }, + argTypes: { + disabled: { + control: { type: 'boolean' } + }, + error: { + control: { type: 'boolean' } + }, + placeholder: { + control: { type: 'text' } + }, + value: { + control: { type: 'text' } + }, + InputProps: { + table: { + disable: true + } + } + }, + args: { + value: 'Text' + } +}; + +export default meta; +type Story = StoryObj; + +export const Demo: Story = { + render: (args) => { + return ; + } +}; diff --git a/packages/react/src/components/InlineTextField/InlineTextField.tsx b/packages/react/src/components/InlineTextField/InlineTextField.tsx new file mode 100644 index 000000000..6858ac0ab --- /dev/null +++ b/packages/react/src/components/InlineTextField/InlineTextField.tsx @@ -0,0 +1,61 @@ +import { ComponentPropsWithoutRef } from 'react'; + +import { styled } from '@mui/material/styles'; +import { inputBaseClasses, TextField, TypographyProps } from '@mui/material'; + +const InlineTextFieldRoot = styled(TextField, { + name: 'ESInlineTextField', + slot: 'Root', + overridesResolver: (props, styles) => styles.root +})<{ + ownerState: { typography: Exclude }; +}>(({ theme, ownerState }) => ({ + '.MuiInput-root:not(.Mui-error)::before': { + borderBottom: '1px solid transparent' + }, + + '.MuiInput-root.Mui-disabled::before': { + borderBottom: `1px dotted ${theme.palette.monoA.A200}` + }, + + '.MuiInput-root:hover:not(.Mui-disabled, .Mui-error)::before': { + borderBottom: `1px solid ${theme.palette.monoA.A200}` + }, + + [`& .${inputBaseClasses.root}`]: { + padding: 0 + }, + + [`& .${inputBaseClasses.input}`]: { + ...theme.typography[ownerState.typography], + padding: '5px 0', + + '&::placeholder': { + color: theme.palette.monoA.A400, + opacity: 1 + }, + + '&, &:disabled': { + color: theme.palette.monoA.A900, + WebkitTextFillColor: 'unset' + } + } +})); + +export const InlineTextField = ({ + typography = 'body200', + placeholder, + ...props +}: Omit, 'ownerState'> & { + typography?: Exclude; +}) => { + return ( + + ); +}; diff --git a/packages/react/src/components/InlineTextField/index.ts b/packages/react/src/components/InlineTextField/index.ts new file mode 100644 index 000000000..cc1e589c7 --- /dev/null +++ b/packages/react/src/components/InlineTextField/index.ts @@ -0,0 +1,2 @@ +export { InlineTextField } from './InlineTextField'; +export { InlineTextFieldClasses, inlineTextFieldClasses, InlineTextFieldClassKey } from './InlineTextField.classes'; From d7bf656f930911ff5765b98e384b217dd7802f4a Mon Sep 17 00:00:00 2001 From: Daria Alekhina Date: Thu, 16 May 2024 15:46:57 +0300 Subject: [PATCH 2/2] feat(InlineTextField): add component props --- .../InlineTextField/InlineTextField.tsx | 41 +++++++++++++++---- .../InlineTextField/InlineTextField.types.ts | 5 +++ .../src/components/InlineTextField/index.ts | 1 + packages/react/src/components/index.ts | 1 + packages/react/src/overrides.d.ts | 7 ++++ 5 files changed, 46 insertions(+), 9 deletions(-) create mode 100644 packages/react/src/components/InlineTextField/InlineTextField.types.ts diff --git a/packages/react/src/components/InlineTextField/InlineTextField.tsx b/packages/react/src/components/InlineTextField/InlineTextField.tsx index 6858ac0ab..4e003e088 100644 --- a/packages/react/src/components/InlineTextField/InlineTextField.tsx +++ b/packages/react/src/components/InlineTextField/InlineTextField.tsx @@ -1,7 +1,26 @@ -import { ComponentPropsWithoutRef } from 'react'; +import { InlineTextFieldProps } from './InlineTextField.types'; + +import clsx from 'clsx'; +import { getInlineTextFieldUtilityClass } from './InlineTextField.classes'; + +import { unstable_composeClasses as composeClasses } from '@mui/base'; import { styled } from '@mui/material/styles'; -import { inputBaseClasses, TextField, TypographyProps } from '@mui/material'; +import { inputBaseClasses, TextField, TextFieldClasses, TypographyProps } from '@mui/material'; + +type InlineTextFieldOwnerState = { + classes?: Partial; +}; + +const useUtilityClasses = (ownerState: InlineTextFieldOwnerState) => { + const { classes } = ownerState; + + const slots = { + root: ['root'] + }; + + return composeClasses(slots, getInlineTextFieldUtilityClass, classes); +}; const InlineTextFieldRoot = styled(TextField, { name: 'ESInlineTextField', @@ -15,11 +34,11 @@ const InlineTextFieldRoot = styled(TextField, { }, '.MuiInput-root.Mui-disabled::before': { - borderBottom: `1px dotted ${theme.palette.monoA.A200}` + borderBottom: `1px dotted ${theme.vars.palette.monoA.A200}` }, '.MuiInput-root:hover:not(.Mui-disabled, .Mui-error)::before': { - borderBottom: `1px solid ${theme.palette.monoA.A200}` + borderBottom: `1px solid ${theme.vars.palette.monoA.A200}` }, [`& .${inputBaseClasses.root}`]: { @@ -31,12 +50,12 @@ const InlineTextFieldRoot = styled(TextField, { padding: '5px 0', '&::placeholder': { - color: theme.palette.monoA.A400, + color: theme.vars.palette.monoA.A400, opacity: 1 }, '&, &:disabled': { - color: theme.palette.monoA.A900, + color: theme.vars.palette.monoA.A900, WebkitTextFillColor: 'unset' } } @@ -45,13 +64,17 @@ const InlineTextFieldRoot = styled(TextField, { export const InlineTextField = ({ typography = 'body200', placeholder, + classes: inClasses, + className, ...props -}: Omit, 'ownerState'> & { - typography?: Exclude; -}) => { +}: InlineTextFieldProps) => { + const ownerState = { classes: inClasses }; + const classes = useUtilityClasses(ownerState); return ( & { + typography?: Exclude; +}; diff --git a/packages/react/src/components/InlineTextField/index.ts b/packages/react/src/components/InlineTextField/index.ts index cc1e589c7..c0150baa5 100644 --- a/packages/react/src/components/InlineTextField/index.ts +++ b/packages/react/src/components/InlineTextField/index.ts @@ -1,2 +1,3 @@ export { InlineTextField } from './InlineTextField'; export { InlineTextFieldClasses, inlineTextFieldClasses, InlineTextFieldClassKey } from './InlineTextField.classes'; +export { InlineTextFieldProps } from './InlineTextField.types'; diff --git a/packages/react/src/components/index.ts b/packages/react/src/components/index.ts index 4efbb41a3..3d47c3c9c 100644 --- a/packages/react/src/components/index.ts +++ b/packages/react/src/components/index.ts @@ -23,6 +23,7 @@ export * from './Flags'; export * from './FormatDate'; export * from './FormatSize'; export * from './Gallery'; +export * from './InlineTextField'; export * from './Kbd'; export * from './Link'; export * from './LoadingButton'; diff --git a/packages/react/src/overrides.d.ts b/packages/react/src/overrides.d.ts index 898348580..f6cd69bb0 100644 --- a/packages/react/src/overrides.d.ts +++ b/packages/react/src/overrides.d.ts @@ -145,6 +145,7 @@ import { GalleryThumbnailsItemProps, GalleryThumbnailsProps } from './components/Gallery'; +import { InlineTextFieldClassKey, InlineTextField } from './components/InlineTextField'; import { KbdClassKey, KbdProps } from './components/Kbd'; import { LinkClassKey, LinkProps } from './components/Link'; import { LoadingButtonClassKey, LoadingButtonProps } from './components/LoadingButton'; @@ -371,6 +372,7 @@ declare module '@mui/material/styles/props' { ESGalleryThumbnails: GalleryThumbnailsProps; ESGalleryThumbnailsImage: GalleryThumbnailsImageProps; ESGalleryThumbnailsItem: GalleryThumbnailsItemProps; + ESInlineTextField: InlineTextFieldProps; ESKbd: KbdProps; ESLink: LinkProps; ESLoadingButton: LoadingButtonProps; @@ -489,6 +491,7 @@ declare module '@mui/material/styles/overrides' { ESGalleryThumbnails: GalleryThumbnailsClassKey; ESGalleryThumbnailsImage: GalleryThumbnailsImageClassKey; ESGalleryThumbnailsItem: GalleryThumbnailsItemClassKey; + ESInlineTextField: InlineTextFieldClassKey; ESKbd: KbdClassKey; ESLink: LinkClassKey; ESLoadingButton: LoadingButtonClassKey; @@ -802,6 +805,10 @@ declare module '@mui/material/styles/components' { ESFormatSize?: { defaultProps?: ComponentsProps['ESFormatSize']; }; + ESInlineTextField?: { + defaultProps?: ComponentsProps['ESInlineTextField']; + styleOverrides?: ComponentsOverrides['ESInlineTextField']; + }; ESKbd?: { defaultProps?: ComponentsProps['ESKbd']; };