8000 feat(Property): add new component by feerzlay · Pull Request #410 · Elonsoft/esfront · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

feat(Property): add new component #410

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions packages/react/src/components/Property/Property.api.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Meta } from '@storybook/blocks';
import LinkTo from '@storybook/addon-links/react';
import { TableInterface } from '~storybook/components/TableInterface';

<Meta title="Components API/Property" />

# Property API

```js
import { Property } from '@esfront/react';
```

## Component name

The name `ESProperty` can be used when providing default props in the theme.

## Props

<TableInterface name="PropertyProps" variant="props" />

<br />

## CSS

<TableInterface name="PropertyClasses" variant="css" />

<br />

## Demos

<ul>
<li>
<LinkTo kind="components-Property" story="demo">
<code>Property</code>
</LinkTo>
</li>
</ul>
30 changes: 30 additions & 0 deletions packages/react/src/components/Property/Property.classes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { generateUtilityClass, generateUtilityClasses } from '@mui/material';

export type PropertyClasses = {
/** Styles applied to the root element. */
root: string;
/** Styles applied to the root element if size='s'. */
sizeS: string;
/** Styles applied to the root element if size='m'. */
sizeM: string;
/** Styles applied to the name element. */
name: string;
/** Styles applied to the value element. */
value: string;
/** Styles applied to the divider element. */
divider: string;
};
export type PropertyClassKey = keyof PropertyClasses;

export function getPropertyUtilityClass(slot: string): string {
return generateUtilityClass('ESProperty', slot);
}

export const propertyClasses: PropertyClasses = generateUtilityClasses('ESProperty', [
'root',
'sizeS',
'sizeM',
'name',
'value',
'divider',
]);
56 changes: 56 additions & 0 deletions packages/react/src/components/Property/Property.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { Meta, StoryObj } from '@storybook/react';

import { Box } from '@mui/material';

import { Property } from '.';

import { InformationIcon } from '../InformationIcon';
import { Tooltip } from '../Tooltip';

const meta: Meta<typeof Property> = {
tags: ['autodocs'],
component: Property,
parameters: {
references: ['Property'],
},
argTypes: {
name: {
table: {
disable: true,
},
},
value: {
table: {
disable: true,
},
},
},
};

export default meta;

type Story = StoryObj<typeof Property>;

