@designbasekorea/ui-wc 0.5.3 → 0.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/lottie-e273b936.js +17032 -0
- package/dist/esm/components/animation-background/canvas-controller.js +121 -1
- package/dist/esm/components/animation-background/controls.js +180 -1
- package/dist/esm/components/animation-background/graphite-controller.js +196 -1
- package/dist/esm/components/animation-background/graphite-presets.js +42 -1
- package/dist/esm/components/animation-background/graphite-shader.js +111 -1
- package/dist/esm/components/animation-background/layers.js +369 -1
- package/dist/esm/components/animation-background/lumina-presets.js +53 -1
- package/dist/esm/components/animation-background/lumina-shaders.js +181 -1
- package/dist/esm/components/animation-background/lumina-utils.js +60 -1
- package/dist/esm/components/animation-background/particle-defaults.js +36 -1
- package/dist/esm/components/animation-background/renderers.js +167 -1
- package/dist/esm/components/animation-background/shader-controller.js +154 -1
- package/dist/esm/components/color-picker-utils.js +134 -1
- package/dist/esm/components/date-picker-utils.js +140 -1
- package/dist/esm/components/db-accordion.js +304 -1
- package/dist/esm/components/db-ad-banner.js +455 -1
- package/dist/esm/components/db-alert.js +149 -1
- package/dist/esm/components/db-animation-background.js +486 -1
- package/dist/esm/components/db-animation-text.js +601 -1
- package/dist/esm/components/db-app-badge.js +88 -1
- package/dist/esm/components/db-audio-player.js +752 -1
- package/dist/esm/components/db-avatar.js +188 -1
- package/dist/esm/components/db-backdrop.js +139 -1
- package/dist/esm/components/db-badge.js +91 -1
- package/dist/esm/components/db-banner.js +188 -1
- package/dist/esm/components/db-bottom-navigation.js +146 -1
- package/dist/esm/components/db-bottom-sheet.js +481 -1
- package/dist/esm/components/db-breadcrumbs.js +329 -1
- package/dist/esm/components/db-button.js +316 -1
- package/dist/esm/components/db-calendar.js +675 -1
- package/dist/esm/components/db-card.js +265 -1
- package/dist/esm/components/db-carousel.js +264 -1
- package/dist/esm/components/db-checkbox.js +202 -1
- package/dist/esm/components/db-chip.js +104 -1
- package/dist/esm/components/db-code-block.js +304 -1
- package/dist/esm/components/db-color-picker.js +746 -1
- package/dist/esm/components/db-confirm.js +191 -1
- package/dist/esm/components/db-container.js +39 -1
- package/dist/esm/components/db-context-menu.js +265 -1
- package/dist/esm/components/db-countdown.js +146 -1
- package/dist/esm/components/db-cursor-follower.js +173 -1
- package/dist/esm/components/db-date-picker.js +837 -1
- package/dist/esm/components/db-divider.js +66 -1
- package/dist/esm/components/db-drawer.js +245 -1
- package/dist/esm/components/db-dropdown.js +493 -1
- package/dist/esm/components/db-dropzone.js +266 -1
- package/dist/esm/components/db-empty-state.js +97 -1
- package/dist/esm/components/db-file-uploader.js +256 -1
- package/dist/esm/components/db-floating-action-button.js +139 -1
- package/dist/esm/components/db-footer.js +385 -1
- package/dist/esm/components/db-form.js +566 -1
- package/dist/esm/components/db-gantt.js +882 -1
- package/dist/esm/components/db-gradient.js +133 -1
- package/dist/esm/components/db-grid-background.js +909 -1
- package/dist/esm/components/db-grid.js +73 -1
- package/dist/esm/components/db-icons.js +82 -1
- package/dist/esm/components/db-image-list.js +214 -1
- package/dist/esm/components/db-image-placeholder.js +96 -1
- package/dist/esm/components/db-image.js +289 -1
- package/dist/esm/components/db-indicator.js +517 -1
- package/dist/esm/components/db-input.js +420 -1
- package/dist/esm/components/db-kanban.js +538 -1
- package/dist/esm/components/db-label.js +66 -1
- package/dist/esm/components/db-lightbox.js +372 -1
- package/dist/esm/components/db-list.js +340 -1
- package/dist/esm/components/db-logo-svg.js +72 -1
- package/dist/esm/components/db-logo.js +106 -1
- package/dist/esm/components/db-lottie.js +109 -1
- package/dist/esm/components/db-markdown-editor.js +458 -1
- package/dist/esm/components/db-marquee.js +402 -1
- package/dist/esm/components/db-masonry.js +94 -1
- package/dist/esm/components/db-menu-item.js +211 -1
- package/dist/esm/components/db-modal.js +522 -1
- package/dist/esm/components/db-navbar.js +680 -1
- package/dist/esm/components/db-onboarding-modal.js +322 -1
- package/dist/esm/components/db-page-header.js +312 -1
- package/dist/esm/components/db-pagination.js +271 -1
- package/dist/esm/components/db-popover.js +580 -1
- package/dist/esm/components/db-progress-step.js +166 -1
- package/dist/esm/components/db-progress.js +171 -1
- package/dist/esm/components/db-progressbar.js +72 -1
- package/dist/esm/components/db-radio.js +172 -1
- package/dist/esm/components/db-random-gradient.js +121 -1
- package/dist/esm/components/db-range-slider.js +811 -1
- package/dist/esm/components/db-rating.js +325 -1
- package/dist/esm/components/db-reorder.js +286 -1
- package/dist/esm/components/db-resizable-panels.js +282 -1
- package/dist/esm/components/db-scroll-area.js +126 -1
- package/dist/esm/components/db-search-bar.js +668 -1
- package/dist/esm/components/db-section-app-download.js +101 -1
- package/dist/esm/components/db-section-contact.js +102 -1
- package/dist/esm/components/db-section-cta.js +150 -1
- package/dist/esm/components/db-section-faq.js +120 -1
- package/dist/esm/components/db-section-feature-grid.js +137 -1
- package/dist/esm/components/db-section-feature.js +179 -1
- package/dist/esm/components/db-section-hero.js +243 -1
- package/dist/esm/components/db-section-logo-cloud.js +138 -1
- package/dist/esm/components/db-section-pricing.js +166 -1
- package/dist/esm/components/db-section-stats.js +129 -1
- package/dist/esm/components/db-section-testimonials.js +252 -1
- package/dist/esm/components/db-section.js +385 -1
- package/dist/esm/components/db-segment-control.js +231 -1
- package/dist/esm/components/db-select.js +571 -1
- package/dist/esm/components/db-share-icons.js +40 -1
- package/dist/esm/components/db-share.js +489 -1
- package/dist/esm/components/db-sidebar.js +1068 -1
- package/dist/esm/components/db-skeleton.js +94 -1
- package/dist/esm/components/db-spinner.js +102 -1
- package/dist/esm/components/db-split-view.js +297 -1
- package/dist/esm/components/db-stack.js +46 -1
- package/dist/esm/components/db-stat.js +218 -1
- package/dist/esm/components/db-stepper.js +398 -1
- package/dist/esm/components/db-table.js +412 -1
- package/dist/esm/components/db-tabs.js +335 -1
- package/dist/esm/components/db-testimonial.js +162 -1
- package/dist/esm/components/db-textarea.js +233 -1
- package/dist/esm/components/db-time-picker.js +523 -1
- package/dist/esm/components/db-timeline.js +174 -1
- package/dist/esm/components/db-toast.js +158 -1
- package/dist/esm/components/db-toggle.js +162 -1
- package/dist/esm/components/db-toolbar.js +94 -1
- package/dist/esm/components/db-tooltip.js +440 -1
- package/dist/esm/components/db-top-banner.js +121 -1
- package/dist/esm/components/db-tutorial.js +324 -1
- package/dist/esm/components/db-video-player.js +503 -1
- package/dist/esm/components/db-youtube-player.js +194 -1
- package/dist/esm/components/highlight-code.js +65 -1
- package/dist/esm/components/input-validation.js +50 -1
- package/dist/esm/components/marketing-block-host-utils.js +9 -1
- package/dist/esm/components/number-scrub.js +117 -1
- package/dist/esm/components/random-gradient-palettes.js +67 -1
- package/dist/esm/components/section-block-header-utils.js +48 -1
- package/dist/esm/helpers/confirm.js +52 -1
- package/dist/esm/helpers/toast.js +73 -1
- package/dist/esm/index.js +111 -1
- package/dist/esm/node_modules/prismjs/components/prism-bash.js +235 -1
- package/dist/esm/node_modules/prismjs/components/prism-clike.js +31 -1
- package/dist/esm/node_modules/prismjs/components/prism-css.js +64 -1
- package/dist/esm/node_modules/prismjs/components/prism-javascript.js +172 -1
- package/dist/esm/node_modules/prismjs/components/prism-json.js +27 -1
- package/dist/esm/node_modules/prismjs/components/prism-jsx.js +143 -1
- package/dist/esm/node_modules/prismjs/components/prism-markup.js +186 -1
- package/dist/esm/node_modules/prismjs/components/prism-scss.js +81 -1
- package/dist/esm/node_modules/prismjs/components/prism-tsx.js +15 -1
- package/dist/esm/node_modules/prismjs/components/prism-typescript.js +60 -1
- package/dist/index.cjs +55414 -1
- package/dist/index.css +1 -1
- package/dist/index.esm.js +38284 -1
- package/dist/react/chunks/lottie-72a4c6d4.js +17032 -0
- package/dist/react/index.cjs +56503 -1
- package/dist/react/index.d.ts +1 -1
- package/dist/react/index.esm.js +39373 -1
- package/package.json +1 -1
- package/dist/chunks/lottie-2d1f6278.js +0 -1
- package/dist/react/chunks/lottie-14e7addb.js +0 -1
|
@@ -1 +1,40 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* SVG paths synced from @designbasekorea/icons (packages/icons)
|
|
3
|
+
*/
|
|
4
|
+
const SHARE_ICON_PATHS = {
|
|
5
|
+
facebook: '<path fill="currentColor" d="M2.002 12.001c0 4.99 3.656 9.126 8.437 9.879v-6.988h-2.54v-2.891h2.54V9.798c0-2.508 1.493-3.891 3.776-3.891q1.095 0 2.24.195V8.56h-1.264c-1.24 0-1.628.772-1.628 1.563v1.875h2.771l-.443 2.891h-2.328v6.988C18.344 21.129 22 16.992 22 12.001c0-5.522-4.477-10-9.999-10-5.522.001-10 4.478-10 10"/>',
|
|
6
|
+
x: '<path fill="currentColor" d="M17.801 3h3.066l-6.731 7.638L22 21h-6.171l-4.832-6.297L5.466 21H2.4l7.13-8.17L2 3h6.325l4.365 5.752zm-1.073 16.207h1.7L7.432 4.727H5.605z"/>',
|
|
7
|
+
instagram: '<path fill="currentColor" fill-rule="evenodd" d="M7.376 12a4.623 4.623 0 1 0 9.246.002A4.623 4.623 0 0 0 7.376 12m1.619 0a3.003 3.003 0 1 1 6.007.001 3.003 3.003 0 0 1-6.007 0m8.889-4.793a1.078 1.078 0 1 0-2.156 0 1.078 1.078 0 0 0 2.156 0m.016-3.728a6.6 6.6 0 0 0-2.186-.42c-.963-.042-1.268-.054-3.71-.054s-2.755 0-3.71.054a6.6 6.6 0 0 0-2.184.42A4.6 4.6 0 0 0 3.477 6.11a6.6 6.6 0 0 0-.419 2.186c-.043.962-.056 1.267-.056 3.71s0 2.753.056 3.71c.015.748.156 1.486.419 2.187a4.6 4.6 0 0 0 2.634 2.632 6.6 6.6 0 0 0 2.185.45c.963.042 1.268.055 3.71.055s2.755 0 3.71-.055a6.6 6.6 0 0 0 2.186-.42 4.61 4.61 0 0 0 2.633-2.632c.263-.7.404-1.438.419-2.186.043-.962.056-1.267.056-3.71s0-2.753-.056-3.71a6.6 6.6 0 0 0-.421-2.217A4.6 4.6 0 0 0 17.9 3.479m1.104 13.852a2.99 2.99 0 0 1-1.712 1.71 5 5 0 0 1-1.67.312c-.95.044-1.218.055-3.654.055-2.438 0-2.687 0-3.655-.055a5 5 0 0 1-1.67-.311 2.99 2.99 0 0 1-1.718-1.711 5.1 5.1 0 0 1-.311-1.67c-.043-.95-.053-1.217-.053-3.653s0-2.686.053-3.655a5 5 0 0 1 .311-1.687c.305-.79.93-1.41 1.719-1.712a5 5 0 0 1 1.669-.311c.95-.043 1.218-.055 3.655-.055s2.687 0 3.654.055a5 5 0 0 1 1.67.31 3 3 0 0 1 1.712 1.713 5.1 5.1 0 0 1 .311 1.669c.043.95.054 1.218.054 3.655s0 2.698-.043 3.654h-.011v-.001a5 5 0 0 1-.311 1.688" clip-rule="evenodd"/>',
|
|
8
|
+
linkedin: '<path fill="currentColor" fill-rule="evenodd" d="M17 21v-6.75c0-1.059-1.188-1.944-2.246-1.944-1.06 0-1.754.885-1.754 1.944V21H9V9h4v2c.662-1.071 2.356-1.763 3.525-1.763C18.997 9.237 21 11.28 21 13.75V21zM3 21V9h4v12zM7 5a2 2 0 1 1-4 0 2 2 0 0 1 4 0" clip-rule="evenodd"/>',
|
|
9
|
+
youtube: '<path fill="currentColor" d="M23.498 6.186a3.02 3.02 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.02 3.02 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.02 3.02 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.02 3.02 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814M9.545 15.568V8.432L15.818 12z"/>',
|
|
10
|
+
pinterest: '<path fill="currentColor" d="M12 2C6.474 2 2 6.478 2 12.008a10 10 0 0 0 6.351 9.316c-.09-.797-.165-1.999.03-2.87.18-.782 1.172-4.974 1.172-4.974s-.3-.601-.3-1.488c0-1.397.81-2.434 1.801-2.434.856 0 1.261.646 1.261 1.413 0 .856-.54 2.149-.825 3.335-.24.992.495 1.804 1.486 1.804 1.772 0 3.138-1.879 3.138-4.583 0-2.39-1.727-4.072-4.174-4.072-2.838 0-4.52 2.133-4.52 4.342 0 .857.33 1.788.751 2.284.075.105.09.18.075.286-.075.315-.24.991-.27 1.127-.045.18-.15.225-.33.135-1.247-.586-2.027-2.404-2.027-3.877 0-3.155 2.297-6.056 6.606-6.056 3.469 0 6.156 2.48 6.156 5.77 0 3.442-2.177 6.222-5.18 6.222-1.006 0-1.967-.526-2.297-1.142l-.616 2.374c-.225.871-.84 1.953-1.246 2.63.931.285 1.922.45 2.958.45 5.526 0 10-4.478 10-10.007C22 6.478 17.526 2 12 2"/>',
|
|
11
|
+
whatsapp: '<path fill="currentColor" d="M12.042 2a9.92 9.92 0 0 1 7.044 2.906A9.83 9.83 0 0 1 22 11.918c-.003 5.464-4.47 9.91-9.958 9.91h-.005a10 10 0 0 1-4.758-1.206L2 22l1.413-5.136a9.86 9.86 0 0 1-1.329-4.954C2.086 6.446 6.553 2 12.042 2M8.516 7.333a.92.92 0 0 0-.663.31c-.228.249-.872.848-.872 2.066s.89 2.394 1.016 2.562c.124.165 1.722 2.746 4.251 3.739 2.101.825 2.53.661 2.985.62.457-.041 1.473-.6 1.68-1.178s.208-1.074.146-1.178-.229-.165-.478-.289-1.472-.723-1.7-.805-.394-.124-.56.124-.643.805-.788.97c-.145.166-.29.187-.539.063s-1.05-.386-2-1.23c-.74-.656-1.239-1.466-1.385-1.714s-.015-.383.11-.506c.111-.111.248-.29.373-.434.124-.144.166-.248.249-.413s.04-.31-.022-.434c-.062-.123-.545-1.348-.766-1.838-.187-.413-.383-.422-.56-.43z"/>',
|
|
12
|
+
telegram: '<path fill="currentColor" d="M12 2c5.523 0 10 4.477 10 10s-4.477 10-10 10S2 17.523 2 12 6.477 2 12 2m4.08 6.012c-.375.008-.958.209-3.73 1.366-.975.408-2.915 1.248-5.829 2.514-.466.191-.716.375-.74.558-.042.35.457.458 1.081.657.517.167 1.2.358 1.558.367.325.008.682-.125 1.082-.4 2.72-1.838 4.118-2.77 4.213-2.789.066-.017.15-.033.208.017s.059.15.05.175c-.05.208-2.604 2.537-2.755 2.689-.566.583-1.208.94-.217 1.59.858.566 1.349.924 2.231 1.499.558.366 1 .799 1.583.749.266-.025.54-.275.682-1.024.333-1.765.982-5.603 1.132-7.185.017-.133 0-.308-.017-.392a.44.44 0 0 0-.141-.274c-.125-.1-.308-.117-.39-.117"/>',
|
|
13
|
+
mail: '<path fill="currentColor" fill-rule="evenodd" d="m1.665 8.67.67-1.34L12 12.161l9.665-4.833.67 1.342L12 13.839z" clip-rule="evenodd"/><path fill="currentColor" fill-rule="evenodd" d="M4 5.75c-.69 0-1.25.56-1.25 1.25v10c0 .69.56 1.25 1.25 1.25h16c.69 0 1.25-.56 1.25-1.25V7c0-.69-.56-1.25-1.25-1.25zM1.25 7A2.75 2.75 0 0 1 4 4.25h16A2.75 2.75 0 0 1 22.75 7v10A2.75 2.75 0 0 1 20 19.75H4A2.75 2.75 0 0 1 1.25 17z" clip-rule="evenodd"/>',
|
|
14
|
+
link: '<path fill="currentColor" fill-rule="evenodd" d="m15.344 9.698-5.657 5.657-1.06-1.06 5.657-5.657z" clip-rule="evenodd"/><path fill="currentColor" fill-rule="evenodd" d="M17.819 6.163a4.25 4.25 0 0 0-6.01 0l-1.415 1.414-1.06-1.06 1.414-1.414a5.75 5.75 0 0 1 8.132 8.132l-1.416 1.414-1.06-1.062 1.415-1.413a4.25 4.25 0 0 0 0-6.01M6.154 11.818l1.412-1.412-.53-.531-.53-.53-1.414 1.414-.003.003c-2.22 2.244-2.211 5.86.029 8.075 2.245 2.22 5.824 2.31 8.102.056l.003-.003 1.414-1.414-1.06-1.06-1.412 1.41v.002c-1.67 1.65-4.308 1.608-5.993-.057-1.645-1.627-1.659-4.293-.018-5.953" clip-rule="evenodd"/>',
|
|
15
|
+
copy: '<path fill="currentColor" fill-rule="evenodd" d="M8 3.75a.25.25 0 0 0-.25.25v12c0 .138.112.25.25.25h12a.25.25 0 0 0 .25-.25V4a.25.25 0 0 0-.25-.25zM6.25 4c0-.966.784-1.75 1.75-1.75h12c.966 0 1.75.784 1.75 1.75v12A1.75 1.75 0 0 1 20 17.75H8A1.75 1.75 0 0 1 6.25 16z" clip-rule="evenodd"/><path fill="currentColor" fill-rule="evenodd" d="M3.75 9v9A2.25 2.25 0 0 0 6 20.25h9v1.5H6A3.75 3.75 0 0 1 2.25 18V9z" clip-rule="evenodd"/>',
|
|
16
|
+
'scan-qrcode': '<path fill="currentColor" d="M2.25 4c0-.964.786-1.75 1.75-1.75h3v1.5H4a.253.253 0 0 0-.25.25v3h-1.5zM20.25 4a.253.253 0 0 0-.25-.25h-3v-1.5h3c.964 0 1.75.786 1.75 1.75v3h-1.5zM20.25 20v-3h1.5v3c0 .964-.786 1.75-1.75 1.75h-3v-1.5h3c.136 0 .25-.114.25-.25M2.25 20v-3h1.5v3c0 .136.114.25.25.25h3v1.5H4c-.964 0-1.75-.786-1.75-1.75M9.5 7.5v2h-2v-2zM11 6H6v5h5zM16.5 7.5v2h-2v-2zM18 6h-5v5h5zM9.5 14.5v2h-2v-2zM11 13H6v5h5zM14.5 16.5H13V18h1.5zM18 15h-1.5v3H18z"/><path fill="currentColor" d="M18 15h-3v1.5h3zM14.5 13H13v1.5h1.5z"/>',
|
|
17
|
+
'share-alt': '<path fill="currentColor" fill-rule="evenodd" d="M13.69 3.317a.75.75 0 0 1 .804.119l8 7a.75.75 0 0 1 0 1.128l-8 7A.75.75 0 0 1 13.25 18v-3.24c-1.925.051-3.579.315-5.062.932-1.659.692-3.157 1.85-4.588 3.758A.75.75 0 0 1 2.25 19c0-4.145 1.147-6.888 3.291-8.698 1.96-1.655 4.655-2.437 7.709-2.943V4a.75.75 0 0 1 .44-.683m1.06 2.336V8a.75.75 0 0 1-.638.742c-3.283.497-5.85 1.225-7.603 2.706-1.359 1.147-2.303 2.812-2.631 5.39 1.153-1.15 2.386-1.969 3.734-2.53 1.928-.804 4.04-1.058 6.388-1.058a.75.75 0 0 1 .75.75v2.347L20.861 11z" clip-rule="evenodd"/>',
|
|
18
|
+
};
|
|
19
|
+
const PLATFORM_ICON_MAP = {
|
|
20
|
+
facebook: 'facebook',
|
|
21
|
+
x: 'x',
|
|
22
|
+
instagram: 'instagram',
|
|
23
|
+
linkedin: 'linkedin',
|
|
24
|
+
pinterest: 'pinterest',
|
|
25
|
+
whatsapp: 'whatsapp',
|
|
26
|
+
telegram: 'telegram',
|
|
27
|
+
email: 'mail',
|
|
28
|
+
link: 'link',
|
|
29
|
+
qr: 'scan-qrcode',
|
|
30
|
+
};
|
|
31
|
+
function createShareIcon(name, size = 24) {
|
|
32
|
+
const template = document.createElement('template');
|
|
33
|
+
template.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="${size}" height="${size}" aria-hidden="true" focusable="false" data-designbase-icon="${name}">${SHARE_ICON_PATHS[name]}</svg>`;
|
|
34
|
+
return template.content.firstElementChild;
|
|
35
|
+
}
|
|
36
|
+
function createSharePlatformIcon(platform, size = 24) {
|
|
37
|
+
return createShareIcon(PLATFORM_ICON_MAP[platform], size);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export { createShareIcon, createSharePlatformIcon };
|
|
@@ -1 +1,489 @@
|
|
|
1
|
-
import{createShareIcon as t,createSharePlatformIcon as e}from"./db-share-icons.js";const s=["facebook","x","linkedin","whatsapp","email","link"],n={facebook:{name:"Facebook",color:"#1877f2",shareUrl:"https://www.facebook.com/sharer/sharer.php?u={url}"},x:{name:"X",color:"#000000",shareUrl:"https://twitter.com/intent/tweet?url={url}&text={title}&hashtags={hashtags}"},instagram:{name:"Instagram",color:"#e4405f",shareUrl:"https://www.instagram.com/",customShare:()=>{window.alert("Instagram에 직접 공유하려면 링크를 복사하여 사용하세요.")}},linkedin:{name:"LinkedIn",color:"#0077b5",shareUrl:"https://www.linkedin.com/sharing/share-offsite/?url={url}"},pinterest:{name:"Pinterest",color:"#bd081c",shareUrl:"https://pinterest.com/pin/create/button/?url={url}&description={title}&media={imageUrl}"},whatsapp:{name:"WhatsApp",color:"#25d366",shareUrl:"https://wa.me/?text={title}%20{url}"},telegram:{name:"Telegram",color:"#0088cc",shareUrl:"https://t.me/share/url?url={url}&text={title}"},email:{name:"이메일",color:"#ea4335",shareUrl:"mailto:?subject={title}&body={description}%20{url}"},link:{name:"링크 복사",color:"#6c757d",shareUrl:""},qr:{name:"QR 코드",color:"#6c757d",shareUrl:""}};class DbShare extends HTMLElement{constructor(){super(...arguments),this.isCopied=!1,this.qrCodeData="",this.copyResetTimer=null,this.modalEl=null,this.contentSlot=null,this.dropdownEl=null}static get observedAttributes(){return["url","title","description","image-url","hashtags","variant","size","position","platforms","button-text","modal-title","show-qr-code","qr-code-size","copy-success-message","open"]}connectedCallback(){this.render()}disconnectedCallback(){this.copyResetTimer&&clearTimeout(this.copyResetTimer)}attributeChangedCallback(t){"open"===t&&"modal"===this.getAttribute("variant")&&this.modalEl?this.syncModalOpen():"url"===t&&this.contentSlot?this.refreshLinkInputValue():this.render()}get open(){return this.hasAttribute("open")&&"false"!==this.getAttribute("open")}set open(t){t?this.setAttribute("open","true"):this.removeAttribute("open")}parseListAttribute(t){const e=this.getAttribute(t);if(!e)return[];try{const t=JSON.parse(e);if(Array.isArray(t))return t.map(t=>String(t).trim()).filter(Boolean)}catch{}return e.split(",").map(t=>t.trim()).filter(Boolean)}getResolvedUrl(){const t=this.getAttribute("url");return t||("undefined"!=typeof window&&window.location?.href?window.location.href:"")}getContext(){return{url:this.getResolvedUrl(),title:this.getAttribute("share-title")||this.getAttribute("title")||"",description:this.getAttribute("description")||"",imageUrl:this.getAttribute("image-url")||"",hashtags:this.parseListAttribute("hashtags"),host:this}}getActivePlatforms(){const t=this.parseListAttribute("platforms");return(t.length>0?t:s).filter(t=>t in n)}replaceUrlVariables(t,e){return t.replace("{url}",encodeURIComponent(e.url)).replace("{title}",encodeURIComponent(e.title)).replace("{description}",encodeURIComponent(e.description)).replace("{imageUrl}",encodeURIComponent(e.imageUrl)).replace("{hashtags}",e.hashtags.join(","))}async handleCopyLink(t){try{await navigator.clipboard.writeText(t.url),this.isCopied=!0,this.dispatchEvent(new CustomEvent("db-copy-success",{bubbles:!0,composed:!0,detail:{url:t.url}})),this.refreshContent(),this.copyResetTimer&&clearTimeout(this.copyResetTimer),this.copyResetTimer=setTimeout(()=>{this.isCopied=!1,this.refreshContent()},3e3)}catch(t){this.dispatchEvent(new CustomEvent("db-copy-error",{bubbles:!0,composed:!0,detail:{error:t}}))}}handleShowQrCode(t){if(this.qrCodeData=t.url,"modal"===this.getAttribute("variant"))return this.open=!0,void this.refreshContent();this.refreshContent()}handlePlatformShare(t){const e=this.getContext(),s=n[t];if(s)try{if("link"===t)this.handleCopyLink(e);else if("qr"===t)this.handleShowQrCode(e);else if(s.customShare)s.customShare(e);else if(s.shareUrl){const t=this.replaceUrlVariables(s.shareUrl,e);window.open(t,"_blank","width=600,height=400")}this.dispatchEvent(new CustomEvent("db-share",{bubbles:!0,composed:!0,detail:{platform:t,url:e.url}}))}catch(e){this.dispatchEvent(new CustomEvent("db-share-error",{bubbles:!0,composed:!0,detail:{platform:t,error:e}}))}}getPlacement(){const t=this.getAttribute("position")||"bottom";return"top"===t||"left"===t?"top-left":"right"===t?"bottom-right":"bottom-left"}mapButtonSize(){const t=this.getAttribute("size")||"m";return"s"===t?"s":"l"===t?"l":"m"}createTriggerButton(e){const s=document.createElement("db-button");return s.className=e||"designbase-wc-share__trigger",s.setAttribute("variant","secondary"),s.setAttribute("size",this.mapButtonSize()),s.textContent=this.getAttribute("button-text")||"공유",s.prepend(t("share-alt",16)),s.addEventListener("db-click",()=>{"modal"!==this.getAttribute("variant")?this.open=!this.open:this.open=!0}),s}createPlatformIcon(t){const s=document.createElement("span");return s.className="designbase-wc-share__platform-icon",s.append(e(t,24)),s}createPlatformButton(e){const s=n[e],r=document.createElement("button");r.type="button",r.className=["designbase-wc-share__platform-button",`designbase-wc-share__platform-button--${e}`,"link"===e&&this.isCopied?"designbase-wc-share__platform-button--copied":""].filter(Boolean).join(" "),r.style.setProperty("--platform-color",s.color),r.title=s.name,r.setAttribute("aria-label",`${s.name}에 공유하기`),r.append(this.createPlatformIcon(e));const a=document.createElement("span");if(a.className="designbase-wc-share__platform-name",a.textContent=s.name,r.append(a),"link"===e&&this.isCopied){const e=document.createElement("span");e.className="designbase-wc-share__copy-success",e.append(t("copy",12));const s=document.createElement("span");s.textContent="복사됨!",e.append(s),r.append(e)}return r.addEventListener("click",()=>this.handlePlatformShare(e)),r}createLinkInput(t){const e=document.createElement("db-input");return e.className="designbase-wc-share__link-input",e.setAttribute("type","text"),e.setAttribute("readonly",""),e.setAttribute("size","s"),e.setAttribute("full-width",""),e.setAttribute("value",t),customElements.whenDefined("db-input").then(()=>{e.setAttribute("value",t),e.value=t}),e}refreshLinkInputValue(){const t=this.getResolvedUrl(),e=this.contentSlot?.querySelector("db-input.designbase-wc-share__link-input");e&&(e.setAttribute("value",t),e.value=t)}createCopyButton(e){const s=document.createElement("db-button");s.className="designbase-wc-share__copy-button",s.setAttribute("size","s"),s.setAttribute("variant","primary");const n=document.createElement("span");return n.className="designbase-wc-button__start-icon",n.setAttribute("aria-hidden","true"),n.append(t(this.isCopied?"copy":"link",16)),s.append(n),s.append(document.createTextNode(this.isCopied?"복사됨!":"복사")),s.addEventListener("db-click",()=>{this.handleCopyLink(e)}),s}generateQrCodeUrl(){const t=Number(this.getAttribute("qr-code-size")||200);return`https://api.qrserver.com/v1/create-qr-code/?size=${t}x${t}&data=${encodeURIComponent(this.qrCodeData)}`}createShareContent(){const t=document.createElement("div");return t.className="designbase-wc-share__content",this.populateShareContent(t),t}populateShareContent(t){const e=document.createElement("div");e.className="designbase-wc-share__platforms",this.getActivePlatforms().forEach(t=>{e.append(this.createPlatformButton(t))}),t.append(e);if("false"!==this.getAttribute("show-qr-code")&&this.qrCodeData){const e=document.createElement("div");e.className="designbase-wc-share__qr-section";const s=document.createElement("h4");s.className="designbase-wc-share__qr-title",s.textContent="QR 코드",e.append(s);const n=document.createElement("div");n.className="designbase-wc-share__qr-code";const r=document.createElement("img"),a=Number(this.getAttribute("qr-code-size")||200);r.src=this.generateQrCodeUrl(),r.alt="QR Code",r.width=a,r.height=a,n.append(r),e.append(n);const i=document.createElement("p");i.className="designbase-wc-share__qr-description",i.textContent="QR 코드를 스캔하여 링크에 접속하세요",e.append(i),t.append(e)}const s=this.getContext(),n=document.createElement("div");n.className="designbase-wc-share__link-preview";const r=document.createElement("h4");r.className="designbase-wc-share__link-title",r.textContent="공유 링크",n.append(r);const a=document.createElement("div");a.className="designbase-wc-share__link-container",a.append(this.createLinkInput(s.url)),a.append(this.createCopyButton(s)),n.append(a),t.append(n)}refreshContent(){const t=this.getAttribute("variant");if("inline"===t){const t=this.querySelector(":scope > .designbase-wc-share__content");return void t?.replaceWith(this.createShareContent())}"modal"===t&&this.contentSlot&&(this.contentSlot.replaceChildren(),this.populateShareContent(this.contentSlot))}syncModalOpen(){this.modalEl&&(this.open?(this.refreshLinkInputValue(),this.modalEl.setAttribute("open","true")):this.modalEl.removeAttribute("open"))}renderDropdown(){const t=document.createElement("db-dropdown");t.className="designbase-wc-share__dropdown",t.setAttribute("placement",this.getPlacement()),t.setAttribute("label",this.getAttribute("button-text")||"공유"),t.setAttribute("trigger-variant","secondary"),t.setAttribute("trigger-icon","share-alt"),t.setAttribute("size",this.mapButtonSize()),t.setAttribute("items",JSON.stringify(this.getActivePlatforms().map(t=>({id:t,label:n[t].name})))),t.addEventListener("db-change",t=>{const e=t.detail,s=e?.id;s&&this.handlePlatformShare(s)}),this.dropdownEl=t,this.append(t)}renderModal(){const t=this.createTriggerButton();this.append(t);const e=document.createElement("db-modal");e.className="designbase-wc-share__modal",e.setAttribute("title",this.getAttribute("modal-title")||"공유하기"),e.setAttribute("size","m"),this.contentSlot=document.createElement("div"),this.contentSlot.className="designbase-wc-share designbase-wc-share__content",this.contentSlot.setAttribute("data-modal-part","body"),this.populateShareContent(this.contentSlot),e.append(this.contentSlot),e.addEventListener("db-close",()=>{this.open=!1,this.qrCodeData="",this.contentSlot&&(this.contentSlot.replaceChildren(),this.populateShareContent(this.contentSlot))}),this.modalEl=e,this.append(e),this.syncModalOpen()}render(){const t=this.getAttribute("variant")||"button";this.className=`designbase-wc-share designbase-wc-share--${t}`,this.replaceChildren(),this.modalEl=null,this.contentSlot=null,this.dropdownEl=null,"inline"!==t?"dropdown"!==t?"modal"!==t?this.append(this.createTriggerButton()):this.renderModal():this.renderDropdown():this.append(this.createShareContent())}}customElements.get("db-share")||customElements.define("db-share",DbShare);export{DbShare};
|
|
1
|
+
import { createShareIcon, createSharePlatformIcon } from './db-share-icons.js';
|
|
2
|
+
|
|
3
|
+
const DEFAULT_PLATFORMS = ['facebook', 'x', 'linkedin', 'whatsapp', 'email', 'link'];
|
|
4
|
+
const PLATFORM_CONFIGS = {
|
|
5
|
+
facebook: {
|
|
6
|
+
name: 'Facebook',
|
|
7
|
+
color: '#1877f2',
|
|
8
|
+
shareUrl: 'https://www.facebook.com/sharer/sharer.php?u={url}',
|
|
9
|
+
},
|
|
10
|
+
x: {
|
|
11
|
+
name: 'X',
|
|
12
|
+
color: '#000000',
|
|
13
|
+
shareUrl: 'https://twitter.com/intent/tweet?url={url}&text={title}&hashtags={hashtags}',
|
|
14
|
+
},
|
|
15
|
+
instagram: {
|
|
16
|
+
name: 'Instagram',
|
|
17
|
+
color: '#e4405f',
|
|
18
|
+
shareUrl: 'https://www.instagram.com/',
|
|
19
|
+
customShare: () => {
|
|
20
|
+
window.alert('Instagram에 직접 공유하려면 링크를 복사하여 사용하세요.');
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
linkedin: {
|
|
24
|
+
name: 'LinkedIn',
|
|
25
|
+
color: '#0077b5',
|
|
26
|
+
shareUrl: 'https://www.linkedin.com/sharing/share-offsite/?url={url}',
|
|
27
|
+
},
|
|
28
|
+
pinterest: {
|
|
29
|
+
name: 'Pinterest',
|
|
30
|
+
color: '#bd081c',
|
|
31
|
+
shareUrl: 'https://pinterest.com/pin/create/button/?url={url}&description={title}&media={imageUrl}',
|
|
32
|
+
},
|
|
33
|
+
whatsapp: {
|
|
34
|
+
name: 'WhatsApp',
|
|
35
|
+
color: '#25d366',
|
|
36
|
+
shareUrl: 'https://wa.me/?text={title}%20{url}',
|
|
37
|
+
},
|
|
38
|
+
telegram: {
|
|
39
|
+
name: 'Telegram',
|
|
40
|
+
color: '#0088cc',
|
|
41
|
+
shareUrl: 'https://t.me/share/url?url={url}&text={title}',
|
|
42
|
+
},
|
|
43
|
+
email: {
|
|
44
|
+
name: '이메일',
|
|
45
|
+
color: '#ea4335',
|
|
46
|
+
shareUrl: 'mailto:?subject={title}&body={description}%20{url}',
|
|
47
|
+
},
|
|
48
|
+
link: {
|
|
49
|
+
name: '링크 복사',
|
|
50
|
+
color: '#6c757d',
|
|
51
|
+
shareUrl: '',
|
|
52
|
+
},
|
|
53
|
+
qr: {
|
|
54
|
+
name: 'QR 코드',
|
|
55
|
+
color: '#6c757d',
|
|
56
|
+
shareUrl: '',
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
class DbShare extends HTMLElement {
|
|
60
|
+
constructor() {
|
|
61
|
+
super(...arguments);
|
|
62
|
+
this.isCopied = false;
|
|
63
|
+
this.qrCodeData = '';
|
|
64
|
+
this.copyResetTimer = null;
|
|
65
|
+
this.modalEl = null;
|
|
66
|
+
this.contentSlot = null;
|
|
67
|
+
this.dropdownEl = null;
|
|
68
|
+
}
|
|
69
|
+
static get observedAttributes() {
|
|
70
|
+
return [
|
|
71
|
+
'url',
|
|
72
|
+
'title',
|
|
73
|
+
'description',
|
|
74
|
+
'image-url',
|
|
75
|
+
'hashtags',
|
|
76
|
+
'variant',
|
|
77
|
+
'size',
|
|
78
|
+
'position',
|
|
79
|
+
'platforms',
|
|
80
|
+
'button-text',
|
|
81
|
+
'modal-title',
|
|
82
|
+
'show-qr-code',
|
|
83
|
+
'qr-code-size',
|
|
84
|
+
'copy-success-message',
|
|
85
|
+
'open',
|
|
86
|
+
];
|
|
87
|
+
}
|
|
88
|
+
connectedCallback() {
|
|
89
|
+
this.render();
|
|
90
|
+
}
|
|
91
|
+
disconnectedCallback() {
|
|
92
|
+
if (this.copyResetTimer)
|
|
93
|
+
clearTimeout(this.copyResetTimer);
|
|
94
|
+
}
|
|
95
|
+
attributeChangedCallback(name) {
|
|
96
|
+
if (name === 'open' && this.getAttribute('variant') === 'modal' && this.modalEl) {
|
|
97
|
+
this.syncModalOpen();
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
if (name === 'url' && this.contentSlot) {
|
|
101
|
+
this.refreshLinkInputValue();
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
this.render();
|
|
105
|
+
}
|
|
106
|
+
get open() {
|
|
107
|
+
return this.hasAttribute('open') && this.getAttribute('open') !== 'false';
|
|
108
|
+
}
|
|
109
|
+
set open(value) {
|
|
110
|
+
if (value)
|
|
111
|
+
this.setAttribute('open', 'true');
|
|
112
|
+
else
|
|
113
|
+
this.removeAttribute('open');
|
|
114
|
+
}
|
|
115
|
+
parseListAttribute(name) {
|
|
116
|
+
const raw = this.getAttribute(name);
|
|
117
|
+
if (!raw)
|
|
118
|
+
return [];
|
|
119
|
+
try {
|
|
120
|
+
const parsed = JSON.parse(raw);
|
|
121
|
+
if (Array.isArray(parsed))
|
|
122
|
+
return parsed.map((item) => String(item).trim()).filter(Boolean);
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
// fall through to comma-separated parsing
|
|
126
|
+
}
|
|
127
|
+
return raw
|
|
128
|
+
.split(',')
|
|
129
|
+
.map((item) => item.trim())
|
|
130
|
+
.filter(Boolean);
|
|
131
|
+
}
|
|
132
|
+
getResolvedUrl() {
|
|
133
|
+
const explicit = this.getAttribute('url');
|
|
134
|
+
if (explicit)
|
|
135
|
+
return explicit;
|
|
136
|
+
if (typeof window !== 'undefined' && window.location?.href) {
|
|
137
|
+
return window.location.href;
|
|
138
|
+
}
|
|
139
|
+
return '';
|
|
140
|
+
}
|
|
141
|
+
getContext() {
|
|
142
|
+
return {
|
|
143
|
+
url: this.getResolvedUrl(),
|
|
144
|
+
title: this.getAttribute('share-title') || this.getAttribute('title') || '',
|
|
145
|
+
description: this.getAttribute('description') || '',
|
|
146
|
+
imageUrl: this.getAttribute('image-url') || '',
|
|
147
|
+
hashtags: this.parseListAttribute('hashtags'),
|
|
148
|
+
host: this,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
getActivePlatforms() {
|
|
152
|
+
const platforms = this.parseListAttribute('platforms');
|
|
153
|
+
const resolved = platforms.length > 0 ? platforms : DEFAULT_PLATFORMS;
|
|
154
|
+
return resolved.filter((platform) => platform in PLATFORM_CONFIGS);
|
|
155
|
+
}
|
|
156
|
+
replaceUrlVariables(template, context) {
|
|
157
|
+
return template
|
|
158
|
+
.replace('{url}', encodeURIComponent(context.url))
|
|
159
|
+
.replace('{title}', encodeURIComponent(context.title))
|
|
160
|
+
.replace('{description}', encodeURIComponent(context.description))
|
|
161
|
+
.replace('{imageUrl}', encodeURIComponent(context.imageUrl))
|
|
162
|
+
.replace('{hashtags}', context.hashtags.join(','));
|
|
163
|
+
}
|
|
164
|
+
async handleCopyLink(context) {
|
|
165
|
+
try {
|
|
166
|
+
await navigator.clipboard.writeText(context.url);
|
|
167
|
+
this.isCopied = true;
|
|
168
|
+
this.dispatchEvent(new CustomEvent('db-copy-success', {
|
|
169
|
+
bubbles: true,
|
|
170
|
+
composed: true,
|
|
171
|
+
detail: { url: context.url },
|
|
172
|
+
}));
|
|
173
|
+
this.refreshContent();
|
|
174
|
+
if (this.copyResetTimer)
|
|
175
|
+
clearTimeout(this.copyResetTimer);
|
|
176
|
+
this.copyResetTimer = setTimeout(() => {
|
|
177
|
+
this.isCopied = false;
|
|
178
|
+
this.refreshContent();
|
|
179
|
+
}, 3000);
|
|
180
|
+
}
|
|
181
|
+
catch (error) {
|
|
182
|
+
this.dispatchEvent(new CustomEvent('db-copy-error', {
|
|
183
|
+
bubbles: true,
|
|
184
|
+
composed: true,
|
|
185
|
+
detail: { error },
|
|
186
|
+
}));
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
handleShowQrCode(context) {
|
|
190
|
+
this.qrCodeData = context.url;
|
|
191
|
+
if (this.getAttribute('variant') === 'modal') {
|
|
192
|
+
this.open = true;
|
|
193
|
+
this.refreshContent();
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
this.refreshContent();
|
|
197
|
+
}
|
|
198
|
+
handlePlatformShare(platform) {
|
|
199
|
+
const context = this.getContext();
|
|
200
|
+
const config = PLATFORM_CONFIGS[platform];
|
|
201
|
+
if (!config)
|
|
202
|
+
return;
|
|
203
|
+
try {
|
|
204
|
+
if (platform === 'link') {
|
|
205
|
+
void this.handleCopyLink(context);
|
|
206
|
+
}
|
|
207
|
+
else if (platform === 'qr') {
|
|
208
|
+
this.handleShowQrCode(context);
|
|
209
|
+
}
|
|
210
|
+
else if (config.customShare) {
|
|
211
|
+
config.customShare(context);
|
|
212
|
+
}
|
|
213
|
+
else if (config.shareUrl) {
|
|
214
|
+
const shareUrl = this.replaceUrlVariables(config.shareUrl, context);
|
|
215
|
+
window.open(shareUrl, '_blank', 'width=600,height=400');
|
|
216
|
+
}
|
|
217
|
+
this.dispatchEvent(new CustomEvent('db-share', {
|
|
218
|
+
bubbles: true,
|
|
219
|
+
composed: true,
|
|
220
|
+
detail: { platform, url: context.url },
|
|
221
|
+
}));
|
|
222
|
+
}
|
|
223
|
+
catch (error) {
|
|
224
|
+
this.dispatchEvent(new CustomEvent('db-share-error', {
|
|
225
|
+
bubbles: true,
|
|
226
|
+
composed: true,
|
|
227
|
+
detail: { platform, error },
|
|
228
|
+
}));
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
getPlacement() {
|
|
232
|
+
const position = this.getAttribute('position') || 'bottom';
|
|
233
|
+
if (position === 'top')
|
|
234
|
+
return 'top-left';
|
|
235
|
+
if (position === 'left')
|
|
236
|
+
return 'top-left';
|
|
237
|
+
if (position === 'right')
|
|
238
|
+
return 'bottom-right';
|
|
239
|
+
return 'bottom-left';
|
|
240
|
+
}
|
|
241
|
+
mapButtonSize() {
|
|
242
|
+
const size = this.getAttribute('size') || 'm';
|
|
243
|
+
if (size === 's')
|
|
244
|
+
return 's';
|
|
245
|
+
if (size === 'l')
|
|
246
|
+
return 'l';
|
|
247
|
+
return 'm';
|
|
248
|
+
}
|
|
249
|
+
createTriggerButton(className) {
|
|
250
|
+
const button = document.createElement('db-button');
|
|
251
|
+
button.className = className || 'designbase-wc-share__trigger';
|
|
252
|
+
button.setAttribute('variant', 'secondary');
|
|
253
|
+
button.setAttribute('size', this.mapButtonSize());
|
|
254
|
+
button.textContent = this.getAttribute('button-text') || '공유';
|
|
255
|
+
button.prepend(createShareIcon('share-alt', 16));
|
|
256
|
+
button.addEventListener('db-click', () => {
|
|
257
|
+
const variant = this.getAttribute('variant');
|
|
258
|
+
if (variant === 'modal') {
|
|
259
|
+
this.open = true;
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
this.open = !this.open;
|
|
263
|
+
});
|
|
264
|
+
return button;
|
|
265
|
+
}
|
|
266
|
+
createPlatformIcon(platform) {
|
|
267
|
+
const iconWrap = document.createElement('span');
|
|
268
|
+
iconWrap.className = 'designbase-wc-share__platform-icon';
|
|
269
|
+
iconWrap.append(createSharePlatformIcon(platform, 24));
|
|
270
|
+
return iconWrap;
|
|
271
|
+
}
|
|
272
|
+
createPlatformButton(platform) {
|
|
273
|
+
const config = PLATFORM_CONFIGS[platform];
|
|
274
|
+
const button = document.createElement('button');
|
|
275
|
+
button.type = 'button';
|
|
276
|
+
button.className = [
|
|
277
|
+
'designbase-wc-share__platform-button',
|
|
278
|
+
`designbase-wc-share__platform-button--${platform}`,
|
|
279
|
+
platform === 'link' && this.isCopied ? 'designbase-wc-share__platform-button--copied' : '',
|
|
280
|
+
]
|
|
281
|
+
.filter(Boolean)
|
|
282
|
+
.join(' ');
|
|
283
|
+
button.style.setProperty('--platform-color', config.color);
|
|
284
|
+
button.title = config.name;
|
|
285
|
+
button.setAttribute('aria-label', `${config.name}에 공유하기`);
|
|
286
|
+
button.append(this.createPlatformIcon(platform));
|
|
287
|
+
const name = document.createElement('span');
|
|
288
|
+
name.className = 'designbase-wc-share__platform-name';
|
|
289
|
+
name.textContent = config.name;
|
|
290
|
+
button.append(name);
|
|
291
|
+
if (platform === 'link' && this.isCopied) {
|
|
292
|
+
const success = document.createElement('span');
|
|
293
|
+
success.className = 'designbase-wc-share__copy-success';
|
|
294
|
+
success.append(createShareIcon('copy', 12));
|
|
295
|
+
const label = document.createElement('span');
|
|
296
|
+
label.textContent = '복사됨!';
|
|
297
|
+
success.append(label);
|
|
298
|
+
button.append(success);
|
|
299
|
+
}
|
|
300
|
+
button.addEventListener('click', () => this.handlePlatformShare(platform));
|
|
301
|
+
return button;
|
|
302
|
+
}
|
|
303
|
+
createLinkInput(url) {
|
|
304
|
+
const input = document.createElement('db-input');
|
|
305
|
+
input.className = 'designbase-wc-share__link-input';
|
|
306
|
+
input.setAttribute('type', 'text');
|
|
307
|
+
input.setAttribute('readonly', '');
|
|
308
|
+
input.setAttribute('size', 's');
|
|
309
|
+
input.setAttribute('full-width', '');
|
|
310
|
+
input.setAttribute('value', url);
|
|
311
|
+
customElements.whenDefined('db-input').then(() => {
|
|
312
|
+
input.setAttribute('value', url);
|
|
313
|
+
input.value = url;
|
|
314
|
+
});
|
|
315
|
+
return input;
|
|
316
|
+
}
|
|
317
|
+
refreshLinkInputValue() {
|
|
318
|
+
const url = this.getResolvedUrl();
|
|
319
|
+
const input = this.contentSlot?.querySelector('db-input.designbase-wc-share__link-input');
|
|
320
|
+
if (!input)
|
|
321
|
+
return;
|
|
322
|
+
input.setAttribute('value', url);
|
|
323
|
+
input.value = url;
|
|
324
|
+
}
|
|
325
|
+
createCopyButton(context) {
|
|
326
|
+
const copyButton = document.createElement('db-button');
|
|
327
|
+
copyButton.className = 'designbase-wc-share__copy-button';
|
|
328
|
+
copyButton.setAttribute('size', 's');
|
|
329
|
+
copyButton.setAttribute('variant', 'primary');
|
|
330
|
+
const iconWrap = document.createElement('span');
|
|
331
|
+
iconWrap.className = 'designbase-wc-button__start-icon';
|
|
332
|
+
iconWrap.setAttribute('aria-hidden', 'true');
|
|
333
|
+
iconWrap.append(createShareIcon(this.isCopied ? 'copy' : 'link', 16));
|
|
334
|
+
copyButton.append(iconWrap);
|
|
335
|
+
copyButton.append(document.createTextNode(this.isCopied ? '복사됨!' : '복사'));
|
|
336
|
+
copyButton.addEventListener('db-click', () => {
|
|
337
|
+
void this.handleCopyLink(context);
|
|
338
|
+
});
|
|
339
|
+
return copyButton;
|
|
340
|
+
}
|
|
341
|
+
generateQrCodeUrl() {
|
|
342
|
+
const qrCodeSize = Number(this.getAttribute('qr-code-size') || 200);
|
|
343
|
+
return `https://api.qrserver.com/v1/create-qr-code/?size=${qrCodeSize}x${qrCodeSize}&data=${encodeURIComponent(this.qrCodeData)}`;
|
|
344
|
+
}
|
|
345
|
+
createShareContent() {
|
|
346
|
+
const content = document.createElement('div');
|
|
347
|
+
content.className = 'designbase-wc-share__content';
|
|
348
|
+
this.populateShareContent(content);
|
|
349
|
+
return content;
|
|
350
|
+
}
|
|
351
|
+
populateShareContent(content) {
|
|
352
|
+
const platformsWrap = document.createElement('div');
|
|
353
|
+
platformsWrap.className = 'designbase-wc-share__platforms';
|
|
354
|
+
this.getActivePlatforms().forEach((platform) => {
|
|
355
|
+
platformsWrap.append(this.createPlatformButton(platform));
|
|
356
|
+
});
|
|
357
|
+
content.append(platformsWrap);
|
|
358
|
+
const showQrCode = this.getAttribute('show-qr-code') !== 'false';
|
|
359
|
+
if (showQrCode && this.qrCodeData) {
|
|
360
|
+
const qrSection = document.createElement('div');
|
|
361
|
+
qrSection.className = 'designbase-wc-share__qr-section';
|
|
362
|
+
const qrTitle = document.createElement('h4');
|
|
363
|
+
qrTitle.className = 'designbase-wc-share__qr-title';
|
|
364
|
+
qrTitle.textContent = 'QR 코드';
|
|
365
|
+
qrSection.append(qrTitle);
|
|
366
|
+
const qrCode = document.createElement('div');
|
|
367
|
+
qrCode.className = 'designbase-wc-share__qr-code';
|
|
368
|
+
const qrImage = document.createElement('img');
|
|
369
|
+
const qrCodeSize = Number(this.getAttribute('qr-code-size') || 200);
|
|
370
|
+
qrImage.src = this.generateQrCodeUrl();
|
|
371
|
+
qrImage.alt = 'QR Code';
|
|
372
|
+
qrImage.width = qrCodeSize;
|
|
373
|
+
qrImage.height = qrCodeSize;
|
|
374
|
+
qrCode.append(qrImage);
|
|
375
|
+
qrSection.append(qrCode);
|
|
376
|
+
const qrDescription = document.createElement('p');
|
|
377
|
+
qrDescription.className = 'designbase-wc-share__qr-description';
|
|
378
|
+
qrDescription.textContent = 'QR 코드를 스캔하여 링크에 접속하세요';
|
|
379
|
+
qrSection.append(qrDescription);
|
|
380
|
+
content.append(qrSection);
|
|
381
|
+
}
|
|
382
|
+
const context = this.getContext();
|
|
383
|
+
const linkPreview = document.createElement('div');
|
|
384
|
+
linkPreview.className = 'designbase-wc-share__link-preview';
|
|
385
|
+
const linkTitle = document.createElement('h4');
|
|
386
|
+
linkTitle.className = 'designbase-wc-share__link-title';
|
|
387
|
+
linkTitle.textContent = '공유 링크';
|
|
388
|
+
linkPreview.append(linkTitle);
|
|
389
|
+
const linkContainer = document.createElement('div');
|
|
390
|
+
linkContainer.className = 'designbase-wc-share__link-container';
|
|
391
|
+
linkContainer.append(this.createLinkInput(context.url));
|
|
392
|
+
linkContainer.append(this.createCopyButton(context));
|
|
393
|
+
linkPreview.append(linkContainer);
|
|
394
|
+
content.append(linkPreview);
|
|
395
|
+
}
|
|
396
|
+
refreshContent() {
|
|
397
|
+
const variant = this.getAttribute('variant');
|
|
398
|
+
if (variant === 'inline') {
|
|
399
|
+
const content = this.querySelector(':scope > .designbase-wc-share__content');
|
|
400
|
+
content?.replaceWith(this.createShareContent());
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
if (variant === 'modal' && this.contentSlot) {
|
|
404
|
+
this.contentSlot.replaceChildren();
|
|
405
|
+
this.populateShareContent(this.contentSlot);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
syncModalOpen() {
|
|
409
|
+
if (!this.modalEl)
|
|
410
|
+
return;
|
|
411
|
+
if (this.open) {
|
|
412
|
+
this.refreshLinkInputValue();
|
|
413
|
+
this.modalEl.setAttribute('open', 'true');
|
|
414
|
+
}
|
|
415
|
+
else {
|
|
416
|
+
this.modalEl.removeAttribute('open');
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
renderDropdown() {
|
|
420
|
+
const dropdown = document.createElement('db-dropdown');
|
|
421
|
+
dropdown.className = 'designbase-wc-share__dropdown';
|
|
422
|
+
dropdown.setAttribute('placement', this.getPlacement());
|
|
423
|
+
dropdown.setAttribute('label', this.getAttribute('button-text') || '공유');
|
|
424
|
+
dropdown.setAttribute('trigger-variant', 'secondary');
|
|
425
|
+
dropdown.setAttribute('trigger-icon', 'share-alt');
|
|
426
|
+
dropdown.setAttribute('size', this.mapButtonSize());
|
|
427
|
+
dropdown.setAttribute('items', JSON.stringify(this.getActivePlatforms().map((platform) => ({
|
|
428
|
+
id: platform,
|
|
429
|
+
label: PLATFORM_CONFIGS[platform].name,
|
|
430
|
+
}))));
|
|
431
|
+
dropdown.addEventListener('db-change', (event) => {
|
|
432
|
+
const detail = event.detail;
|
|
433
|
+
const platform = detail?.id;
|
|
434
|
+
if (platform)
|
|
435
|
+
this.handlePlatformShare(platform);
|
|
436
|
+
});
|
|
437
|
+
this.dropdownEl = dropdown;
|
|
438
|
+
this.append(dropdown);
|
|
439
|
+
}
|
|
440
|
+
renderModal() {
|
|
441
|
+
const trigger = this.createTriggerButton();
|
|
442
|
+
this.append(trigger);
|
|
443
|
+
const modal = document.createElement('db-modal');
|
|
444
|
+
modal.className = 'designbase-wc-share__modal';
|
|
445
|
+
modal.setAttribute('title', this.getAttribute('modal-title') || '공유하기');
|
|
446
|
+
modal.setAttribute('size', 'm');
|
|
447
|
+
this.contentSlot = document.createElement('div');
|
|
448
|
+
this.contentSlot.className = 'designbase-wc-share designbase-wc-share__content';
|
|
449
|
+
this.contentSlot.setAttribute('data-modal-part', 'body');
|
|
450
|
+
this.populateShareContent(this.contentSlot);
|
|
451
|
+
modal.append(this.contentSlot);
|
|
452
|
+
modal.addEventListener('db-close', () => {
|
|
453
|
+
this.open = false;
|
|
454
|
+
this.qrCodeData = '';
|
|
455
|
+
if (this.contentSlot) {
|
|
456
|
+
this.contentSlot.replaceChildren();
|
|
457
|
+
this.populateShareContent(this.contentSlot);
|
|
458
|
+
}
|
|
459
|
+
});
|
|
460
|
+
this.modalEl = modal;
|
|
461
|
+
this.append(modal);
|
|
462
|
+
this.syncModalOpen();
|
|
463
|
+
}
|
|
464
|
+
render() {
|
|
465
|
+
const variant = (this.getAttribute('variant') || 'button');
|
|
466
|
+
this.className = `designbase-wc-share designbase-wc-share--${variant}`;
|
|
467
|
+
this.replaceChildren();
|
|
468
|
+
this.modalEl = null;
|
|
469
|
+
this.contentSlot = null;
|
|
470
|
+
this.dropdownEl = null;
|
|
471
|
+
if (variant === 'inline') {
|
|
472
|
+
this.append(this.createShareContent());
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
if (variant === 'dropdown') {
|
|
476
|
+
this.renderDropdown();
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
if (variant === 'modal') {
|
|
480
|
+
this.renderModal();
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
483
|
+
this.append(this.createTriggerButton());
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
if (!customElements.get('db-share'))
|
|
487
|
+
customElements.define('db-share', DbShare);
|
|
488
|
+
|
|
489
|
+
export { DbShare };
|