Checkbox.svelte 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. <script>
  2. import { getContext } from 'svelte';
  3. import Icon from '../icon/Icon.svelte';
  4. /** @typedef {import('../../index.d').Checkbox} CheckboxProps */
  5. /** @type {CheckboxProps} */
  6. let { name = '', checkeds = [], outControl = false, textPosition = 'r', icon = 'default', iconChecked = 'default', children } = $props();
  7. // 父组件传过来的选定值
  8. // Selected value passed from parent component
  9. const STDF_checkboxCheckedsStore = getContext('STDF_checkboxCheckedsContext');
  10. // 设定当前选定值
  11. // Set current selected value
  12. STDF_checkboxCheckedsStore.set(checkeds);
  13. // 当前选定值
  14. // Current selected value
  15. let currentChecked = $derived(outControl ? checkeds.includes(name) : $STDF_checkboxCheckedsStore.includes(name));
  16. // 父组件传过来的排列方式
  17. // Layout type passed from parent component
  18. const STDF_checkboxLayoutStore = getContext('STDF_checkboxLayoutContext');
  19. // 点击选项事件
  20. // Click option event
  21. const clickRadioFun = () => {
  22. outControl && STDF_checkboxCheckedsStore.set([...checkeds]);
  23. if ($STDF_checkboxCheckedsStore.includes(name)) {
  24. const currentCheckeds = $STDF_checkboxCheckedsStore;
  25. currentCheckeds.splice(
  26. currentCheckeds.findIndex(item => item === name),
  27. 1,
  28. );
  29. STDF_checkboxCheckedsStore.set(currentCheckeds);
  30. } else {
  31. STDF_checkboxCheckedsStore.update(olds => [...olds, name]);
  32. }
  33. };
  34. </script>
  35. <!-- svelte-ignore a11y_click_events_have_key_events -->
  36. <!-- svelte-ignore a11y_no_static_element_interactions -->
  37. <div
  38. class={`${$STDF_checkboxLayoutStore === 'inline' ? 'inline-block' : 'flex'} grow active:opacity-80 ${
  39. textPosition === 'l' && $STDF_checkboxLayoutStore != 'v' ? 'justify-between' : ''
  40. } ${
  41. textPosition === 'b' || textPosition === 't'
  42. ? 'flex-col items-center'
  43. : $STDF_checkboxLayoutStore === 'h'
  44. ? 'justify-center'
  45. : 'items-center'
  46. }`}
  47. onclick={clickRadioFun}
  48. >
  49. {#if textPosition === 'l' || textPosition === 't'}
  50. <div class={`${textPosition === 'l' && icon !== 'none' ? 'mr-0.5' : ''} ${$STDF_checkboxLayoutStore === 'v' ? 'grow' : ''}`}>
  51. {@render children?.()}
  52. </div>
  53. {/if}
  54. <div class:hidden={!currentChecked}>
  55. {#if iconChecked === 'none'}
  56. <!-- none -->
  57. {:else if iconChecked === 'default'}
  58. <Icon name="ri-checkbox-fill" theme top={textPosition === 't' || textPosition === 'b' ? 0 : -1} />
  59. {:else}
  60. <Icon {...iconChecked} theme />
  61. {/if}
  62. </div>
  63. <div class:hidden={currentChecked}>
  64. {#if icon === 'none'}
  65. <!-- none -->
  66. {:else if icon === 'default'}
  67. <Icon name="ri-checkbox-line" alpha={0.1} top={textPosition === 't' || textPosition === 'b' ? 0 : -1} />
  68. {:else}
  69. <Icon alpha={0.1} {...icon} />
  70. {/if}
  71. </div>
  72. {#if textPosition === 'r' || textPosition === 'b'}
  73. <div class={`${textPosition === 'r' && icon !== 'none' ? 'ml-0.5' : ''} ${$STDF_checkboxLayoutStore === 'v' ? 'grow' : ''}`}>
  74. {@render children?.()}
  75. </div>
  76. {/if}
  77. </div>