কাস্টম উপাদান সেরা অভ্যাস

কাস্টম উপাদান আপনাকে আপনার নিজস্ব HTML ট্যাগ তৈরি করতে দেয়। এই চেকলিস্টটি আপনাকে উচ্চ মানের উপাদান তৈরি করতে সাহায্য করার জন্য সর্বোত্তম অনুশীলনগুলিকে কভার করে৷

কাস্টম উপাদানগুলি আপনাকে HTML প্রসারিত করতে এবং আপনার নিজস্ব ট্যাগ সংজ্ঞায়িত করতে দেয়। এগুলি একটি অবিশ্বাস্যভাবে শক্তিশালী বৈশিষ্ট্য, তবে এগুলি নিম্ন-স্তরের, যার অর্থ আপনার নিজের উপাদানটি কীভাবে সর্বোত্তমভাবে প্রয়োগ করা যায় তা সর্বদা পরিষ্কার নয়৷

আপনাকে সর্বোত্তম সম্ভাব্য অভিজ্ঞতা তৈরি করতে সহায়তা করার জন্য আমরা এই চেকলিস্টটি একসাথে রেখেছি। এটি একটি ভাল আচরণ করা কাস্টম উপাদান হতে আমাদের মনে হয় এমন সমস্ত জিনিস ভেঙে দেয়।

চেকলিস্ট

ছায়া DOM

শৈলী এনক্যাপসুলেট করতে একটি শ্যাডো রুট তৈরি করুন।

কেন? আপনার এলিমেন্টের শ্যাডো রুটে স্টাইল এনক্যাপসুলেট করা নিশ্চিত করে যে এটি যেখানেই ব্যবহার করা হোক না কেন এটি কাজ করবে। এটি বিশেষভাবে গুরুত্বপূর্ণ যদি একজন বিকাশকারী আপনার উপাদানটিকে অন্য উপাদানের ছায়া রুটের ভিতরে রাখতে চান। এটি একটি চেকবক্স বা রেডিও বোতামের মতো সাধারণ উপাদানগুলিতেও প্রযোজ্য। এটি এমন হতে পারে যে আপনার শ্যাডো রুটের অভ্যন্তরে একমাত্র বিষয়বস্তু স্টাইলগুলিই হবে।
উদাহরণ <howto-checkbox> উপাদান।

কনস্ট্রাক্টরে আপনার ছায়া রুট তৈরি করুন।

কেন? কনস্ট্রাক্টর হল যখন আপনার উপাদান সম্পর্কে একচেটিয়া জ্ঞান থাকে। বাস্তবায়নের বিশদ সেটআপ করার জন্য এটি একটি দুর্দান্ত সময় যা আপনি চান না যে অন্যান্য উপাদানগুলি এলোমেলো হয়ে যাক। পরবর্তী কলব্যাকে এই কাজটি করা, যেমন connectedCallback , মানে আপনাকে এমন পরিস্থিতি থেকে রক্ষা করতে হবে যেখানে আপনার উপাদানটি বিচ্ছিন্ন করা হয় এবং তারপরে নথিতে পুনরায় সংযুক্ত করা হয়।
উদাহরণ <howto-checkbox> উপাদান।

উপাদানটি তৈরি করে এমন যেকোনো শিশুকে তার ছায়ামূলে রাখুন।

কেন? আপনার উপাদান দ্বারা তৈরি শিশু এটি বাস্তবায়নের অংশ এবং ব্যক্তিগত হওয়া উচিত। ছায়া গোড়ার সুরক্ষা ছাড়া, জাভাস্ক্রিপ্টের বাইরে অসাবধানতাবশত এই শিশুদের সাথে হস্তক্ষেপ করতে পারে।
উদাহরণ <howto-tabs> উপাদান।

হালকা DOM শিশুদের আপনার ছায়া DOM-এ প্রজেক্ট করতে <slot> ব্যবহার করুন

কেন? আপনার কম্পোনেন্টের ব্যবহারকারীদের আপনার কম্পোনেন্টে বিষয়বস্তু নির্দিষ্ট করার অনুমতি দিন কারণ HTML বাচ্চারা আপনার কম্পোনেন্টকে আরও কম্পোজযোগ্য করে তোলে। যখন একটি ব্রাউজার কাস্টম উপাদান সমর্থন করে না, নেস্টেড সামগ্রী উপলব্ধ, দৃশ্যমান এবং অ্যাক্সেসযোগ্য থাকে।
উদাহরণ <howto-tabs> উপাদান।

