snice 7.6.0 → 7.8.0
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/adapters/react/SniceProvider.js +1 -1
- package/adapters/react/SniceRouter.js +1 -1
- package/adapters/react/calendar.d.ts +1 -0
- package/adapters/react/calendar.d.ts.map +1 -1
- package/adapters/react/calendar.js +1 -1
- package/adapters/react/calendar.js.map +1 -1
- package/adapters/react/calendar.tsx +2 -1
- package/adapters/react/matchRoute.js +1 -1
- package/adapters/react/useRequestHandler.js +1 -1
- package/bin/analyzer-contracts.js +8 -2
- package/custom-elements.json +15 -1
- package/dist/cdn/accordion/snice-accordion.js +1 -1
- package/dist/cdn/action-bar/snice-action-bar.js +1 -1
- package/dist/cdn/activity-feed/snice-activity-feed.js +1 -1
- package/dist/cdn/alert/snice-alert.js +1 -1
- package/dist/cdn/app-tiles/snice-app-tiles.js +1 -1
- package/dist/cdn/approval-flow/snice-approval-flow.js +1 -1
- package/dist/cdn/audio-recorder/snice-audio-recorder.js +1 -1
- package/dist/cdn/availability/snice-availability.js +1 -1
- package/dist/cdn/avatar/snice-avatar.js +1 -1
- package/dist/cdn/avatar-group/snice-avatar-group.js +1 -1
- package/dist/cdn/badge/snice-badge.js +1 -1
- package/dist/cdn/banner/snice-banner.js +1 -1
- package/dist/cdn/binpack/snice-binpack.js +1 -1
- package/dist/cdn/book/snice-book.js +1 -1
- package/dist/cdn/booking/snice-booking.js +1 -1
- package/dist/cdn/breadcrumbs/snice-breadcrumbs.js +1 -1
- package/dist/cdn/button/snice-button.js +2 -2
- package/dist/cdn/button/snice-button.js.map +1 -1
- package/dist/cdn/button/snice-button.min.js +1 -1
- package/dist/cdn/button/snice-button.min.js.map +1 -1
- package/dist/cdn/calendar/README.md +2 -2
- package/dist/cdn/calendar/snice-calendar.js +26 -2
- package/dist/cdn/calendar/snice-calendar.js.map +1 -1
- package/dist/cdn/calendar/snice-calendar.min.js +2 -2
- package/dist/cdn/calendar/snice-calendar.min.js.map +1 -1
- package/dist/cdn/camera/snice-camera.js +1 -1
- package/dist/cdn/camera-annotate/snice-camera-annotate.js +1 -1
- package/dist/cdn/candlestick/snice-candlestick.js +1 -1
- package/dist/cdn/card/snice-card.js +1 -1
- package/dist/cdn/carousel/snice-carousel.js +1 -1
- package/dist/cdn/cart/snice-cart.js +1 -1
- package/dist/cdn/chart/snice-chart.js +1 -1
- package/dist/cdn/chat/snice-chat.js +1 -1
- package/dist/cdn/checkbox/snice-checkbox.js +1 -1
- package/dist/cdn/chip/snice-chip.js +1 -1
- package/dist/cdn/code-block/snice-code-block.js +1 -1
- package/dist/cdn/color-display/snice-color-display.js +1 -1
- package/dist/cdn/color-picker/snice-color-picker.js +1 -1
- package/dist/cdn/command-palette/snice-command-palette.js +1 -1
- package/dist/cdn/comments/snice-comments.js +1 -1
- package/dist/cdn/countdown/snice-countdown.js +1 -1
- package/dist/cdn/cropper/snice-cropper.js +1 -1
- package/dist/cdn/data-card/snice-data-card.js +1 -1
- package/dist/cdn/date-picker/snice-date-picker.js +1 -1
- package/dist/cdn/date-range-picker/snice-date-range-picker.js +1 -1
- package/dist/cdn/date-time-picker/snice-date-time-picker.js +1 -1
- package/dist/cdn/diff/snice-diff.js +1 -1
- package/dist/cdn/divider/snice-divider.js +1 -1
- package/dist/cdn/doc/snice-doc.js +1 -1
- package/dist/cdn/draw/snice-draw.js +1 -1
- package/dist/cdn/drawer/snice-drawer.js +1 -1
- package/dist/cdn/empty-state/snice-empty-state.js +1 -1
- package/dist/cdn/estimate/snice-estimate.js +1 -1
- package/dist/cdn/file-gallery/snice-file-gallery.js +1 -1
- package/dist/cdn/file-upload/snice-file-upload.js +1 -1
- package/dist/cdn/flip-card/snice-flip-card.js +1 -1
- package/dist/cdn/flow/snice-flow.js +1 -1
- package/dist/cdn/form-layout/snice-form-layout.js +1 -1
- package/dist/cdn/funnel/snice-funnel.js +1 -1
- package/dist/cdn/gantt/snice-gantt.js +1 -1
- package/dist/cdn/gauge/snice-gauge.js +1 -1
- package/dist/cdn/grid/snice-grid.js +1 -1
- package/dist/cdn/heatmap/snice-heatmap.js +1 -1
- package/dist/cdn/image/snice-image.js +1 -1
- package/dist/cdn/input/snice-input.js +1 -1
- package/dist/cdn/invoice/snice-invoice.js +1 -1
- package/dist/cdn/kanban/snice-kanban.js +1 -1
- package/dist/cdn/key-value/snice-key-value.js +1 -1
- package/dist/cdn/kpi/snice-kpi.js +1 -1
- package/dist/cdn/layout/snice-layout.js +1 -1
- package/dist/cdn/leaderboard/snice-leaderboard.js +1 -1
- package/dist/cdn/link/snice-link.js +1 -1
- package/dist/cdn/link-preview/snice-link-preview.js +1 -1
- package/dist/cdn/list/snice-list.js +1 -1
- package/dist/cdn/location/snice-location.js +1 -1
- package/dist/cdn/login/README.md +1 -1
- package/dist/cdn/login/snice-login.js +2 -2
- package/dist/cdn/login/snice-login.js.map +1 -1
- package/dist/cdn/login/snice-login.min.js +1 -1
- package/dist/cdn/login/snice-login.min.js.map +1 -1
- package/dist/cdn/map/snice-map.js +1 -1
- package/dist/cdn/markdown/snice-markdown.js +1 -1
- package/dist/cdn/masonry/snice-masonry.js +1 -1
- package/dist/cdn/menu/snice-menu.js +1 -1
- package/dist/cdn/message-strip/snice-message-strip.js +1 -1
- package/dist/cdn/modal/snice-modal.js +1 -1
- package/dist/cdn/music-player/snice-music-player.js +1 -1
- package/dist/cdn/nav/snice-nav.js +1 -1
- package/dist/cdn/network-graph/snice-network-graph.js +1 -1
- package/dist/cdn/notification-center/snice-notification-center.js +1 -1
- package/dist/cdn/order-tracker/snice-order-tracker.js +1 -1
- package/dist/cdn/org-chart/snice-org-chart.js +1 -1
- package/dist/cdn/pagination/snice-pagination.js +1 -1
- package/dist/cdn/paint/snice-paint.js +1 -1
- package/dist/cdn/pdf-viewer/snice-pdf-viewer.js +1 -1
- package/dist/cdn/permission-matrix/snice-permission-matrix.js +1 -1
- package/dist/cdn/podcast-player/snice-podcast-player.js +1 -1
- package/dist/cdn/popover/snice-popover.js +1 -1
- package/dist/cdn/pricing-table/snice-pricing-table.js +1 -1
- package/dist/cdn/product-card/snice-product-card.js +1 -1
- package/dist/cdn/progress/snice-progress.js +1 -1
- package/dist/cdn/progress-ring/snice-progress-ring.js +1 -1
- package/dist/cdn/qr-code/snice-qr-code.js +1 -1
- package/dist/cdn/qr-reader/snice-qr-reader.js +1 -1
- package/dist/cdn/radio/snice-radio.js +1 -1
- package/dist/cdn/range-slider/snice-range-slider.js +1 -1
- package/dist/cdn/rating/snice-rating.js +1 -1
- package/dist/cdn/receipt/snice-receipt.js +1 -1
- package/dist/cdn/recipe/snice-recipe.js +1 -1
- package/dist/cdn/runtime/README.md +2 -2
- package/dist/cdn/runtime/snice-runtime.esm.js +130 -31
- package/dist/cdn/runtime/snice-runtime.esm.js.map +1 -1
- package/dist/cdn/runtime/snice-runtime.esm.min.js +1 -1
- package/dist/cdn/runtime/snice-runtime.esm.min.js.map +1 -1
- package/dist/cdn/runtime/snice-runtime.js +130 -31
- package/dist/cdn/runtime/snice-runtime.js.map +1 -1
- package/dist/cdn/runtime/snice-runtime.min.js +1 -1
- package/dist/cdn/runtime/snice-runtime.min.js.map +1 -1
- package/dist/cdn/sankey/snice-sankey.js +1 -1
- package/dist/cdn/segmented-control/snice-segmented-control.js +1 -1
- package/dist/cdn/select/snice-select.js +1 -1
- package/dist/cdn/skeleton/snice-skeleton.js +1 -1
- package/dist/cdn/slider/snice-slider.js +1 -1
- package/dist/cdn/sortable/snice-sortable.js +1 -1
- package/dist/cdn/sparkline/snice-sparkline.js +1 -1
- package/dist/cdn/spinner/snice-spinner.js +1 -1
- package/dist/cdn/split-button/snice-split-button.js +1 -1
- package/dist/cdn/split-pane/snice-split-pane.js +1 -1
- package/dist/cdn/spotlight/snice-spotlight.js +1 -1
- package/dist/cdn/stat-group/snice-stat-group.js +1 -1
- package/dist/cdn/step-input/snice-step-input.js +1 -1
- package/dist/cdn/stepper/snice-stepper.js +1 -1
- package/dist/cdn/switch/snice-switch.js +1 -1
- package/dist/cdn/table/README.md +2 -2
- package/dist/cdn/table/snice-table.esm.js +227 -36
- package/dist/cdn/table/snice-table.esm.js.map +1 -1
- package/dist/cdn/table/snice-table.esm.min.js +69 -48
- package/dist/cdn/table/snice-table.esm.min.js.map +1 -1
- package/dist/cdn/table/snice-table.js +226 -35
- package/dist/cdn/table/snice-table.js.map +1 -1
- package/dist/cdn/table/snice-table.min.js +47 -26
- package/dist/cdn/table/snice-table.min.js.map +1 -1
- package/dist/cdn/tabs/snice-tabs.js +1 -1
- package/dist/cdn/tag/snice-tag.js +1 -1
- package/dist/cdn/tag-input/README.md +2 -2
- package/dist/cdn/tag-input/snice-tag-input.js +10 -16
- package/dist/cdn/tag-input/snice-tag-input.js.map +1 -1
- package/dist/cdn/tag-input/snice-tag-input.min.js +2 -2
- package/dist/cdn/tag-input/snice-tag-input.min.js.map +1 -1
- package/dist/cdn/terminal/snice-terminal.js +1 -1
- package/dist/cdn/testimonial/snice-testimonial.js +1 -1
- package/dist/cdn/textarea/snice-textarea.js +1 -1
- package/dist/cdn/time-picker/snice-time-picker.js +1 -1
- package/dist/cdn/time-range-picker/snice-time-range-picker.js +1 -1
- package/dist/cdn/timeline/snice-timeline.js +1 -1
- package/dist/cdn/timer/snice-timer.js +1 -1
- package/dist/cdn/toast/snice-toast.js +1 -1
- package/dist/cdn/tooltip/snice-tooltip.js +1 -1
- package/dist/cdn/tree/snice-tree.js +1 -1
- package/dist/cdn/treemap/snice-treemap.js +1 -1
- package/dist/cdn/user-card/snice-user-card.js +1 -1
- package/dist/cdn/video-player/snice-video-player.js +1 -1
- package/dist/cdn/virtual-scroller/snice-virtual-scroller.js +1 -1
- package/dist/cdn/waterfall/snice-waterfall.js +1 -1
- package/dist/cdn/weather/snice-weather.js +1 -1
- package/dist/cdn/work-order/snice-work-order.js +1 -1
- package/dist/components/button/snice-button.js +1 -1
- package/dist/components/button/snice-button.js.map +1 -1
- package/dist/components/calendar/snice-calendar.d.ts +2 -0
- package/dist/components/calendar/snice-calendar.js +25 -1
- package/dist/components/calendar/snice-calendar.js.map +1 -1
- package/dist/components/table/snice-row.d.ts +6 -0
- package/dist/components/table/snice-row.js +11 -3
- package/dist/components/table/snice-row.js.map +1 -1
- package/dist/components/table/snice-table.d.ts +40 -3
- package/dist/components/table/snice-table.js +157 -17
- package/dist/components/table/snice-table.js.map +1 -1
- package/dist/components/table/table-cell-presentation.d.ts +11 -0
- package/dist/components/table/table-cell-presentation.js +25 -8
- package/dist/components/table/table-cell-presentation.js.map +1 -1
- package/dist/components/table/table-export.d.ts +6 -0
- package/dist/components/table/table-export.js +11 -2
- package/dist/components/table/table-export.js.map +1 -1
- package/dist/components/table/table-keyboard.js +1 -1
- package/dist/components/table/table-keyboard.js.map +1 -1
- package/dist/components/table/table-master-detail.d.ts +11 -2
- package/dist/components/table/table-master-detail.js +20 -3
- package/dist/components/table/table-master-detail.js.map +1 -1
- package/dist/components/tag-input/snice-tag-input.d.ts +2 -2
- package/dist/components/tag-input/snice-tag-input.js +9 -15
- package/dist/components/tag-input/snice-tag-input.js.map +1 -1
- package/dist/index.cjs +127 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.esm.js +127 -28
- package/dist/index.esm.js.map +1 -1
- package/dist/index.iife.js +127 -28
- package/dist/index.iife.js.map +1 -1
- package/dist/react/SniceProvider.js +1 -1
- package/dist/react/SniceRouter.js +1 -1
- package/dist/react/index.js +1 -1
- package/dist/react/matchRoute.js +1 -1
- package/dist/react/useRequestHandler.js +1 -1
- package/dist/request-response.d.ts +24 -1
- package/dist/symbols.cjs +1 -1
- package/dist/symbols.esm.js +1 -1
- package/dist/testing-dom.cjs +1 -1
- package/dist/testing-dom.esm.js +1 -1
- package/dist/transitions.cjs +1 -1
- package/dist/transitions.esm.js +1 -1
- package/docs/ai/DEVELOPMENT.md +1 -1
- package/docs/ai/components/calendar.md +8 -0
- package/docs/ai/components/tag-input.md +4 -0
- package/docs/ai/controllers.md +22 -6
- package/docs/components/calendar.md +24 -0
- package/docs/components/tag-input.md +6 -1
- package/docs/controllers.md +57 -6
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* snice v7.
|
|
2
|
+
* snice v7.7.0
|
|
3
3
|
* A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
|
|
4
4
|
* (c) 2024
|
|
5
5
|
* Released under the MIT License.
|
|
@@ -3053,7 +3053,7 @@ if(typeof globalThis.Snice==="undefined"){console.warn("[snice] snice-runtime.mi
|
|
|
3053
3053
|
return _classThis;
|
|
3054
3054
|
})();
|
|
3055
3055
|
|
|
3056
|
-
var cssContent$i = ":host([hidden]){display:none}:host{display:inline-block;position:relative;width:auto;cursor:pointer}:host([disabled]){cursor:not-allowed}:host([justify-text=start]) .button{justify-content:flex-start}:host([justify-text=end]) .button{justify-content:flex-end}:host([justify-text=center]) .button{justify-content:center}.button{display:inline-flex;align-items:center;justify-content:center;width:100%;border:1px solid;font-family:var(--snice-font-family, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif);font-weight:var(--snice-font-weight-medium,500);text-decoration:none;user-select:none;white-space:nowrap;vertical-align:middle;padding:0;box-shadow:var(--snice-shadow-xs,0 1px 2px 0 rgb(0 0 0 / .03));transition:color var(--snice-transition-fast, 150ms) var(--snice-ease-out, cubic-bezier(.22,1,.36,1)),background-color var(--snice-transition-fast, 150ms) var(--snice-ease-out, cubic-bezier(.22,1,.36,1)),border-color var(--snice-transition-fast, 150ms) var(--snice-ease-out, cubic-bezier(.22,1,.36,1)),box-shadow var(--snice-transition-fast, 150ms) var(--snice-ease-out, cubic-bezier(.22,1,.36,1)),transform 180ms var(--snice-ease-spring, cubic-bezier(.34,1.56,.64,1));cursor:inherit;position:relative}.button::before{content:'';position:absolute;inset:0;border-radius:inherit;background:var(--snice-gradient-convex,none);pointer-events:none}.button:active:not(.button--disabled){transition:color 50ms var(--snice-ease-out, ease),background-color 50ms var(--snice-ease-out, ease),border-color 50ms var(--snice-ease-out, ease),box-shadow 50ms var(--snice-ease-out, ease),transform 80ms var(--snice-ease-out, ease);transform:translateY(0) scale(.97)}.button:focus-visible{outline:0;box-shadow:0 0 0 var(--snice-focus-ring-width,2px) var(--snice-focus-ring-color,rgb(59 130 246 / .5))}.button--disabled{opacity:.5;cursor:not-allowed;box-shadow:none}.button--small{font-size:var(--snice-font-size-sm, .875rem);height:2rem;padding:0 var(--snice-spacing-sm,.75rem);border-radius:var(--snice-border-radius-md,.25rem)}.button--medium{font-size:var(--snice-font-size-md, 1rem);height:2.5rem;padding:0 var(--snice-spacing-md,1rem);border-radius:var(--snice-border-radius-md,.25rem)}.button--large{font-size:var(--snice-font-size-lg, 1.125rem);height:3rem;padding:0 var(--snice-spacing-lg,1.5rem);border-radius:var(--snice-border-radius-md,.25rem)}.button--default{background-color:var(--snice-color-surface,rgb(255 255 255));color:var(--snice-color-text,rgb(23 23 23));border-color:var(--snice-color-border,rgb(226 226 226))}.button--default:hover:not(.button--disabled){background-color:var(--snice-color-surface-container-low,rgb(250 250 250));border-color:var(--snice-color-border-hover,rgb(204 204 204));box-shadow:var(--snice-shadow-sm,0 1px 2px 0 rgb(0 0 0 / .05));transform:translateY(-1px)}.button--default:active:not(.button--disabled){background-color:var(--snice-color-surface-container,rgb(248 248 248));border-color:var(--snice-color-border-hover,rgb(204 204 204));box-shadow:var(--snice-shadow-inset-sm,inset 0 1px 2px rgb(0 0 0 / .05));transform:translateY(0) scale(.97)}.button--primary{background-color:var(--snice-color-primary,rgb(37 99 235));color:var(--snice-color-text-inverse,rgb(250 250 250));border-color:var(--snice-color-primary,rgb(37 99 235))}.button--primary:hover:not(.button--disabled){background-color:var(--snice-color-primary-hover,rgb(29 78 216));border-color:var(--snice-color-primary-hover,rgb(29 78 216));box-shadow:var(--snice-shadow-sm,0 1px 2px 0 rgb(0 0 0 / .05));transform:translateY(-1px)}.button--primary:active:not(.button--disabled){background-color:color-mix(in srgb,var(--snice-color-primary,rgb(37 99 235)) 85%,#fff);border-color:color-mix(in srgb,var(--snice-color-primary,rgb(37 99 235)) 85%,#fff);box-shadow:var(--snice-shadow-inset-sm,inset 0 1px 2px rgb(0 0 0 / .05));transform:translateY(0) scale(.97)}.button--success{background-color:var(--snice-color-success,rgb(22 163 74));color:var(--snice-color-text-inverse,rgb(250 250 250));border-color:var(--snice-color-success,rgb(22 163 74))}.button--success:hover:not(.button--disabled){background-color:var(--snice-color-success-hover,rgb(21 128 61));border-color:var(--snice-color-success-hover,rgb(21 128 61));box-shadow:var(--snice-shadow-sm,0 1px 2px 0 rgb(0 0 0 / .05));transform:translateY(-1px)}.button--success:active:not(.button--disabled){background-color:color-mix(in srgb,var(--snice-color-success,rgb(22 163 74)) 85%,#fff);border-color:color-mix(in srgb,var(--snice-color-success,rgb(22 163 74)) 85%,#fff);box-shadow:var(--snice-shadow-inset-sm,inset 0 1px 2px rgb(0 0 0 / .05));transform:translateY(0) scale(.97)}.button--warning{background-color:var(--snice-color-warning,rgb(202 138 4));color:var(--button-warning-text,rgb(69 26 3));border-color:var(--snice-color-warning,rgb(202 138 4))}.button--warning:hover:not(.button--disabled){background-color:var(--snice-color-warning-hover,rgb(161 98 7));border-color:var(--snice-color-warning-hover,rgb(161 98 7));box-shadow:var(--snice-shadow-sm,0 1px 2px 0 rgb(0 0 0 / .05));transform:translateY(-1px)}.button--warning:active:not(.button--disabled){background-color:color-mix(in srgb,var(--snice-color-warning,rgb(202 138 4)) 85%,#fff);border-color:color-mix(in srgb,var(--snice-color-warning,rgb(202 138 4)) 85%,#fff);box-shadow:var(--snice-shadow-inset-sm,inset 0 1px 2px rgb(0 0 0 / .05));transform:translateY(0) scale(.97)}.button--danger{background-color:var(--snice-color-danger,rgb(220 38 38));color:var(--snice-color-text-inverse,rgb(250 250 250));border-color:var(--snice-color-danger,rgb(220 38 38))}.button--danger:hover:not(.button--disabled){background-color:var(--snice-color-danger-hover,rgb(185 28 28));border-color:var(--snice-color-danger-hover,rgb(185 28 28));box-shadow:var(--snice-shadow-sm,0 1px 2px 0 rgb(0 0 0 / .05));transform:translateY(-1px)}.button--danger:active:not(.button--disabled){background-color:color-mix(in srgb,var(--snice-color-danger,rgb(220 38 38)) 85%,#fff);border-color:color-mix(in srgb,var(--snice-color-danger,rgb(220 38 38)) 85%,#fff);box-shadow:var(--snice-shadow-inset-sm,inset 0 1px 2px rgb(0 0 0 / .05));transform:translateY(0) scale(.97)}.button--text{background-color:transparent;color:var(--snice-color-primary,rgb(37 99 235));border-color:transparent;box-shadow:none}.button--text::before{display:none}.button--text:hover:not(.button--disabled){background-color:var(--snice-color-primary-alpha,rgb(37 99 235 / .1));color:var(--snice-color-primary-hover,rgb(29 78 216));box-shadow:none;transform:none}.button--text:active:not(.button--disabled){background-color:var(--snice-color-primary-alpha-strong,rgb(37 99 235 / .15));box-shadow:none;transform:none}.button--outline{box-shadow:none}.button--outline::before{display:none}.button--outline.button--default{background-color:transparent;color:var(--snice-color-text,rgb(23 23 23))}.button--outline.button--primary{background-color:transparent;color:var(--snice-color-primary,rgb(37 99 235))}.button--outline.button--success{background-color:transparent;color:var(--snice-color-success,rgb(22 163 74))}.button--outline.button--warning{background-color:transparent;color:var(--snice-color-warning,rgb(202 138 4))}.button--outline.button--danger{background-color:transparent;color:var(--snice-color-danger,rgb(220 38 38))}.button--outline.button--default:hover:not(.button--disabled){background-color:var(--snice-color-surface-hover,rgb(245 245 245));box-shadow:none;transform:none}.button--outline.button--primary:hover:not(.button--disabled){background-color:var(--snice-color-primary-subtle,rgb(239 246 255));color:var(--snice-color-primary-hover,rgb(29 78 216));box-shadow:none;transform:none}.button--outline.button--success:hover:not(.button--disabled){background-color:var(--snice-color-success-subtle,rgb(220 252 231));color:var(--snice-color-success-hover,rgb(21 128 61));box-shadow:none;transform:none}.button--outline.button--warning:hover:not(.button--disabled){background-color:var(--snice-color-warning-subtle,rgb(254 249 195));color:var(--snice-color-warning-hover,rgb(161 98 7));box-shadow:none;transform:none}.button--outline.button--danger:hover:not(.button--disabled){background-color:var(--snice-color-danger-subtle,rgb(254 226 226));color:var(--snice-color-danger-hover,rgb(185 28 28));box-shadow:none;transform:none}.button--outline:active:not(.button--disabled){background-color:var(--snice-color-primary-subtle-hover,var(--snice-color-surface-active,rgb(235 235 235)));box-shadow:none;transform:none}.button--pill{border-radius:var(--snice-border-radius-pill,9999px)}.button--circle{border-radius:var(--snice-border-radius-circle,50%);width:var(--size);padding:0}.button--small.button--circle{--size:2rem}.button--medium.button--circle{--size:2.5rem}.button--large.button--circle{--size:3rem}.button--loading{position:relative;cursor:wait}.button--loading .label{visibility:hidden}.spinner{display:none;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:1em;height:1em}.button--loading .spinner{display:block}.spinner::after{content:'';display:block;width:100%;height:100%;box-sizing:border-box;border:2px solid currentColor;border-right-color:transparent;border-radius:50%;animation:.6s linear infinite spin}@keyframes spin{to{transform:rotate(360deg)}}.icon-slot{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:1.25em;height:1.25em;line-height:1}.icon-slot:empty{display:none}.icon{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:1.25em;height:1.25em;line-height:1}.icon img{width:100%;height:100%;object-fit:contain}.icon svg{width:100%;height:100%}.icon-slot ::slotted(*){display:flex;align-items:center;justify-content:center;font-size:1.25em;line-height:1}.icon-slot ::slotted(svg){width:1.25em;height:1.25em}.icon-slot ::slotted(img){width:1.25em;height:1.25em;object-fit:contain}.button--icon-start .icon,.button--icon-start .icon-slot{margin-right:.5em}.button--icon-end .icon,.button--icon-end .icon-slot{margin-left:.5em}.button--circle .icon,.button--circle .icon-slot{margin:0;transform:none;width:auto;height:auto}.button--circle .icon-slot ::slotted(*){font-size:1.25em;line-height:1;display:flex;align-items:center;justify-content:center}.button--circle .icon-slot ::slotted(svg){width:1.25em;height:1.25em}@media (prefers-reduced-motion:reduce){.icon-slot,.spinner,button,button:active{transition-duration:0s!important;animation-duration:0s!important}button:active{transform:none}}";
|
|
3056
|
+
var cssContent$i = ":host([hidden]){display:none}:host{display:inline-block;position:relative;width:auto;cursor:pointer}:host([disabled]){cursor:not-allowed}:host([justify-text=start]) .button{justify-content:flex-start}:host([justify-text=end]) .button{justify-content:flex-end}:host([justify-text=center]) .button{justify-content:center}.button{display:inline-flex;align-items:center;justify-content:center;width:100%;border:1px solid;font-family:var(--snice-font-family, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif);font-weight:var(--snice-font-weight-medium,500);text-decoration:none;user-select:none;white-space:nowrap;vertical-align:middle;padding:0;box-shadow:var(--snice-shadow-xs,0 1px 2px 0 rgb(0 0 0 / .03));transition:color var(--snice-transition-fast, 150ms) var(--snice-ease-out, cubic-bezier(.22,1,.36,1)),background-color var(--snice-transition-fast, 150ms) var(--snice-ease-out, cubic-bezier(.22,1,.36,1)),border-color var(--snice-transition-fast, 150ms) var(--snice-ease-out, cubic-bezier(.22,1,.36,1)),box-shadow var(--snice-transition-fast, 150ms) var(--snice-ease-out, cubic-bezier(.22,1,.36,1)),transform 180ms var(--snice-ease-spring, cubic-bezier(.34,1.56,.64,1));cursor:inherit;position:relative}.button::before{content:'';position:absolute;inset:0;border-radius:inherit;background:var(--snice-gradient-convex,none);pointer-events:none}.button:active:not(.button--disabled){transition:color 50ms var(--snice-ease-out, ease),background-color 50ms var(--snice-ease-out, ease),border-color 50ms var(--snice-ease-out, ease),box-shadow 50ms var(--snice-ease-out, ease),transform 80ms var(--snice-ease-out, ease);transform:translateY(0) scale(.97)}.button:focus-visible{outline:0;box-shadow:0 0 0 var(--snice-focus-ring-width,2px) var(--snice-focus-ring-color,rgb(59 130 246 / .5))}.button--disabled{opacity:.5;cursor:not-allowed;box-shadow:none}.button--small{font-size:var(--snice-font-size-sm, .875rem);height:2rem;padding:0 var(--snice-spacing-sm,.75rem);border-radius:var(--snice-border-radius-md,.25rem)}.button--medium{font-size:var(--snice-font-size-md, 1rem);height:2.5rem;padding:0 var(--snice-spacing-md,1rem);border-radius:var(--snice-border-radius-md,.25rem)}.button--large{font-size:var(--snice-font-size-lg, 1.125rem);height:3rem;padding:0 var(--snice-spacing-lg,1.5rem);border-radius:var(--snice-border-radius-md,.25rem)}.button--default{background-color:var(--snice-color-surface,rgb(255 255 255));color:var(--snice-color-text,rgb(23 23 23));border-color:var(--snice-color-border,rgb(226 226 226))}.button--default:hover:not(.button--disabled){background-color:var(--snice-color-surface-container-low,rgb(250 250 250));border-color:var(--snice-color-border-hover,rgb(204 204 204));box-shadow:var(--snice-shadow-sm,0 1px 2px 0 rgb(0 0 0 / .05));transform:translateY(-1px)}.button--default:active:not(.button--disabled){background-color:var(--snice-color-surface-container,rgb(248 248 248));border-color:var(--snice-color-border-hover,rgb(204 204 204));box-shadow:var(--snice-shadow-inset-sm,inset 0 1px 2px rgb(0 0 0 / .05));transform:translateY(0) scale(.97)}.button--primary{background-color:var(--snice-color-primary,rgb(37 99 235));color:var(--snice-color-text-inverse,rgb(250 250 250));border-color:var(--snice-color-primary,rgb(37 99 235))}.button--primary:hover:not(.button--disabled){background-color:var(--snice-color-primary-hover,rgb(29 78 216));border-color:var(--snice-color-primary-hover,rgb(29 78 216));box-shadow:var(--snice-shadow-sm,0 1px 2px 0 rgb(0 0 0 / .05));transform:translateY(-1px)}.button--primary:active:not(.button--disabled){background-color:color-mix(in srgb,var(--snice-color-primary,rgb(37 99 235)) 85%,#fff);border-color:color-mix(in srgb,var(--snice-color-primary,rgb(37 99 235)) 85%,#fff);box-shadow:var(--snice-shadow-inset-sm,inset 0 1px 2px rgb(0 0 0 / .05));transform:translateY(0) scale(.97)}.button--success{background-color:var(--snice-color-success,rgb(22 163 74));color:var(--snice-color-text-inverse,rgb(250 250 250));border-color:var(--snice-color-success,rgb(22 163 74))}.button--success:hover:not(.button--disabled){background-color:var(--snice-color-success-hover,rgb(21 128 61));border-color:var(--snice-color-success-hover,rgb(21 128 61));box-shadow:var(--snice-shadow-sm,0 1px 2px 0 rgb(0 0 0 / .05));transform:translateY(-1px)}.button--success:active:not(.button--disabled){background-color:color-mix(in srgb,var(--snice-color-success,rgb(22 163 74)) 85%,#fff);border-color:color-mix(in srgb,var(--snice-color-success,rgb(22 163 74)) 85%,#fff);box-shadow:var(--snice-shadow-inset-sm,inset 0 1px 2px rgb(0 0 0 / .05));transform:translateY(0) scale(.97)}.button--warning{background-color:var(--snice-color-warning,rgb(202 138 4));color:var(--button-warning-text,rgb(69 26 3));border-color:var(--snice-color-warning,rgb(202 138 4))}.button--warning:hover:not(.button--disabled){background-color:var(--snice-color-warning-hover,rgb(161 98 7));border-color:var(--snice-color-warning-hover,rgb(161 98 7));box-shadow:var(--snice-shadow-sm,0 1px 2px 0 rgb(0 0 0 / .05));transform:translateY(-1px)}.button--warning:active:not(.button--disabled){background-color:color-mix(in srgb,var(--snice-color-warning,rgb(202 138 4)) 85%,#fff);border-color:color-mix(in srgb,var(--snice-color-warning,rgb(202 138 4)) 85%,#fff);box-shadow:var(--snice-shadow-inset-sm,inset 0 1px 2px rgb(0 0 0 / .05));transform:translateY(0) scale(.97)}.button--danger{background-color:var(--snice-color-danger,rgb(220 38 38));color:var(--snice-color-text-inverse,rgb(250 250 250));border-color:var(--snice-color-danger,rgb(220 38 38))}.button--danger:hover:not(.button--disabled){background-color:var(--snice-color-danger-hover,rgb(185 28 28));border-color:var(--snice-color-danger-hover,rgb(185 28 28));box-shadow:var(--snice-shadow-sm,0 1px 2px 0 rgb(0 0 0 / .05));transform:translateY(-1px)}.button--danger:active:not(.button--disabled){background-color:color-mix(in srgb,var(--snice-color-danger,rgb(220 38 38)) 85%,#fff);border-color:color-mix(in srgb,var(--snice-color-danger,rgb(220 38 38)) 85%,#fff);box-shadow:var(--snice-shadow-inset-sm,inset 0 1px 2px rgb(0 0 0 / .05));transform:translateY(0) scale(.97)}.button--text{background-color:transparent;color:var(--snice-color-primary,rgb(37 99 235));border-color:transparent;box-shadow:none}.button--text::before{display:none}.button--text:hover:not(.button--disabled){background-color:var(--snice-color-primary-alpha,rgb(37 99 235 / .1));color:var(--snice-color-primary-hover,rgb(29 78 216));box-shadow:none;transform:none}.button--text:active:not(.button--disabled){background-color:var(--snice-color-primary-alpha-strong,rgb(37 99 235 / .15));box-shadow:none;transform:none}.button--outline{box-shadow:none}.button--outline::before{display:none}.button--outline.button--default{background-color:transparent;color:var(--snice-color-text,rgb(23 23 23))}.button--outline.button--primary{background-color:transparent;color:var(--snice-color-primary,rgb(37 99 235))}.button--outline.button--success{background-color:transparent;color:var(--snice-color-success,rgb(22 163 74))}.button--outline.button--warning{background-color:transparent;color:var(--snice-color-warning,rgb(202 138 4))}.button--outline.button--danger{background-color:transparent;color:var(--snice-color-danger,rgb(220 38 38))}.button--outline.button--default:hover:not(.button--disabled){background-color:var(--snice-color-surface-hover,rgb(245 245 245));box-shadow:none;transform:none}.button--outline.button--primary:hover:not(.button--disabled){background-color:var(--snice-color-primary-subtle,rgb(239 246 255));color:var(--snice-color-primary-hover,rgb(29 78 216));box-shadow:none;transform:none}.button--outline.button--success:hover:not(.button--disabled){background-color:var(--snice-color-success-subtle,rgb(220 252 231));color:var(--snice-color-success-hover,rgb(21 128 61));box-shadow:none;transform:none}.button--outline.button--warning:hover:not(.button--disabled){background-color:var(--snice-color-warning-subtle,rgb(254 249 195));color:var(--snice-color-warning-hover,rgb(161 98 7));box-shadow:none;transform:none}.button--outline.button--danger:hover:not(.button--disabled){background-color:var(--snice-color-danger-subtle,rgb(254 226 226));color:var(--snice-color-danger-hover,rgb(185 28 28));box-shadow:none;transform:none}.button--outline:active:not(.button--disabled){background-color:var(--snice-color-primary-subtle-hover,var(--snice-color-surface-active,rgb(235 235 235)));box-shadow:none;transform:none}.button--pill{border-radius:var(--snice-border-radius-pill,9999px)}.button--circle{border-radius:var(--snice-border-radius-circle,50%);width:var(--size);padding:0}.button--small.button--circle{--size:2rem}.button--medium.button--circle{--size:2.5rem}.button--large.button--circle{--size:3rem}.button--loading{position:relative;cursor:wait}.button--loading .label{visibility:hidden}.spinner{display:none;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:1em;height:1em}.button--loading .spinner{display:block}.spinner::after{content:'';display:block;width:100%;height:100%;box-sizing:border-box;border:2px solid currentColor;border-right-color:transparent;border-radius:50%;animation:.6s linear infinite spin}@keyframes spin{to{transform:rotate(360deg)}}.icon-slot{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:1.25em;height:1.25em;line-height:1}.icon-slot:empty{display:none}.icon{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:1.25em;height:1.25em;line-height:1}.icon img{width:100%;height:100%;object-fit:contain}.icon svg{width:100%;height:100%}.icon-slot ::slotted(*){display:flex;align-items:center;justify-content:center;font-size:1.25em;line-height:1}.icon-slot ::slotted(svg){width:1.25em;height:1.25em}.icon-slot ::slotted(img){width:1.25em;height:1.25em;object-fit:contain}.button--icon-start .icon,.button--icon-start .icon-slot{margin-right:.5em}.button--icon-end .icon,.button--icon-end .icon-slot{margin-left:.5em}.button--circle .icon,.button--circle .icon-slot{margin:0;transform:none;width:auto;height:auto}.button--circle .icon svg{width:1.25em;height:1.25em}.button--circle .icon-slot ::slotted(*){font-size:1.25em;line-height:1;display:flex;align-items:center;justify-content:center}.button--circle .icon-slot ::slotted(svg){width:1.25em;height:1.25em}@media (prefers-reduced-motion:reduce){.icon-slot,.spinner,button,button:active{transition-duration:0s!important;animation-duration:0s!important}button:active{transform:none}}";
|
|
3057
3057
|
|
|
3058
3058
|
(() => {
|
|
3059
3059
|
let _classDecorators = [snice.element('snice-button', { formAssociated: true, delegatesFocus: true })];
|
|
@@ -4274,6 +4274,17 @@ if(typeof globalThis.Snice==="undefined"){console.warn("[snice] snice-runtime.mi
|
|
|
4274
4274
|
* Give every standalone specialized table cell the common ColumnDefinition
|
|
4275
4275
|
* presentation contract. The observer reapplies after Snice's differential
|
|
4276
4276
|
* renderer changes shadow content; equality guards prevent mutation loops.
|
|
4277
|
+
*
|
|
4278
|
+
* Display formatters
|
|
4279
|
+
* ------------------
|
|
4280
|
+
* `formatter` is the column's display formatter and `valueFormatter` its
|
|
4281
|
+
* fallback, so `formatter` wins. `formatterOverride` says the cell does NOT
|
|
4282
|
+
* apply `column.formatter` itself, so this module owns both formatters for it.
|
|
4283
|
+
*
|
|
4284
|
+
* A host marked `formatted` was handed its display text as `value` by the
|
|
4285
|
+
* table, which already resolved the pipeline. Its content is that text
|
|
4286
|
+
* verbatim — the marker exists so a rating/progress/link/tag cell, which
|
|
4287
|
+
* renders structure rather than text, still shows the formatted string.
|
|
4277
4288
|
*/
|
|
4278
4289
|
function installCellPresentation(host, formatterOverride = false) {
|
|
4279
4290
|
if (installed.has(host))
|
|
@@ -4320,15 +4331,21 @@ if(typeof globalThis.Snice==="undefined"){console.warn("[snice] snice-runtime.mi
|
|
|
4320
4331
|
? column.tooltip(host.value, host.rowData)
|
|
4321
4332
|
: (host.value == null ? '' : String(host.value));
|
|
4322
4333
|
}
|
|
4323
|
-
|
|
4324
|
-
|
|
4325
|
-
|
|
4326
|
-
|
|
4334
|
+
// `formatter` beats `valueFormatter`. A cell that applies `formatter`
|
|
4335
|
+
// itself has already painted it, so the fallback must not overwrite that
|
|
4336
|
+
// content — only a formatter-less column falls through to valueFormatter.
|
|
4337
|
+
const formatter = column.formatter
|
|
4338
|
+
? (formatterOverride ? column.formatter : null)
|
|
4339
|
+
: column.valueFormatter;
|
|
4340
|
+
// Pre-formatted hosts read the attribute, not the property: a cell whose
|
|
4341
|
+
// value property is typed (boolean, number) coerces the display string.
|
|
4342
|
+
const display = host.hasAttribute('formatted')
|
|
4343
|
+
? (host.getAttribute('value') ?? '')
|
|
4344
|
+
: (formatter ? String(formatter(host.value, host.rowData) ?? '') : null);
|
|
4345
|
+
if (display !== null) {
|
|
4327
4346
|
const content = host.shadowRoot?.querySelector('[part~="content"]');
|
|
4328
|
-
if (
|
|
4329
|
-
|
|
4330
|
-
if (content.textContent !== value || content.childElementCount > 0)
|
|
4331
|
-
content.textContent = value;
|
|
4347
|
+
if (content && (content.textContent !== display || content.childElementCount > 0)) {
|
|
4348
|
+
content.textContent = display;
|
|
4332
4349
|
}
|
|
4333
4350
|
}
|
|
4334
4351
|
}
|
|
@@ -9421,6 +9438,15 @@ if(typeof globalThis.Snice==="undefined"){console.warn("[snice] snice-runtime.mi
|
|
|
9421
9438
|
this.updateRowAttributes();
|
|
9422
9439
|
this.configureCells();
|
|
9423
9440
|
}
|
|
9441
|
+
/**
|
|
9442
|
+
* The column's working value for this row: `valueGetter` runs for display
|
|
9443
|
+
* here exactly as it does on the table's own render path, so a column whose
|
|
9444
|
+
* key names a server field rather than a row field still paints.
|
|
9445
|
+
*/
|
|
9446
|
+
cellValue(column) {
|
|
9447
|
+
const raw = this.data?.[column.key];
|
|
9448
|
+
return column.valueGetter ? column.valueGetter(raw, this.data) : raw;
|
|
9449
|
+
}
|
|
9424
9450
|
configureCells() {
|
|
9425
9451
|
if (!this.columns) {
|
|
9426
9452
|
return;
|
|
@@ -9428,7 +9454,7 @@ if(typeof globalThis.Snice==="undefined"){console.warn("[snice] snice-runtime.mi
|
|
|
9428
9454
|
this.columns.forEach((column, index) => {
|
|
9429
9455
|
const cellElement = this.shadowRoot?.querySelector(`[data-column-index="${index}"]`);
|
|
9430
9456
|
if (cellElement) {
|
|
9431
|
-
const value = this.
|
|
9457
|
+
const value = this.cellValue(column);
|
|
9432
9458
|
if (typeof column.renderCell === 'function') {
|
|
9433
9459
|
const output = column.renderCell(value, this.data, column);
|
|
9434
9460
|
const replacement = output instanceof HTMLElement ? output : document.createElement('span');
|
|
@@ -9440,7 +9466,7 @@ if(typeof globalThis.Snice==="undefined"){console.warn("[snice] snice-runtime.mi
|
|
|
9440
9466
|
return;
|
|
9441
9467
|
}
|
|
9442
9468
|
const formatter = column.formatter || column.valueFormatter;
|
|
9443
|
-
cellElement.value = formatter ? formatter(value, this.data) : value;
|
|
9469
|
+
cellElement.value = formatter ? String(formatter(value, this.data) ?? '') : value;
|
|
9444
9470
|
cellElement.column = formatter
|
|
9445
9471
|
? { ...column, type: 'text', formatter: undefined, valueFormatter: undefined }
|
|
9446
9472
|
: column;
|
|
@@ -9530,7 +9556,6 @@ if(typeof globalThis.Snice==="undefined"){console.warn("[snice] snice-runtime.mi
|
|
|
9530
9556
|
`;
|
|
9531
9557
|
}
|
|
9532
9558
|
renderCell(column, columnIndex) {
|
|
9533
|
-
this.data[column.key];
|
|
9534
9559
|
const cellComponent = this.getCellComponent(column.formatter || column.valueFormatter ? 'text' : column.type);
|
|
9535
9560
|
return snice.html /*html*/ `
|
|
9536
9561
|
<div class="cell cell--${column.type}" part="cell" style="${this.getCellStyles(column)}">
|
|
@@ -10937,7 +10962,7 @@ if(typeof globalThis.Snice==="undefined"){console.warn("[snice] snice-runtime.mi
|
|
|
10937
10962
|
});
|
|
10938
10963
|
}
|
|
10939
10964
|
// Body rows
|
|
10940
|
-
const bodyRows = table.querySelectorAll('tbody tr:not(.virtual-spacer)');
|
|
10965
|
+
const bodyRows = table.querySelectorAll('tbody tr:not(.virtual-spacer):not(.table-fill-row)');
|
|
10941
10966
|
bodyRows.forEach((row, i) => {
|
|
10942
10967
|
row.setAttribute('role', 'row');
|
|
10943
10968
|
row.setAttribute('aria-rowindex', String(this.ariaRowOffset + i + 2)); // +2 for 1-based + header
|
|
@@ -11144,7 +11169,7 @@ if(typeof globalThis.Snice==="undefined"){console.warn("[snice] snice-runtime.mi
|
|
|
11144
11169
|
// Data rows
|
|
11145
11170
|
for (const row of data) {
|
|
11146
11171
|
const cells = exportColumns.map(c => {
|
|
11147
|
-
const value = row
|
|
11172
|
+
const value = this.cellValue(row, c);
|
|
11148
11173
|
return this.escapeCSV(value == null ? '' : String(value), delimiter);
|
|
11149
11174
|
});
|
|
11150
11175
|
rows.push(cells.join(delimiter));
|
|
@@ -11256,7 +11281,7 @@ if(typeof globalThis.Snice==="undefined"){console.warn("[snice] snice-runtime.mi
|
|
|
11256
11281
|
if (rows.length === 0)
|
|
11257
11282
|
return false;
|
|
11258
11283
|
const text = rows.map(row => columns.map(c => {
|
|
11259
|
-
const value = row
|
|
11284
|
+
const value = this.cellValue(row, c);
|
|
11260
11285
|
return useFormatted ? this.formatValue(value, row, c) : this.rawValue(value);
|
|
11261
11286
|
}).join(delimiter)).join('\n');
|
|
11262
11287
|
try {
|
|
@@ -11281,6 +11306,15 @@ if(typeof globalThis.Snice==="undefined"){console.warn("[snice] snice-runtime.mi
|
|
|
11281
11306
|
}
|
|
11282
11307
|
return value;
|
|
11283
11308
|
}
|
|
11309
|
+
/**
|
|
11310
|
+
* The column's working value for a row: `valueGetter` "runs for display,
|
|
11311
|
+
* sort, aggregation" — and for export, which must ship what the table shows,
|
|
11312
|
+
* not a row field the column may not even have.
|
|
11313
|
+
*/
|
|
11314
|
+
cellValue(row, column) {
|
|
11315
|
+
const raw = row?.[column.key];
|
|
11316
|
+
return column.valueGetter ? column.valueGetter(raw, row) : raw;
|
|
11317
|
+
}
|
|
11284
11318
|
rawValue(value) {
|
|
11285
11319
|
if (value == null)
|
|
11286
11320
|
return '';
|
|
@@ -11385,6 +11419,8 @@ if(typeof globalThis.Snice==="undefined"){console.warn("[snice] snice-runtime.mi
|
|
|
11385
11419
|
this.options = null;
|
|
11386
11420
|
this.tableElement = null;
|
|
11387
11421
|
this.contentCache = new Map();
|
|
11422
|
+
/** Last value signature seen per row, so in-place mutations evict the cache. */
|
|
11423
|
+
this.fingerprints = new Map();
|
|
11388
11424
|
this.rowByIndex = new Map();
|
|
11389
11425
|
this.measuredHeights = new Map();
|
|
11390
11426
|
this.onHeightChange = null;
|
|
@@ -11393,18 +11429,33 @@ if(typeof globalThis.Snice==="undefined"){console.warn("[snice] snice-runtime.mi
|
|
|
11393
11429
|
this.tableElement = tableEl;
|
|
11394
11430
|
this.options = options;
|
|
11395
11431
|
this.contentCache.clear();
|
|
11432
|
+
this.fingerprints.clear();
|
|
11396
11433
|
this.rowByIndex.clear();
|
|
11397
11434
|
this.measuredHeights.clear();
|
|
11398
11435
|
}
|
|
11399
|
-
/**
|
|
11400
|
-
|
|
11436
|
+
/**
|
|
11437
|
+
* Eagerly construct detail content when lazy=false.
|
|
11438
|
+
*
|
|
11439
|
+
* `fingerprint` (the table's per-row value signature) also evicts rows whose
|
|
11440
|
+
* fields were mutated in place: the cache is keyed by row identity, so an
|
|
11441
|
+
* unchanged identity would otherwise keep serving a panel built from the
|
|
11442
|
+
* pre-mutation values.
|
|
11443
|
+
*/
|
|
11444
|
+
prepare(rows, fingerprint) {
|
|
11401
11445
|
if (!this.options)
|
|
11402
11446
|
return;
|
|
11403
11447
|
this.rowByIndex = new Map(rows.map((row, index) => [index, row]));
|
|
11404
11448
|
const currentRows = new Set(rows);
|
|
11405
|
-
for (const row of this.contentCache.keys()) {
|
|
11449
|
+
for (const row of [...this.contentCache.keys()]) {
|
|
11406
11450
|
if (!currentRows.has(row))
|
|
11407
11451
|
this.contentCache.delete(row);
|
|
11452
|
+
else if (fingerprint && this.fingerprints.get(row) !== fingerprint(row)) {
|
|
11453
|
+
this.contentCache.delete(row);
|
|
11454
|
+
this.measuredHeights.delete(row);
|
|
11455
|
+
}
|
|
11456
|
+
}
|
|
11457
|
+
if (fingerprint) {
|
|
11458
|
+
this.fingerprints = new Map(rows.map(row => [row, fingerprint(row)]));
|
|
11408
11459
|
}
|
|
11409
11460
|
for (const row of this.measuredHeights.keys()) {
|
|
11410
11461
|
if (!currentRows.has(row))
|
|
@@ -13193,6 +13244,7 @@ if(typeof globalThis.Snice==="undefined"){console.warn("[snice] snice-runtime.mi
|
|
|
13193
13244
|
let _getTableData_decorators;
|
|
13194
13245
|
let _styles_decorators;
|
|
13195
13246
|
let _render_decorators;
|
|
13247
|
+
let _handleFrameResize_decorators;
|
|
13196
13248
|
let _initialize_decorators;
|
|
13197
13249
|
let _handleDeclarativeColumnChange_decorators;
|
|
13198
13250
|
let _handleSelectorOptionsChange_decorators;
|
|
@@ -13290,6 +13342,7 @@ if(typeof globalThis.Snice==="undefined"){console.warn("[snice] snice-runtime.mi
|
|
|
13290
13342
|
_getTableData_decorators = [snice.request('table/data')];
|
|
13291
13343
|
_styles_decorators = [snice.styles()];
|
|
13292
13344
|
_render_decorators = [snice.render()];
|
|
13345
|
+
_handleFrameResize_decorators = [snice.observe('resize', '.table-frame')];
|
|
13293
13346
|
_initialize_decorators = [snice.ready()];
|
|
13294
13347
|
_handleDeclarativeColumnChange_decorators = [snice.on('column-changed')];
|
|
13295
13348
|
_handleSelectorOptionsChange_decorators = [snice.watch('selectorOptions')];
|
|
@@ -13338,6 +13391,7 @@ if(typeof globalThis.Snice==="undefined"){console.warn("[snice] snice-runtime.mi
|
|
|
13338
13391
|
__esDecorate(this, null, _getTableData_decorators, { kind: "method", name: "getTableData", static: false, private: false, access: { has: obj => "getTableData" in obj, get: obj => obj.getTableData }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
13339
13392
|
__esDecorate(this, null, _styles_decorators, { kind: "method", name: "styles", static: false, private: false, access: { has: obj => "styles" in obj, get: obj => obj.styles }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
13340
13393
|
__esDecorate(this, null, _render_decorators, { kind: "method", name: "render", static: false, private: false, access: { has: obj => "render" in obj, get: obj => obj.render }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
13394
|
+
__esDecorate(this, null, _handleFrameResize_decorators, { kind: "method", name: "handleFrameResize", static: false, private: false, access: { has: obj => "handleFrameResize" in obj, get: obj => obj.handleFrameResize }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
13341
13395
|
__esDecorate(this, null, _initialize_decorators, { kind: "method", name: "initialize", static: false, private: false, access: { has: obj => "initialize" in obj, get: obj => obj.initialize }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
13342
13396
|
__esDecorate(this, null, _handleDeclarativeColumnChange_decorators, { kind: "method", name: "handleDeclarativeColumnChange", static: false, private: false, access: { has: obj => "handleDeclarativeColumnChange" in obj, get: obj => obj.handleDeclarativeColumnChange }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
13343
13397
|
__esDecorate(this, null, _handleSelectorOptionsChange_decorators, { kind: "method", name: "handleSelectorOptionsChange", static: false, private: false, access: { has: obj => "handleSelectorOptionsChange" in obj, get: obj => obj.handleSelectorOptionsChange }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
@@ -13656,6 +13710,27 @@ if(typeof globalThis.Snice==="undefined"){console.warn("[snice] snice-runtime.mi
|
|
|
13656
13710
|
border-bottom: none;
|
|
13657
13711
|
}
|
|
13658
13712
|
|
|
13713
|
+
/* Height fill: when the host is taller than its rows, an inert filler
|
|
13714
|
+
row (cloned from the last data row, so column widths and pinning
|
|
13715
|
+
track the table engine) keeps the column grid running to the bottom
|
|
13716
|
+
edge instead of the borders cutting off where the rows end. */
|
|
13717
|
+
tbody tr.table-fill-row {
|
|
13718
|
+
pointer-events: none;
|
|
13719
|
+
}
|
|
13720
|
+
|
|
13721
|
+
tbody tr.table-fill-row td {
|
|
13722
|
+
border-bottom: none;
|
|
13723
|
+
padding: 0;
|
|
13724
|
+
}
|
|
13725
|
+
|
|
13726
|
+
:host([striped]) tbody tr.table-fill-row {
|
|
13727
|
+
background: transparent;
|
|
13728
|
+
}
|
|
13729
|
+
|
|
13730
|
+
:host([hoverable]) tbody tr.table-fill-row:hover {
|
|
13731
|
+
background: transparent;
|
|
13732
|
+
}
|
|
13733
|
+
|
|
13659
13734
|
th {
|
|
13660
13735
|
padding: var(--snice-spacing-sm, 0.75rem) var(--snice-spacing-sm, 0.75rem);
|
|
13661
13736
|
}
|
|
@@ -14679,6 +14754,11 @@ if(typeof globalThis.Snice==="undefined"){console.warn("[snice] snice-runtime.mi
|
|
|
14679
14754
|
}
|
|
14680
14755
|
container.appendChild(controlsDiv);
|
|
14681
14756
|
}
|
|
14757
|
+
// Re-derive the fill row whenever the frame's box changes (host resized,
|
|
14758
|
+
// fullscreen toggled) — the leftover space below the rows changes with it.
|
|
14759
|
+
handleFrameResize() {
|
|
14760
|
+
this.updateFillRow();
|
|
14761
|
+
}
|
|
14682
14762
|
async initialize() {
|
|
14683
14763
|
// Listen for controller attached event
|
|
14684
14764
|
this.addEventListener('controller-attached', this.onAttached);
|
|
@@ -14980,8 +15060,14 @@ if(typeof globalThis.Snice==="undefined"){console.warn("[snice] snice-runtime.mi
|
|
|
14980
15060
|
if (this.settingSortedData)
|
|
14981
15061
|
return;
|
|
14982
15062
|
this.unsortedData = [...this.data];
|
|
15063
|
+
// C3: rows delivered while a client-side sort is active must land in that
|
|
15064
|
+
// sorted order — the currentSort watcher only fires when the sort itself
|
|
15065
|
+
// changes, so without this the body silently contradicts the header. In
|
|
15066
|
+
// remote mode the server owns the ordering.
|
|
15067
|
+
if (this.mode !== 'remote' && this.currentSort.length > 0)
|
|
15068
|
+
this.applyLocalSortOrder();
|
|
14983
15069
|
this.rebuildRowIndex();
|
|
14984
|
-
this.masterDetail.prepare(this.data);
|
|
15070
|
+
this.masterDetail.prepare(this.data, row => this.rowValueSignature(row));
|
|
14985
15071
|
if (this.settingDataImperative)
|
|
14986
15072
|
return; // imperative setData(): caller renders
|
|
14987
15073
|
this.scheduleRender('body');
|
|
@@ -15437,6 +15523,7 @@ if(typeof globalThis.Snice==="undefined"){console.warn("[snice] snice-runtime.mi
|
|
|
15437
15523
|
// Still render pagination
|
|
15438
15524
|
if (this.pagination)
|
|
15439
15525
|
this.renderPagination();
|
|
15526
|
+
this.updateSelectAllState();
|
|
15440
15527
|
return;
|
|
15441
15528
|
}
|
|
15442
15529
|
if (this.data.length === 0 && this.columns.length > 0) {
|
|
@@ -15653,10 +15740,52 @@ if(typeof globalThis.Snice==="undefined"){console.warn("[snice] snice-runtime.mi
|
|
|
15653
15740
|
this.reconcileRows(entries);
|
|
15654
15741
|
// Re-establish grid role + roving tabindex after the body changed.
|
|
15655
15742
|
this.keyboard.refresh();
|
|
15743
|
+
// The select-all control describes the *filtered* row set, so it goes stale
|
|
15744
|
+
// whenever the denominator moves (rows delivered, filter cleared) even
|
|
15745
|
+
// though `selectedRows` — its only other trigger — never changed.
|
|
15746
|
+
this.updateSelectAllState();
|
|
15656
15747
|
// Render pagination after body
|
|
15657
15748
|
if (this.pagination) {
|
|
15658
15749
|
this.renderPagination();
|
|
15659
15750
|
}
|
|
15751
|
+
this.updateFillRow();
|
|
15752
|
+
}
|
|
15753
|
+
/**
|
|
15754
|
+
* When the host is taller than its rows, append an inert filler row so the
|
|
15755
|
+
* column grid runs to the bottom edge of the frame. Cloned from the last
|
|
15756
|
+
* data row, so column widths, pinning, and alignment track the table
|
|
15757
|
+
* engine natively. Removed entirely when content fills (or overflows) the
|
|
15758
|
+
* frame, restoring the plain last-row styling.
|
|
15759
|
+
*/
|
|
15760
|
+
updateFillRow() {
|
|
15761
|
+
const frame = this.shadowRoot?.querySelector('.table-frame');
|
|
15762
|
+
const tableEl = frame?.querySelector('table');
|
|
15763
|
+
const tbody = tableEl?.querySelector('tbody');
|
|
15764
|
+
if (!frame || !tableEl || !tbody)
|
|
15765
|
+
return;
|
|
15766
|
+
tbody.querySelector('tr.table-fill-row')?.remove();
|
|
15767
|
+
if (this.list && this.listRenderer)
|
|
15768
|
+
return;
|
|
15769
|
+
const rows = tbody.querySelectorAll('tr[data-index]');
|
|
15770
|
+
const lastRow = rows[rows.length - 1];
|
|
15771
|
+
if (!lastRow)
|
|
15772
|
+
return;
|
|
15773
|
+
const leftover = Math.floor(frame.clientHeight - tableEl.offsetHeight);
|
|
15774
|
+
if (leftover <= 1)
|
|
15775
|
+
return;
|
|
15776
|
+
const fill = lastRow.cloneNode(true);
|
|
15777
|
+
fill.className = 'table-fill-row';
|
|
15778
|
+
for (const attr of ['data-index', 'data-selected', 'role', 'aria-rowindex', 'aria-selected', 'tabindex', 'id']) {
|
|
15779
|
+
fill.removeAttribute(attr);
|
|
15780
|
+
}
|
|
15781
|
+
fill.setAttribute('aria-hidden', 'true');
|
|
15782
|
+
fill.querySelectorAll('td').forEach(td => {
|
|
15783
|
+
td.replaceChildren();
|
|
15784
|
+
for (const attr of ['role', 'aria-colindex', 'tabindex', 'aria-selected'])
|
|
15785
|
+
td.removeAttribute(attr);
|
|
15786
|
+
});
|
|
15787
|
+
fill.style.height = `${leftover}px`;
|
|
15788
|
+
tbody.appendChild(fill);
|
|
15660
15789
|
}
|
|
15661
15790
|
// ── Task B: render-path reconciler ──────────────────────────────────────
|
|
15662
15791
|
//
|
|
@@ -15747,15 +15876,41 @@ if(typeof globalThis.Snice==="undefined"){console.warn("[snice] snice-runtime.mi
|
|
|
15747
15876
|
`tree=${this.treeData.isEnabled() ? this.treeData.getGroupColumn() : ''}`,
|
|
15748
15877
|
].join('|');
|
|
15749
15878
|
}
|
|
15879
|
+
/**
|
|
15880
|
+
* A fingerprint of a row's own field values, so a row object that was mutated
|
|
15881
|
+
* IN PLACE (the same identity re-delivered by a poll/websocket patch, or an
|
|
15882
|
+
* array the app edits) is rebuilt instead of recycled with stale cells.
|
|
15883
|
+
*
|
|
15884
|
+
* Tradeoff, deliberately chosen: this walks the row's OWN, SHALLOW fields
|
|
15885
|
+
* rather than running each column's valueGetter/formatter. It therefore costs
|
|
15886
|
+
* one string build per rendered row — never a user callback, so call counts
|
|
15887
|
+
* for `valueGetter` stay exactly one per row per render — and it still catches
|
|
15888
|
+
* getter-derived columns, because a getter reads the fields this covers.
|
|
15889
|
+
* Nested objects collapse to their String() form, so a mutation buried inside
|
|
15890
|
+
* a nested object (or an object rendered by a JSON/progress cell) is not
|
|
15891
|
+
* detected; those callers should hand over a new row object. Recycling keeps
|
|
15892
|
+
* its payoff: rows whose values did not change are still reused untouched.
|
|
15893
|
+
*/
|
|
15894
|
+
rowValueSignature(rowData) {
|
|
15895
|
+
if (rowData === null || typeof rowData !== 'object')
|
|
15896
|
+
return String(rowData);
|
|
15897
|
+
const parts = [];
|
|
15898
|
+
for (const key of Object.keys(rowData)) {
|
|
15899
|
+
const value = rowData[key];
|
|
15900
|
+
parts.push(`${key}=${value === null || value === undefined ? '' : String(value)}`);
|
|
15901
|
+
}
|
|
15902
|
+
// A separator keeps {a:'1b'} from colliding with {a:'1',b:''}.
|
|
15903
|
+
return parts.join('|');
|
|
15904
|
+
}
|
|
15750
15905
|
/**
|
|
15751
15906
|
* The per-row rebuild signature. Selection and the plain data-index are
|
|
15752
15907
|
* re-stamped on reuse (not here) so they never force a rebuild; this captures
|
|
15753
|
-
*
|
|
15754
|
-
* when a feature embeds the index in a row-scoped
|
|
15755
|
-
* master-detail toggle index) — the index itself.
|
|
15908
|
+
* the row's cell values plus what a re-stamp cannot repair: tree node state,
|
|
15909
|
+
* per-row height, and — when a feature embeds the index in a row-scoped
|
|
15910
|
+
* closure (row DnD drag index, master-detail toggle index) — the index itself.
|
|
15756
15911
|
*/
|
|
15757
15912
|
rowSignature(rowData, index, structuralSig, treeRow) {
|
|
15758
|
-
const parts = [structuralSig];
|
|
15913
|
+
const parts = [structuralSig, `v:${this.rowValueSignature(rowData)}`];
|
|
15759
15914
|
if (treeRow)
|
|
15760
15915
|
parts.push(`t:${treeRow.depth}:${treeRow.expanded ? 1 : 0}:${treeRow.hasChildren ? 1 : 0}`);
|
|
15761
15916
|
if (this.rowHeightCallback)
|
|
@@ -15952,6 +16107,15 @@ if(typeof globalThis.Snice==="undefined"){console.warn("[snice] snice-runtime.mi
|
|
|
15952
16107
|
const active = page === this.currentPage ? ' pagination__btn--active' : '';
|
|
15953
16108
|
return `<button class="pagination__btn pagination__page${active}" data-page="${page}">${page}</button>`;
|
|
15954
16109
|
}
|
|
16110
|
+
/**
|
|
16111
|
+
* The column's display text, or null when the column declares no display
|
|
16112
|
+
* formatter. `formatter` (row-aware) is the display formatter and
|
|
16113
|
+
* `valueFormatter` its documented fallback, so `formatter` wins.
|
|
16114
|
+
*/
|
|
16115
|
+
cellDisplayText(column, value, row) {
|
|
16116
|
+
const formatter = column.formatter || column.valueFormatter;
|
|
16117
|
+
return formatter ? String(formatter(value, row) ?? '') : null;
|
|
16118
|
+
}
|
|
15955
16119
|
/** Create a cell element safely using createElement + setAttribute */
|
|
15956
16120
|
createCellElement(column, value, row) {
|
|
15957
16121
|
// E2: a custom renderCell bypasses the type-based cell entirely. A string
|
|
@@ -15976,22 +16140,38 @@ if(typeof globalThis.Snice==="undefined"){console.warn("[snice] snice-runtime.mi
|
|
|
15976
16140
|
if (column.align)
|
|
15977
16141
|
el.setAttribute('align', column.align);
|
|
15978
16142
|
el.setAttribute('in-table', 'true');
|
|
16143
|
+
// A declared display formatter makes the cell's value its DISPLAY text:
|
|
16144
|
+
// the pipeline (valueGetter -> formatter, valueFormatter as the fallback)
|
|
16145
|
+
// is resolved here, once, so the `value` channel a caller reads is what the
|
|
16146
|
+
// cell actually shows. The cell is marked `formatted` and handed a column
|
|
16147
|
+
// without the formatters, which keeps it from formatting again and tells
|
|
16148
|
+
// the shared presentation contract to paint the text over any type-specific
|
|
16149
|
+
// rendering (a rating/progress/link cell cannot render display text).
|
|
16150
|
+
const displayText = this.cellDisplayText(column, value, row);
|
|
16151
|
+
const cellColumn = displayText === null
|
|
16152
|
+
? column
|
|
16153
|
+
: { ...column, formatter: undefined, valueFormatter: undefined };
|
|
15979
16154
|
// Set the property directly so arrays/objects reach progress, sparkline,
|
|
15980
16155
|
// JSON, action, and tag cells without a lossy attribute conversion. Keep a
|
|
15981
16156
|
// primitive attribute for declarative inspection and CSS selectors.
|
|
15982
|
-
if (
|
|
16157
|
+
if (displayText !== null) {
|
|
16158
|
+
el.setAttribute('formatted', '');
|
|
16159
|
+
el.value = displayText;
|
|
16160
|
+
el.setAttribute('value', displayText);
|
|
16161
|
+
}
|
|
16162
|
+
else if (column.type === 'sparkline' && value !== null && typeof value === 'object') {
|
|
15983
16163
|
el.setAttribute('value', JSON.stringify(value));
|
|
15984
16164
|
if (Array.isArray(value))
|
|
15985
16165
|
el.data = value;
|
|
15986
16166
|
}
|
|
15987
16167
|
else {
|
|
15988
16168
|
el.value = value ?? '';
|
|
15989
|
-
|
|
15990
|
-
|
|
15991
|
-
|
|
16169
|
+
if (value === null || typeof value !== 'object') {
|
|
16170
|
+
el.setAttribute('value', String(value ?? ''));
|
|
16171
|
+
}
|
|
15992
16172
|
}
|
|
15993
16173
|
// Column definition as property (for formatter access etc.)
|
|
15994
|
-
el.column =
|
|
16174
|
+
el.column = cellColumn;
|
|
15995
16175
|
// Row-aware formatters, conditional formatting, and action-cell events all
|
|
15996
16176
|
// consume the originating row through the cell's property API.
|
|
15997
16177
|
el.rowData = row ?? null;
|
|
@@ -16281,7 +16461,12 @@ if(typeof globalThis.Snice==="undefined"){console.warn("[snice] snice-runtime.mi
|
|
|
16281
16461
|
this.sortLocalData();
|
|
16282
16462
|
}
|
|
16283
16463
|
}
|
|
16284
|
-
|
|
16464
|
+
/**
|
|
16465
|
+
* Reorder `this.data` to the current client-side sort (or back to delivery
|
|
16466
|
+
* order when the sort was cleared). Split out of sortLocalData so a fresh
|
|
16467
|
+
* delivery can land sorted without re-entering the render/index bookkeeping.
|
|
16468
|
+
*/
|
|
16469
|
+
applyLocalSortOrder() {
|
|
16285
16470
|
if (!this.unsortedData.length) {
|
|
16286
16471
|
this.unsortedData = [...this.data];
|
|
16287
16472
|
}
|
|
@@ -16296,16 +16481,19 @@ if(typeof globalThis.Snice==="undefined"){console.warn("[snice] snice-runtime.mi
|
|
|
16296
16481
|
for (const { column, direction } of this.currentSort) {
|
|
16297
16482
|
const colDef = this.columns.find(c => c.key === column);
|
|
16298
16483
|
const customComparator = colDef?.sortComparator;
|
|
16484
|
+
// The value pipeline feeds BOTH sort paths: valueGetter "runs for
|
|
16485
|
+
// display, sort, aggregation", so a custom comparator sees the same
|
|
16486
|
+
// derived value the cell shows (remote columns routinely key on the
|
|
16487
|
+
// server's sort field and bridge the display with a getter).
|
|
16488
|
+
const aVal = colDef?.valueGetter ? colDef.valueGetter(a[column], a) : a[column];
|
|
16489
|
+
const bVal = colDef?.valueGetter ? colDef.valueGetter(b[column], b) : b[column];
|
|
16299
16490
|
if (customComparator) {
|
|
16300
|
-
const cmp = customComparator(
|
|
16491
|
+
const cmp = customComparator(aVal, bVal, direction);
|
|
16301
16492
|
if (cmp !== 0)
|
|
16302
16493
|
return cmp;
|
|
16303
16494
|
}
|
|
16304
16495
|
else {
|
|
16305
|
-
|
|
16306
|
-
const aVal = colDef?.valueGetter ? colDef.valueGetter(a[column], a) : (a[column] ?? '');
|
|
16307
|
-
const bVal = colDef?.valueGetter ? colDef.valueGetter(b[column], b) : (b[column] ?? '');
|
|
16308
|
-
const cmp = String(aVal).localeCompare(String(bVal), undefined, { numeric: true });
|
|
16496
|
+
const cmp = String(aVal ?? '').localeCompare(String(bVal ?? ''), undefined, { numeric: true });
|
|
16309
16497
|
if (cmp !== 0)
|
|
16310
16498
|
return direction === 'asc' ? cmp : -cmp;
|
|
16311
16499
|
}
|
|
@@ -16314,6 +16502,9 @@ if(typeof globalThis.Snice==="undefined"){console.warn("[snice] snice-runtime.mi
|
|
|
16314
16502
|
});
|
|
16315
16503
|
}
|
|
16316
16504
|
this.settingSortedData = false;
|
|
16505
|
+
}
|
|
16506
|
+
sortLocalData() {
|
|
16507
|
+
this.applyLocalSortOrder();
|
|
16317
16508
|
// Sort replaced this.data (new order + reference) — resync the row-index
|
|
16318
16509
|
// map and drop the stale filtered snapshot before re-rendering. Render is
|
|
16319
16510
|
// queued (not synchronous): sortLocalData is reachable from the currentSort
|