snice 2.5.4 → 3.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/README.md +501 -882
- package/bin/templates/base/src/components/counter-button.ts +13 -26
- package/bin/templates/base/src/controllers/counter-controller.ts +3 -3
- package/dist/components/accordion/snice-accordion-item.d.ts +4 -5
- package/dist/components/accordion/snice-accordion-item.js +37 -39
- package/dist/components/accordion/snice-accordion-item.js.map +1 -1
- package/dist/components/accordion/snice-accordion.d.ts +5 -11
- package/dist/components/accordion/snice-accordion.js +51 -52
- package/dist/components/accordion/snice-accordion.js.map +1 -1
- package/dist/components/alert/snice-alert.d.ts +2 -6
- package/dist/components/alert/snice-alert.js +41 -56
- package/dist/components/alert/snice-alert.js.map +1 -1
- package/dist/components/avatar/snice-avatar.d.ts +2 -6
- package/dist/components/avatar/snice-avatar.js +64 -71
- package/dist/components/avatar/snice-avatar.js.map +1 -1
- package/dist/components/badge/snice-badge.d.ts +2 -3
- package/dist/components/badge/snice-badge.js +22 -23
- package/dist/components/badge/snice-badge.js.map +1 -1
- package/dist/components/breadcrumbs/snice-breadcrumbs.d.ts +5 -12
- package/dist/components/breadcrumbs/snice-breadcrumbs.js +88 -89
- package/dist/components/breadcrumbs/snice-breadcrumbs.js.map +1 -1
- package/dist/components/button/snice-button.d.ts +3 -7
- package/dist/components/button/snice-button.js +37 -58
- package/dist/components/button/snice-button.js.map +1 -1
- package/dist/components/card/snice-card.d.ts +5 -8
- package/dist/components/card/snice-card.js +71 -56
- package/dist/components/card/snice-card.js.map +1 -1
- package/dist/components/checkbox/snice-checkbox.d.ts +4 -13
- package/dist/components/checkbox/snice-checkbox.js +66 -137
- package/dist/components/checkbox/snice-checkbox.js.map +1 -1
- package/dist/components/chip/snice-chip.d.ts +5 -11
- package/dist/components/chip/snice-chip.js +44 -47
- package/dist/components/chip/snice-chip.js.map +1 -1
- package/dist/components/date-picker/snice-date-picker.d.ts +11 -11
- package/dist/components/date-picker/snice-date-picker.js +134 -133
- package/dist/components/date-picker/snice-date-picker.js.map +1 -1
- package/dist/components/divider/snice-divider.d.ts +2 -4
- package/dist/components/divider/snice-divider.js +14 -22
- package/dist/components/divider/snice-divider.js.map +1 -1
- package/dist/components/drawer/snice-drawer.d.ts +4 -4
- package/dist/components/drawer/snice-drawer.js +25 -19
- package/dist/components/drawer/snice-drawer.js.map +1 -1
- package/dist/components/input/snice-input.d.ts +8 -6
- package/dist/components/input/snice-input.js +122 -105
- package/dist/components/input/snice-input.js.map +1 -1
- package/dist/components/layout/snice-layout-blog.d.ts +4 -4
- package/dist/components/layout/snice-layout-blog.js +21 -19
- package/dist/components/layout/snice-layout-blog.js.map +1 -1
- package/dist/components/layout/snice-layout-card.d.ts +2 -2
- package/dist/components/layout/snice-layout-card.js +16 -9
- package/dist/components/layout/snice-layout-card.js.map +1 -1
- package/dist/components/layout/snice-layout-centered.d.ts +2 -2
- package/dist/components/layout/snice-layout-centered.js +14 -7
- package/dist/components/layout/snice-layout-centered.js.map +1 -1
- package/dist/components/layout/snice-layout-dashboard.d.ts +5 -5
- package/dist/components/layout/snice-layout-dashboard.js +38 -30
- package/dist/components/layout/snice-layout-dashboard.js.map +1 -1
- package/dist/components/layout/snice-layout-fullscreen.d.ts +2 -2
- package/dist/components/layout/snice-layout-fullscreen.js +17 -10
- package/dist/components/layout/snice-layout-fullscreen.js.map +1 -1
- package/dist/components/layout/snice-layout-landing.d.ts +4 -4
- package/dist/components/layout/snice-layout-landing.js +21 -19
- package/dist/components/layout/snice-layout-landing.js.map +1 -1
- package/dist/components/layout/snice-layout-minimal.d.ts +2 -2
- package/dist/components/layout/snice-layout-minimal.js +17 -6
- package/dist/components/layout/snice-layout-minimal.js.map +1 -1
- package/dist/components/layout/snice-layout-sidebar.d.ts +5 -4
- package/dist/components/layout/snice-layout-sidebar.js +42 -20
- package/dist/components/layout/snice-layout-sidebar.js.map +1 -1
- package/dist/components/layout/snice-layout-split.d.ts +2 -2
- package/dist/components/layout/snice-layout-split.js +14 -7
- package/dist/components/layout/snice-layout-split.js.map +1 -1
- package/dist/components/layout/snice-layout.d.ts +4 -4
- package/dist/components/layout/snice-layout.js +16 -10
- package/dist/components/layout/snice-layout.js.map +1 -1
- package/dist/components/login/snice-login.d.ts +6 -11
- package/dist/components/login/snice-login.js +97 -71
- package/dist/components/login/snice-login.js.map +1 -1
- package/dist/components/modal/snice-modal.d.ts +5 -9
- package/dist/components/modal/snice-modal.js +47 -78
- package/dist/components/modal/snice-modal.js.map +1 -1
- package/dist/components/nav/snice-nav.d.ts +13 -7
- package/dist/components/nav/snice-nav.js +191 -100
- package/dist/components/nav/snice-nav.js.map +1 -1
- package/dist/components/nav/snice-nav.types.d.ts +3 -3
- package/dist/components/pagination/snice-pagination.d.ts +6 -7
- package/dist/components/pagination/snice-pagination.js +94 -81
- package/dist/components/pagination/snice-pagination.js.map +1 -1
- package/dist/components/progress/snice-progress.d.ts +2 -7
- package/dist/components/progress/snice-progress.js +41 -98
- package/dist/components/progress/snice-progress.js.map +1 -1
- package/dist/components/radio/snice-radio.d.ts +4 -4
- package/dist/components/radio/snice-radio.js +52 -44
- package/dist/components/radio/snice-radio.js.map +1 -1
- package/dist/components/select/snice-option.d.ts +2 -1
- package/dist/components/select/snice-option.js +12 -5
- package/dist/components/select/snice-option.js.map +1 -1
- package/dist/components/select/snice-select.d.ts +9 -21
- package/dist/components/select/snice-select.js +98 -170
- package/dist/components/select/snice-select.js.map +1 -1
- package/dist/components/skeleton/snice-skeleton.d.ts +2 -6
- package/dist/components/skeleton/snice-skeleton.js +18 -49
- package/dist/components/skeleton/snice-skeleton.js.map +1 -1
- package/dist/components/snice-cell-BLFVdxPp.js +4 -0
- package/dist/components/snice-cell-BLFVdxPp.js.map +1 -0
- package/dist/components/switch/snice-switch.d.ts +2 -2
- package/dist/components/switch/snice-switch.js +38 -26
- package/dist/components/switch/snice-switch.js.map +1 -1
- package/dist/components/table/snice-cell-actions.d.ts +24 -0
- package/dist/components/table/snice-cell-actions.js +149 -0
- package/dist/components/table/snice-cell-actions.js.map +1 -0
- package/dist/components/table/snice-cell-boolean.d.ts +2 -2
- package/dist/components/table/snice-cell-boolean.js +13 -7
- package/dist/components/table/snice-cell-boolean.js.map +1 -1
- package/dist/components/table/snice-cell-color.d.ts +18 -0
- package/dist/components/table/snice-cell-color.js +149 -0
- package/dist/components/table/snice-cell-color.js.map +1 -0
- package/dist/components/table/snice-cell-currency.d.ts +24 -0
- package/dist/components/table/snice-cell-currency.js +235 -0
- package/dist/components/table/snice-cell-currency.js.map +1 -0
- package/dist/components/table/snice-cell-date.d.ts +2 -2
- package/dist/components/table/snice-cell-date.js +14 -8
- package/dist/components/table/snice-cell-date.js.map +1 -1
- package/dist/components/table/snice-cell-duration.d.ts +2 -2
- package/dist/components/table/snice-cell-duration.js +12 -6
- package/dist/components/table/snice-cell-duration.js.map +1 -1
- package/dist/components/table/snice-cell-email.d.ts +15 -0
- package/dist/components/table/snice-cell-email.js +125 -0
- package/dist/components/table/snice-cell-email.js.map +1 -0
- package/dist/components/table/snice-cell-filesize.d.ts +2 -2
- package/dist/components/table/snice-cell-filesize.js +12 -6
- package/dist/components/table/snice-cell-filesize.js.map +1 -1
- package/dist/components/table/snice-cell-image.d.ts +20 -0
- package/dist/components/table/snice-cell-image.js +162 -0
- package/dist/components/table/snice-cell-image.js.map +1 -0
- package/dist/components/table/snice-cell-json.d.ts +20 -0
- package/dist/components/table/snice-cell-json.js +186 -0
- package/dist/components/table/snice-cell-json.js.map +1 -0
- package/dist/components/table/snice-cell-link.d.ts +17 -0
- package/dist/components/table/snice-cell-link.js +142 -0
- package/dist/components/table/snice-cell-link.js.map +1 -0
- package/dist/components/table/snice-cell-location.d.ts +19 -0
- package/dist/components/table/snice-cell-location.js +185 -0
- package/dist/components/table/snice-cell-location.js.map +1 -0
- package/dist/components/table/snice-cell-number.d.ts +2 -2
- package/dist/components/table/snice-cell-number.js +12 -6
- package/dist/components/table/snice-cell-number.js.map +1 -1
- package/dist/components/table/snice-cell-percentage.d.ts +22 -0
- package/dist/components/table/snice-cell-percentage.js +208 -0
- package/dist/components/table/snice-cell-percentage.js.map +1 -0
- package/dist/components/table/snice-cell-phone.d.ts +18 -0
- package/dist/components/table/snice-cell-phone.js +153 -0
- package/dist/components/table/snice-cell-phone.js.map +1 -0
- package/dist/components/table/snice-cell-progress.d.ts +2 -2
- package/dist/components/table/snice-cell-progress.js +12 -6
- package/dist/components/table/snice-cell-progress.js.map +1 -1
- package/dist/components/table/snice-cell-rating.d.ts +2 -2
- package/dist/components/table/snice-cell-rating.js +12 -6
- package/dist/components/table/snice-cell-rating.js.map +1 -1
- package/dist/components/table/snice-cell-sparkline.d.ts +2 -2
- package/dist/components/table/snice-cell-sparkline.js +13 -7
- package/dist/components/table/snice-cell-sparkline.js.map +1 -1
- package/dist/components/table/snice-cell-status.d.ts +17 -0
- package/dist/components/table/snice-cell-status.js +144 -0
- package/dist/components/table/snice-cell-status.js.map +1 -0
- package/dist/components/table/snice-cell-tag.d.ts +16 -0
- package/dist/components/table/snice-cell-tag.js +131 -0
- package/dist/components/table/snice-cell-tag.js.map +1 -0
- package/dist/components/table/snice-cell-text.d.ts +2 -2
- package/dist/components/table/snice-cell-text.js +14 -8
- package/dist/components/table/snice-cell-text.js.map +1 -1
- package/dist/components/table/snice-cell.d.ts +2 -2
- package/dist/components/table/snice-cell.js +12 -6
- package/dist/components/table/snice-cell.js.map +1 -1
- package/dist/components/table/snice-column.d.ts +1 -1
- package/dist/components/table/snice-column.js +6 -3
- package/dist/components/table/snice-column.js.map +1 -1
- package/dist/components/table/snice-header.d.ts +5 -5
- package/dist/components/table/snice-header.js +60 -50
- package/dist/components/table/snice-header.js.map +1 -1
- package/dist/components/table/snice-progress.d.ts +2 -2
- package/dist/components/table/snice-progress.js +18 -11
- package/dist/components/table/snice-progress.js.map +1 -1
- package/dist/components/table/snice-rating.d.ts +2 -2
- package/dist/components/table/snice-rating.js +15 -8
- package/dist/components/table/snice-rating.js.map +1 -1
- package/dist/components/table/snice-row.d.ts +17 -6
- package/dist/components/table/snice-row.js +95 -44
- package/dist/components/table/snice-row.js.map +1 -1
- package/dist/components/table/snice-table.d.ts +18 -10
- package/dist/components/table/snice-table.js +355 -173
- package/dist/components/table/snice-table.js.map +1 -1
- package/dist/components/table/snice-table.types.d.ts +101 -2
- package/dist/components/tabs/snice-tab-panel.d.ts +2 -2
- package/dist/components/tabs/snice-tab-panel.js +12 -6
- package/dist/components/tabs/snice-tab-panel.js.map +1 -1
- package/dist/components/tabs/snice-tab.d.ts +6 -5
- package/dist/components/tabs/snice-tab.js +36 -19
- package/dist/components/tabs/snice-tab.js.map +1 -1
- package/dist/components/tabs/snice-tabs.d.ts +5 -5
- package/dist/components/tabs/snice-tabs.js +38 -28
- package/dist/components/tabs/snice-tabs.js.map +1 -1
- package/dist/components/toast/snice-toast-container.d.ts +7 -7
- package/dist/components/toast/snice-toast-container.js +19 -12
- package/dist/components/toast/snice-toast-container.js.map +1 -1
- package/dist/components/toast/snice-toast.d.ts +3 -15
- package/dist/components/toast/snice-toast.js +49 -108
- package/dist/components/toast/snice-toast.js.map +1 -1
- package/dist/components/tooltip/snice-tooltip.d.ts +2 -2
- package/dist/components/tooltip/snice-tooltip.js +14 -7
- package/dist/components/tooltip/snice-tooltip.js.map +1 -1
- package/dist/context.d.ts +44 -0
- package/dist/element-ready.d.ts +40 -0
- package/dist/{types/element.d.ts → element.d.ts} +2 -8
- package/dist/{types/events.d.ts → events.d.ts} +0 -4
- package/dist/index.cjs +2589 -605
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +21 -0
- package/dist/index.esm.js +2568 -604
- package/dist/index.esm.js.map +1 -1
- package/dist/index.iife.js +2589 -605
- package/dist/index.iife.js.map +1 -1
- package/dist/method-decorators.d.ts +121 -0
- package/dist/on.d.ts +59 -0
- package/dist/parts.d.ts +159 -0
- package/dist/render-debug.d.ts +27 -0
- package/dist/render-tracker.d.ts +14 -0
- package/dist/render.d.ts +96 -0
- package/dist/symbols.cjs +163 -0
- package/dist/symbols.cjs.map +1 -1
- package/dist/{types/symbols.d.ts → symbols.d.ts} +22 -0
- package/dist/symbols.esm.js +27 -3
- package/dist/symbols.esm.js.map +1 -1
- package/dist/template.d.ts +100 -0
- package/dist/transitions.cjs +219 -0
- package/dist/transitions.esm.js +2 -2
- package/dist/types/context.d.ts +48 -0
- package/dist/types/element-options.d.ts +26 -0
- package/dist/types/index.d.ts +25 -9
- package/dist/types/nav-context.d.ts +19 -0
- package/dist/types/{types/on-options.d.ts → on-options.d.ts} +2 -0
- package/dist/types/{types/placard.d.ts → placard.d.ts} +0 -1
- package/docs/ai/README.md +17 -0
- package/docs/ai/api.md +175 -0
- package/docs/ai/architecture.md +160 -0
- package/docs/ai/components/accordion.md +174 -0
- package/docs/ai/components/alert.md +77 -0
- package/docs/ai/components/avatar.md +61 -0
- package/docs/ai/components/badge.md +69 -0
- package/docs/ai/components/breadcrumbs.md +74 -0
- package/docs/ai/components/button.md +75 -0
- package/docs/ai/components/card.md +61 -0
- package/docs/ai/components/checkbox.md +74 -0
- package/docs/ai/components/chip.md +73 -0
- package/docs/ai/components/date-picker.md +75 -0
- package/docs/ai/components/divider.md +66 -0
- package/docs/ai/components/drawer.md +80 -0
- package/docs/ai/components/input.md +111 -0
- package/docs/ai/components/login.md +109 -0
- package/docs/ai/components/modal.md +67 -0
- package/docs/ai/components/nav.md +76 -0
- package/docs/ai/components/pagination.md +55 -0
- package/docs/ai/components/progress.md +72 -0
- package/docs/ai/components/radio.md +79 -0
- package/docs/ai/components/select.md +92 -0
- package/docs/ai/components/skeleton.md +57 -0
- package/docs/ai/components/switch.md +53 -0
- package/docs/ai/components/table.md +227 -0
- package/docs/ai/components/tabs.md +83 -0
- package/docs/ai/components/toast.md +140 -0
- package/docs/ai/components/tooltip.md +146 -0
- package/docs/ai/patterns.md +244 -0
- package/docs/components/accordion.md +558 -0
- package/docs/components/drawer.md +602 -0
- package/docs/components/modal.md +558 -0
- package/docs/components/nav.md +239 -0
- package/docs/components/pagination.md +289 -0
- package/docs/components/select.md +599 -0
- package/docs/components/switch.md +354 -0
- package/docs/components/tabs.md +546 -0
- package/docs/components/toast.md +506 -0
- package/docs/components/tooltip.md +523 -0
- package/docs/controllers.md +744 -0
- package/docs/elements.md +855 -0
- package/docs/events.md +807 -0
- package/docs/migration-v2-to-v3.md +569 -0
- package/docs/observe.md +588 -0
- package/docs/placards.md +401 -0
- package/docs/request-response.md +852 -0
- package/docs/routing.md +1186 -0
- package/package.json +10 -11
- package/dist/components/snice-cell-C9N6yGxQ.js +0 -4
- package/dist/components/snice-cell-C9N6yGxQ.js.map +0 -1
- package/dist/types/types/index.d.ts +0 -23
- /package/dist/{types/controller.d.ts → controller.d.ts} +0 -0
- /package/dist/{types/global.d.ts → global.d.ts} +0 -0
- /package/dist/{types/observe.d.ts → observe.d.ts} +0 -0
- /package/dist/{types/request-response.d.ts → request-response.d.ts} +0 -0
- /package/dist/{types/router.d.ts → router.d.ts} +0 -0
- /package/dist/{types/testing.d.ts → testing.d.ts} +0 -0
- /package/dist/{types/transitions.d.ts → transitions.d.ts} +0 -0
- /package/dist/types/{types/adopted-options.d.ts → adopted-options.d.ts} +0 -0
- /package/dist/types/{types/app-context.d.ts → app-context.d.ts} +0 -0
- /package/dist/types/{types/dispatch-options.d.ts → dispatch-options.d.ts} +0 -0
- /package/dist/types/{types/guard.d.ts → guard.d.ts} +0 -0
- /package/dist/types/{types/i-controller.d.ts → i-controller.d.ts} +0 -0
- /package/dist/types/{types/moved-options.d.ts → moved-options.d.ts} +0 -0
- /package/dist/types/{types/observe-options.d.ts → observe-options.d.ts} +0 -0
- /package/dist/types/{types/page-options.d.ts → page-options.d.ts} +0 -0
- /package/dist/types/{types/part-options.d.ts → part-options.d.ts} +0 -0
- /package/dist/types/{types/property-converter.d.ts → property-converter.d.ts} +0 -0
- /package/dist/types/{types/property-options.d.ts → property-options.d.ts} +0 -0
- /package/dist/types/{types/query-options.d.ts → query-options.d.ts} +0 -0
- /package/dist/types/{types/request-options.d.ts → request-options.d.ts} +0 -0
- /package/dist/types/{types/respond-options.d.ts → respond-options.d.ts} +0 -0
- /package/dist/types/{types/route-params.d.ts → route-params.d.ts} +0 -0
- /package/dist/types/{types/router-instance.d.ts → router-instance.d.ts} +0 -0
- /package/dist/types/{types/router-options.d.ts → router-options.d.ts} +0 -0
- /package/dist/types/{types/simple-array.d.ts → simple-array.d.ts} +0 -0
- /package/dist/types/{types/snice-element.d.ts → snice-element.d.ts} +0 -0
- /package/dist/types/{types/snice-global.d.ts → snice-global.d.ts} +0 -0
- /package/dist/types/{types/transition.d.ts → transition.d.ts} +0 -0
- /package/dist/{types/utils.d.ts → utils.d.ts} +0 -0
package/docs/placards.md
ADDED
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
# Placards API
|
|
2
|
+
|
|
3
|
+
Placards provide rich metadata about pages that layouts can consume to dynamically build navigation, breadcrumbs, help systems, and other UI elements. This enables layouts to be populated with data instead of having hardcoded content.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The Placard system allows pages to declare metadata that describes their purpose, structure, and behavior. Layouts can then query this metadata to automatically build:
|
|
8
|
+
|
|
9
|
+
- Dynamic navigation menus
|
|
10
|
+
- Hierarchical breadcrumbs
|
|
11
|
+
- Context-sensitive help
|
|
12
|
+
- Search functionality
|
|
13
|
+
- Keyboard shortcuts
|
|
14
|
+
|
|
15
|
+
## Basic Usage
|
|
16
|
+
|
|
17
|
+
Define a placard for your page using the `placard` option in the `@page` decorator:
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { page, Placard, render, html } from 'snice';
|
|
21
|
+
|
|
22
|
+
const placard: Placard<AppContext> = {
|
|
23
|
+
name: 'dashboard',
|
|
24
|
+
title: 'Dashboard',
|
|
25
|
+
description: 'Main analytics and overview dashboard',
|
|
26
|
+
icon: '📊',
|
|
27
|
+
show: true,
|
|
28
|
+
order: 1
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
@page({
|
|
32
|
+
tag: 'dashboard-page',
|
|
33
|
+
routes: ['/dashboard'],
|
|
34
|
+
placard: placard
|
|
35
|
+
})
|
|
36
|
+
class DashboardPage extends HTMLElement {
|
|
37
|
+
@render()
|
|
38
|
+
renderContent() {
|
|
39
|
+
return html`<h1>Dashboard</h1>`;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Placard Interface
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
interface Placard<T = any> {
|
|
48
|
+
// Identification
|
|
49
|
+
name: string;
|
|
50
|
+
|
|
51
|
+
// Core display
|
|
52
|
+
title: string;
|
|
53
|
+
description?: string;
|
|
54
|
+
icon?: string;
|
|
55
|
+
|
|
56
|
+
// Help & discovery
|
|
57
|
+
tooltip?: string;
|
|
58
|
+
searchTerms?: string[];
|
|
59
|
+
hotkeys?: string[];
|
|
60
|
+
helpUrl?: string;
|
|
61
|
+
|
|
62
|
+
// Navigation structure
|
|
63
|
+
breadcrumbs?: string[];
|
|
64
|
+
group?: string;
|
|
65
|
+
parent?: string;
|
|
66
|
+
order?: number;
|
|
67
|
+
show?: boolean;
|
|
68
|
+
|
|
69
|
+
// Dynamic visibility
|
|
70
|
+
visibleOn?: Guard<T> | Guard<T>[];
|
|
71
|
+
|
|
72
|
+
// Extensibility
|
|
73
|
+
attributes?: Record<string, any>;
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Field Reference
|
|
78
|
+
|
|
79
|
+
### Identification
|
|
80
|
+
|
|
81
|
+
**`name`** (required)
|
|
82
|
+
- Unique identifier for this placard
|
|
83
|
+
- Used for referencing in breadcrumbs and parent-child relationships
|
|
84
|
+
- Should be kebab-case, e.g., 'user-settings', 'admin-dashboard'
|
|
85
|
+
|
|
86
|
+
### Core Display
|
|
87
|
+
|
|
88
|
+
**`title`** (required)
|
|
89
|
+
- Display name shown in navigation and breadcrumbs
|
|
90
|
+
- Should be concise and descriptive
|
|
91
|
+
|
|
92
|
+
**`description`** (optional)
|
|
93
|
+
- Longer description of the page's purpose
|
|
94
|
+
- Used in tooltips, search results, or help text
|
|
95
|
+
|
|
96
|
+
**`icon`** (optional)
|
|
97
|
+
- Visual icon representing the page
|
|
98
|
+
- Can be emoji, icon font class, or SVG path
|
|
99
|
+
|
|
100
|
+
### Help & Discovery
|
|
101
|
+
|
|
102
|
+
**`tooltip`** (optional)
|
|
103
|
+
- Brief help text shown on hover
|
|
104
|
+
- Explains what the page does or when to use it
|
|
105
|
+
|
|
106
|
+
**`searchTerms`** (optional)
|
|
107
|
+
- Additional keywords for search functionality
|
|
108
|
+
- Helps users discover pages through alternate terms
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
searchTerms: ['settings', 'preferences', 'config', 'options']
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**`hotkeys`** (optional)
|
|
115
|
+
- Keyboard shortcuts to navigate to this page
|
|
116
|
+
- Uses standard key notation
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
hotkeys: ['ctrl+d', 'cmd+d', 'alt+shift+d']
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
**`helpUrl`** (optional)
|
|
123
|
+
- Link to detailed documentation or help for this page
|
|
124
|
+
|
|
125
|
+
### Navigation Structure
|
|
126
|
+
|
|
127
|
+
**`group`** (optional)
|
|
128
|
+
- Logical grouping for navigation organization
|
|
129
|
+
- Pages with the same group are displayed together
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
group: 'admin' // Groups with other admin pages
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**`parent`** (optional)
|
|
136
|
+
- References another placard's `name` to create hierarchy
|
|
137
|
+
- Used for nested navigation and breadcrumb construction
|
|
138
|
+
|
|
139
|
+
```typescript
|
|
140
|
+
parent: 'users' // Child of the 'users' page
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
**`order`** (optional)
|
|
144
|
+
- Numeric sort order within the group or parent
|
|
145
|
+
- Lower numbers appear first
|
|
146
|
+
|
|
147
|
+
**`show`** (optional)
|
|
148
|
+
- Whether to display this page in navigation menus
|
|
149
|
+
- Defaults to `true` if not specified
|
|
150
|
+
|
|
151
|
+
### Dynamic Visibility
|
|
152
|
+
|
|
153
|
+
**`visibleOn`** (optional)
|
|
154
|
+
- Guard functions that determine if the page should appear in navigation
|
|
155
|
+
- Reuses the same guard system as route protection
|
|
156
|
+
|
|
157
|
+
```typescript
|
|
158
|
+
visibleOn: [isAuthenticated, hasAdminRole]
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Extensibility
|
|
162
|
+
|
|
163
|
+
**`attributes`** (optional)
|
|
164
|
+
- Arbitrary metadata for custom layout needs
|
|
165
|
+
- Domain-specific or framework-specific data
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
attributes: {
|
|
169
|
+
category: 'reporting',
|
|
170
|
+
experimental: true,
|
|
171
|
+
requiredFeatures: ['analytics', 'charts']
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Hierarchical Navigation Example
|
|
176
|
+
|
|
177
|
+
```typescript
|
|
178
|
+
// Parent page
|
|
179
|
+
const usersPlacard: Placard<AppContext> = {
|
|
180
|
+
name: 'users',
|
|
181
|
+
title: 'Users',
|
|
182
|
+
icon: '👥',
|
|
183
|
+
show: true,
|
|
184
|
+
order: 1,
|
|
185
|
+
group: 'admin'
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
// Child pages
|
|
189
|
+
const userListPlacard: Placard<AppContext> = {
|
|
190
|
+
name: 'user-list',
|
|
191
|
+
title: 'All Users',
|
|
192
|
+
parent: 'users',
|
|
193
|
+
order: 1,
|
|
194
|
+
show: true
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
const userCreatePlacard: Placard<AppContext> = {
|
|
198
|
+
name: 'user-create',
|
|
199
|
+
title: 'Create User',
|
|
200
|
+
parent: 'users',
|
|
201
|
+
order: 2,
|
|
202
|
+
show: true,
|
|
203
|
+
visibleOn: [canCreateUsers]
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
// Grandchild page
|
|
207
|
+
const userEditPlacard: Placard<AppContext> = {
|
|
208
|
+
name: 'user-edit',
|
|
209
|
+
title: 'Edit User',
|
|
210
|
+
parent: 'user-list',
|
|
211
|
+
show: false, // Hidden from nav, accessible via direct link
|
|
212
|
+
breadcrumbs: ['users', 'user-list', 'user-edit']
|
|
213
|
+
};
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## Breadcrumb Resolution
|
|
217
|
+
|
|
218
|
+
Breadcrumbs can be automatically resolved using the `parent` hierarchy or explicitly defined:
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
// Automatic breadcrumbs using parent chain
|
|
222
|
+
const settingsPlacard: Placard<AppContext> = {
|
|
223
|
+
name: 'user-settings',
|
|
224
|
+
title: 'Settings',
|
|
225
|
+
parent: 'user-profile'
|
|
226
|
+
// Breadcrumbs will be auto-resolved: Users > Profile > Settings
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
// Explicit breadcrumbs
|
|
230
|
+
const advancedPlacard: Placard<AppContext> = {
|
|
231
|
+
name: 'advanced-settings',
|
|
232
|
+
title: 'Advanced',
|
|
233
|
+
breadcrumbs: ['dashboard', 'settings', 'advanced-settings']
|
|
234
|
+
// Explicitly defined breadcrumb path
|
|
235
|
+
};
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## Layout Integration
|
|
239
|
+
|
|
240
|
+
Layouts can access placard data to build dynamic UI. The exact mechanism depends on your router implementation, but typically involves:
|
|
241
|
+
|
|
242
|
+
1. **Router Context** - Placards available through router context
|
|
243
|
+
2. **Navigation Builder** - Helper functions to build nav from placards
|
|
244
|
+
3. **Event System** - Layouts listen for route changes and update UI
|
|
245
|
+
|
|
246
|
+
```typescript
|
|
247
|
+
import { layout, render, html, Layout } from 'snice';
|
|
248
|
+
|
|
249
|
+
@layout('app-shell')
|
|
250
|
+
class AppShell extends HTMLElement implements Layout {
|
|
251
|
+
private placards: Placard[] = [];
|
|
252
|
+
private currentRoute = '';
|
|
253
|
+
|
|
254
|
+
@render()
|
|
255
|
+
renderContent() {
|
|
256
|
+
return html`
|
|
257
|
+
<header>
|
|
258
|
+
<nav>
|
|
259
|
+
${this.placards
|
|
260
|
+
.filter(p => p.show !== false && !p.parent)
|
|
261
|
+
.map(p => html`
|
|
262
|
+
<a
|
|
263
|
+
href="#/${p.name}"
|
|
264
|
+
class="${this.currentRoute === p.name ? 'active' : ''}"
|
|
265
|
+
>
|
|
266
|
+
${p.icon} ${p.title}
|
|
267
|
+
</a>
|
|
268
|
+
`)}
|
|
269
|
+
</nav>
|
|
270
|
+
</header>
|
|
271
|
+
<main>
|
|
272
|
+
<slot name="page"></slot>
|
|
273
|
+
</main>
|
|
274
|
+
`;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Called by router when route changes
|
|
278
|
+
update(appContext: any, placards: Placard[], currentRoute: string, routeParams: any) {
|
|
279
|
+
this.placards = placards;
|
|
280
|
+
this.currentRoute = currentRoute;
|
|
281
|
+
// Property changes trigger re-render
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### Building Navigation from Placards
|
|
287
|
+
|
|
288
|
+
```typescript
|
|
289
|
+
@layout('sidebar-layout')
|
|
290
|
+
class SidebarLayout extends HTMLElement implements Layout {
|
|
291
|
+
private placards: Placard[] = [];
|
|
292
|
+
private grouped: Record<string, Placard[]> = {};
|
|
293
|
+
|
|
294
|
+
@render()
|
|
295
|
+
renderContent() {
|
|
296
|
+
return html`
|
|
297
|
+
<aside class="sidebar">
|
|
298
|
+
${Object.entries(this.grouped).map(([group, items]) => html`
|
|
299
|
+
<div class="nav-group">
|
|
300
|
+
<h3>${group}</h3>
|
|
301
|
+
<ul>
|
|
302
|
+
${items
|
|
303
|
+
.sort((a, b) => (a.order || 0) - (b.order || 0))
|
|
304
|
+
.map(p => html`
|
|
305
|
+
<li>
|
|
306
|
+
<a href="#/${p.name}" title="${p.tooltip || ''}">
|
|
307
|
+
${p.icon} ${p.title}
|
|
308
|
+
</a>
|
|
309
|
+
</li>
|
|
310
|
+
`)}
|
|
311
|
+
</ul>
|
|
312
|
+
</div>
|
|
313
|
+
`)}
|
|
314
|
+
</aside>
|
|
315
|
+
<main>
|
|
316
|
+
<slot name="page"></slot>
|
|
317
|
+
</main>
|
|
318
|
+
`;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
update(appContext: any, placards: Placard[], currentRoute: string, routeParams: any) {
|
|
322
|
+
this.placards = placards.filter(p => p.show !== false);
|
|
323
|
+
|
|
324
|
+
// Group placards
|
|
325
|
+
this.grouped = this.placards.reduce((acc, p) => {
|
|
326
|
+
const group = p.group || 'main';
|
|
327
|
+
if (!acc[group]) acc[group] = [];
|
|
328
|
+
acc[group].push(p);
|
|
329
|
+
return acc;
|
|
330
|
+
}, {} as Record<string, Placard[]>);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
### Building Breadcrumbs
|
|
336
|
+
|
|
337
|
+
```typescript
|
|
338
|
+
@layout('breadcrumb-layout')
|
|
339
|
+
class BreadcrumbLayout extends HTMLElement implements Layout {
|
|
340
|
+
private breadcrumbs: Placard[] = [];
|
|
341
|
+
|
|
342
|
+
@render()
|
|
343
|
+
renderContent() {
|
|
344
|
+
return html`
|
|
345
|
+
<nav class="breadcrumbs">
|
|
346
|
+
${this.breadcrumbs.map((p, i) => html`
|
|
347
|
+
${i > 0 ? html`<span class="separator">/</span>` : ''}
|
|
348
|
+
<a href="#/${p.name}">${p.title}</a>
|
|
349
|
+
`)}
|
|
350
|
+
</nav>
|
|
351
|
+
<main>
|
|
352
|
+
<slot name="page"></slot>
|
|
353
|
+
</main>
|
|
354
|
+
`;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
update(appContext: any, placards: Placard[], currentRoute: string, routeParams: any) {
|
|
358
|
+
// Find current page placard
|
|
359
|
+
const current = placards.find(p => p.name === currentRoute);
|
|
360
|
+
if (!current) return;
|
|
361
|
+
|
|
362
|
+
// Build breadcrumb trail
|
|
363
|
+
this.breadcrumbs = this.buildBreadcrumbs(current, placards);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
buildBreadcrumbs(placard: Placard, all: Placard[]): Placard[] {
|
|
367
|
+
const trail: Placard[] = [placard];
|
|
368
|
+
|
|
369
|
+
// Use explicit breadcrumbs if defined
|
|
370
|
+
if (placard.breadcrumbs) {
|
|
371
|
+
return placard.breadcrumbs
|
|
372
|
+
.map(name => all.find(p => p.name === name))
|
|
373
|
+
.filter(Boolean) as Placard[];
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// Otherwise follow parent chain
|
|
377
|
+
let current = placard;
|
|
378
|
+
while (current.parent) {
|
|
379
|
+
const parent = all.find(p => p.name === current.parent);
|
|
380
|
+
if (!parent) break;
|
|
381
|
+
trail.unshift(parent);
|
|
382
|
+
current = parent;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
return trail;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
## Best Practices
|
|
391
|
+
|
|
392
|
+
1. **Use consistent naming**: Use kebab-case for placard names
|
|
393
|
+
2. **Provide helpful icons**: Visual indicators improve navigation UX
|
|
394
|
+
3. **Set meaningful order**: Lower numbers appear first in navigation
|
|
395
|
+
4. **Use groups wisely**: Group related pages for better organization
|
|
396
|
+
5. **Define search terms**: Help users discover features through search
|
|
397
|
+
6. **Leverage guards**: Use visibleOn to show/hide navigation based on permissions
|
|
398
|
+
7. **Explicit when needed**: Use explicit breadcrumbs for complex hierarchies
|
|
399
|
+
8. **Keep titles short**: Navigation labels should be concise
|
|
400
|
+
9. **Provide tooltips**: Add helpful context for ambiguous page names
|
|
401
|
+
10. **Use parent relationships**: Build hierarchical navigation automatically
|