More chips

This commit is contained in:
OfficialDakari 2025-03-28 17:50:56 +05:00
parent 84dcaf227a
commit bad3880768
6 changed files with 178 additions and 44 deletions

View File

@ -1,17 +1,18 @@
import React, { CSSProperties, ReactNode } from 'react';
import styled from '@emotion/styled';
type BoxProps = {
export type BoxProps = {
style?: CSSProperties;
children: ReactNode;
children?: ReactNode;
display?: 'flex' | 'block' | 'inline-block' | 'inline' | 'grid' | 'inline-grid' | 'contents' | 'list-item' | 'hidden' | 'initial' | 'inherit';
flexDirection?: 'row' | 'row-reverse' | 'column' | 'column-reverse';
flexWrap?: 'nowrap' | 'wrap' | 'wrap-reverse';
justifyContent?: 'flex-start' | 'flex-end' | 'center' | 'space-between' | 'space-around' | 'space-evenly';
alignItems?: 'flex-start' | 'flex-end' | 'center' | 'baseline' | 'stretch';
alignContent?: 'flex-start' | 'flex-end' | 'center' | 'space-between' | 'space-around' | 'space-evenly' | 'stretch' | 'baseline' | 'first baseline' | 'last baseline' | 'safe center' | 'unsafe center' | 'left' | 'right' | 'safe left' | 'safe right' | 'unsafe left' | 'unsafe right';
gap?: number;
rowGap?: number;
columnGap?: number;
gap?: string;
rowGap?: string;
columnGap?: string;
flex?: number;
flexGrow?: number;
flexShrink?: number;
@ -19,30 +20,34 @@ type BoxProps = {
flexFlow?: 'row' | 'row-reverse' | 'column' | 'column-reverse';
alignSelf?: 'auto' | 'flex-start' | 'flex-end' | 'center' | 'baseline' | 'stretch';
order?: number;
id?: string;
className?: string;
};
export const Box = ({ style, children, alignContent, alignSelf, justifyContent, alignItems, display, flex, flexBasis, flexDirection, flexFlow, flexGrow, flexShrink, flexWrap, gap, rowGap, columnGap, order }: BoxProps) => {
const StyledBox = styled.div<BoxProps>`
display: ${props => props.display};
flex-direction: ${props => props.flexDirection};
flex-wrap: ${props => props.flexWrap};
justify-content: ${props => props.justifyContent};
align-items: ${props => props.alignItems};
align-content: ${props => props.alignContent};
gap: ${props => props.gap};
row-gap: ${props => props.rowGap};
column-gap: ${props => props.columnGap};
flex: ${props => props.flex};
flex-grow: ${props => props.flexGrow};
flex-shrink: ${props => props.flexShrink};
flex-basis: ${props => props.flexBasis};
flex-flow: ${props => props.flexFlow};
align-self: ${props => props.alignSelf};
order: ${props => props.order};
`;
export const Box = (props: BoxProps) => {
const { style, children, ...restProps } = props;
return (
<div style={{
...style,
display,
flexDirection,
flexWrap,
justifyContent,
alignItems,
alignContent,
gap,
rowGap,
columnGap,
flex,
flexGrow,
flexShrink,
flexBasis,
flexFlow,
alignSelf,
order,
}}>
<StyledBox style={style} {...restProps}>
{children}
</div>
</StyledBox>
);
};

101
src/components/Chip.tsx Normal file
View File

@ -0,0 +1,101 @@
import React from "react";
import { MdAssistChip as MdAssistChipWebComponent } from "@material/web/chips/assist-chip";
import { MdChipSet as MdChipSetWebComponent } from "@material/web/chips/chip-set";
import { MdFilterChip as MdFilterChipWebComponent } from "@material/web/chips/filter-chip";
import { MdInputChip as MdInputChipWebComponent } from "@material/web/chips/input-chip";
import { createComponent } from "@lit/react";
const MdChipSet = createComponent({
react: React,
tagName: 'md-chip-set',
elementClass: MdChipSetWebComponent,
});
type ChipSetProps = {
children: React.ReactNode;
};
export const ChipSet = (props: ChipSetProps) => {
return (
<MdChipSet>
{props.children}
</MdChipSet>
);
};
type AssistChipProps = {
label?: string;
elevated?: boolean;
href?: string;
target?: '_blank' | '_parent' | '_self' | '_top';
disabled?: boolean;
alwaysFocusable?: boolean;
};
const MdAssistChip = createComponent({
react: React,
tagName: 'md-assist-chip',
elementClass: MdAssistChipWebComponent,
events: {
onClick: 'click',
onKeyDown: 'keydown',
onFocus: 'focus',
onBlur: 'blur',
},
});
export const AssistChip = (props: AssistChipProps) => {
const { label, elevated, href, target, disabled, alwaysFocusable } = props;
return <MdAssistChip label={label} elevated={elevated} href={href} target={target} disabled={disabled} alwaysFocusable={alwaysFocusable} />;
};
type FilterChipProps = {
elevated?: boolean;
removable?: boolean;
selected?: boolean;
hasSelectedIcon?: boolean;
disabled?: boolean;
alwaysFocusable?: boolean;
label: string;
};
const MdFilterChip = createComponent({
react: React,
tagName: 'md-filter-chip',
elementClass: MdFilterChipWebComponent,
events: {
onRemove: 'remove',
onUpdateFocus: 'update-focus',
},
});
export const FilterChip = (props: FilterChipProps) => {
const { label, elevated, removable, selected, hasSelectedIcon, disabled, alwaysFocusable } = props;
return <MdFilterChip label={label} elevated={elevated} removable={removable} selected={selected} hasSelectedIcon={hasSelectedIcon} disabled={disabled} alwaysFocusable={alwaysFocusable} />;
};
type InputChipProps = {
avatar?: boolean;
href?: string;
target?: '_blank' | '_parent' | '_self' | '_top';
removeOnly?: boolean;
selected?: boolean;
disabled?: boolean;
alwaysFocusable?: boolean;
label: string;
};
const MdInputChip = createComponent({
react: React,
tagName: 'md-input-chip',
elementClass: MdInputChipWebComponent,
events: {
onRemove: 'remove',
onUpdateFocus: 'update-focus',
},
});
export const InputChip = (props: InputChipProps) => {
const { label, avatar, href, target, removeOnly, selected, disabled, alwaysFocusable } = props;
return <MdInputChip label={label} avatar={avatar} href={href} target={target} removeOnly={removeOnly} selected={selected} disabled={disabled} alwaysFocusable={alwaysFocusable} />;
};

22
src/components/Paper.tsx Normal file
View File

@ -0,0 +1,22 @@
import React from "react";
import { Box, BoxProps } from "./Box";
import { usePalette } from "../hooks/useTheme";
export const Paper = ({ children, style, ...props }: BoxProps) => {
console.log(props, style);
return (
<Box
{...props}
style={{
borderRadius: '28px',
backgroundColor: 'var(--md-sys-color-surface)',
color: 'var(--md-sys-color-on-surface)',
padding: '18px',
display: 'flex',
...style,
}}
>
{children}
</Box>
);
};

View File

@ -5,7 +5,7 @@ type TypographyProps = {
children: React.ReactNode;
variant?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "p" | "span" | "label";
className?: string;
color?: 'primary' | 'secondary' | 'tertiary' | 'error' | 'on-primary' | 'on-secondary' | 'on-tertiary' | 'on-error' | string;
color?: 'primary' | 'secondary' | 'tertiary' | 'error' | 'on-primary' | 'on-secondary' | 'on-tertiary' | 'on-error' | 'scrim' | 'outline' | 'outline-variant' | string;
align?: "left" | "center" | "right";
style?: React.CSSProperties;
noWrap?: boolean;
@ -23,6 +23,11 @@ export const Typography = ({ children, variant = "span", className, color = "",
if (color === 'on-secondary') return 'var(--md-sys-color-on-secondary)';
if (color === 'on-tertiary') return 'var(--md-sys-color-on-tertiary)';
if (color === 'on-error') return 'var(--md-sys-color-on-error)';
if (color === 'on-surface') return 'var(--md-sys-color-on-surface)';
if (color === 'scrim') return 'var(--md-sys-color-scrim)';
if (color === 'outline') return 'var(--md-sys-color-outline)';
if (color === 'outline-variant') return 'var(--md-sys-color-outline-variant)';
return color;
}, [color]);

View File

@ -51,6 +51,7 @@ export function ThemeProvider({ children, theme, scheme }: { children: React.Rea
--md-sys-color-on-tertiary-container: ${hexFromArgb(theme.schemes[scheme].onTertiaryContainer)};
--md-sys-color-on-error: ${hexFromArgb(theme.schemes[scheme].onError)};
--md-sys-color-on-error-container: ${hexFromArgb(theme.schemes[scheme].onErrorContainer)};
--md-sys-color-on-background: ${hexFromArgb(theme.schemes[scheme].onBackground)};
--md-sys-typescale-headline-small-font: 'Roboto Flex';
--md-sys-typescale-headline-medium-font: 'Roboto Flex';
@ -103,6 +104,7 @@ export function ThemeProvider({ children, theme, scheme }: { children: React.Rea
--md-sys-typescale-label-large-line-height: 24px;
background-color: var(--md-sys-color-background);
color: var(--md-sys-color-on-background);
}
`}
</style>

View File

@ -8,6 +8,8 @@ import { Checkbox } from "./components/Checkbox";
import { Switch } from "./components/Switch";
import { Typography } from "./components/Typography";
import { FormLabel } from "./components/Forms";
import { Paper } from "./components/Paper";
import { AssistChip, InputChip } from "./components/Chip";
const mountApp = async () => {
const rootContainer = document.getElementById('root');
@ -21,24 +23,21 @@ const mountApp = async () => {
const root = createRoot(rootContainer);
root.render(
<ThemeProvider theme={theme} scheme='dark'>
<Box
flexDirection="column"
style={{
width: '100%',
height: '100vh',
backgroundColor: 'var(--md-sys-color-background)',
}}
>
<Typography variant='h1'>Hello</Typography>
<Button onClick={() => alert('Hello')} variant='filled'>Hello</Button>
<Checkbox />
<Typography variant='h1'>Hello</Typography>
<Button onClick={() => alert('Hello')} variant='filled'>Hello</Button>
<Checkbox />
<Switch />
<Typography variant='p'>Hello</Typography>
<FormLabel>
<Switch />
<Typography variant='p'>Hello</Typography>
<FormLabel>
<Switch />
<Typography variant='h6'>Hello</Typography>
</FormLabel>
</Box>
<Typography variant='h6'>Hello</Typography>
</FormLabel>
<Paper display="flex" gap='18px' justifyContent="center" alignItems="center">
<Typography variant='h6'>Hello</Typography>
<Switch />
</Paper>
<AssistChip label="Hello" />
<InputChip label="Hello" />
</ThemeProvider>
);
};