Material-ui: [withStyles] أضف القدرة على الحصول على دعائم المكون من داخل كائن النمط

تم إنشاؤها على ٢ أغسطس ٢٠١٧  ·  39تعليقات  ·  مصدر: mui-org/material-ui

وصف

عند استخدام createStyleSheet ، لا توجد طريقة (على الأقل أعرفها) للوصول إلى عناصر المكون. أعتقد أن هذا مهم ، لأنه في بعض الأحيان يكون مطلوبًا لتمرير الأحجام وصور عنوان url وأنماط أخرى كدعامات للمكون.

اليوم الحل الوحيد لذلك هو فصل هذه الأشياء إلى أنماط مضمنة ، ولكن بقدر ما أعرف ، تستخدم Material-ui v1 jss و react-jss ، وهذان العنصران يمنحك بالفعل إمكانية للوصول إلى الدعائم عبر الوظائف التي تستقبل الدعائم ثم تعيد النمط المطلوب ، على النحو التالي:

const styles = {
  button: {
    background: props => props.color
  },
  root: {
    backgroundImage: props => `url(${props.backgroundImage})`
  }
}

// Reference: https://github.com/cssinjs/react-jss#example

ما رأيك في تطبيق شيء من هذا القبيل على واجهة المستخدم المادية أيضًا؟

enhancement important

التعليق الأكثر فائدة

أقوم بإضافة هذه المشكلة في الإصدار 1.x الأساسي . كثير من الناس يطلبونه. سنصل إليه قريبًا.

capture d ecran 2018-07-29 a 13 12 03

ال 39 كومينتر

رد فعل- jss تطبيق هذه الميزة. يمكنك دائمًا استخدامه على حل التصميم الخاص بنا. يجب أن يكون الدافع الحقيقي لتنفيذ هذه الميزة هنا حول التطبيق الداخلي الأبسط / الأفضل للمكونات.

الرد-JSS injectStyles () يفعل ذلك أيضا، ولكن يبدو أن ذلك سيكون من الأفضل لإضافة الدعائم إلى StyleRuleCallback .

const styles = (props, theme) => ({})
بهذه الطريقة لن تكون مقيدًا بالقيم التي تعتمد على الدعائم فقط.

تجعلني تعليقات color مخصص لمكوناتنا ، بدلاً من المكون المحدد مسبقًا. تأثير حجم CSS غير واضح ولكنه سيجعل تجاوز لون المكون أبسط. هذا شيء للتحقيق. بعد ذلك ، بمجرد أن يصبح دعم متصفح متغيرات css عاليًا بدرجة كافية (سنتان من الآن؟) ، يمكننا الاعتماد عليه.

oliviertassinari ألن ينخفض حجم css فعليًا في بعض الحالات؟
عندما أحصل عليه ، نحدد حاليًا جميع الفئات لـ ...Primary و ...Accent - ألا يعني هذا التغيير ، أنه سيتعين علينا فقط الاحتفاظ بالفصول مقابل ...Colorized ؟ أو هل أنت قلق بشأن ملف المغلق الذي تم إنشاؤه؟

في كلتا الحالتين ، أعتقد أن هذا سيحسن dx بشكل كبير حيث يتعين علينا إعادة تطبيق الفئات المعقدة بشكل أساسي مثل https://github.com/callemall/material-ui/blob/v1-beta/src/Button/Button.js#L11 عندما نقوم تريد استخدام ألوان غير لوح الألوان.

ألن ينخفض ​​حجم css فعليًا في بعض الحالات؟

sakulstra من الصعب معرفة ذلك. سوف يعتمد على التنفيذ. يمكن :).

من منظور كتابة TypeScript ، سيكون من الجيد لو تم الوصول إلى _both_ props و theme بهذه الطريقة ضمن مواصفات الأنماط:

const styles = {
  button: {
    background: ({ theme }) => theme.palette.primary[200]
  },
  root: {
    backgroundImage: ({ props }) => `url(${props.backgroundImage})`
  }
};

والسبب هو أن TypeScript يفشل كثيرًا في استنتاج النوع الصحيح لـ withStyles عندما يتم تمرير كائن دالة ، لذلك عليك تقديم تعليقات توضيحية إضافية من النوع لجعلها تعمل ، على سبيل المثال