export const Demo: Story = {
render: (args, context) => {
const locale = context.globals.locale;

return (
<Box sx={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
<Property {...args} name={locale === 'ru' ? 'Цвет' : 'Color'} value={locale === 'ru' ? 'Черный' : 'Black'} />
<Property
{...args}
name={
<>
<span>{locale === 'ru' ? 'Размер' : 'Size'}</span>
<Tooltip title={locale === 'ru' ? 'Ширина / Высота / Длина' : 'Width / Height / Length'}>
<InformationIcon variant="question" />
</Tooltip>
</>
}
value={locale === 'ru' ? '10см / 10см / 30см' : '10cm / 10cm / 30cm'}
/>
</Box>
);
},
};
113 changes: 113 additions & 0 deletions packages/react/src/components/Property/Property.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import { PropertyProps } from './Property.types';

import clsx from 'clsx';
import { getPropertyUtilityClass, propertyClasses } from './Property.classes';

import { unstable_composeClasses as composeClasses } from '@mui/base';

import { styled, useThemeProps } from '@mui/material/styles';
import { capitalize } from '@mui/material';

type PropertyOwnerState = {
classes?: PropertyProps['classes'];
size: NonNullable<PropertyProps['size']>;
};

const useUtilityClasses = (ownerState: PropertyOwnerState) => {
const { classes, size } = ownerState;

const slots = {
root: ['root', `size${capitalize(size)}`],
name: ['name'],
value: ['value'],
divider: ['divider'],
};

return composeClasses(slots, getPropertyUtilityClass, classes);
};

const PropertyRoot = styled('div', {
name: 'ESProperty',
slot: 'Root',
overridesResolver: (props, styles) => {
const {
ownerState: { size },
} = props;
return [styles.root, styles[`size${capitalize(size)}`]];
},
})<{ ownerState: PropertyOwnerState }>(({ theme }) => ({
alignItems: 'center',
display: 'flex',
gap: '8px',
padding: '2px 0',

variants: [
{
props: {
size: 's',
},
style: {
[`& .${propertyClasses.value}`]: {
...theme.typography.body100,
},
},
},
{
props: {
size: 'm',
},
style: {
[`& .${propertyClasses.value}`]: {
...theme.typography.body200,
},
},
},
],
}));

const PropertyName = styled('div', {
name: 'ESProperty',
slot: 'Name',
overridesResolver: (props, styles) => styles.name,
})(({ theme }) => ({
...theme.typography.body100,
alignItems: 'center',
color: theme.vars.palette.monoA.A600,
display: 'flex',
gap: '4px',
}));

const PropertyValue = styled('div', {
name: 'ESProperty',
slot: 'Root',
overridesResolver: (props, styles) => styles.value,
})(({ theme }) => ({
color: theme.vars.palette.monoA.A800,
}));

const PropertyDivider = styled('div', {
name: 'ESProperty',
slot: 'Divider',
overridesResolver: (props, styles) => styles.divider,
})(({ theme }) => ({
borderBottom: `2px dotted ${theme.vars.palette.monoA.A150}`,
flexGrow: 1,
}));

/**
* Display attributes are characteristics that describe a entity.
*/
export const Property = (inProps: PropertyProps) => {
const { name, value, className, sx, size = 'm', ...props } = useThemeProps({ props: inProps, name: 'ESProperty' });

const ownerState = { ...props, size };
const classes = useUtilityClasses(ownerState);

return (
<PropertyRoot className={clsx(classes.root, className)} ownerState={ownerState} sx={sx}>
<PropertyName className={classes.name}>{name}</PropertyName>
<PropertyDivider className={classes.divider} />
<PropertyValue className={classes.value}>{value}</PropertyValue>
</PropertyRoot>
);
};
28 changes: 28 additions & 0 deletions packages/react/src/components/Property/Property.types.ts
AE88
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { ReactNode } from 'react';

import { PropertyClasses } from './Property.classes';

import { SxProps, Theme } from '@mui/material';

import { OverridableStringUnion } from '@mui/types';

// eslint-disable-next-line @typescript-eslint/no-empty-object-type
export interface PropertyPropsSizeOverrides {}

export interface PropertyProps {
name?: ReactNode;
value?: ReactNode;

/** Override or extend the styles applied to the component. */
classes?: Partial<PropertyClasses>;
/** Class applied to the root element. */
className?: string;
/** The system prop that allows defining system overrides as well as additional CSS styles. */
sx?: SxProps<Theme>;

/**
* Size of the component.
* @default 'm'
*/
size?: OverridableStringUnion<'s' | 'm', PropertyPropsSizeOverrides>;
}
4 changes: 4 additions & 0 deletions packages/react/src/components/Property/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export { Property } from './Property';
export type { PropertyClasses, PropertyClassKey } from './Property.classes';
export { propertyClasses } from './Property.classes';
export type { PropertyProps, PropertyPropsSizeOverrides } from './Property.types';
1 change: 1 addition & 0 deletions packages/react/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export * from './MenuItem';
export * from './PageHGroup';
export * from './Pagination';
export * from './PasswordField';
export * from './Property';
export * from './Radio';
export * from './RadioGroup';
export * from './RibbonBadge';
Expand Down
7 changes: 7 additions & 0 deletions packages/react/src/overrides.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ import {
PaginationRangeProps,
} from './components/Pagination';
import { PasswordFieldClassKey, PasswordFieldProps } from './components/PasswordField';
import { PropertyClassKey, PropertyProps } from './components/Property';
import { RadioClassKey, RadioIconClassKey, RadioIconProps, RadioProps } from './components/Radio';
import { RadioGroupClassKey, RadioGroupProps } from './components/RadioGroup';
import { RibbonBadgeClassKey, RibbonBadgeProps } from './components/RibbonBadge';
Expand Down Expand Up @@ -440,6 +441,7 @@ declare module '@mui/material/styles/props' {
ESPaginationPages: PaginationPagesProps;
ESPaginationRange: PaginationRangeProps;
ESPasswordField: PasswordFieldProps;
ESProperty: PropertyProps;
ESRadio: RadioProps;
ESRadioIcon: RadioIconProps;
ESRadioGroup: RadioGroupProps;
Expand Down Expand Up @@ -588,6 +590,7 @@ declare module '@mui/material/styles/overrides' {
ESPaginationPages: PaginationPagesClassKey;
ESPaginationRange: PaginationRangeClassKey;
ESPasswordField: PasswordFieldClassKey;
ESProperty: PropertyClassKey;
ESRadio: RadioClassKey;
ESRadioIcon: RadioIconClassKey;
ESRadioGroup: RadioGroupClassKey;
Expand Down Expand Up @@ -1024,6 +1027,10 @@ declare module '@mui/material/styles/components' {
defaultProps?: ComponentsProps['ESPasswordField'];
styleOverrides?: ComponentsOverrides['ESPasswordField'];
};
ESProperty?: {
defaultProps?: ComponentsProps['ESProperty'];
styleOverrides?: ComponentsOverrides['ESProperty'];
};
ESRadio?: {
defaultProps?: ComponentsProps['ESRadio'];
styleOverrides?: ComponentsOverrides['ESRadio'];
Expand Down
Loading
0