Dialog.svelte 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. <script>
  2. import { getContext } from 'svelte';
  3. import Popup from '../popup/Popup.svelte';
  4. import Button from '../button/Button.svelte';
  5. import Icon from '../icon/Icon.svelte';
  6. import zh_CN from '../../lang/zh_CN';
  7. // 当前语言
  8. // current language
  9. const currentLang = getContext('STDF_lang') || zh_CN;
  10. const dialogLang = currentLang.dialog;
  11. /** @typedef {import('../../index.d').Dialog} DialogProps */
  12. /** @type {DialogProps} */
  13. let {
  14. visible = $bindable(false),
  15. title = dialogLang.title,
  16. titleAlign = 'center',
  17. content = dialogLang.content,
  18. popup = {},
  19. showIcon = false,
  20. icon = {},
  21. btnStyle = 'button',
  22. primaryText = dialogLang.primaryText,
  23. primaryButton = {},
  24. secondaryText = dialogLang.secondaryText,
  25. secondaryButton = {},
  26. btnRatio = [1, 1],
  27. btnReverse = false,
  28. secondaryClose = true,
  29. btnGap = '2',
  30. onsecondary,
  31. onprimary,
  32. onclose,
  33. contentChild,
  34. primaryChild,
  35. } = $props();
  36. // 标题对齐方式
  37. // Title alignment
  38. const titleAlignClass = { left: ' text-left', center: ' text-center', right: ' text-right' };
  39. // 按钮间距
  40. // Button spacing
  41. const btnGapClass = { '0': '', '1': ' gap-1', '2': ' gap-2', '4': ' gap-4', '8': ' gap-8', '12': ' gap-12', '16': ' gap-16' };
  42. </script>
  43. <Popup
  44. bind:visible
  45. size={0}
  46. maskClosable={false}
  47. duration={300}
  48. outDuration={150}
  49. position="center"
  50. radiusPosition="all"
  51. radius="lg"
  52. px="4"
  53. {...popup}
  54. >
  55. <div class="px-4 pt-4{btnStyle === 'button' ? ' pb-2' : ''} text-center space-y-4">
  56. <div class="font-bold{titleAlignClass[titleAlign] || titleAlignClass['center']}">{title}</div>
  57. {#if showIcon}
  58. <div><Icon {...icon} /></div>
  59. {/if}
  60. <div>
  61. {#if contentChild}
  62. {@render contentChild?.()}
  63. {:else}
  64. {content}
  65. {/if}
  66. </div>
  67. <div
  68. class="flex w-full{btnGapClass[btnGap] || btnGapClass['2']}{btnReverse ? ' flex-row-reverse' : ''}{btnStyle === 'textLine'
  69. ? ' border-t border-black/10 dark:border-white/10'
  70. : ''}"
  71. >
  72. <div class={btnStyle === 'textLine' && !btnReverse ? 'border-r border-black/10 dark:border-white/10' : ''} style="flex:{btnRatio[1]}">
  73. <Button
  74. size="full"
  75. fill={btnStyle === 'button' ? 'colorLight' : 'text'}
  76. heightIn={btnStyle === 'button' ? '3' : '2'}
  77. injClass={btnStyle === 'button' ? '' : 'font-bold'}
  78. {...secondaryButton}
  79. onclick={() => {
  80. if (secondaryClose) {
  81. visible = false;
  82. onclose && onclose();
  83. }
  84. onsecondary && onsecondary();
  85. }}
  86. >
  87. {secondaryText}
  88. </Button>
  89. </div>
  90. <div class={btnStyle === 'textLine' && btnReverse ? 'border-r border-black/10 dark:border-white/10' : ''} style="flex:{btnRatio[0]}">
  91. <Button
  92. size="full"
  93. fill={btnStyle === 'button' ? 'base' : 'textTheme'}
  94. heightIn={btnStyle === 'button' ? '3' : '2'}
  95. injClass={btnStyle === 'button' ? '' : 'font-bold'}
  96. {...primaryButton}
  97. onclick={() => onprimary && onprimary()}
  98. >
  99. {#if primaryChild}
  100. {@render primaryChild?.()}
  101. {:else}
  102. {primaryText}
  103. {/if}
  104. </Button>
  105. </div>
  106. </div>
  107. </div>
  108. </Popup>