withStyles<'button' | 'root'>(theme => ...)

إذا تم تمرير الدعائم أيضًا ، فسيصبح هذا

withStyles<'button' | 'root', Props>((theme, props) => ...)

ما هو الوضع الحالي لهذا؟ سيكون من الرائع حقًا أن يكون لديك هذه الميزة

lucasmafra لقد أضفت هذه الميزة إلى ما بعد الإصدار v1. كلما أسرعنا في إصدار الإصدار 1 ، كان ذلك أفضل.

هذه الوظيفة هي مفتاح القدرة على كتابة قواعد نمط معبرة تجمع بين الدعائم واستعلامات الوسائط والحالات التفاعلية. لا يمكنك استبدال هذه الوظيفة بأنماط مضمنة. لسوء الحظ ، withStyles غير قابل للاستخدام في أي من مشاريعي حتى تتم إضافة هذا.

يمكنك دائمًا إعداد سمة مخصصة ، واستخدام هذا الاصطلاح: نحن نحب حقًا كيف تمنحك المكونات المصممة حق الوصول إلى props.theme خارج الصندوق عن طريق تداخل ThemeProvider داخل MuiThemeProvider عندما يُطلق على كلاهما سمة = {theme}. إنه يوسع السمة الافتراضية التي يعرضها mui

//inline with HOC Method
 h1 style= {{ 'color: this.props.theme.palette.primary[500]' }}

//styled components ( no method necessary )
const Heading = styled.h1`
  color: ${p => p.theme.palette.primary['500']};
`

كنت بحاجة فقط إلى استخدام قيم الدالة ، لذلك استخدمت وظيفة رد فعل-jss ' injectSheet() . أنا معتاد على استخدام وظيفة Mui withStyles() ، فهل هناك أي عيب عند استخدام injectionSheet بدلاً من withStyles؟

@ damien-monni لا يمكنك الوصول إلى سمة MUI الخاصة بك.

مرحبًا بالجميع ، أردت فقط مشاركة إصداري من واجهة برمجة التطبيقات التي تشبه مكونات واجهة المستخدم المادية. لم يتم اختباره "بشكل مكثف" ولكن يبدو أنه يعمل بشكل جيد ويوفر:

  • رفع props و theme لوظيفة النمط.
  • تمرير props المخصص للمكون المغلف
  • إعادة توجيه المراجع عبر React.forwardRef
    (تحرير: تعمل المراجع حاليًا فقط مع علامات html ، وليس معظم مكونات واجهة المستخدم المادية الأساسية ، وهذا يتطلب دعمًا داخليًا. قد يعمل على العلاقات العامة عندما يكون لدي وقت ، سيتطلب قبول function أو object دعامة-أنواعها، والقيام الشيكات على مكونات عديمي الجنسية سواء بالمرور إلى الطفل)

القضايا ذات الصلة: # 10825 ، # 7633

على غرار js

import React, { Component } from 'react';
import classNames from 'classnames';
import PropTypes from 'prop-types';
import { withStyles } from 'material-ui/styles';

function styled(WrappedComponent, customProps) {
  return (style, options) => {
    class StyledComponent extends Component {
      render() {
        let {
          forwardRef,
          classes,
          className,
          ...passThroughProps
        } = this.props;
        return (
          <WrappedComponent
            ref={forwardRef}
            className={classNames(classes.root, className)}
            {...passThroughProps}
            {...customProps}
          />
        );
      }
    }

    StyledComponent.propTypes = {
      classes: PropTypes.object.isRequired,
      className: PropTypes.string,
    };

    let hoistedProps = {};

    const styles =
      typeof style === 'function'
        ? theme => {
            return { root: style({ ...theme, theme, props: hoistedProps }) };
          }
        : { root: style };

    const WithRef = withStyles(styles, options)(StyledComponent);

    return React.forwardRef((props, ref) => {
      hoistedProps = props;
      return <WithRef {...props} forwardRef={ref} />;
    });
  };
}

export default styled;

استخدام المثال

const MobileNav = styled('nav')(({ theme, props }) => ({
  '&.pos-fixed': {
    top: 0,
    position: props.fixed ? 'fixed' : 'absolute',
    zIndex: 99,
    animation: 'fadeInDown 0.3s ease-out forwards',
    backgroundColor: theme.palette.common.white,
  },
}));