একটি :host প্রদর্শন শৈলী (যেমন block , inline-block , flex ) সেট করুন যদি না আপনি inline ডিফল্ট পছন্দ করেন।

কেন? কাস্টম উপাদানগুলি display: inline , তাই তাদের width বা height সেট করার কোন প্রভাব থাকবে না। এটি প্রায়শই বিকাশকারীদের কাছে অবাক হয়ে আসে এবং পৃষ্ঠাটি সাজানোর সাথে সম্পর্কিত সমস্যার কারণ হতে পারে। আপনি যদি inline ডিসপ্লে পছন্দ না করেন, আপনার সবসময় একটি ডিফল্ট display মান সেট করা উচিত।
উদাহরণ <howto-checkbox> উপাদান।

একটি :host প্রদর্শন শৈলী যোগ করুন যা লুকানো বৈশিষ্ট্যকে সম্মান করে।

কেন? একটি ডিফল্ট display শৈলী সহ একটি কাস্টম উপাদান, যেমন :host { display: block } , নিম্ন নির্দিষ্টতা অন্তর্নির্মিত hidden বৈশিষ্ট্যকে ওভাররাইড করবে। এটি আপনাকে অবাক করে দিতে পারে যদি আপনি আশা করেন যে আপনার উপাদানটিতে hidden অ্যাট্রিবিউট সেট করে এটি display: none । একটি ডিফল্ট display শৈলী ছাড়াও, :host([hidden]) { display: none } দিয়ে hidden এর জন্য সমর্থন যোগ করুন।
উদাহরণ <howto-checkbox> উপাদান।

গুণাবলী এবং বৈশিষ্ট্য

লেখক-সেট, গ্লোবাল অ্যাট্রিবিউট ওভাররাইড করবেন না।

কেন? গ্লোবাল অ্যাট্রিবিউটগুলি হল সেইগুলি যেগুলি সমস্ত HTML উপাদানগুলিতে উপস্থিত থাকে৷ কিছু উদাহরণ tabindex এবং role অন্তর্ভুক্ত. একটি কাস্টম উপাদান তার প্রাথমিক tabindex 0 এ সেট করতে চাইতে পারে তাই এটি কীবোর্ড ফোকাসযোগ্য হবে। কিন্তু আপনার এলিমেন্ট ব্যবহারকারী ডেভেলপার এটিকে অন্য কোনো মান নির্ধারণ করেছে কিনা তা দেখার জন্য আপনাকে সর্বদা প্রথমে পরীক্ষা করা উচিত। যদি, উদাহরণস্বরূপ, তারা tabindex -1 সেট করে থাকে, এটি একটি সংকেত যে তারা উপাদানটি ইন্টারেক্টিভ হতে চায় না।
উদাহরণ <howto-checkbox> উপাদান। এটি আরও ব্যাখ্যা করা হয়েছে পৃষ্ঠা লেখককে ওভাররাইড করবেন না।

সর্বদা আদিম ডেটা (স্ট্রিং, সংখ্যা, বুলিয়ান) হয় বৈশিষ্ট্য বা বৈশিষ্ট্য হিসাবে গ্রহণ করুন।

কেন? কাস্টম উপাদান, যেমন তাদের অন্তর্নির্মিত প্রতিরূপ, কনফিগারযোগ্য হওয়া উচিত। কনফিগারেশন ঘোষণামূলকভাবে, বৈশিষ্ট্যের মাধ্যমে বা জাভাস্ক্রিপ্ট বৈশিষ্ট্যের মাধ্যমে অপরিহার্যভাবে পাস করা যেতে পারে। আদর্শভাবে প্রতিটি বৈশিষ্ট্য একটি সংশ্লিষ্ট সম্পত্তি লিঙ্ক করা উচিত.
উদাহরণ <howto-checkbox> উপাদান।

আদিম ডেটা অ্যাট্রিবিউট এবং প্রোপার্টিগুলিকে সিঙ্কে রাখা, প্রোপার্টি থেকে অ্যাট্রিবিউটে প্রতিফলিত করা এবং এর বিপরীতে লক্ষ্য করা।

কেন? আপনি কখনই জানেন না কিভাবে একজন ব্যবহারকারী আপনার উপাদানের সাথে ইন্টারঅ্যাক্ট করবে। তারা জাভাস্ক্রিপ্টে একটি সম্পত্তি সেট করতে পারে এবং তারপর getAttribute() এর মত একটি API ব্যবহার করে সেই মানটি পড়ার আশা করতে পারে। যদি প্রতিটি অ্যাট্রিবিউটের একটি সংশ্লিষ্ট বৈশিষ্ট্য থাকে এবং উভয়ই প্রতিফলিত হয়, তাহলে এটি ব্যবহারকারীদের জন্য আপনার উপাদানের সাথে কাজ করা সহজ করে তুলবে। অন্য কথায়, setAttribute('foo', value) কল করার জন্য একটি সংশ্লিষ্ট foo প্রপার্টি সেট করা উচিত এবং এর বিপরীতে। এই নিয়মের ব্যতিক্রম অবশ্যই আছে। আপনার উচ্চ ফ্রিকোয়েন্সি বৈশিষ্ট্যগুলি প্রতিফলিত করা উচিত নয়, যেমন একটি ভিডিও প্লেয়ারে currentTime । আপনার সেরা বিচার ব্যবহার করুন. যদি মনে হয় একজন ব্যবহারকারী একটি সম্পত্তি বা বৈশিষ্ট্যের সাথে ইন্টারঅ্যাক্ট করবে এবং এটি প্রতিফলিত করা কঠিন নয়, তাহলে তা করুন।
উদাহরণ <howto-checkbox> উপাদান। পুনঃপ্রবেশ সমস্যা এড়িয়ে চলুন -এ এটি আরও ব্যাখ্যা করা হয়েছে।

বৈশিষ্ট্য হিসাবে শুধুমাত্র সমৃদ্ধ ডেটা (বস্তু, অ্যারে) গ্রহণ করার লক্ষ্য রাখুন।

কেন? সাধারণভাবে বলতে গেলে, বিল্ট-ইন এইচটিএমএল উপাদানের কোনো উদাহরণ নেই যা তাদের বৈশিষ্ট্যের মাধ্যমে সমৃদ্ধ ডেটা (প্লেন জাভাস্ক্রিপ্ট অবজেক্ট এবং অ্যারে) গ্রহণ করে। রিচ ডেটা পরিবর্তে পদ্ধতি কল বা বৈশিষ্ট্যের মাধ্যমে গ্রহণ করা হয়। বৈশিষ্ট্য হিসাবে সমৃদ্ধ ডেটা গ্রহণ করার কয়েকটি সুস্পষ্ট নেতিবাচক দিক রয়েছে: একটি বড় বস্তুকে একটি স্ট্রিং-এ সিরিয়ালাইজ করা ব্যয়বহুল হতে পারে এবং এই স্ট্রিংকরণ প্রক্রিয়ায় যেকোন অবজেক্ট রেফারেন্স হারিয়ে যাবে। উদাহরণস্বরূপ, যদি আপনি এমন একটি বস্তুকে স্ট্রিংফাই করেন যার অন্য কোনো বস্তুর একটি রেফারেন্স আছে, বা সম্ভবত একটি DOM নোড, সেই রেফারেন্সগুলি হারিয়ে যাবে।

বৈশিষ্ট্যগুলিতে সমৃদ্ধ ডেটা বৈশিষ্ট্যগুলি প্রতিফলিত করবেন না।

কেন? বৈশিষ্ট্যগুলিতে সমৃদ্ধ ডেটা বৈশিষ্ট্যগুলি প্রতিফলিত করা অপ্রয়োজনীয়ভাবে ব্যয়বহুল, একই জাভাস্ক্রিপ্ট অবজেক্টের সিরিয়ালাইজিং এবং ডিসিরিয়ালাইজ করা প্রয়োজন। যদি না আপনার কাছে এমন একটি ব্যবহারের ক্ষেত্রে থাকে যা শুধুমাত্র এই বৈশিষ্ট্যটির মাধ্যমে সমাধান করা যেতে পারে, সম্ভবত এটি এড়িয়ে যাওয়াই ভাল।

উপাদানটি আপগ্রেড করার আগে সেট করা থাকতে পারে এমন বৈশিষ্ট্যগুলির জন্য পরীক্ষা করার কথা বিবেচনা করুন৷

কেন? আপনার উপাদান ব্যবহার করে একজন বিকাশকারী উপাদানটির সংজ্ঞা লোড হওয়ার আগে একটি বৈশিষ্ট্য সেট করার চেষ্টা করতে পারে। এটি বিশেষত সত্য যদি বিকাশকারী এমন একটি কাঠামো ব্যবহার করে যা লোডিং উপাদানগুলি পরিচালনা করে, সেগুলিকে পৃষ্ঠায় স্ট্যাম্পিং করে এবং একটি মডেলের সাথে তাদের বৈশিষ্ট্যগুলি আবদ্ধ করে৷
উদাহরণ <howto-checkbox> উপাদান। আরও ব্যাখ্যা করা হয়েছে বৈশিষ্ট্যগুলিকে অলস করুন

স্ব-প্রয়োগ ক্লাস করবেন না।

কেন? যে উপাদানগুলিকে তাদের অবস্থা প্রকাশ করতে হবে তাদের বৈশিষ্ট্যগুলি ব্যবহার করে তা করা উচিত। class অ্যাট্রিবিউটটি সাধারণত আপনার উপাদান ব্যবহার করে বিকাশকারীর মালিকানাধীন বলে মনে করা হয় এবং এটি নিজে লিখলে অসাবধানতাবশত বিকাশকারী ক্লাসে স্টপ হতে পারে।

ঘটনা

অভ্যন্তরীণ উপাদান কার্যকলাপ প্রতিক্রিয়া ইভেন্ট প্রেরণ.

কেন? আপনার উপাদানের এমন বৈশিষ্ট্য থাকতে পারে যা কার্যকলাপের প্রতিক্রিয়ায় পরিবর্তিত হয় যেগুলি সম্পর্কে শুধুমাত্র আপনার উপাদান জানে, উদাহরণস্বরূপ, যদি একটি টাইমার বা অ্যানিমেশন সম্পূর্ণ হয়, বা একটি সংস্থান লোডিং শেষ হয়। হোস্টকে অবহিত করতে এই পরিবর্তনগুলির প্রতিক্রিয়া হিসাবে ইভেন্টগুলি প্রেরণ করা সহায়ক যে উপাদানটির অবস্থা আলাদা।

হোস্ট সেটিং একটি সম্পত্তি (নিম্নমুখী তথ্য প্রবাহ) প্রতিক্রিয়া হিসাবে ঘটনা প্রেরণ করবেন না.

কেন? হোস্টের প্রপার্টি সেট করার প্রতিক্রিয়া হিসাবে একটি ইভেন্ট প্রেরণ করা অপ্রয়োজনীয় (হোস্ট বর্তমান অবস্থা জানে কারণ এটি কেবল এটি সেট করেছে)। হোস্ট সেটিংয়ের প্রতিক্রিয়া হিসাবে ইভেন্টগুলি প্রেরণের ফলে ডেটা বাইন্ডিং সিস্টেমের সাথে অসীম লুপ হতে পারে।
উদাহরণ <howto-checkbox> উপাদান।

ব্যাখ্যাকারী

পৃষ্ঠার লেখককে ওভাররাইড করবেন না

এটা সম্ভব যে আপনার উপাদান ব্যবহার করে একজন বিকাশকারী তার প্রাথমিক অবস্থার কিছু ওভাররাইড করতে চাইতে পারে। উদাহরণস্বরূপ, tabindex সাথে এর ARIA role বা ফোকাসযোগ্যতা পরিবর্তন করা। আপনার নিজস্ব মান প্রয়োগ করার আগে এইগুলি এবং অন্য কোন বৈশ্বিক বৈশিষ্ট্যগুলি সেট করা হয়েছে কিনা তা পরীক্ষা করে দেখুন।

connectedCallback() {
  if (!this.hasAttribute('role'))
    this.setAttribute('role', 'checkbox');
  if (!this.hasAttribute('tabindex'))
    this.setAttribute('tabindex', 0);

বৈশিষ্ট্য অলস করা

একজন বিকাশকারী আপনার উপাদানটির সংজ্ঞা লোড হওয়ার আগে একটি সম্পত্তি সেট করার চেষ্টা করতে পারে। এটি বিশেষভাবে সত্য যদি বিকাশকারী এমন একটি কাঠামো ব্যবহার করে যা লোডিং উপাদানগুলি পরিচালনা করে, সেগুলিকে পৃষ্ঠায় সন্নিবেশ করায় এবং একটি মডেলের সাথে তাদের বৈশিষ্ট্যগুলি আবদ্ধ করে৷

নিম্নলিখিত উদাহরণে, Angular ঘোষণামূলকভাবে তার মডেলের isChecked প্রপার্টি চেকবক্সের checked সম্পত্তির সাথে আবদ্ধ করছে। Howto-checkbox-এর সংজ্ঞাটি অলসভাবে লোড করা হলে, উপাদানটি আপগ্রেড হওয়ার আগে Angular চেক করা সম্পত্তি সেট করার চেষ্টা করতে পারে।

<howto-checkbox [checked]="defaults.isChecked"></howto-checkbox>

একটি কাস্টম উপাদান এর উদাহরণে ইতিমধ্যে কোনো বৈশিষ্ট্য সেট করা আছে কিনা তা পরীক্ষা করে এই দৃশ্যটি পরিচালনা করা উচিত। <howto-checkbox> _upgradeProperty() নামক একটি পদ্ধতি ব্যবহার করে এই প্যাটার্নটি প্রদর্শন করে।

connectedCallback() {
  ...
  this._upgradeProperty('checked');
}

_upgradeProperty(prop) {
  if (this.hasOwnProperty(prop)) {
    let value = this[prop];
    delete this[prop];
    this[prop] = value;
  }
}

_upgradeProperty() আপগ্রেড না করা ইন্সট্যান্স থেকে মান ক্যাপচার করে এবং প্রপার্টি মুছে দেয় যাতে এটি কাস্টম এলিমেন্টের নিজস্ব প্রপার্টি সেটারের ছায়া না দেয়। এইভাবে, যখন উপাদানটির সংজ্ঞা অবশেষে লোড হয়, এটি অবিলম্বে সঠিক অবস্থা প্রতিফলিত করতে পারে।

পুনরায় প্রবেশের সমস্যা এড়িয়ে চলুন

একটি অন্তর্নিহিত সম্পত্তিতে রাষ্ট্র প্রতিফলিত করার জন্য attributeChangedCallback() ব্যবহার করা প্রলুব্ধকর, উদাহরণস্বরূপ:

// When the [checked] attribute changes, set the checked property to match.
attributeChangedCallback(name, oldValue, newValue) {
  if (name === 'checked')
    this.checked = newValue;
}

কিন্তু এটি একটি অসীম লুপ তৈরি করতে পারে যদি প্রপার্টি সেটারও অ্যাট্রিবিউটে প্রতিফলিত হয়।

set checked(value) {
  const isChecked = Boolean(value);
  if (isChecked)
    // OOPS! This will cause an infinite loop because it triggers the
    // attributeChangedCallback() which then sets this property again.
    this.setAttribute('checked', '');
  else
    this.removeAttribute('checked');
}

একটি বিকল্প হল প্রপার্টি সেটারকে অ্যাট্রিবিউটে প্রতিফলিত করার অনুমতি দেওয়া এবং গেটারকে অ্যাট্রিবিউটের উপর ভিত্তি করে এর মান নির্ধারণ করা।

set checked(value) {
  const isChecked = Boolean(value);
  if (isChecked)
    this.setAttribute('checked', '');
  else
    this.removeAttribute('checked');
}

get checked() {
  return this.hasAttribute('checked');
}

এই উদাহরণে, অ্যাট্রিবিউট যোগ করা বা অপসারণ করাও প্রপার্টি সেট করবে।

অবশেষে, attributeChangedCallback() এআরআইএ স্টেট প্রয়োগ করার মতো পার্শ্ব প্রতিক্রিয়াগুলি পরিচালনা করতে ব্যবহার করা যেতে পারে।

attributeChangedCallback(name, oldValue, newValue) {
  const hasValue = newValue !== null;
  switch (name) {
    case 'checked':
      // Note the attributeChangedCallback is only handling the *side effects*
      // of setting the attribute.
      this.setAttribute('aria-checked', hasValue);
      break;
    ...
  }
}