snice 7.0.2 → 7.1.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/.agents/skills/snice/SKILL.md +4 -0
- package/.agents/skills/snice/references/core-kitchen-sink.ts +39 -1
- package/README.md +59 -14
- package/adapters/react/SniceProvider.js +2 -2
- package/adapters/react/SniceRouter.js +2 -2
- package/adapters/react/matchRoute.js +2 -2
- package/adapters/react/useRequestHandler.js +2 -2
- package/bin/analyzer-contracts.js +6 -1
- package/bin/postinstall.js +59 -0
- package/bin/project-analyzer.js +466 -5
- package/bin/snice.js +3 -0
- package/dist/app-context.d.ts +11 -0
- package/dist/cdn/accordion/snice-accordion.js +2 -2
- package/dist/cdn/action-bar/snice-action-bar.js +2 -2
- package/dist/cdn/activity-feed/snice-activity-feed.js +2 -2
- package/dist/cdn/alert/snice-alert.js +2 -2
- package/dist/cdn/app-tiles/snice-app-tiles.js +2 -2
- package/dist/cdn/approval-flow/snice-approval-flow.js +2 -2
- package/dist/cdn/audio-recorder/snice-audio-recorder.js +2 -2
- package/dist/cdn/availability/snice-availability.js +2 -2
- package/dist/cdn/avatar/snice-avatar.js +2 -2
- package/dist/cdn/avatar-group/snice-avatar-group.js +2 -2
- package/dist/cdn/badge/snice-badge.js +2 -2
- package/dist/cdn/banner/snice-banner.js +2 -2
- package/dist/cdn/binpack/snice-binpack.js +2 -2
- package/dist/cdn/book/snice-book.js +2 -2
- package/dist/cdn/booking/snice-booking.js +2 -2
- package/dist/cdn/breadcrumbs/snice-breadcrumbs.js +2 -2
- package/dist/cdn/button/snice-button.js +2 -2
- package/dist/cdn/calendar/snice-calendar.js +2 -2
- package/dist/cdn/camera/snice-camera.js +2 -2
- package/dist/cdn/camera-annotate/snice-camera-annotate.js +2 -2
- package/dist/cdn/candlestick/snice-candlestick.js +2 -2
- package/dist/cdn/card/snice-card.js +2 -2
- package/dist/cdn/carousel/snice-carousel.js +2 -2
- package/dist/cdn/cart/snice-cart.js +2 -2
- package/dist/cdn/chart/snice-chart.js +2 -2
- package/dist/cdn/chat/snice-chat.js +2 -2
- package/dist/cdn/checkbox/snice-checkbox.js +2 -2
- package/dist/cdn/chip/snice-chip.js +2 -2
- package/dist/cdn/code-block/snice-code-block.js +2 -2
- package/dist/cdn/color-display/snice-color-display.js +2 -2
- package/dist/cdn/color-picker/snice-color-picker.js +2 -2
- package/dist/cdn/command-palette/snice-command-palette.js +2 -2
- package/dist/cdn/comments/snice-comments.js +2 -2
- package/dist/cdn/countdown/snice-countdown.js +2 -2
- package/dist/cdn/cropper/snice-cropper.js +2 -2
- package/dist/cdn/data-card/snice-data-card.js +2 -2
- package/dist/cdn/date-picker/snice-date-picker.js +2 -2
- package/dist/cdn/date-range-picker/snice-date-range-picker.js +2 -2
- package/dist/cdn/date-time-picker/snice-date-time-picker.js +2 -2
- package/dist/cdn/diff/snice-diff.js +2 -2
- package/dist/cdn/divider/snice-divider.js +2 -2
- package/dist/cdn/doc/snice-doc.js +2 -2
- package/dist/cdn/draw/snice-draw.js +2 -2
- package/dist/cdn/drawer/snice-drawer.js +2 -2
- package/dist/cdn/empty-state/snice-empty-state.js +2 -2
- package/dist/cdn/estimate/snice-estimate.js +2 -2
- package/dist/cdn/file-gallery/snice-file-gallery.js +2 -2
- package/dist/cdn/file-upload/snice-file-upload.js +2 -2
- package/dist/cdn/flip-card/snice-flip-card.js +2 -2
- package/dist/cdn/flow/snice-flow.js +2 -2
- package/dist/cdn/form-layout/snice-form-layout.js +2 -2
- package/dist/cdn/funnel/snice-funnel.js +2 -2
- package/dist/cdn/gantt/snice-gantt.js +2 -2
- package/dist/cdn/gauge/snice-gauge.js +2 -2
- package/dist/cdn/grid/snice-grid.js +2 -2
- package/dist/cdn/heatmap/snice-heatmap.js +2 -2
- package/dist/cdn/image/snice-image.js +2 -2
- package/dist/cdn/input/snice-input.js +2 -2
- package/dist/cdn/invoice/snice-invoice.js +2 -2
- package/dist/cdn/kanban/snice-kanban.js +2 -2
- package/dist/cdn/key-value/snice-key-value.js +2 -2
- package/dist/cdn/kpi/snice-kpi.js +2 -2
- package/dist/cdn/layout/README.md +17 -2
- package/dist/cdn/layout/snice-layout.js +1656 -11
- package/dist/cdn/layout/snice-layout.js.map +1 -1
- package/dist/cdn/layout/snice-layout.min.js +379 -2
- package/dist/cdn/layout/snice-layout.min.js.map +1 -1
- package/dist/cdn/leaderboard/snice-leaderboard.js +2 -2
- package/dist/cdn/link/snice-link.js +2 -2
- package/dist/cdn/link-preview/snice-link-preview.js +2 -2
- package/dist/cdn/list/snice-list.js +2 -2
- package/dist/cdn/location/snice-location.js +2 -2
- package/dist/cdn/login/snice-login.js +2 -2
- package/dist/cdn/map/snice-map.js +2 -2
- package/dist/cdn/markdown/snice-markdown.js +2 -2
- package/dist/cdn/masonry/snice-masonry.js +2 -2
- package/dist/cdn/menu/snice-menu.js +2 -2
- package/dist/cdn/message-strip/snice-message-strip.js +2 -2
- package/dist/cdn/modal/snice-modal.js +2 -2
- package/dist/cdn/music-player/snice-music-player.js +2 -2
- package/dist/cdn/nav/snice-nav.js +2 -2
- package/dist/cdn/network-graph/snice-network-graph.js +2 -2
- package/dist/cdn/notification-center/snice-notification-center.js +2 -2
- package/dist/cdn/order-tracker/snice-order-tracker.js +2 -2
- package/dist/cdn/org-chart/snice-org-chart.js +2 -2
- package/dist/cdn/pagination/snice-pagination.js +2 -2
- package/dist/cdn/paint/snice-paint.js +2 -2
- package/dist/cdn/pdf-viewer/snice-pdf-viewer.js +2 -2
- package/dist/cdn/permission-matrix/snice-permission-matrix.js +2 -2
- package/dist/cdn/podcast-player/snice-podcast-player.js +2 -2
- package/dist/cdn/popover/snice-popover.js +2 -2
- package/dist/cdn/pricing-table/snice-pricing-table.js +2 -2
- package/dist/cdn/product-card/snice-product-card.js +2 -2
- package/dist/cdn/progress/snice-progress.js +2 -2
- package/dist/cdn/progress-ring/snice-progress-ring.js +2 -2
- package/dist/cdn/qr-code/snice-qr-code.js +2 -2
- package/dist/cdn/qr-reader/snice-qr-reader.js +2 -2
- package/dist/cdn/radio/snice-radio.js +2 -2
- package/dist/cdn/range-slider/snice-range-slider.js +2 -2
- package/dist/cdn/rating/snice-rating.js +2 -2
- package/dist/cdn/receipt/snice-receipt.js +2 -2
- package/dist/cdn/recipe/snice-recipe.js +3 -3
- package/dist/cdn/recipe/snice-recipe.js.map +1 -1
- package/dist/cdn/recipe/snice-recipe.min.js +1 -1
- package/dist/cdn/recipe/snice-recipe.min.js.map +1 -1
- package/dist/cdn/runtime/README.md +2 -2
- package/dist/cdn/runtime/snice-runtime.esm.js +3725 -3336
- 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 +3727 -3335
- 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 +2 -2
- package/dist/cdn/segmented-control/snice-segmented-control.js +2 -2
- package/dist/cdn/select/snice-select.js +2 -2
- package/dist/cdn/skeleton/snice-skeleton.js +2 -2
- package/dist/cdn/slider/snice-slider.js +2 -2
- package/dist/cdn/sortable/snice-sortable.js +2 -2
- package/dist/cdn/sparkline/snice-sparkline.js +2 -2
- package/dist/cdn/spinner/snice-spinner.js +2 -2
- package/dist/cdn/split-button/snice-split-button.js +2 -2
- package/dist/cdn/split-pane/snice-split-pane.js +2 -2
- package/dist/cdn/spotlight/snice-spotlight.js +2 -2
- package/dist/cdn/stat-group/snice-stat-group.js +2 -2
- package/dist/cdn/step-input/snice-step-input.js +2 -2
- package/dist/cdn/stepper/snice-stepper.js +2 -2
- package/dist/cdn/switch/snice-switch.js +2 -2
- package/dist/cdn/table/README.md +6 -2
- package/dist/cdn/table/snice-table.esm.js +366 -56
- package/dist/cdn/table/snice-table.esm.js.map +1 -1
- package/dist/cdn/table/snice-table.esm.min.js +107 -46
- package/dist/cdn/table/snice-table.esm.min.js.map +1 -1
- package/dist/cdn/table/snice-table.js +367 -59
- package/dist/cdn/table/snice-table.js.map +1 -1
- package/dist/cdn/table/snice-table.min.js +155 -94
- package/dist/cdn/table/snice-table.min.js.map +1 -1
- package/dist/cdn/tabs/snice-tabs.js +2 -2
- package/dist/cdn/tag/snice-tag.js +2 -2
- package/dist/cdn/tag-input/snice-tag-input.js +2 -2
- package/dist/cdn/terminal/snice-terminal.js +3 -2
- package/dist/cdn/terminal/snice-terminal.js.map +1 -1
- package/dist/cdn/terminal/snice-terminal.min.js +1 -0
- package/dist/cdn/terminal/snice-terminal.min.js.map +1 -1
- package/dist/cdn/testimonial/snice-testimonial.js +2 -2
- package/dist/cdn/textarea/snice-textarea.js +2 -2
- package/dist/cdn/time-picker/snice-time-picker.js +2 -2
- package/dist/cdn/time-range-picker/snice-time-range-picker.js +2 -2
- package/dist/cdn/timeline/snice-timeline.js +2 -2
- package/dist/cdn/timer/snice-timer.js +2 -2
- package/dist/cdn/toast/snice-toast.js +2 -2
- package/dist/cdn/tooltip/snice-tooltip.js +2 -2
- package/dist/cdn/tree/snice-tree.js +2 -2
- package/dist/cdn/treemap/snice-treemap.js +2 -2
- package/dist/cdn/user-card/snice-user-card.js +2 -2
- package/dist/cdn/video-player/README.md +1 -1
- package/dist/cdn/video-player/snice-video-player.js +3 -2
- package/dist/cdn/video-player/snice-video-player.js.map +1 -1
- package/dist/cdn/video-player/snice-video-player.min.js +1 -0
- package/dist/cdn/video-player/snice-video-player.min.js.map +1 -1
- package/dist/cdn/virtual-scroller/snice-virtual-scroller.js +2 -2
- package/dist/cdn/waterfall/snice-waterfall.js +2 -2
- package/dist/cdn/weather/snice-weather.js +2 -2
- package/dist/cdn/work-order/snice-work-order.js +2 -2
- package/dist/components/recipe/snice-recipe.js +1 -1
- package/dist/components/recipe/snice-recipe.js.map +1 -1
- package/dist/components/table/snice-table.d.ts +1 -0
- package/dist/components/table/snice-table.js +18 -2
- package/dist/components/table/snice-table.js.map +1 -1
- package/dist/components/table/table-tree-data.js +1 -0
- package/dist/components/table/table-tree-data.js.map +1 -1
- package/dist/components/terminal/snice-terminal.js +1 -0
- package/dist/components/terminal/snice-terminal.js.map +1 -1
- package/dist/components/video-player/snice-video-player.js +1 -0
- package/dist/components/video-player/snice-video-player.js.map +1 -1
- package/dist/context-provider.d.ts +16 -0
- package/dist/daemon-target.d.ts +10 -0
- package/dist/daemon.d.ts +10 -0
- package/dist/index.cjs +3721 -3329
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.esm.js +3719 -3330
- package/dist/index.esm.js.map +1 -1
- package/dist/index.iife.js +3721 -3329
- package/dist/index.iife.js.map +1 -1
- package/dist/keyboard-filter.d.ts +25 -0
- package/dist/on.d.ts +1 -1
- package/dist/parts.d.ts +0 -17
- package/dist/react/SniceProvider.js +2 -2
- package/dist/react/SniceRouter.js +2 -2
- package/dist/react/index.js +2 -2
- package/dist/react/matchRoute.js +2 -2
- package/dist/react/useRequestHandler.js +2 -2
- package/dist/request-response.d.ts +9 -1
- package/dist/symbols.cjs +11 -2
- package/dist/symbols.cjs.map +1 -1
- package/dist/symbols.d.ts +3 -0
- package/dist/symbols.esm.js +9 -3
- package/dist/symbols.esm.js.map +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/transitions.cjs +2 -2
- package/dist/transitions.esm.js +2 -2
- package/dist/types/app-context.d.ts +9 -58
- package/dist/types/daemon.d.ts +8 -0
- package/dist/types/dispatch-options.d.ts +2 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/on-options.d.ts +5 -0
- package/dist/types/request-options.d.ts +2 -0
- package/dist/types/respond-options.d.ts +2 -0
- package/docs/ai/DEVELOPMENT.md +15 -1
- package/docs/ai/README.md +5 -1
- package/docs/ai/api.md +13 -4
- package/docs/ai/architecture.md +50 -1
- package/docs/ai/cli.md +9 -0
- package/docs/ai/components/avatar.md +8 -8
- package/docs/ai/components/breadcrumbs.md +2 -1
- package/docs/ai/components/button.md +2 -7
- package/docs/ai/components/calendar.md +1 -1
- package/docs/ai/components/camera.md +1 -1
- package/docs/ai/components/chart.md +3 -1
- package/docs/ai/components/code-block.md +2 -2
- package/docs/ai/components/date-picker.md +5 -19
- package/docs/ai/components/date-range-picker.md +4 -12
- package/docs/ai/components/draw.md +5 -5
- package/docs/ai/components/drawer.md +4 -4
- package/docs/ai/components/form-layout.md +2 -0
- package/docs/ai/components/icons.md +7 -16
- package/docs/ai/components/key-value.md +3 -22
- package/docs/ai/components/layout.md +8 -12
- package/docs/ai/components/leaderboard.md +2 -2
- package/docs/ai/components/link-preview.md +4 -3
- package/docs/ai/components/login.md +11 -0
- package/docs/ai/components/markdown.md +7 -0
- package/docs/ai/components/masonry.md +6 -0
- package/docs/ai/components/menu.md +1 -1
- package/docs/ai/components/modal.md +7 -0
- package/docs/ai/components/notification-center.md +5 -4
- package/docs/ai/components/radio.md +7 -0
- package/docs/ai/components/rating.md +3 -3
- package/docs/ai/components/select.md +4 -13
- package/docs/ai/components/spotlight.md +2 -0
- package/docs/ai/components/table.md +1 -4
- package/docs/ai/components/tag-input.md +6 -0
- package/docs/ai/components/terminal.md +6 -0
- package/docs/ai/components/tooltip.md +10 -16
- package/docs/ai/components/tree.md +2 -2
- package/docs/ai/components/video-player.md +5 -0
- package/docs/ai/components/waterfall.md +7 -0
- package/docs/ai/daemons.md +80 -0
- package/docs/ai/decorators.md +6 -4
- package/docs/ai/events.md +35 -0
- package/docs/ai/patterns.md +45 -1
- package/docs/ai/request-response.md +26 -9
- package/docs/ai/routing.md +16 -1
- package/docs/cli.md +7 -0
- package/docs/components/breadcrumbs.md +2 -1
- package/docs/components/calendar.md +1 -1
- package/docs/components/camera.md +1 -1
- package/docs/components/chart.md +1 -1
- package/docs/components/code-block.md +13 -4
- package/docs/components/color-picker.md +6 -5
- package/docs/components/date-time-picker.md +14 -0
- package/docs/components/diff.md +2 -1
- package/docs/components/draw.md +5 -5
- package/docs/components/drawer.md +4 -4
- package/docs/components/input.md +1 -0
- package/docs/components/layout.md +20 -22
- package/docs/components/leaderboard.md +10 -3
- package/docs/components/link-preview.md +11 -9
- package/docs/components/login.md +4 -0
- package/docs/components/menu.md +1 -1
- package/docs/components/modal.md +1 -0
- package/docs/components/nav.md +1 -0
- package/docs/components/network-graph.md +1 -0
- package/docs/components/notification-center.md +2 -1
- package/docs/components/product-card.md +1 -0
- package/docs/components/qr-reader.md +1 -0
- package/docs/components/rating.md +4 -4
- package/docs/components/select.md +1 -0
- package/docs/components/spotlight.md +2 -0
- package/docs/components/tabs.md +1 -0
- package/docs/components/terminal.md +3 -0
- package/docs/components/textarea.md +1 -1
- package/docs/components/time-picker.md +14 -0
- package/docs/components/tooltip.md +2 -0
- package/docs/components/tree.md +2 -2
- package/docs/daemons.md +200 -0
- package/docs/events.md +92 -2
- package/docs/request-response.md +20 -13
- package/docs/routing.md +25 -1
- package/package.json +6 -4
package/docs/ai/api.md
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
// attachController(el, MyController) | el.controller = MyController
|
|
16
16
|
// controller="name" string attr (only channel in raw HTML; still supported everywhere)
|
|
17
17
|
// Class binding: reference-deduped, removes controller attr, attr writes ignored while bound
|
|
18
|
+
@daemon // Explicitly constructed app-context state/lifecycle object; no name or global registration
|
|
18
19
|
@layout('name') // Define page wrapper
|
|
19
20
|
```
|
|
20
21
|
|
|
@@ -112,13 +113,13 @@ html`
|
|
|
112
113
|
```typescript
|
|
113
114
|
@on(event: string | string[], selector?: string, options?: OnOptions)
|
|
114
115
|
// Works in elements + controllers
|
|
115
|
-
// Options: { debounce?, throttle?, preventDefault?, stopPropagation?, once?, capture?, passive?, target?, scope? }
|
|
116
|
+
// Options: { debounce?, throttle?, preventDefault?, stopPropagation?, once?, capture?, passive?, target?, scope?, daemon? }
|
|
116
117
|
// target: CSS selector for shadow DOM event delegation
|
|
117
118
|
// scope: 'global' | selector | EventTarget | () => EventTarget | null — redirects listener attachment
|
|
118
119
|
// Keyboard: 'keydown:Enter', 'keydown.escape', 'keydown:ctrl+s', 'keydown:~Space'
|
|
119
120
|
// Supports both ':' and '.' notation
|
|
120
121
|
|
|
121
|
-
@dispatch(eventName: string, options?: { debounce?, throttle?, dispatchOnUndefined?, scope?, ...EventInit })
|
|
122
|
+
@dispatch(eventName: string, options?: { debounce?, throttle?, dispatchOnUndefined?, scope?, daemon?, ...EventInit })
|
|
122
123
|
// Fires CustomEvent after method, detail = return value
|
|
123
124
|
// Supports async methods (dispatches after promise resolves)
|
|
124
125
|
// dispatchOnUndefined: false (default) — skips dispatch if method returns undefined
|
|
@@ -142,7 +143,7 @@ html`
|
|
|
142
143
|
## Communication
|
|
143
144
|
|
|
144
145
|
```typescript
|
|
145
|
-
@request(channel: string, options?: { timeout?, discoveryTimeout?, debounce?, throttle?, bubbles?, cancelable? })
|
|
146
|
+
@request(channel: string, options?: { daemon?, timeout?, discoveryTimeout?, debounce?, throttle?, bubbles?, cancelable? })
|
|
146
147
|
// Request pattern using async generator syntax
|
|
147
148
|
// Method must be async generator that yields payload and receives response
|
|
148
149
|
// Returns Promise<T>
|
|
@@ -166,7 +167,7 @@ html`
|
|
|
166
167
|
// }
|
|
167
168
|
// // Usage: const user = await this.fetchUser('123');
|
|
168
169
|
|
|
169
|
-
@respond(channel: string, options?: { debounce?, throttle? })
|
|
170
|
+
@respond(channel: string, options?: { daemon?, debounce?, throttle? })
|
|
170
171
|
// Respond to requests from @request decorators
|
|
171
172
|
// Method receives payload and returns response
|
|
172
173
|
// Works in both elements and controllers
|
|
@@ -182,6 +183,14 @@ html`
|
|
|
182
183
|
// }
|
|
183
184
|
```
|
|
184
185
|
|
|
186
|
+
Daemon addressing:
|
|
187
|
+
```typescript
|
|
188
|
+
const release = provideContext(appRoot, { daemons: { session: new SessionDaemon() } });
|
|
189
|
+
const context = getContext(elementOrController);
|
|
190
|
+
// Consumers use { daemon: 'session' }; daemon methods default to their own private target.
|
|
191
|
+
// Provide before connect/attach. Call release() during app/test teardown.
|
|
192
|
+
```
|
|
193
|
+
|
|
185
194
|
## Observers
|
|
186
195
|
|
|
187
196
|
```typescript
|
package/docs/ai/architecture.md
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
- **Pages:** Orchestrate elements, handle URLs
|
|
8
8
|
- **Elements:** Generic visual building blocks — no fetch(), no API calls, no business logic
|
|
9
9
|
- **Controllers:** Specific behavior (data, APIs, business rules) — swappable per element
|
|
10
|
+
- **Daemons:** Explicitly constructed app-owned state/lifecycle objects — addressable through context, never global singletons
|
|
10
11
|
|
|
11
12
|
**Generic vs Specific:** Elements say *what* they need, controllers decide *how*.
|
|
12
13
|
Swap controllers to change behavior without touching the component.
|
|
@@ -16,6 +17,26 @@ Mock controller for tests, real API controller in production — same element.
|
|
|
16
17
|
- Down: Properties
|
|
17
18
|
- Up: Events
|
|
18
19
|
- Sideways: Request/Response channels
|
|
20
|
+
- App services: daemon-addressed request/response or dispatch/on
|
|
21
|
+
|
|
22
|
+
## Project Structure
|
|
23
|
+
|
|
24
|
+
Conventional application layout:
|
|
25
|
+
|
|
26
|
+
```text
|
|
27
|
+
src/
|
|
28
|
+
main.ts
|
|
29
|
+
router.ts
|
|
30
|
+
pages/ # @page classes; route orchestration and presentation
|
|
31
|
+
components/ # reusable @element visual components
|
|
32
|
+
controllers/ # @controller data, API, and reusable business behavior
|
|
33
|
+
daemons/ # explicitly constructed @daemon state/lifecycle services
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Pages may coordinate a route and perform a small one-off load. Move behavior to
|
|
37
|
+
a controller when a page owns several storage/server/timer operations or when
|
|
38
|
+
substantial non-visual logic is copied across pages. `snice check` reports these
|
|
39
|
+
as architecture suggestions, not errors.
|
|
19
40
|
|
|
20
41
|
## Rendering System
|
|
21
42
|
|
|
@@ -74,6 +95,15 @@ Mock controller for tests, real API controller in production — same element.
|
|
|
74
95
|
- Class bindings own the element: attribute writes ignored while a class is bound
|
|
75
96
|
- Native elements: class bindings attach via ControllerPart; string attrs via MutationObserver
|
|
76
97
|
|
|
98
|
+
**Daemon lifecycle:**
|
|
99
|
+
1. Application constructs an `@daemon` class with `new`
|
|
100
|
+
2. `provideContext(root, { daemons })` activates its private communication target
|
|
101
|
+
3. Elements/controllers resolve the nearest context by string address
|
|
102
|
+
4. Provider release removes daemon handlers and deactivates that target
|
|
103
|
+
- Router provides its `context` through the same mechanism
|
|
104
|
+
- Multiple instances of the same class remain independent
|
|
105
|
+
- No implicit construction, registry scan, singleton, start, or stop hook
|
|
106
|
+
|
|
77
107
|
## Router System
|
|
78
108
|
|
|
79
109
|
**Registration:**
|
|
@@ -136,7 +166,7 @@ onChange() { return { value: this.value }; }
|
|
|
136
166
|
```typescript
|
|
137
167
|
// Element requests (async generator: yield sends, await receives)
|
|
138
168
|
@request('fetch-data')
|
|
139
|
-
async *fetchData():
|
|
169
|
+
async *fetchData(): Response<Data> {
|
|
140
170
|
return await (yield { id: this.dataId }); // single yield per call
|
|
141
171
|
}
|
|
142
172
|
|
|
@@ -148,6 +178,25 @@ async handleFetch(payload: { id: string }) {
|
|
|
148
178
|
// Wiring: html`<my-element controller=${MyController}></my-element>` (or controller="my-controller" in raw HTML)
|
|
149
179
|
```
|
|
150
180
|
|
|
181
|
+
**Element/Controller ↔ Daemon:** Addressed communication
|
|
182
|
+
```typescript
|
|
183
|
+
@daemon
|
|
184
|
+
class SessionDaemon {
|
|
185
|
+
@respond('session/get') get() { return this.session; }
|
|
186
|
+
@dispatch('session/changed') changed() { return this.session; }
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const session = new SessionDaemon();
|
|
190
|
+
const release = provideContext(appRoot, { daemons: { session } });
|
|
191
|
+
|
|
192
|
+
// Consumer imports no daemon implementation class.
|
|
193
|
+
@request('session/get', { daemon: 'session' })
|
|
194
|
+
async *getSession(): Response<Session | null> { return yield {}; }
|
|
195
|
+
|
|
196
|
+
@on('session/changed', { daemon: 'session' })
|
|
197
|
+
sessionChanged(event: CustomEvent<Session | null>) {}
|
|
198
|
+
```
|
|
199
|
+
|
|
151
200
|
**Global State:** Context
|
|
152
201
|
```typescript
|
|
153
202
|
@context() handleContext(ctx: Context) {
|
package/docs/ai/cli.md
CHANGED
|
@@ -44,6 +44,15 @@ npx snice validate # source analyzer only
|
|
|
44
44
|
`validate` runs the analyzer over source. Catches mistakes that compile but never work:
|
|
45
45
|
- an `@element`-decorated class that does not extend `HTMLElement` (or a Snice element subclass) — Snice registers/renders only element subclasses
|
|
46
46
|
- deep imports that were never released package paths, e.g. `snice/decorators`
|
|
47
|
+
- Router missing `target`, `type`, or a project-wide `initialize()` call
|
|
48
|
+
- a routed class combining `@page` with redundant `@element`
|
|
49
|
+
|
|
50
|
+
Non-blocking architecture suggestions:
|
|
51
|
+
- `@page` -> `src/pages/`
|
|
52
|
+
- `@element` -> `src/components/`
|
|
53
|
+
- `@controller` -> `src/controllers/`
|
|
54
|
+
- `@daemon` -> `src/daemons/`
|
|
55
|
+
- several external-effect methods or substantial logic repeated across pages -> extract a controller
|
|
47
56
|
|
|
48
57
|
Both `doctor` and `validate` accept `--json`.
|
|
49
58
|
|
|
@@ -72,11 +72,11 @@ fallbackBackground: string = ''; // attr: fallback-background — overrides
|
|
|
72
72
|
|
|
73
73
|
### Size Reference
|
|
74
74
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
75
|
+
Size — dimension / font-size:
|
|
76
|
+
|
|
77
|
+
- `xs` 1.5rem (24px) / 0.625rem
|
|
78
|
+
- `small` 2rem (32px) / 0.75rem
|
|
79
|
+
- `medium` 2.5rem (40px) / 0.875rem
|
|
80
|
+
- `large` 3rem (48px) / 1rem
|
|
81
|
+
- `xl` 4rem (64px) / 1.25rem
|
|
82
|
+
- `xxl` 6rem (96px) / 2rem
|
|
@@ -13,9 +13,10 @@ Navigation breadcrumb trail.
|
|
|
13
13
|
|
|
14
14
|
```typescript
|
|
15
15
|
items: BreadcrumbItem[] = []; // JS property only
|
|
16
|
-
separator: '/'|'>'|'
|
|
16
|
+
separator: '/'|'>'|'»'|'•'|'|' = '/';
|
|
17
17
|
size: 'small'|'medium'|'large' = 'medium';
|
|
18
18
|
maxItems: number = 0; // 0 = show all, attr: max-items
|
|
19
|
+
collapsed: boolean = true; // ellipsis state; ellipsis click sets false, resets on items/separator/maxItems change
|
|
19
20
|
```
|
|
20
21
|
|
|
21
22
|
### snice-crumb
|
|
@@ -53,16 +53,11 @@ readonly labels: NodeList | null;
|
|
|
53
53
|
```html
|
|
54
54
|
<snice-button>Click me</snice-button>
|
|
55
55
|
|
|
56
|
-
<!-- Variants -->
|
|
56
|
+
<!-- Variants: default|primary|success|warning|danger|text -->
|
|
57
57
|
<snice-button variant="primary">Primary</snice-button>
|
|
58
|
-
<snice-button variant="success">Success</snice-button>
|
|
59
|
-
<snice-button variant="warning">Warning</snice-button>
|
|
60
|
-
<snice-button variant="danger">Danger</snice-button>
|
|
61
|
-
<snice-button variant="text">Text</snice-button>
|
|
62
58
|
|
|
63
|
-
<!-- Sizes -->
|
|
59
|
+
<!-- Sizes: small|medium|large -->
|
|
64
60
|
<snice-button size="small">Small</snice-button>
|
|
65
|
-
<snice-button size="large">Large</snice-button>
|
|
66
61
|
|
|
67
62
|
<!-- States -->
|
|
68
63
|
<snice-button disabled>Disabled</snice-button>
|
|
@@ -10,7 +10,7 @@ view: 'month'|'week'|'day' = 'month';
|
|
|
10
10
|
events: CalendarEvent[] = [];
|
|
11
11
|
minDate: Date | string = ''; // attribute: min-date
|
|
12
12
|
maxDate: Date | string = ''; // attribute: max-date
|
|
13
|
-
disabledDates: (Date | string)[] = []; // attribute
|
|
13
|
+
disabledDates: (Date | string)[] = []; // JS-only; no attribute
|
|
14
14
|
highlightToday: boolean = true; // attribute: highlight-today
|
|
15
15
|
showWeekNumbers: boolean = false; // attribute: show-week-numbers
|
|
16
16
|
firstDayOfWeek: number = 0; // attribute: first-day-of-week (0=Sun, 1=Mon)
|
|
@@ -5,7 +5,7 @@ Live camera feed with built-in mobile-style controls.
|
|
|
5
5
|
## Properties
|
|
6
6
|
|
|
7
7
|
```typescript
|
|
8
|
-
autoStart: boolean =
|
|
8
|
+
autoStart: boolean = false; // attribute: auto-start
|
|
9
9
|
facingMode: 'user'|'environment' = 'user'; // attribute: facing-mode
|
|
10
10
|
mirror: boolean = true;
|
|
11
11
|
controlsPosition: ControlsPosition = 'auto'; // attribute: controls-position
|
|
@@ -8,7 +8,9 @@ General-purpose chart component with 10 chart types and animations.
|
|
|
8
8
|
type: 'line'|'bar'|'horizontal-bar'|'area'|'pie'|'donut'|'scatter'|'bubble'|'radar'|'mixed' = 'line';
|
|
9
9
|
datasets: ChartDataset[] = []; // property only
|
|
10
10
|
labels: string[] = []; // property only
|
|
11
|
-
options: ChartOptions = {
|
|
11
|
+
options: ChartOptions = { responsive: true, maintainAspectRatio: false, legend: {position:'top', clickable:true},
|
|
12
|
+
tooltip: {trigger:'hover'}, animation: {enabled:true, duration:500, easing:'ease-out'},
|
|
13
|
+
xAxis: {grid:true}, yAxis: {grid:true} }; // property only
|
|
12
14
|
width: number = 0; // 0 = auto
|
|
13
15
|
height: number = 0; // 0 = auto
|
|
14
16
|
```
|
|
@@ -7,10 +7,10 @@ Code display with syntax highlighting, line numbers, copy, and grammar-based for
|
|
|
7
7
|
```typescript
|
|
8
8
|
code: string = ''; // Set via slot or property
|
|
9
9
|
language: 'javascript'|'typescript'|'html'|'css'|'json'|'python'|'bash'|'plaintext' = 'plaintext';
|
|
10
|
-
grammar: GrammarDefinition | string | null =
|
|
10
|
+
grammar: GrammarDefinition | string | null = ''; // Grammar object or URL to JSON
|
|
11
11
|
showLineNumbers: boolean = false; // attribute: show-line-numbers
|
|
12
12
|
startLine: number = 1; // attribute: start-line
|
|
13
|
-
highlightLines: number[] = []; // attribute
|
|
13
|
+
highlightLines: number[] = []; // JS-only; no attribute
|
|
14
14
|
copyable: boolean = true;
|
|
15
15
|
filename: string = '';
|
|
16
16
|
format: string = ''; // Formatter name (e.g. "pretty"), or truthy string with setFormatter()
|
|
@@ -17,11 +17,8 @@ value: string = '';
|
|
|
17
17
|
// Maps to the value content attribute and is restored by form reset.
|
|
18
18
|
defaultValue: string = '';
|
|
19
19
|
|
|
20
|
-
format:
|
|
21
|
-
|
|
22
|
-
| 'yyyy-mm-dd' | 'yyyy/mm/dd'
|
|
23
|
-
| 'dd-mm-yyyy' | 'mm-dd-yyyy'
|
|
24
|
-
| 'mmmm dd, yyyy' = 'mm/dd/yyyy';
|
|
20
|
+
format: 'mm/dd/yyyy' | 'dd/mm/yyyy' | 'yyyy-mm-dd' | 'yyyy/mm/dd'
|
|
21
|
+
| 'dd-mm-yyyy' | 'mm-dd-yyyy' | 'mmmm dd, yyyy' = 'mm/dd/yyyy';
|
|
25
22
|
|
|
26
23
|
variant: 'outlined' | 'filled' | 'underlined' = 'outlined';
|
|
27
24
|
size: 'small' | 'medium' | 'large' = 'medium';
|
|
@@ -29,14 +26,9 @@ placeholder: string = '';
|
|
|
29
26
|
label: string = '';
|
|
30
27
|
helperText: string = ''; // helper-text
|
|
31
28
|
errorText: string = ''; // error-text
|
|
32
|
-
disabled: boolean = false;
|
|
33
|
-
readonly: boolean = false;
|
|
34
|
-
loading: boolean = false;
|
|
35
|
-
required: boolean = false;
|
|
29
|
+
disabled | readonly | loading | required | clearable: boolean = false;
|
|
36
30
|
invalid: boolean = false; // presentation only, not constraint validity
|
|
37
|
-
|
|
38
|
-
min: string = ''; // canonical YYYY-MM-DD recommended
|
|
39
|
-
max: string = ''; // canonical YYYY-MM-DD recommended
|
|
31
|
+
min: string = ''; max: string = ''; // canonical YYYY-MM-DD recommended
|
|
40
32
|
name: string = '';
|
|
41
33
|
open: boolean = false;
|
|
42
34
|
firstDayOfWeek: number = 0; // first-day-of-week; 0=Sunday
|
|
@@ -140,13 +132,7 @@ All component events bubble and are composed. Direct property/default changes, r
|
|
|
140
132
|
|
|
141
133
|
## CSS Parts
|
|
142
134
|
|
|
143
|
-
- `
|
|
144
|
-
- `calendar-toggle`
|
|
145
|
-
- `clear`
|
|
146
|
-
- `spinner`
|
|
147
|
-
- `calendar`
|
|
148
|
-
- `helper-text`
|
|
149
|
-
- `error-text`
|
|
135
|
+
`input`, `calendar-toggle`, `clear`, `spinner`, `calendar`, `helper-text`, `error-text`
|
|
150
136
|
|
|
151
137
|
## Keyboard/accessibility
|
|
152
138
|
|
|
@@ -20,11 +20,8 @@ end: string = '';
|
|
|
20
20
|
defaultStart: string = '';
|
|
21
21
|
defaultEnd: string = '';
|
|
22
22
|
|
|
23
|
-
format:
|
|
24
|
-
|
|
25
|
-
| 'yyyy-mm-dd' | 'yyyy/mm/dd'
|
|
26
|
-
| 'dd-mm-yyyy' | 'mm-dd-yyyy'
|
|
27
|
-
| 'mmmm dd, yyyy' = 'mm/dd/yyyy';
|
|
23
|
+
format: 'mm/dd/yyyy' | 'dd/mm/yyyy' | 'yyyy-mm-dd' | 'yyyy/mm/dd'
|
|
24
|
+
| 'dd-mm-yyyy' | 'mm-dd-yyyy' | 'mmmm dd, yyyy' = 'mm/dd/yyyy';
|
|
28
25
|
|
|
29
26
|
size: 'small' | 'medium' | 'large' = 'medium';
|
|
30
27
|
variant: 'outlined' | 'filled' | 'underlined' = 'outlined';
|
|
@@ -32,14 +29,9 @@ placeholder: string = '';
|
|
|
32
29
|
label: string = '';
|
|
33
30
|
helperText: string = ''; // helper-text
|
|
34
31
|
errorText: string = ''; // error-text
|
|
35
|
-
disabled: boolean = false;
|
|
36
|
-
readonly: boolean = false;
|
|
37
|
-
loading: boolean = false;
|
|
38
|
-
required: boolean = false;
|
|
32
|
+
disabled | readonly | loading | required | clearable: boolean = false;
|
|
39
33
|
invalid: boolean = false; // presentation only, not constraint validity
|
|
40
|
-
|
|
41
|
-
min: string = ''; // canonical YYYY-MM-DD recommended
|
|
42
|
-
max: string = ''; // canonical YYYY-MM-DD recommended
|
|
34
|
+
min: string = ''; max: string = ''; // canonical YYYY-MM-DD recommended
|
|
43
35
|
name: string = ''; // base name for {name}-start and {name}-end
|
|
44
36
|
columns: number = 1; // supported layouts: 1 or 2
|
|
45
37
|
firstDayOfWeek: number = 0; // first-day-of-week; 0=Sunday
|
|
@@ -48,11 +48,11 @@ interface DrawStroke {
|
|
|
48
48
|
|
|
49
49
|
## Events
|
|
50
50
|
|
|
51
|
-
- `draw-start` - Drawing started
|
|
52
|
-
- `draw-end` → `{ stroke }` - Stroke completed
|
|
53
|
-
- `draw-clear` - Canvas cleared
|
|
54
|
-
- `draw-undo` - Undo performed
|
|
55
|
-
- `draw-redo` - Redo performed
|
|
51
|
+
- `draw-start` → `{ draw, point }` - Drawing started
|
|
52
|
+
- `draw-end` → `{ draw, stroke }` - Stroke completed
|
|
53
|
+
- `draw-clear` → `{ draw }` - Canvas cleared
|
|
54
|
+
- `draw-undo` → `{ draw }` - Undo performed
|
|
55
|
+
- `draw-redo` → `{ draw }` - Redo performed
|
|
56
56
|
|
|
57
57
|
## CSS Parts
|
|
58
58
|
|
|
@@ -44,10 +44,10 @@ contained: boolean = false; // Position relative to parent
|
|
|
44
44
|
- `--snice-drawer-control-size` - Drawer control size
|
|
45
45
|
- `--drawer-width-small` through `--drawer-width-xxxl` - Width per size
|
|
46
46
|
- `--drawer-height-small` through `--drawer-height-xxxl` - Height per size (top/bottom)
|
|
47
|
-
- `--drawer-bg` - Background (default: `var(--snice-color-surface, white)`)
|
|
48
|
-
- `--drawer-shadow` - Shadow (default: `var(--snice-shadow-
|
|
49
|
-
- `--drawer-backdrop` - Backdrop color (default: `
|
|
50
|
-
- `--drawer-transition` - Transition timing
|
|
47
|
+
- `--drawer-bg` - Background (default: `var(--snice-color-surface-container-highest, var(--snice-color-surface, white))`)
|
|
48
|
+
- `--drawer-shadow` - Shadow (default: `var(--snice-shadow-2xl, ...)`)
|
|
49
|
+
- `--drawer-backdrop` - Backdrop color (default: `var(--snice-drawer-backdrop, rgb(0 0 0 / 0.6))`)
|
|
50
|
+
- `--drawer-transition` - Transition timing (default: `transform 320ms var(--snice-ease-out, cubic-bezier(0.22, 1, 0.36, 1))`)
|
|
51
51
|
- `--drawer-z-index` - Z-index (default: `1050`)
|
|
52
52
|
|
|
53
53
|
## CSS Parts
|
|
@@ -59,4 +59,6 @@ import 'snice/components/form-layout/snice-form-layout';
|
|
|
59
59
|
</snice-form-layout>
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
+
Span columns with CSS `grid-column` on a slotted child: `<snice-textarea style="grid-column: 1 / -1">`.
|
|
63
|
+
|
|
62
64
|
No events -- layout-only component. Responsive: collapses to single column on mobile (<640px).
|
|
@@ -35,22 +35,13 @@ Snice embeds a small set of Heroicons (MIT © Tailwind Labs) as defaults. Consum
|
|
|
35
35
|
|
|
36
36
|
## Components with built-in defaults
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
| `<snice-approval-flow>` | step status (pending/approved/rejected/skipped) |
|
|
46
|
-
| `<snice-data-card>` | Edit/Done button |
|
|
47
|
-
| `<snice-kpi>` | trend indicator |
|
|
48
|
-
| `<snice-cell-percentage>` (table) | trend indicator |
|
|
49
|
-
| `<snice-cell-json>` (table) | expand/collapse chevron |
|
|
50
|
-
| `<snice-header>` (table) | sort direction |
|
|
51
|
-
| `<snice-modal>` | close button |
|
|
52
|
-
| `<snice-drawer>` | close button |
|
|
53
|
-
| `<snice-toast>` | close button |
|
|
38
|
+
- Variant status icon: `<snice-alert>`, `<snice-banner>`; `<snice-timeline>` marker (per item variant)
|
|
39
|
+
- Placeholder: `<snice-image>` (no `src`), `<snice-cell-image>` (table)
|
|
40
|
+
- `<snice-approval-flow>` step status (pending/approved/rejected/skipped)
|
|
41
|
+
- Trend indicator: `<snice-kpi>`, `<snice-cell-percentage>` (table)
|
|
42
|
+
- `<snice-cell-json>` expand/collapse chevron; `<snice-header>` sort direction (both table)
|
|
43
|
+
- Close button: `<snice-modal>`, `<snice-drawer>`, `<snice-toast>`
|
|
44
|
+
- `<snice-data-card>` Edit/Done button
|
|
54
45
|
|
|
55
46
|
## Importing built-in glyphs directly
|
|
56
47
|
|
|
@@ -2,19 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
Form-associated ordered string-pair editor. Preserves duplicates, descriptions, Unicode, and row order. Direct `<snice-kv-pair>` children or imperative data API.
|
|
4
4
|
|
|
5
|
-
## Table of Contents
|
|
6
|
-
|
|
7
|
-
- [Components](#components)
|
|
8
|
-
- [Properties](#properties)
|
|
9
|
-
- [Methods](#methods)
|
|
10
|
-
- [Events](#events)
|
|
11
|
-
- [Slots](#slots)
|
|
12
|
-
- [CSS Parts](#css-parts)
|
|
13
|
-
- [Basic Usage](#basic-usage)
|
|
14
|
-
- [Examples](#examples)
|
|
15
|
-
- [Keyboard Navigation](#keyboard-navigation)
|
|
16
|
-
- [Accessibility](#accessibility)
|
|
17
|
-
|
|
18
5
|
## Components
|
|
19
6
|
|
|
20
7
|
- `snice-key-value` - Editor/display/FACE control.
|
|
@@ -32,19 +19,13 @@ showDescription: boolean = false; // attr: show-description
|
|
|
32
19
|
keyPlaceholder: string = 'Key'; // attr: key-placeholder
|
|
33
20
|
valuePlaceholder: string = 'Value'; // attr: value-placeholder
|
|
34
21
|
placeholders: Array<{key:string;value:string}> = []; // JS only
|
|
35
|
-
disabled: boolean = false;
|
|
36
|
-
readonly: boolean = false;
|
|
37
|
-
required: boolean = false;
|
|
22
|
+
disabled | readonly | required: boolean = false;
|
|
38
23
|
name: string = '';
|
|
39
24
|
variant: 'default'|'compact' = 'default';
|
|
40
25
|
mode: 'edit'|'view' = 'edit';
|
|
41
26
|
showCopy: boolean = false; // attr: show-copy
|
|
42
|
-
readonly type: 'key-value';
|
|
43
|
-
readonly
|
|
44
|
-
readonly validity: ValidityState;
|
|
45
|
-
readonly validationMessage: string;
|
|
46
|
-
readonly willValidate: boolean;
|
|
47
|
-
readonly labels: NodeList|null;
|
|
27
|
+
readonly type: 'key-value'; form: HTMLFormElement|null; validity: ValidityState;
|
|
28
|
+
readonly validationMessage: string; willValidate: boolean; labels: NodeList|null;
|
|
48
29
|
```
|
|
49
30
|
|
|
50
31
|
```ts
|
|
@@ -59,12 +59,12 @@ Siblings of `snice-layout` for the other standard page shapes. All regions are s
|
|
|
59
59
|
- `snice-layout-sidebar` — app shell: `brand`, `header`, `sidebar`, `page`, `footer`
|
|
60
60
|
- `snice-layout-dashboard` — app shell + toolbar + right rail: `brand`, `header`, `toolbar`, `sidebar`, `page`, `right-sidebar`
|
|
61
61
|
- `snice-layout-blog` — article measure: `brand`, `nav`, `page`, `sidebar`, `footer`
|
|
62
|
-
- `snice-layout-centered` — auth card: `brand`, `page`, `footer`
|
|
63
|
-
- `snice-layout-split` — two panes: `left`, `right` (`direction
|
|
64
|
-
- `snice-layout-landing` — marketing bands: `brand`, `nav`, `cta`, `hero`, `page`, `footer` (`use-nav`)
|
|
65
|
-
- `snice-layout-card` — card grid: `header`, `page`, `footer` (`columns
|
|
62
|
+
- `snice-layout-centered` — auth card: `brand`, `page`, `footer` (`width`: `sm`|`md`|`lg`|`xl`, default `md`)
|
|
63
|
+
- `snice-layout-split` — two panes: `left`, `right` (`direction`: `horizontal` default|`vertical`; `ratio`: `50-50` default|`60-40`|`70-30`|`33-67`|`67-33`)
|
|
64
|
+
- `snice-layout-landing` — marketing bands: `brand`, `nav`, `cta`, `hero`, `page`, `footer` (`use-nav` boolean, default false)
|
|
65
|
+
- `snice-layout-card` — card grid: `header`, `page`, `footer` (`columns`: `1`|`2`|`3` default|`4`|`6`; `gap`: `sm`|`md` default|`lg`|`xl`)
|
|
66
66
|
- `snice-layout-minimal` — `page` only
|
|
67
|
-
- `snice-layout-fullscreen` — layers: `background`, `overlay`, `page`, `controls` (`overlay`)
|
|
67
|
+
- `snice-layout-fullscreen` — layers: `background`, `overlay`, `page`, `controls` (`overlay` boolean, default false)
|
|
68
68
|
- `snice-layout-master-detail` — list + detail: `brand`, `header`, `list`, `detail`, `empty` (`selected`); <641px single pane, back emits `detail-closed`
|
|
69
69
|
- `snice-layout-docs` — three panes: `brand`, `header`, `sidebar`, `page`, `toc`, `footer`; rail drops at 1152px, tree → drawer at 996px; skip link + heading scroll-margin
|
|
70
70
|
- `snice-layout-auth-split` — form + decorative panel: `brand`, `page`, `footer`, `panel` (`panel-position`: `end` default | `start`); panel hidden <768px
|
|
@@ -104,13 +104,9 @@ Layouts own the screen. App shells (`sidebar`, `dashboard`, `fullscreen`) are `p
|
|
|
104
104
|
|
|
105
105
|
## CSS Custom Properties
|
|
106
106
|
|
|
107
|
-
- `--snice-layout-auth-panel-bg` - Layout auth panel background
|
|
108
|
-
- `--snice-layout-control-size` - Layout control size
|
|
109
|
-
- `--snice-layout-docs-header-height` - Layout docs header height
|
|
110
|
-
- `--snice-layout-docs-header-height-compact` - Layout docs header height compact
|
|
111
|
-
|
|
112
|
-
## Sizing hooks
|
|
113
|
-
|
|
114
107
|
- `--snice-layout-sidebar-width` (`16rem`), `--snice-layout-rail-collapsed-width` (`3rem`)
|
|
115
108
|
- `--snice-layout-rail-width` (`18rem`), `--snice-layout-measure` (`65ch`), `--snice-layout-container` (`80rem`)
|
|
116
109
|
- `--snice-layout-list-width` (`20rem`), `--snice-layout-docs-nav-width` / `--snice-layout-docs-toc-width` (`18.75rem`), `--snice-layout-auth-width` (`24rem`)
|
|
110
|
+
- `--snice-layout-docs-header-height` (`4rem`), `--snice-layout-docs-header-height-compact` (`3.5rem`) — docs sticky header, compact below 768px
|
|
111
|
+
- `--snice-layout-auth-panel-bg` (`var(--snice-color-surface-container)`) — auth split panel
|
|
112
|
+
- `--snice-layout-control-size` (`2rem`) — sidebar / drawer toggle buttons
|
|
@@ -12,7 +12,7 @@ Ranked list with podium variant, avatars, change indicators. Dual API: declarati
|
|
|
12
12
|
```ts
|
|
13
13
|
variant: 'default'|'podium'|'compact' = 'default';
|
|
14
14
|
size: 'small'|'medium'|'large' = 'medium';
|
|
15
|
-
title: string = '';
|
|
15
|
+
title: string = ''; // JS-only; a title attribute is the native tooltip, not this
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
## Methods
|
|
@@ -62,7 +62,7 @@ interface LeaderboardEntry {
|
|
|
62
62
|
## Basic Usage
|
|
63
63
|
|
|
64
64
|
```html
|
|
65
|
-
<snice-leaderboard variant="podium" title=
|
|
65
|
+
<snice-leaderboard id="board" variant="podium"> <!-- title is JS-only: board.title = 'Top Players' -->
|
|
66
66
|
<snice-leaderboard-entry rank="1" name="Alice" score="2500" change="3" highlighted></snice-leaderboard-entry>
|
|
67
67
|
<snice-leaderboard-entry rank="2" name="Bob" score="2100" change="-1"></snice-leaderboard-entry>
|
|
68
68
|
</snice-leaderboard>
|
|
@@ -6,7 +6,7 @@ Rich URL preview card with image, title, description, and site info.
|
|
|
6
6
|
|
|
7
7
|
```ts
|
|
8
8
|
url: string = '';
|
|
9
|
-
title: string = '';
|
|
9
|
+
title: string = ''; // JS-only; a title attribute is the native tooltip, not this
|
|
10
10
|
description: string = '';
|
|
11
11
|
image: string = '';
|
|
12
12
|
siteName: string = ''; // attr: site-name
|
|
@@ -34,16 +34,17 @@ import 'snice/components/link-preview/snice-link-preview';
|
|
|
34
34
|
```html
|
|
35
35
|
<!-- Vertical (default) -->
|
|
36
36
|
<snice-link-preview
|
|
37
|
+
id="preview"
|
|
37
38
|
url="https://example.com"
|
|
38
|
-
title="Article Title"
|
|
39
39
|
description="Brief summary."
|
|
40
40
|
image="/images/og.jpg"
|
|
41
41
|
site-name="example.com"
|
|
42
42
|
favicon="/icons/favicon.ico">
|
|
43
43
|
</snice-link-preview>
|
|
44
|
+
<script>document.getElementById('preview').title = 'Article Title';</script>
|
|
44
45
|
|
|
45
46
|
<!-- Horizontal, small -->
|
|
46
47
|
<snice-link-preview variant="horizontal" size="small"
|
|
47
|
-
url="https://example.com"
|
|
48
|
+
url="https://example.com" description="Short.">
|
|
48
49
|
</snice-link-preview>
|
|
49
50
|
```
|
|
@@ -13,6 +13,8 @@ loading: boolean = false;
|
|
|
13
13
|
showRememberMe: boolean = true; // attr: show-remember-me
|
|
14
14
|
showForgotPassword: boolean = true; // attr: show-forgot-password
|
|
15
15
|
actionText: string = 'Sign In'; // attr: action-text
|
|
16
|
+
alertMessage: string = ''; // JS only; inline alert above the form
|
|
17
|
+
alertVariant: 'error'|'success'|'' = ''; // JS only; styles alertMessage
|
|
16
18
|
```
|
|
17
19
|
|
|
18
20
|
## Methods
|
|
@@ -22,6 +24,8 @@ actionText: string = 'Sign In'; // attr: action-text
|
|
|
22
24
|
- `reset()` → Clear form, alert, loading
|
|
23
25
|
- `setError(message)` → Show error alert
|
|
24
26
|
- `clearError()` → Clear alert
|
|
27
|
+
- `showAlert(message, 'error'|'success')` → Show inline alert; `setError` is the error-only shorthand
|
|
28
|
+
- `clearAlert()` → Remove inline alert
|
|
25
29
|
|
|
26
30
|
## Requests
|
|
27
31
|
|
|
@@ -107,3 +111,10 @@ class AuthController {
|
|
|
107
111
|
// Event fallback
|
|
108
112
|
login.addEventListener('login-success', () => location.href = '/dashboard');
|
|
109
113
|
```
|
|
114
|
+
|
|
115
|
+
## Accessibility
|
|
116
|
+
|
|
117
|
+
- Inputs use `<label for>`; `autocomplete="username"` / `"current-password"`
|
|
118
|
+
- Required fields carry `required`
|
|
119
|
+
- Enter on the password field submits
|
|
120
|
+
- Loading and disabled states propagate to every input and the submit button
|
|
@@ -70,3 +70,10 @@ md.addEventListener('link-click', (e) => {
|
|
|
70
70
|
console.log('Navigating to:', e.detail.href);
|
|
71
71
|
});
|
|
72
72
|
```
|
|
73
|
+
|
|
74
|
+
## Accessibility
|
|
75
|
+
|
|
76
|
+
- Rendered HTML keeps the semantic heading hierarchy (h1-h6) for screen readers
|
|
77
|
+
- Links in rendered content are keyboard accessible
|
|
78
|
+
- Tables render real `<thead>`/`<tbody>` structure for assistive technology
|
|
79
|
+
- `link-click` lets you take over navigation without losing that behavior
|
|
@@ -44,3 +44,9 @@ import 'snice/components/masonry/snice-masonry';
|
|
|
44
44
|
<div>Card 2</div>
|
|
45
45
|
</snice-masonry>
|
|
46
46
|
```
|
|
47
|
+
|
|
48
|
+
## Accessibility
|
|
49
|
+
|
|
50
|
+
- Container carries `role="list"` for screen readers
|
|
51
|
+
- Items flow top-to-bottom, left-to-right within CSS columns
|
|
52
|
+
- `break-inside: avoid` keeps an item from splitting across columns
|
|
@@ -75,7 +75,7 @@ selected: boolean = false;
|
|
|
75
75
|
--menu-border: var(--snice-color-border, #e5e7eb);
|
|
76
76
|
--menu-shadow: var(--snice-shadow-lg);
|
|
77
77
|
--menu-z-index: var(--snice-z-floating, 1000);
|
|
78
|
-
--menu-border-radius: var(--snice-radius-md, 0.
|
|
78
|
+
--menu-border-radius: var(--snice-border-radius-md, 0.25rem);
|
|
79
79
|
--menu-min-width: 10rem;
|
|
80
80
|
```
|
|
81
81
|
|
|
@@ -72,3 +72,10 @@ modal.addEventListener('modal-close', () => console.log('Closed'));
|
|
|
72
72
|
|
|
73
73
|
- Escape closes (unless `no-escape-dismiss`)
|
|
74
74
|
- Tab/Shift+Tab cycle focus within modal
|
|
75
|
+
|
|
76
|
+
## Accessibility
|
|
77
|
+
|
|
78
|
+
- `role="dialog"` + `aria-modal="true"` + `aria-label`
|
|
79
|
+
- Focus trapped by default (`no-focus-trap` disables); first focusable element focused on open, previous focus restored on close
|
|
80
|
+
- Body scroll locked while open
|
|
81
|
+
- Close button labelled `Close modal`
|
|
@@ -8,6 +8,7 @@ Bell icon with dropdown notification panel. Shows unread badge, supports dismiss
|
|
|
8
8
|
notifications: NotificationItem[] = []; // attr: none (JS only)
|
|
9
9
|
open: boolean = false; // Panel visibility
|
|
10
10
|
icon: string = ''; // Custom bell icon (URL, image, emoji)
|
|
11
|
+
placement: 'start'|'end' = 'end'; // Panel alignment side
|
|
11
12
|
```
|
|
12
13
|
|
|
13
14
|
## Methods
|
|
@@ -37,15 +38,15 @@ icon: string = ''; // Custom bell icon (URL, image, emoji)
|
|
|
37
38
|
|
|
38
39
|
```css
|
|
39
40
|
--snice-color-primary /* Mark all read link, unread highlight */
|
|
40
|
-
--snice-color-primary-subtle
|
|
41
|
+
--snice-color-primary-subtle-hover /* Unread item hover (base tint derives from --snice-color-primary) */
|
|
41
42
|
--snice-color-danger /* Badge background, dismiss hover */
|
|
42
|
-
--snice-color-
|
|
43
|
+
--snice-color-surface /* Badge text, via the nested snice-badge */
|
|
43
44
|
--snice-color-text-secondary /* Message text */
|
|
44
45
|
--snice-color-text-tertiary /* Timestamp, empty state, dismiss icon */
|
|
45
46
|
--snice-color-border /* Panel, item borders */
|
|
46
47
|
--snice-color-surface /* Panel background */
|
|
47
|
-
--snice-color-surface-
|
|
48
|
-
--snice-shadow-
|
|
48
|
+
--snice-color-surface-hover /* Item hover, bell hover */
|
|
49
|
+
--snice-shadow-xl /* Panel shadow */
|
|
49
50
|
```
|
|
50
51
|
|
|
51
52
|
## Basic Usage
|