مع الدعائم المخصصة

const StyledButton = styled(Button, { component: Link })(
  ({ theme, props }) => ({
    color: props.disabled ? 'gray' : 'blue',
    [theme.breakpoints.down('sm')]: {
      color: 'red',
    },
  })
);

oliviertassinari لحل هذه المشكلة ، أستخدم الحل أدناه:

    componentWillMount() {
        const {color} = this.props;
        jss.setup(jssPreset());
        const stylesheet = jss.createStyleSheet({
            underline: {
              "&:after": {
                backgroundColor: `${color} !important`
              }
            }
        }).attach();
        this.underlineClass = stylesheet.classes.underline;
    }

إنه يعمل بشكل رائع ولكن هل هناك بعض المشكلات المحتملة التي لا أراها؟ لا يعجبني أنه لا بد لي من استدعاء jss.setup مرتين على سبيل المثال 😅. لست متأكدًا من فهمي لدورة حياة jss . لقد فوجئت بضرورة استدعاء setup() هنا.

إنه يعمل بشكل رائع ولكن هل هناك بعض المشكلات المحتملة التي لا أراها؟

wcandillon بعض

لقد طورت هذه المكتبة للحصول على دعائم بأسلوب أنيق:

https://github.com/JacquesBonet/jss-material-ui

تم اختباره بنجاح في المشروع.

في البداية ، أستخدم حل danielmahon ، لكني أحصل على مشكلة وراثة النمط.

oliviertassinari هل لدينا نهج بديل لإنشاء رسوم متحركة / css ديناميكية في الوقت الحالي؟ شكرا :)

HunderlineK بعض البدائل: https://material-ui.com/customization/overrides/#2 -dynamic-variation-for-a-one-time-status.

danielmahon نهجك هو فقط ما أبحث عنه الآن لحل مشكلتي ، على الرغم من أن "المكون الأنيق" لا يعاد عرضه عند تلقيه دعائم جديدة. هل جربت أي شيء آخر؟

سأفكر في شيء مختلف ، وإذا توصلت إلى شيء سأعلمك به

💰 فقط أرفقت مكافأة قدرها 50 دولارًا لتلك المكافأة :)

https://www.bountysource.com/issues/47838203-withstyles-add-the-ability-to-get-the-component-s-props-from-within-the-style-object

مثل @ lewisdiamond قال ، const styles = (props, theme) => ({}) سيكون رائعًا حقًا.

أو ربما يكون const styles = (theme, props) => ({}) غير منكسر.

أقوم بإضافة هذه المشكلة في الإصدار 1.x الأساسي . كثير من الناس يطلبونه. سنصل إليه قريبًا.

capture d ecran 2018-07-29 a 13 12 03

oliviertassinari ربما يكون لهذا آثار مهمة على كتابة withStyles ، يُرجى إعلامي إذا كان بإمكاني المساعدة في ذلك

pelotom شكرا ،

هل هناك عمل جار بخصوص هذا؟ إنها ميزة أساسية IMO ، ربما يمكنني المساعدة في ذلك.

تحرير: لقد بدأت العمل عليه. تمكن من تمرير الدعائم إلى styles وظيفة أن withStyles يقبل، المشكلة الوحيدة هي لا يتم تحديث الأنماط عندما تغير الدعائم. سيتم إنشاء علاقات عامة عند حل ذلك.

مرحبًا ، لقد صادفت للتو حالة استخدام حيث كنت بحاجة إلى ذلك لتخصيص ألوان مكون الصورة الرمزية ولا توجد طريقة أخرى للتحكم في النمط لجميع متغيرات المكون بخلاف هذا.

const styles = theme => ({
  chip:{
  },
  separator: {
    marginRight: theme.spacing.unit,
  },
  fright: {
    float: 'right',
  },
  fleft: {
    float: 'left',
  },
  outlinedPrimary:{
    color: props =>  stringToColor( props.username),
    border: props => `1px solid ${fade(stringToColor(props.username), 0.5)}`,
    '$clickable&:hover, $clickable&:focus, $deletable&:focus': props => ({
      backgroundColor: fade(stringToColor(props.username), theme.palette.action.hoverOpacity),
      border: `1px solid ${stringToColor(props.username)}`,
      }),
  },
  outlined: {
    backgroundColor: 'transparent',
    border: props => `1px solid ${
      theme.palette.type === 'light' ? stringToColor(props.username) : fade(stringToColor(props.username))
    }`,
    '$clickable&:hover, $clickable&:focus, $deletable&:focus': props => ({
      backgroundColor: fade(stringToColor(props.username), theme.palette.action.hoverOpacity),
      }),
    },
});

