Spaces:
Running
Running
| <script lang="ts"> | |
| import { createEventDispatcher } from "svelte"; | |
| import { sampleDatasets } from "./sampleData"; | |
| const dispatch = createEventDispatcher(); | |
| export let selectedDataset = "basic"; | |
| export let currentTheme = "default"; | |
| export let editable = true; | |
| export let show_row_numbers = true; | |
| export let show_search: "none" | "search" | "filter" = "search"; | |
| export let show_copy_button = true; | |
| export let show_fullscreen_button = true; | |
| export let show_label = true; | |
| export let label = "Sample Data"; | |
| export let max_height = 500; | |
| export let line_breaks = true; | |
| export let wrap = false; | |
| export let max_chars: number | undefined = undefined; | |
| // Controls panel state | |
| let activeControlsTab = "properties"; // "properties" or "actions" | |
| function switchDataset(dataset: string) { | |
| selectedDataset = dataset; | |
| dispatch('datasetChange', { dataset }); | |
| } | |
| function applyTheme(theme: string) { | |
| currentTheme = theme; | |
| dispatch('themeChange', { theme }); | |
| } | |
| function addCustomColumn() { | |
| dispatch('addColumn'); | |
| } | |
| function addCustomRow() { | |
| dispatch('addRow'); | |
| } | |
| </script> | |
| <!-- Storybook Controls Panel --> | |
| <div class="h-full flex flex-col w-full"> | |
| <!-- Controls Tab Header --> | |
| <div class="p-4 border-b-2 border-[#e0e0e0] bg-[#f8fafc]"> | |
| <div class="flex items-center justify-between"> | |
| <h2 class="text-xs font-bold text-[#2e3438] uppercase tracking-wider">Controls</h2> | |
| <div class="flex space-x-4"> | |
| <button | |
| on:click={() => activeControlsTab = "properties"} | |
| class="flex items-center py-2.5 !px-4 text-sm font-medium transition-all duration-200 rounded-lg | |
| {activeControlsTab === 'properties' | |
| ? 'text-[#F87701] bg-white border border-[#F87701]' | |
| : 'text-[#64748b] hover:text-[#F87701] hover:bg-white/50 border border-transparent'}" | |
| > | |
| <span class="mr-2">⚙️</span> | |
| Properties | |
| </button> | |
| <button | |
| on:click={() => activeControlsTab = "actions"} | |
| class="flex items-center py-2.5 !px-4 text-sm font-medium transition-all duration-200 rounded-lg | |
| {activeControlsTab === 'actions' | |
| ? 'text-[#F87701] bg-white border border-[#F87701]' | |
| : 'text-[#64748b] hover:text-[#F87701] hover:bg-white/50 border border-transparent'}" | |
| > | |
| <span class="mr-2">📝</span> | |
| Actions | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Controls Content --> | |
| <div class="flex-1 overflow-x-scroll overflow-y-scroll p-4 min-h-0"> | |
| {#if activeControlsTab === "properties"} | |
| <!-- Properties Tab Content --> | |
| <div class="flex space-x-8 min-w-max"> | |
| <!-- Boolean Controls --> | |
| <div class="min-w-[300px]"> | |
| <h4 class="text-xs font-bold text-[#2e3438] uppercase tracking-wider mb-4">Display</h4> | |
| <div class="space-y-4"> | |
| <label class="flex items-center justify-between py-3 px-3 hover:bg-[#f6f9fc] rounded-lg transition-all duration-200"> | |
| <span class="text-[14px] text-[#2e3438]">editable</span> | |
| <input | |
| type="checkbox" | |
| bind:checked={editable} | |
| class="w-5 h-5 rounded border-[#e0e0e0] text-[#F87701] focus:ring-[#F87701] focus:ring-2 bg-white" | |
| > | |
| </label> | |
| <label class="flex items-center justify-between py-3 px-3 hover:bg-[#f6f9fc] rounded-lg transition-all duration-200"> | |
| <span class="text-[14px] text-[#2e3438]">show_row_numbers</span> | |
| <input | |
| type="checkbox" | |
| bind:checked={show_row_numbers} | |
| class="w-5 h-5 rounded border-[#e0e0e0] text-[#F87701] focus:ring-[#F87701] focus:ring-2 bg-white" | |
| > | |
| </label> | |
| <label class="flex items-center justify-between py-3 px-3 hover:bg-[#f6f9fc] rounded-lg transition-all duration-200"> | |
| <span class="text-[14px] text-[#2e3438]">show_copy_button</span> | |
| <input | |
| type="checkbox" | |
| bind:checked={show_copy_button} | |
| class="w-5 h-5 rounded border-[#e0e0e0] text-[#F87701] focus:ring-[#F87701] focus:ring-2 bg-white" | |
| > | |
| </label> | |
| <label class="flex items-center justify-between py-3 px-3 hover:bg-[#f6f9fc] rounded-lg transition-all duration-200"> | |
| <span class="text-[14px] text-[#2e3438]">show_fullscreen_button</span> | |
| <input | |
| type="checkbox" | |
| bind:checked={show_fullscreen_button} | |
| class="w-5 h-5 rounded border-[#e0e0e0] text-[#F87701] focus:ring-[#F87701] focus:ring-2 bg-white" | |
| > | |
| </label> | |
| <label class="flex items-center justify-between py-3 px-3 hover:bg-[#f6f9fc] rounded-lg transition-all duration-200"> | |
| <span class="text-[14px] text-[#2e3438]">show_label</span> | |
| <input | |
| type="checkbox" | |
| bind:checked={show_label} | |
| class="w-5 h-5 rounded border-[#e0e0e0] text-[#F87701] focus:ring-[#F87701] focus:ring-2 bg-white" | |
| > | |
| </label> | |
| <label class="flex items-center justify-between py-3 px-3 hover:bg-[#f6f9fc] rounded-lg transition-all duration-200"> | |
| <span class="text-[14px] text-[#2e3438]">line_breaks</span> | |
| <input | |
| type="checkbox" | |
| bind:checked={line_breaks} | |
| class="w-5 h-5 rounded border-[#e0e0e0] text-[#F87701] focus:ring-[#F87701] focus:ring-2 bg-white" | |
| > | |
| </label> | |
| <label class="flex items-center justify-between py-3 px-3 hover:bg-[#f6f9fc] rounded-lg transition-all duration-200"> | |
| <span class="text-[14px] text-[#2e3438]">wrap</span> | |
| <input | |
| type="checkbox" | |
| bind:checked={wrap} | |
| class="w-5 h-5 rounded border-[#e0e0e0] text-[#F87701] focus:ring-[#F87701] focus:ring-2 bg-white" | |
| > | |
| </label> | |
| </div> | |
| </div> | |
| <!-- Options Controls --> | |
| <div class="min-w-[250px]"> | |
| <h4 class="text-xs font-bold text-[#2e3438] uppercase tracking-wider mb-4">Options</h4> | |
| <div class="space-y-2"> | |
| <label for="show-search" class="block text-sm font-medium text-[#374151] mb-2">Search Type</label> | |
| <div class="relative"> | |
| <select | |
| id="show-search" | |
| bind:value={show_search} | |
| class="w-full px-4 py-3 !rounded-sm text-sm border-2 border-[#e5e7eb] rounded-lg bg-[#f9fafb] text-[#374151] focus:ring-2 focus:ring-[#F87701] focus:border-[#F87701] focus:bg-white transition-all duration-200 appearance-none cursor-pointer shadow-sm" | |
| > | |
| <option value="none">None</option> | |
| <option value="search">Search</option> | |
| <option value="filter">Filter</option> | |
| </select> | |
| <div class="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none"> | |
| <svg class="w-4 h-4 text-[#9ca3af]" fill="none" stroke="currentColor" viewBox="0 0 24 24"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path> | |
| </svg> | |
| </div> | |
| </div> | |
| <p class="text-xs text-[#6b7280] mt-1">Configure search functionality</p> | |
| </div> | |
| </div> | |
| <!-- Number Controls --> | |
| <div class="min-w-[250px]"> | |
| <h4 class="text-xs font-bold text-[#2e3438] uppercase tracking-wider mb-4">Numbers</h4> | |
| <div class="space-y-6"> | |
| <div class="space-y-2"> | |
| <label for="max-height" class="block text-sm font-medium text-[#374151]">Maximum Height</label> | |
| <div class="relative"> | |
| <input | |
| id="max-height" | |
| type="number" | |
| bind:value={max_height} | |
| min="200" | |
| max="1000" | |
| step="50" | |
| class="w-full px-4 py-3 text-sm !rounded-sm border-2 border-[#e5e7eb] rounded-lg bg-[#f9fafb] text-[#374151] focus:ring-2 focus:ring-[#F87701] focus:border-[#F87701] focus:bg-white transition-all duration-200 shadow-sm" | |
| > | |
| <div class="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none"> | |
| <span class="text-xs text-[#9ca3af] font-medium">px</span> | |
| </div> | |
| </div> | |
| <p class="text-xs text-[#6b7280]">Height constraint for the table (200-1000px)</p> | |
| </div> | |
| <div class="space-y-2"> | |
| <label for="max-chars" class="block text-sm font-medium text-[#374151]">Character Limit</label> | |
| <input | |
| id="max-chars" | |
| type="number" | |
| bind:value={max_chars} | |
| min="10" | |
| max="1000" | |
| step="10" | |
| placeholder="No limit" | |
| class="w-full px-4 py-3 text-sm !rounded-sm border-2 border-[#e5e7eb] rounded-lg bg-[#f9fafb] text-[#374151] placeholder-[#9ca3af] focus:ring-2 focus:ring-[#F87701] focus:border-[#F87701] focus:bg-white transition-all duration-200 shadow-sm" | |
| > | |
| <p class="text-xs text-[#6b7280]">Maximum characters per cell (leave empty for no limit)</p> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Text Controls --> | |
| <div class="min-w-[250px]"> | |
| <h4 class="text-xs font-bold text-[#2e3438] uppercase tracking-wider mb-4">Text</h4> | |
| <div class="space-y-2"> | |
| <label for="label-input" class="block text-sm font-medium text-[#374151]">Table Label</label> | |
| <div class="relative"> | |
| <input | |
| id="label-input" | |
| type="text" | |
| bind:value={label} | |
| placeholder="Enter table label..." | |
| class="w-full px-4 py-3 text-sm !rounded-sm border-2 border-[#e5e7eb] rounded-lg bg-[#f9fafb] text-[#374151] placeholder-[#9ca3af] focus:ring-2 focus:ring-[#F87701] focus:border-[#F87701] focus:bg-white transition-all duration-200 shadow-sm" | |
| > | |
| <div class="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none"> | |
| <svg class="w-4 h-4 text-[#9ca3af]" fill="none" stroke="currentColor" viewBox="0 0 24 24"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-7 7a.997.997 0 01-1.414 0l-7-7A1.997 1.997 0 013 12V7a4 4 0 014-4z"></path> | |
| </svg> | |
| </div> | |
| </div> | |
| <p class="text-xs text-[#6b7280]">Display label shown above the dataframe</p> | |
| </div> | |
| </div> | |
| </div> | |
| {:else if activeControlsTab === "actions"} | |
| <!-- Actions Tab Content --> | |
| <div class="flex space-x-8 min-w-max"> | |
| <!-- Data Manipulation Section --> | |
| <div class="min-w-[300px]"> | |
| <div> | |
| <h4 class="text-xs font-bold text-[#2e3438] uppercase tracking-wider mb-3">Data Manipulation</h4> | |
| <p class="text-sm text-[#64748b] mb-5 leading-relaxed">Add new rows and columns to the dataframe</p> | |
| <div class="grid grid-cols-1 gap-3"> | |
| <button | |
| on:click={addCustomColumn} | |
| class="flex items-center justify-center px-6 py-4 text-sm font-semibold bg-gradient-to-r from-[#F87701] to-[#0f8bda] text-white rounded-xl hover:from-[#0f8bda] hover:to-[#0569b5] focus:ring-2 focus:ring-[#F87701] focus:ring-offset-2 transition-all duration-200" | |
| > | |
| <svg class="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5"> | |
| <path stroke-linecap="round" stroke-linejoin="round" d="M12 4v16m8-8H4"></path> | |
| </svg> | |
| Add Column | |
| </button> | |
| <button | |
| on:click={addCustomRow} | |
| class="flex items-center justify-center px-6 py-4 text-sm font-semibold bg-gradient-to-r from-[#10b981] to-[#059669] text-white rounded-xl hover:from-[#059669] hover:to-[#047857] focus:ring-2 focus:ring-[#10b981] focus:ring-offset-2 transition-all duration-200" | |
| > | |
| <svg class="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5"> | |
| <path stroke-linecap="round" stroke-linejoin="round" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path> | |
| </svg> | |
| Add Row | |
| </button> | |
| </div> | |
| </div> | |
| <div class="border-t border-[#e2e8f0] pt-6"> | |
| <h4 class="text-xs font-bold text-[#2e3438] uppercase tracking-wider mb-3">Export Options</h4> | |
| <p class="text-sm text-[#64748b] mb-5 leading-relaxed">Export your data in different formats</p> | |
| <div class="grid grid-cols-1 gap-3"> | |
| <button | |
| class="flex items-center justify-center px-4 py-3 text-sm font-medium bg-[#f59e0b] text-white rounded-lg hover:bg-[#d97706] focus:ring-2 focus:ring-[#f59e0b] focus:ring-offset-2 transition-all duration-200 shadow-sm" | |
| > | |
| <svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path> | |
| </svg> | |
| Export as CSV | |
| </button> | |
| <button | |
| class="flex items-center justify-center px-4 py-3 text-sm font-medium bg-[#8b5cf6] text-white rounded-lg hover:bg-[#7c3aed] focus:ring-2 focus:ring-[#8b5cf6] focus:ring-offset-2 transition-all duration-200 shadow-sm" | |
| > | |
| <svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path> | |
| </svg> | |
| Copy to Clipboard | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Export & Reset Actions --> | |
| <div class="min-w-[300px]"> | |
| <h4 class="text-xs font-bold text-[#2e3438] uppercase tracking-wider mb-3">Export Options</h4> | |
| <p class="text-sm text-[#64748b] mb-5 leading-relaxed">Export your data in different formats</p> | |
| <div class="grid grid-cols-1 gap-3 mb-6"> | |
| <button | |
| class="flex items-center justify-center px-5 py-3 text-sm font-semibold bg-gradient-to-r from-[#f59e0b] to-[#d97706] text-white rounded-xl hover:from-[#d97706] hover:to-[#b45309] focus:ring-2 focus:ring-[#f59e0b] focus:ring-offset-2 transition-all duration-200" | |
| > | |
| <svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5"> | |
| <path stroke-linecap="round" stroke-linejoin="round" d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path> | |
| </svg> | |
| Export CSV | |
| </button> | |
| <button | |
| class="flex items-center justify-center px-5 py-3 text-sm font-semibold bg-gradient-to-r from-[#6366f1] to-[#4f46e5] text-white rounded-xl hover:from-[#4f46e5] hover:to-[#4338ca] focus:ring-2 focus:ring-[#6366f1] focus:ring-offset-2 transition-all duration-200" | |
| > | |
| <svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5"> | |
| <path stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path> | |
| </svg> | |
| Copy to Clipboard | |
| </button> | |
| </div> | |
| <div class="border-t border-[#e2e8f0] pt-4"> | |
| <h4 class="text-xs font-bold text-[#2e3438] uppercase tracking-wider mb-3">Reset Actions</h4> | |
| <button | |
| class="w-full flex items-center justify-center px-5 py-3 text-sm font-semibold bg-gradient-to-r from-[#ef4444] to-[#dc2626] text-white rounded-xl hover:from-[#dc2626] hover:to-[#b91c1c] focus:ring-2 focus:ring-[#ef4444] focus:ring-offset-2 transition-all duration-200" | |
| > | |
| <svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5"> | |
| <path stroke-linecap="round" stroke-linejoin="round" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"></path> | |
| </svg> | |
| Reset Data | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| {/if} | |
| </div> | |
| </div> | |