मैं सामग्री-यूआई प्रबंधित शैलियों को गैर-सामग्री-यूआई, गैर-प्रतिक्रिया तत्वों पर कैसे लागू करूंगा?


9

मेरे पास एक एप्लिकेशन है जहां मैं सामग्री यूआई और उसके विषय प्रदाता (जेएसएस का उपयोग करके) का उपयोग कर रहा हूं।

मैं अब फुलकैन्डर-रिएक्ट को शामिल कर रहा हूं , जो वास्तव में पूरी तरह से प्रतिक्रियाशील पुस्तकालय नहीं है - यह मूल फुलक्लेन्डर कोड के चारों ओर सिर्फ एक पतली रिएक्ट घटक आवरण है।

यह कहना है, यह है कि मैं कैसे अपने तत्वों को शैली को नियंत्रित करने के लिए सहारा सौंपनेवाला जैसी चीजों तक पहुंच नहीं है।

हालांकि, यह आपको कॉलबैक के माध्यम से सीधे DOM तत्वों तक पहुंच प्रदान करता है, जिसे कॉल किया जाता है, जब यह उन्हें प्रदान करता है (उदाहरण के लिए, रेंडरर विधि )।

यहाँ एक बुनियादी डेमो सैंडबॉक्स है।

यहां छवि विवरण दर्ज करें

अब मैं जो करना चाहता हूं वह फुल कैलेंडर घटकों (जैसे, बटन) को एक ही देखो और मेरे आवेदन के बाकी हिस्सों के रूप में साझा करना है।

ऐसा करने का एक तरीका यह है, कि मैं शैली के सभी नामों को मैन्युअल रूप से ओवरराइड कर सकता हूं, जो शैली का उपयोग कर रहा है और तदनुसार शैली को लागू कर रहा है।

या - मैं बूटस्ट्रैप थीम को लागू कर सकता था - जैसा कि उनके प्रलेखन में सुझाया गया है।

लेकिन इन समाधानों में से किसी एक के साथ समस्या यह है कि:

  1. यह बहुत काम का होगा
  2. मुझे सिंक्रोनाइज़ेशन की समस्या होती, अगर मैं अपने MUI थीम में बदलाव करता और कैलेंडर थीम को अपडेट करना भूल जाता तो वे अलग दिखते।

मैं जो करना चाहूंगा वह है:

  • जादुई रूप से MUI थीम को बूटस्ट्रैप थीम में बदलें।
  • या MUI वर्ग नामों और कैलेंडर वर्ग नामों के बीच एक मानचित्रण बनाएं, कुछ इस तरह:
.fc-button = .MuiButtonBase-root.MuiButton-root.MuiButton-contained
.fc-button-primary= .MuiButton-containedPrimary

मुझे यह काम करने के लिए चयनकर्ताओं आदि की मालिश करने का मन नहीं होगा (उदाहरण के लिए - एमयूआई बटन में दो आंतरिक स्पैन हैं, जबकि पूर्ण कैलेंडर में सिर्फ एक है)। यह ज्यादातर तब होता है जब मैं थीम बदलता हूं - दो स्थानों पर इसे बदलना नहीं चाहता।

अपने @extendवाक्य रचना के साथ सैस जैसी किसी चीज़ का उपयोग करना मेरे मन में है। मैं आसानी से पर्याप्त के साथ फुल-कैलेंडर CSS बना सकता था - लेकिन Sass MuiTheme तक कैसे पहुंचेगा?

शायद मैं इसके विपरीत रुख अपना सकता हूं - MUI को बताएं 'अरे ये वर्ग के नाम यहां इन MUI वर्गों की तरह स्टाइल किए जाने चाहिए'।

इस पर कोई ठोस सुझाव कि मैं इसे कैसे हल करूंगा?

जवाबों:


4

यहाँ मेरा सुझाव है (जाहिर है, यह सीधे आगे नहीं है)। MUI थीम से शैलियों को लें और styleउपयोग के आधार पर टैग बनाएं react-helmet। इसे अच्छी तरह से करने के लिए, मैंने एक "आवरण" घटक बनाया जो नक्शे को पूरा करता है। मैंने केवल प्राथमिक नियम लागू किया लेकिन इसे अन्य सभी के लिए बढ़ाया जा सकता है।

इस तरह, आप थीम में कोई भी परिवर्तन मैप किए गए चयनकर्ताओं को भी प्रभावित करेंगे।

import React from "react";
import { Helmet } from "react-helmet";

export function MuiAdapter({ theme }) {
  if (!theme.palette) {
    return <></>;
  }
  return (
    <Helmet>
      <style type="text/css">{`
          .fc-button-primary {
            background: ${theme.palette.primary.main}
          }
          /* more styles go here */
      `}</style>
    </Helmet>
  );
}

और एडॉप्टर का उपयोग

<MuiAdapter theme={theme} />

वर्किंग डेमो: https://codesandbox.io/s/reverent-mccarthy-3o856

स्क्रीन शॉट


मुझे यह सोच पसंद है। इस समाधान के साथ समस्या यह है कि आप अभी भी मूल रूप से सभी शैलियों को स्वयं लागू कर रहे हैं (यानी, होवर रंग, गद्दी, सीमा त्रिज्या आदि)। यदि उदाहरण के लिए, आपने तय किया है कि बटन टेक्स्ट को रेखांकित किया जाना चाहिए, तो आपको text-decorationसंपत्ति को हेलमेट में जोड़ने के लिए याद रखना होगा ।
dwjohnston