يمكنك التحقق من الحل الخاص بي Japrogramer: https://github.com/JacquesBonet/jss-material-ui

شكرا ، سوف ألقي نظرة عليه.

كنت بحاجة إلى هذه الميزة في وقت سابق اليوم ، لذلك كتبت HOC. withStyles ببعض التخزين المؤقت من تلقاء نفسه ، لذا لا يمكنني تحديد مدى تأثير ذلك على ذلك ، لكنني سألقي نظرة على تنفيذ التخزين المؤقت لـ withStyles في وقت فراغي ، في الوقت الحالي ، أي شخص يبحث عن طريقة سريعة للحصول على الدعائم والموضوع للعب بشكل لطيف هناك تذهب

تحذير

سيقوم هذا المكون بإعادة التحميل الكامل إذا غيرت الدعائم شيئًا ما يتعلق برقم الفهرس الخاص بفئة ورقة الأنماط المتغيرة أو أي شيء في withStyles HOC

import React from 'react';
import { withStyles } from '@material-ui/core/styles';

const { createElement, forwardRef } = React

const withPropsStyles = ( style ) => {

    const withPropsStyles = ( component ) => {

        return forwardRef( (props, ref) => {

            const proxy = (theme) => style(props, theme)

            const hoc = withStyles(proxy)(component)

            return props.children ? 
                createElement(hoc, { ...props, ref}, props.children) :
                createElement(hoc, {...props, ref}) 
        }) 
    }

    return withPropsStyles
}

export default withPropsStyles

استخدام المثال

const styles = (props, theme) => ({
    root:{
        backgroundColor: props.light ? theme.palette.primary.light : theme.palette.primary.main 
    },
})

const SomeComponent = ({classes}) => <div className={classes.root}/>

export default withPropsStyles(styles)(SomeComponent)

استنتاج

بسيط ويعمل (ولكن مع إعادة التكلفة الكاملة أيضًا)

مع هذا التغيير ، هل يمكننا إزالة استخدام النمط المضمن من المكتبة لصالح 100٪ JSS؟ لا يعمل تطبيقي مع الأنماط المضمنة وعندما ذهبت لاستبدال تأثير التموج بـ JSS أدركت أنني بحاجة إلى هذه الميزة. ربما حدث أداء صغير ، لكن يبدو أنظف.

@ koshea تخلص من النمط المضمن. أنا أيضًا لا أحب الأنماط المضمنة أيضًا ، يجب أن تعمل بشكل جيد كبديل عن withStyles كديكور أو كما في المثال.

أردت أيضًا أن أذكر ، أن استخدام الأنماط المضمنة لا يسمح بتمكين سياسة أمان المحتوى القوية.
يتطلب إضافة علامة unsafe-inline إلى توجيهات الأنماط ، وهي ليست آمنة.

يجب أن تحل الأنماط الديناميكية مع دعم الدعائم هذه المشكلة

مرحبًا يا شباب ، آسف للقفز إلى المناقشة "تمامًا مثل هذا". لقد بدأت مؤخرًا في استخدام Mui (مع Typescript) وبينما أجدها مكتبة قوية للغاية ، فمن المؤكد أنها تحتوي على تعقيداتها.

لقد لاحظت في بعض التعليقات أعلاه أن هناك القليل من النقاش حول ما إذا كانت هذه الميزة يجب أن تكون (props, theme) => {} أو (theme, props) => {} . أرغب في تعزيز ما قاله pelotom حول إنشاء خصائص مسماة props و theme في تعليقه . من المحتمل أن يسهل علينا جعل الأمر بهذه الطريقة إعادة تشكيل تعريفات النمط بمجرد هبوط هذا التغيير (وهو ما أتطلع إليه حقًا). هتاف 🙂

