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

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

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

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

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

enter image description here

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

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

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

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

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

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

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

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

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

शायद मैं विपरीत दृष्टिकोण ले सकता था - एमयूआई को बताएं 'अरे इन वर्ग नामों को इन एमयूआई कक्षाओं की तरह स्टाइल किया जाना चाहिए'।

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

10
dwjohnston 6 पद 2019, 08:19

2 जवाब

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

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

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

screen shot

4
Mosh Feu 10 पद 2019, 13:07
मुझे यह सोच पसंद है। इस समाधान के साथ समस्या यह है कि आप अभी भी मूल रूप से सभी शैलियों को स्वयं लागू कर रहे होंगे (यानी होवर रंग, पैडिंग, सीमा त्रिज्या इत्यादि)। उदाहरण के लिए, यदि आपने तय किया है कि बटन टेक्स्ट को रेखांकित किया जाना चाहिए, तो आपको हेलमेट में text-decoration गुण जोड़ना याद रखना होगा।
 – 
dwjohnston
11 पद 2019, 03:04
मैं समझता हूं कि आप क्या मांगते हैं। मैंने एक अलग दृष्टिकोण लेने और MUI style टैग में हेरफेर करने और उन्हें .fc- चयनकर्ताओं को मानचित्र के अनुसार जोड़ने की कोशिश की, लेकिन उनके पास आधार स्तरों में संघर्ष हैं (जैसे display, padding आदि) इसलिए मैं नहीं देखता कि यह कैसे काम करेगा, भले ही आपके पास इसे scss में माइग्रेट करने का विकल्प होगा। उदाहरण के लिए: codesandbox.io/s/charming-sound-3xmj9
 – 
Mosh Feu
11 पद 2019, 13:39
हाहा - अब यह मुझे पसंद है। मैं इसे बाद में एक बेहतर रूप दूंगा।
 – 
dwjohnston
12 पद 2019, 03:59

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

रेफरी जोड़ें

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

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

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

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

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

componentDidMount() से सही DOM नोड को लक्षित करने के लिए आपको जो भी तर्क चाहिए उसे जोड़ें (आपके मामले के लिए, मैंने 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);
    }
  });
};

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

चेतावनी

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

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

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

3
sallf 13 पद 2019, 20:21
1
यह काम। ध्यान दें कि आपको किसी वर्ग घटक में कनवर्ट करने की आवश्यकता नहीं है - ऐसा करने के लिए आप हुक का उपयोग कर सकते हैं।
 – 
dwjohnston
13 पद 2019, 07:12
हां आप सही हैं, यह एक कार्यात्मक घटक में हुक के साथ किया जा सकता है। मैंने इसे प्रतिबिंबित करने के लिए उत्तर अपडेट कर दिया है।
 – 
sallf
13 पद 2019, 20:22
अच्छा, काफी व्यावहारिक दृष्टिकोण। लेकिन वास्तव में संभव नहीं है क्योंकि आपको हमेशा एक रेफरी की आवश्यकता होगी।
 – 
Aniket Chowdhury
15 पद 2019, 12:49