मैं समझता हूँ कि तुम क्या माँगते हो। मैंने एक अलग दृष्टिकोण लेने और एमयूआई styleटैग में हेरफेर करने और उन्हें .fc-मानचित्र के अनुसार चयनकर्ताओं को जोड़ने की कोशिश की , लेकिन उनके पास आधार स्तरों (जैसे display, paddingआदि) में संघर्ष है , इसलिए मैं नहीं देखता कि यह कैसे काम करेगा, भले ही आपके पास होगा विकल्प के लिए इसे scss में माइग्रेट करें। उदाहरण के लिए: codeandbox.io/s/charming-sound-3xmj9
Mosh Feu

हाहा - अब यह मुझे पसंद है। मैं इसे बाद में एक बेहतर रूप दूँगा।
dwjohnston

3

आप MUI वर्ग के नाम और कैलेंडर वर्ग के नामों के बीच एक मानचित्रण बना सकते हैं ref। यह संभव है कि यह वह नहीं है जिसे कुछ लोग "सर्वोत्तम अभ्यास" कहेंगे ... लेकिन यह एक समाधान है :)। ध्यान दें कि मैंने आपके घटक को एक कार्यात्मक घटक से एक वर्ग घटक में अपडेट किया है, लेकिन आप इसे एक कार्यात्मक घटक में हुक के साथ पूरा कर सकते हैं।

रेफ जोड़ें

refउस MUI तत्व में जोड़ें जिसे आप संदर्भ के रूप में सेट करना चाहते हैं, अपने मामले में Button

<Button
  color="primary"
  variant="contained"
  ref={x => {
    this.primaryBtn = x;
  }}
>

और उस घटक के चारों ओर refएक लपेटकर divजिसे आप मैप करना चाहते हैं। आप इसे सीधे घटक में नहीं जोड़ सकते क्योंकि यह हमें एक्सेस नहीं देगा children

<div
  ref={x => {
    this.fullCal = x;
  }}
>
  <FullCalendar
    ...
  />
</div>

मानचित्र कक्षाएं

componentDidMount()सही डोम नोड को लक्षित करने के लिए आपको जो भी तर्क देने की आवश्यकता है, उसमें से (आपके मामले के लिए, मैंने तर्क जोड़ा है ) typeऔर matchingClass। फिर उस तर्क को सभी FullCalendar DOM नोड्स पर चलाएं और classListकिसी भी मैच पर प्रतिस्थापित करें ।

componentDidMount() {
  this.updatePrimaryBtns();
}

updatePrimaryBtns = () => {
  const children = Array.from(this.fullCal.children);
  // Options
  const type = "BUTTON";
  const matchingClass = "fc-button-primary";

  this.mapClassToElem(children, type, matchingClass);
};

mapClassToElem = (arr, type, matchingClass) => {
  arr.forEach(elem => {
    const { tagName, classList } = elem;
    // Check for match
    if (tagName === type && Array.from(classList).includes(matchingClass)) {
      elem.classList = this.primaryBtn.classList.value;
    }

    // Run on any children
    const next = elem.children;
    if (next.length > 0) {
      this.mapClassToElem(Array.from(next), type, matchingClass);
    }
  });
};

यह शायद थोड़ा भारी हाथ है, लेकिन जब आप अपडेट यूआई को अपडेट करते हैं तो यह आपके भविष्य की प्रमाण की आवश्यकता को पूरा करता है। यह आपको classListकिसी तत्व को पास करने के साथ ही उसे बदलने की भी अनुमति देगा , जिसके स्पष्ट लाभ हैं।

चेतावनियां

यदि FullCalendarआपके द्वारा लक्षित तत्वों पर 'मैप-टू' कंपोनेंट ( ) अपडेटेड क्लासेस (जैसे अगर यह .is-selectedकरंट बटन में जोड़ा जाता है) या बढ़ते जाने के बाद नए बटन जोड़ता है तो आपको संबंधित परिवर्तनों और पुनर्मिलन को ट्रैक करने का एक तरीका पता लगाना होगा तर्क।

मुझे यह भी उल्लेख करना चाहिए कि (स्पष्ट रूप से) बदलने वाली कक्षाओं में एक ब्रेकिंग यूआई जैसे अनपेक्षित परिणाम हो सकते हैं और आपको यह पता लगाना होगा कि उन्हें कैसे ठीक किया जाए।

यहां काम कर रहे सैंडबॉक्स: https://codesandbox.io/s/determined-frog-3loyf है


1
यह काम। ध्यान दें कि आपको कक्षा घटक में बदलने की आवश्यकता नहीं है - ऐसा करने के लिए आप हुक का उपयोग कर सकते हैं।
dwjohnston

हां आप सही हैं, यह एक कार्यात्मक घटक में हुक के साथ किया जा सकता है। मैंने उस उत्तर को प्रतिबिंबित करने के लिए अद्यतन किया है।
sallf

अच्छा, काफी व्यावहारिक दृष्टिकोण। लेकिन वास्तव में संभव नहीं है क्योंकि आपको हमेशा रेफरी की आवश्यकता होगी।
अनिकेत चौधरी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.