شكرا لكم جميعا على الصبر! يتم الاهتمام بهذه المشكلة في # 13503. إنه مطلب لمساعدي المكون الذي نريد تنفيذه. لقد بدأنا أيضًا في تجربة واجهة برمجة تطبيقات الخطاف: https://twitter.com/olivtassinari/status/1058805751404261376.

هل هذا جعله إلى 4.0؟ يبدو أن رد الاتصال makeStyles لا يحتوي على معلمة props .

@ city41 const classes = useStyles(props);

أرى. لذلك يبدو كما هو

const useStyles = makeStyles(theme => {
    return {
        foo: {
            color: theme.props.danger ? '#ff0000' : '#00ff00'
        }
    };
});

function MyComponent(props) {
    const classes = useStyles(props);

    return <div className={classes.foo}>...</div>;
}

لا أرى هذا موثقًا في قسم الأنماط API على موقع الويب. اسمحوا لي أن أرى ما إذا كان بإمكاني إرسال PR.

@ city41 هناك بداية للتوثيق في https://material-ui.com/styles/basics/#adapting -based-on-props.

رائع ، سعيد لرؤية المستندات يتم تحديثها. بالنسبة لأي شخص آخر يتعامل مع هذه المشكلة ، إليك كيفية الجمع بين السمة والدعائم لتصميم مكون

import React from 'react';
import { Button, Theme, makeStyles } from '@material-ui/core';

interface ButtonProps {
    destructive: boolean;
}

const useButtonStyles = makeStyles<Theme, ButtonProps>(theme => {
    return {
        root: props => ({
            backgroundColor: props.destructive ? theme.palette.error.main : theme.palette.primary.main
        })
    };
});

export const PrimaryButton: React.FunctionComponent<ButtonProps> = props => {
    const classes = useButtonStyles(props);

    return <Button {...props} className={classes.root} variant="contained" />;
};

كيف يمكنني استخدام الخاصية في ملف Json لأنماط خارجية؟

على سبيل المثال هذا ملف خارجي

const typographyStyle = {
  title2: {
    fontFamily:"Montserrat",
    fontStyle:"normal",
    fontWeight:"800",
    fontSize:"72px",
    lineHeight:"88px",
    letterSpacing:"-0.02em",
    // color:"#304C82"
    color : props => {
      console.log(props,'c1');
      return props.color
    }

  }
};

export default typographyStyle;

أقوم باستيراد هذا الملف ونشر الكائن

import typographyStyle from "../assets/jss/material-kit-pro-react/views/componentsSections/typographyStyle";


const styles = theme =>  ({
    ...typographyStyle,
    homeSearch:{
        width: '100%',
        '& div':{
            '& input':{
                "color":"#304C82",
                height: 65,
                fontFamily: 'Open Sans',
                fontStyle: 'normal',
                fontWeight: 800,
                fontSize: '48px',
                lineHeight: '65px',
                letterSpacing: '-0.03em',
                '&::placeholder':{
                    fontFamily: 'Open Sans',
                    fontStyle: 'normal',
                    fontWeight: 800,
                    fontSize: '48px',
                    lineHeight: '65px',
                    letterSpacing: '-0.03em',
                    color: '#EAEAEA'
                }
            }
        }
    },

  });

الآن في وظيفة اللون أحصل على الدعائم = {}.

هل يمكن لأحد أن يساعدني في هذا الصدد؟

تحديث:

يبدو أنني أفعل شيئًا خاطئًا لأنني أحصل على كائن فارغ حتى في ملف styles.js الرئيسي

    homeSearch: props => {
        console.log(props);
        return {
        width: '100%',
        border:  `1px solid ${props.color}`
        ,
        '& div':{
            '& input':{
                "color":"#304C82",
                height: 65,
                fontFamily: 'Open Sans',
                fontStyle: 'normal',
                fontWeight: 800,
                fontSize: '48px',
                lineHeight: '65px',
                letterSpacing: '-0.03em',
                '&::placeholder':{
                    fontFamily: 'Open Sans',
                    fontStyle: 'normal',
                    fontWeight: 800,
                    fontSize: '48px',
                    lineHeight: '65px',
                    letterSpacing: '-0.03em',
                    color: '#EAEAEA'
                }
            }
        }
    }
},
هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات