-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Ant Design v5 preparation #2870
Comments
Yes, we need to follow up antd 5.0 after the AntDesign Blazor 1.0 release later this year. But we need to implement css in c# first, do you have any ideas? |
I may have some ideas to do the similar thing without css in C#. Let me give it a go and share the repo for you guys to review. |
Great, we can implement the FloatButton as a test. |
Somehow the website's FloatButton is broken at the moment, so I just created a simple repo (https://github.com/ldsenow/BlazorCssIsolation) with a Button component to demonstrate the potential capabilities. It is a .net 7 solution but I think it can be run under .net 6. |
Look good to me. But it looks like we need a lot of work to synchronize style from design tokens. What do you think? |
😂 Maybe we can use some tool for converting ts to c# https://github.com/mono/TsToCSharp |
I guess we can create a project which uses the antd react's npm pkg to export something like e.g. a json file, a css/less file etc., somehow, the blazor end can use it. I will give it a go and see if it works. |
Yes, we can use Github Actions to synchronize. Look forward to your good news! |
Hi @ldsenow , antd 5.0 have been GA. Do you think we can follow them? |
Have been busy last week at work. The react version use React hook context to inject the tokens. I can't find a better way other than using react testing lib to simulate react's environment. BTW, do we need just need the tokens or we also need the values? I guess we want to derive the values based on a primary, right? |
I think we need the token and algorithm. |
I was looking at the algorithm over the weekend. I can help with that. I guess we dont want to introduce the whole tinycolor right? Re: tokens, i cant find an easy to extract them other than using a converter. I am worried about the maintenance going forward. |
Just to share this repo, it inspires me while I'm looking for the solution under the existing blazor Infrastructure. |
Yes, we should use converter and shell scripts to synchronize the tokens, instead of manual maintenance. I have written part of the code of the color palette in feat/color branch before, but some color conversion parts were not implemented, and the test results were wrong. Help is needed for this work. |
I am able to extract the base tokens from ts and having a bit of difficulties with getting component tokens. However, i think it is good enough to start applying the algorithms. I have updated the repo with the token extraction, please have a look if this helps. https://github.com/ldsenow/BlazorCssIsolation |
This work has made great progress, it helps a lot! Look forward to it being applied to components! |
Just to give an update. I spent not much over the weekend due to the World Cup, but i did have some progress on this and hope to ship something out for early review before i may go down to a wrong path. |
Great, and I'm looking forward to seeing the implementation soon, so we can move to antd5 and have a lot of the topic issues resolved. |
@ldsenow I'm excited to see a lot of updates in your repo. |
Sorry for being slow on this. It could have been a bigger progress however antd react changed some props to internal. So i don't have access on those any more and finding a work around. I have mostly ported their algorithms (certainly refactor is required at the end). I will squeeze some time this weekend if I don't get distracted by the world cup. |
Hello @ldsenow , have you made any progress recently? |
Hello, happy new year! I was in holiday and wasn't allowed to have screen time during the break. The bad news is I didnt do anything but the kind of good news is i will continue shortly. |
Happy new year, wish you a happy holiday! |
Any news? |
More or less I have the default theme algorithm is ready, dark and compact ones are on the way. Theme variables are generated by the algorithm. As you see in the below screenshot. Nested config provider is supported. So the component can have it own override without effecting other components. Component tokens/variables will be difficult to extract from Antd React. I need to implement one by one manually based on their logic. Due to this is just for POC purpose, I am confident enough that will 90% work. @ElderJames If you have time please take a look if the approach is going to be workable / maintainable? P.S: The link to the POC |
I do not want to rush anyone but what is the ETA for v5? @ElderJames |
Any news? |
hello there, one of our contributiors was working on an other project to achieve the v5 styles. I think we can compare this two implementations. |
I'm working on porting the Antd React style to Blazor. Antd React uses the cssinjs style solution, so I provide the cssincs solution here. The following is an example of style conversion using cssincs. import type { CSSInterpolation, CSSObject } from '@ant-design/cssinjs';
import type { FullToken, GenerateStyle } from '../../theme/internal';
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
import { resetComponent } from '../../style';
export interface ComponentToken {}
type AlertToken = FullToken<'Alert'> & {
alertIconSizeLG: number;
alertPaddingHorizontal: number;
};
const genAlertTypeStyle = (
bgColor: string,
borderColor: string,
iconColor: string,
token: AlertToken,
alertCls: string,
): CSSObject => ({
backgroundColor: bgColor,
border: `${token.lineWidth}px ${token.lineType} ${borderColor}`,
[`${alertCls}-icon`]: {
color: iconColor,
},
});
export const genBaseStyle: GenerateStyle<AlertToken> = (token: AlertToken): CSSObject => {
const {
componentCls,
motionDurationSlow: duration,
marginXS,
marginSM,
fontSize,
fontSizeLG,
lineHeight,
borderRadiusLG: borderRadius,
motionEaseInOutCirc,
alertIconSizeLG,
colorText,
paddingContentVerticalSM,
alertPaddingHorizontal,
paddingMD,
paddingContentHorizontalLG,
} = token;
return {
[componentCls]: {
...resetComponent(token),
position: 'relative',
display: 'flex',
alignItems: 'center',
padding: `${paddingContentVerticalSM}px ${alertPaddingHorizontal}px`, // Fixed horizontal padding here.
wordWrap: 'break-word',
borderRadius,
[`&${componentCls}-rtl`]: {
direction: 'rtl',
},
[`${componentCls}-content`]: {
flex: 1,
minWidth: 0,
},
[`${componentCls}-icon`]: {
marginInlineEnd: marginXS,
lineHeight: 0,
},
[`&-description`]: {
display: 'none',
fontSize,
lineHeight,
},
'&-message': {
color: colorText,
},
[`&${componentCls}-motion-leave`]: {
overflow: 'hidden',
opacity: 1,
transition: `max-height ${duration} ${motionEaseInOutCirc}, opacity ${duration} ${motionEaseInOutCirc},
padding-top ${duration} ${motionEaseInOutCirc}, padding-bottom ${duration} ${motionEaseInOutCirc},
margin-bottom ${duration} ${motionEaseInOutCirc}`,
},
[`&${componentCls}-motion-leave-active`]: {
maxHeight: 0,
marginBottom: '0 !important',
paddingTop: 0,
paddingBottom: 0,
opacity: 0,
},
},
[`${componentCls}-with-description`]: {
alignItems: 'flex-start',
paddingInline: paddingContentHorizontalLG,
paddingBlock: paddingMD,
[`${componentCls}-icon`]: {
marginInlineEnd: marginSM,
fontSize: alertIconSizeLG,
lineHeight: 0,
},
[`${componentCls}-message`]: {
display: 'block',
marginBottom: marginXS,
color: colorText,
fontSize: fontSizeLG,
},
[`${componentCls}-description`]: {
display: 'block',
},
},
[`${componentCls}-banner`]: {
marginBottom: 0,
border: '0 !important',
borderRadius: 0,
},
};
};
export const genTypeStyle: GenerateStyle<AlertToken> = (token: AlertToken): CSSObject => {
const {
componentCls,
colorSuccess,
colorSuccessBorder,
colorSuccessBg,
colorWarning,
colorWarningBorder,
colorWarningBg,
colorError,
colorErrorBorder,
colorErrorBg,
colorInfo,
colorInfoBorder,
colorInfoBg,
} = token;
return {
[componentCls]: {
'&-success': genAlertTypeStyle(
colorSuccessBg,
colorSuccessBorder,
colorSuccess,
token,
componentCls,
),
'&-info': genAlertTypeStyle(colorInfoBg, colorInfoBorder, colorInfo, token, componentCls),
'&-warning': genAlertTypeStyle(
colorWarningBg,
colorWarningBorder,
colorWarning,
token,
componentCls,
),
'&-error': {
...genAlertTypeStyle(colorErrorBg, colorErrorBorder, colorError, token, componentCls),
[`${componentCls}-description > pre`]: {
margin: 0,
padding: 0,
},
},
},
};
};
export const genActionStyle: GenerateStyle<AlertToken> = (token: AlertToken): CSSObject => {
const {
componentCls,
iconCls,
motionDurationMid,
marginXS,
fontSizeIcon,
colorIcon,
colorIconHover,
} = token;
return {
[componentCls]: {
[`&-action`]: {
marginInlineStart: marginXS,
},
[`${componentCls}-close-icon`]: {
marginInlineStart: marginXS,
padding: 0,
overflow: 'hidden',
fontSize: fontSizeIcon,
lineHeight: `${fontSizeIcon}px`,
backgroundColor: 'transparent',
border: 'none',
outline: 'none',
cursor: 'pointer',
[`${iconCls}-close`]: {
color: colorIcon,
transition: `color ${motionDurationMid}`,
'&:hover': {
color: colorIconHover,
},
},
},
'&-close-text': {
color: colorIcon,
transition: `color ${motionDurationMid}`,
'&:hover': {
color: colorIconHover,
},
},
},
};
};
export const genAlertStyle: GenerateStyle<AlertToken> = (token: AlertToken): CSSInterpolation => [
genBaseStyle(token),
genTypeStyle(token),
genActionStyle(token),
];
export default genComponentStyleHook('Alert', (token) => {
const { fontSizeHeading3 } = token;
const alertToken = mergeToken<AlertToken>(token, {
alertIconSizeLG: fontSizeHeading3,
alertPaddingHorizontal: 12, // Fixed value here.
});
return [genAlertStyle(alertToken)];
}); Code of using the cssincs, here is blazor alert style code. using CssInCs;
using static AntDesign.GlobalStyle;
namespace AntDesign
{
public class AlertToken : TokenWithCommonCls
{
public int AlertIconSizeLG { get; set; }
public int AlertPaddingHorizontal { get; set; }
}
public partial class Alert
{
public CSSObject GenAlertTypeStyle(
string bgColor,
string borderColor,
string iconColor,
AlertToken token,
string alertCls) => new CSSObject()
{
BackgroundColor = bgColor,
Border = $"{token.LineWidth}px {token.LineType} {borderColor}",
["${alertCls}-icon"] = new CSSObject()
{
Color = iconColor,
},
};
public CSSObject GenBaseStyle(AlertToken token)
{
var (
componentCls,
duration,
marginXS,
marginSM,
fontSize,
fontSizeLG,
lineHeight,
borderRadius,
motionEaseInOutCirc,
alertIconSizeLG,
colorText,
paddingContentVerticalSM,
alertPaddingHorizontal,
paddingMD,
paddingContentHorizontalLG
) = (
token.ComponentCls,
token.MotionDurationSlow,
token.MarginXS,
token.MarginSM,
token.FontSize,
token.FontSizeLG,
token.LineHeight,
token.BorderRadiusLG,
token.MotionEaseInOutCirc,
token.AlertIconSizeLG,
token.ColorText,
token.PaddingContentVerticalSM,
token.AlertPaddingHorizontal,
token.PaddingMD,
token.PaddingContentHorizontalLG
);
return new CSSObject
{
[componentCls] = new CSSObject()
{
["..."] = ResetComponent(token),
Position = "relative",
Display = "flex",
AlignItems = "center",
Padding = $"{paddingContentVerticalSM}px {alertPaddingHorizontal}px", // Fixed horizontal padding here.
WordWrap = "break-word",
BorderRadius = borderRadius,
[$"&{componentCls}-rtl"] = new CSSObject()
{
Direction = "rtl",
},
[$"{componentCls}-content"] = new CSSObject()
{
Flex = 1,
MinWidth = 0,
},
[$"{componentCls}-icon"] = new CSSObject()
{
MarginInlineEnd = marginXS,
LineHeight = 0,
},
["&-description"] = new CSSObject()
{
Display = "none",
FontSize = fontSize,
LineHeight = lineHeight,
},
["&-message"] = new CSSObject()
{
Color = colorText,
},
[$"&{componentCls}-motion-leave"] = new CSSObject()
{
Overflow = "hidden",
Opacity = 1,
Transition = @$"max-height {duration} {motionEaseInOutCirc}, opacity {duration} {motionEaseInOutCirc},
Padding-top {duration} {motionEaseInOutCirc}, padding-bottom {duration} {motionEaseInOutCirc},
Margin-bottom {duration} {motionEaseInOutCirc}",
},
[$"&{componentCls}-motion-leave-active"] = new CSSObject()
{
MaxHeight = 0,
MarginBottom = "0 !important",
PaddingTop = 0,
PaddingBottom = 0,
Opacity = 0,
},
},
[$"{componentCls}-with-description"] = new CSSObject()
{
AlignItems = "flex-start",
PaddingInline = paddingContentHorizontalLG,
PaddingBlock = paddingMD,
[$"{componentCls}-icon"] = new CSSObject()
{
MarginInlineEnd = marginSM,
FontSize = alertIconSizeLG,
LineHeight = 0,
},
[$"{componentCls}-message"] = new CSSObject()
{
Display = "block",
MarginBottom = marginXS,
Color = colorText,
FontSize = fontSizeLG,
},
[$"{componentCls}-description"] = new CSSObject()
{
Display = "block",
},
},
[$"{componentCls}-banner"] = new CSSObject()
{
MarginBottom = 0,
Border = "0 !important",
BorderRadius = 0,
},
};
}
public CSSObject GenTypeStyle(AlertToken token)
{
var (
componentCls,
colorSuccess,
colorSuccessBorder,
colorSuccessBg,
colorWarning,
colorWarningBorder,
colorWarningBg,
colorError,
colorErrorBorder,
colorErrorBg,
colorInfo,
colorInfoBorder,
colorInfoBg
) = (
token.ComponentCls,
token.ColorSuccess,
token.ColorSuccessBorder,
token.ColorSuccessBg,
token.ColorWarning,
token.ColorWarningBorder,
token.ColorWarningBg,
token.ColorError,
token.ColorErrorBorder,
token.ColorErrorBg,
token.ColorInfo,
token.ColorInfoBorder,
token.ColorInfoBg
);
return new CSSObject
{
[componentCls] = new CSSObject()
{
["&-success"] = GenAlertTypeStyle(
colorSuccessBg,
colorSuccessBorder,
colorSuccess,
token,
componentCls
),
["&-info"] = GenAlertTypeStyle(colorInfoBg, colorInfoBorder, colorInfo, token, componentCls),
["&-warning"] = GenAlertTypeStyle(
colorWarningBg,
colorWarningBorder,
colorWarning,
token,
componentCls
),
["&-error"] = new CSSObject()
{
["..."] = GenAlertTypeStyle(colorErrorBg, colorErrorBorder, colorError, token, componentCls),
[$"{componentCls}-description > pre"] = new CSSObject()
{
Margin = 0,
Padding = 0,
},
},
},
};
}
public CSSObject GenActionStyle(AlertToken token)
{
var (
componentCls,
iconCls,
motionDurationMid,
marginXS,
fontSizeIcon,
colorIcon,
colorIconHover
) = (
token.ComponentCls,
token.IconCls,
token.MotionDurationMid,
token.MarginXS,
token.FontSizeIcon,
token.ColorIcon,
token.ColorIconHover
);
return new CSSObject
{
[componentCls] = new CSSObject()
{
["&-action"] = new CSSObject()
{
MarginInlineStart = marginXS,
},
[$"{componentCls}-close-icon"] = new CSSObject()
{
MarginInlineStart = marginXS,
Padding = 0,
Overflow = "hidden",
FontSize = fontSizeIcon,
LineHeight = $"{fontSizeIcon}px",
BackgroundColor = "transparent",
Border = "none",
Outline = "none",
Cursor = "pointer",
[$"{iconCls}-close"] = new CSSObject()
{
Color = colorIcon,
Transition = $"color {motionDurationMid}",
["&:hover"] = new CSSObject()
{
Color = colorIconHover,
},
},
},
["&-close-text"] = new CSSObject()
{
Color = colorIcon,
Transition = $"color {motionDurationMid}",
["&:hover"] = new CSSObject()
{
Color = colorIconHover,
},
},
},
};
}
public CSSObject[] GenAlertStyle(AlertToken token) => new CSSObject[]{
GenBaseStyle(token),
GenTypeStyle(token),
GenActionStyle(token),
};
protected override CSSObject[] UseStyle(GlobalToken token)
{
var fontSizeHeading3 = token.FontSizeHeading3;
var alertToken = MergeToken<AlertToken>(token, new AlertToken
{
AlertIconSizeLG = fontSizeHeading3,
AlertPaddingHorizontal = 12,
});
return GenAlertStyle(alertToken);
}
}
} Yep, you can see that the codes of both are consistent. But one of the problems we face is that we can't automatically convert TS to C# using scripts. |
Any thing i can help with? e.g. convert a component from ts to cs using cssincs |
I decided to use AST to automatically convert TS code to CS code. This may take a lot of time. For now, this solution is still experimental. You can continue to try other solution. I've done part of the style migration work in the v5 branch. |
Can you describe the process you adopted today? (the longest and manual, so we can understand better so we can contribute with tools for automation or even running this most boring and costly part) |
@ElderJames @yoli799480165 any update for v5? |
Is the v5 development still in progress? |
@joa77 Yes, we haven't made any more progress yet. Do you have any idsa? |
Hello there, we are merging antd v5 styles #3574 , please help us review together. |
@ElderJames Great to see the progress and I will have a go. |
Question for v5. Will there be themed css variables (:root), like accent color? |
Hello @mkalinski93 Currently we have the css variables for antd v4, you can replace the css link with |
Hey guys, any news or progress about the v5? |
Hello @ldsenow @eduardocp @joa77 @gitlsl @juliolitwin , we are very happy that the early version for Ant Design v5 have been release to Nuget, and you can try it by install the package: .csproj: <PackageReference Include="AntDesign" Version="0.0.1-v5-*" /> _import.razor: @using CssInCSharp App.razor: <link no-antblazor-css />
<StyleOutlet @rendermode="InteractiveServer" />
@* <HeadOutlet @rendermode="InteractiveServer" /> *@ Please try and give us your feedback. We will continue the improvment for the development experience. |
@ElderJames I tried to generate a new project and apply the instructions above, but I think I miss something, because the CSS is not entire complete. This is my test repository https://github.com/eduardocp/antd-blazor-v5-test |
@eduardocp This is because of the default style of browser. |
@ElderJames Yes, but like 4V, I thought there would be any reset css to do that. By the way, thanks for the fast reply ❤️ |
I'm closing this issue, and please follow #4146 |
Hi guys,
Are we looking into the upcoming AntD v5 for Blazor?
ant-design/ant-design#33862
It is dropping the less and use css-in-js. It is better for MFE.
The text was updated successfully, but these errors were encountered: