Style.ts 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import { BaseComponent } from '../../types';
  2. import { create, find, isHTMLElement, remove } from '../../utils';
  3. /**
  4. * The interface for the Style component.
  5. *
  6. * @since 3.0.0
  7. */
  8. export interface StyleComponent extends BaseComponent {
  9. rule( selector: string, prop: string, value: string | number ): void;
  10. ruleBy( target: string | HTMLElement, prop: string, value: string | number ): void;
  11. }
  12. /**
  13. * The component for managing styles of the slider.
  14. *
  15. * @since 3.0.0
  16. *
  17. * @return A Style component object.
  18. */
  19. export function Style(): StyleComponent {
  20. /**
  21. * The style element for the slider.
  22. */
  23. let style: HTMLStyleElement;
  24. /**
  25. * The CSSStyleSheet object of the created style element.
  26. */
  27. let sheet: CSSStyleSheet;
  28. /**
  29. * Called when the component is mounted.
  30. */
  31. function mount(): void {
  32. style = create( 'style', {}, document.head );
  33. sheet = style.sheet;
  34. }
  35. /**
  36. * Destroys the component.
  37. */
  38. function destroy(): void {
  39. remove( style );
  40. sheet = null;
  41. }
  42. /**
  43. * Registers the style for the selector.
  44. *
  45. * @param selector - A selector string.
  46. * @param prop - A CSS property, accepting the camel case.
  47. * @param value - A CSS value.
  48. */
  49. function rule( selector: string, prop: string, value: string | number ): void {
  50. const { cssRules } = sheet;
  51. const cssRule = find( cssRules, cssRule => isCSSStyleRule( cssRule ) && cssRule.selectorText === selector )
  52. || cssRules[ sheet.insertRule( `${ selector }{}`, 0 ) ];
  53. if ( isCSSStyleRule( cssRule ) ) {
  54. const { style } = cssRule;
  55. value = `${ value }`;
  56. if ( style[ prop ] !== value ) {
  57. style[ prop ] = value;
  58. }
  59. }
  60. }
  61. /**
  62. * Registers the style by the element or the ID.
  63. *
  64. * @param target - A target element or ID.
  65. * @param prop - A CSS property, accepting the camel case.
  66. * @param value - A CSS value.
  67. */
  68. function ruleBy( target: string | HTMLElement, prop: string, value: string | number ): void {
  69. rule( `#${ isHTMLElement( target ) ? target.id : target }`, prop, value );
  70. }
  71. /**
  72. * Checks if the provided rule is a CSSStyleRule instance or not.
  73. *
  74. * @param cssRule - An instance to check.
  75. *
  76. * @return `true` if the cssRule is an instance of CSSStyleRule, or otherwise `false`.
  77. */
  78. function isCSSStyleRule( cssRule: CSSRule ): cssRule is CSSStyleRule {
  79. return cssRule instanceof CSSStyleRule;
  80. }
  81. return {
  82. mount,
  83. destroy,
  84. rule,
  85. ruleBy,
  86. };
  87. }