@geoit/ui 0.0.5 → 0.0.7

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.
Files changed (53) hide show
  1. package/README.md +45 -4
  2. package/ai/AGENTS.md +122 -42
  3. package/ai/README.md +29 -29
  4. package/ai/catalog.json +328 -194
  5. package/ai/components/geo-chart.md +18 -6
  6. package/ai/components/geo-dashboard.md +17 -6
  7. package/ai/components/geo-empty-state.md +5 -5
  8. package/ai/components/geo-feedback-form.md +5 -5
  9. package/ai/components/geo-forgot-password.md +8 -5
  10. package/ai/components/geo-list-page.md +8 -5
  11. package/ai/components/geo-login.md +18 -6
  12. package/ai/components/geo-map-admin-filter.md +11 -5
  13. package/ai/components/geo-map-basemap-switcher.md +9 -5
  14. package/ai/components/geo-map-help.md +5 -5
  15. package/ai/components/geo-map-layer-card.md +5 -5
  16. package/ai/components/geo-map-layer-panel.md +5 -5
  17. package/ai/components/geo-map-layers-drawer.md +5 -5
  18. package/ai/components/geo-map-legend.md +6 -5
  19. package/ai/components/geo-map-locate.md +5 -5
  20. package/ai/components/geo-map-location-chip.md +5 -5
  21. package/ai/components/geo-map-measure.md +5 -5
  22. package/ai/components/geo-map-opacity.md +5 -5
  23. package/ai/components/geo-map-parcel-popup.md +10 -5
  24. package/ai/components/geo-map-search.md +11 -5
  25. package/ai/components/geo-map-shell.md +49 -6
  26. package/ai/components/geo-map-snapshot.md +5 -5
  27. package/ai/components/geo-map-swipe.md +5 -5
  28. package/ai/components/geo-map-toolbar.md +10 -5
  29. package/ai/components/geo-map-zoom.md +5 -5
  30. package/ai/components/geo-map.md +16 -9
  31. package/ai/components/geo-overlap-result.md +5 -5
  32. package/ai/components/geo-page-header.md +5 -5
  33. package/ai/components/geo-slider.md +1 -1
  34. package/ai/components/geo-stat-card.md +5 -5
  35. package/ai/components/geo-tree.md +2 -0
  36. package/ai/mockup.html +2 -2
  37. package/ai/recipes.md +86 -0
  38. package/esm2022/lib/figma/geo-chart/geo-chart.component.mjs +14 -3
  39. package/esm2022/lib/figma/geo-list-page/geo-list-page.component.mjs +3 -3
  40. package/esm2022/lib/figma/geo-map/chrome/geo-map-admin-filter/geo-map-admin-filter.component.mjs +5 -3
  41. package/esm2022/lib/figma/geo-map/chrome/geo-map-legend/geo-map-legend.component.mjs +5 -3
  42. package/esm2022/lib/figma/geo-map/chrome/geo-map-shell/geo-map-shell.component.mjs +22 -3
  43. package/esm2022/lib/figma/geo-map/geo-map.constants.mjs +13 -1
  44. package/esm2022/lib/figma/geo-tree/geo-tree.component.mjs +17 -3
  45. package/fesm2022/geoit-ui.mjs +72 -13
  46. package/fesm2022/geoit-ui.mjs.map +1 -1
  47. package/lib/figma/geo-chart/geo-chart.component.d.ts +9 -0
  48. package/lib/figma/geo-map/chrome/geo-map-admin-filter/geo-map-admin-filter.component.d.ts +3 -1
  49. package/lib/figma/geo-map/chrome/geo-map-legend/geo-map-legend.component.d.ts +3 -1
  50. package/lib/figma/geo-map/chrome/geo-map-shell/geo-map-shell.component.d.ts +19 -2
  51. package/lib/figma/geo-map/geo-map.constants.d.ts +6 -0
  52. package/lib/figma/geo-tree/geo-tree.component.d.ts +5 -1
  53. package/package.json +1 -1
@@ -5,7 +5,7 @@
5
5
  > Read this file before using the component. Use **only** the Inputs/Outputs listed here.
6
6
 
7
7
  ## Summary
8
- GeoMapOpacityComponent
8
+ Layer opacity slider bound to a map layer id.
9
9
 
10
10
  ## Import
11
11
 
@@ -23,13 +23,13 @@ imports: [GeoMapOpacityComponent]
23
23
  `geo-map-opacity`
24
24
 
25
25
  ## Category
26
- `other`
26
+ `map`
27
27
 
28
28
  ## When to use
29
-
29
+ Adjust overlay transparency in custom layer UI.
30
30
 
31
31
  ## Do not use when
32
-
32
+ Full layer list use geo-map-layer-panel / layers drawer.
33
33
 
34
34
 
35
35
  ## Binding
@@ -59,7 +59,7 @@ _None_
59
59
  ### Example
60
60
 
61
61
  ```html
62
- <geo-map-opacity></geo-map-opacity>
62
+ <geo-map-opacity [controller]="ctrl" layerId="demo-qhsdd-2020" [(opacity)]="opacity"></geo-map-opacity>
63
63
  ```
64
64
 
65
65
  ## Package path
@@ -5,7 +5,7 @@
5
5
  > Read this file before using the component. Use **only** the Inputs/Outputs listed here.
6
6
 
7
7
  ## Summary
8
- GeoMapParcelPopupComponent
8
+ Parcel detail popup (citizen / specialist audience).
9
9
 
10
10
  ## Import
11
11
 
@@ -23,13 +23,13 @@ imports: [GeoMapParcelPopupComponent]
23
23
  `geo-map-parcel-popup`
24
24
 
25
25
  ## Category
26
- `other`
26
+ `map`
27
27
 
28
28
  ## When to use
29
-
29
+ Show thửa detail after search or map click.
30
30
 
31
31
  ## Do not use when
32
-
32
+ Full detail page navigate to a route instead.
33
33
 
34
34
 
35
35
  ## Binding
@@ -63,7 +63,12 @@ Every supported Input (do not invent others):
63
63
  ### Example
64
64
 
65
65
  ```html
66
- <geo-map-parcel-popup></geo-map-parcel-popup>
66
+ <geo-map-parcel-popup
67
+ [(open)]="parcelOpen"
68
+ [parcel]="selected"
69
+ audience="citizen"
70
+ (exportClick)="exportPdf($event)"
71
+ ></geo-map-parcel-popup>
67
72
  ```
68
73
 
69
74
  ## Package path
@@ -5,7 +5,7 @@
5
5
  > Read this file before using the component. Use **only** the Inputs/Outputs listed here.
6
6
 
7
7
  ## Summary
8
- GeoMapSearchComponent
8
+ Map search panel (owner / certificate / parcel / address / coordinates).
9
9
 
10
10
  ## Import
11
11
 
@@ -23,13 +23,13 @@ imports: [GeoMapSearchComponent]
23
23
  `geo-map-search`
24
24
 
25
25
  ## Category
26
- `other`
26
+ `map`
27
27
 
28
28
  ## When to use
29
-
29
+ Tra cứu thửa on portal; prefer via geo-map-shell.
30
30
 
31
31
  ## Do not use when
32
-
32
+ Global app search unrelated to map.
33
33
 
34
34
 
35
35
  ## Binding
@@ -67,7 +67,13 @@ Every supported Input (do not invent others):
67
67
  ### Example
68
68
 
69
69
  ```html
70
- <geo-map-search></geo-map-search>
70
+ <geo-map-search
71
+ [(open)]="searchOpen"
72
+ mode="parcel"
73
+ [results]="results"
74
+ (search)="runSearch($event)"
75
+ (resultSelect)="onSelect($event)"
76
+ ></geo-map-search>
71
77
  ```
72
78
 
73
79
  ## Package path
@@ -5,7 +5,7 @@
5
5
  > Read this file before using the component. Use **only** the Inputs/Outputs listed here.
6
6
 
7
7
  ## Summary
8
- GeoMapShellComponent
8
+ Full map portal chrome: search, ĐVHC, layers, legend, measure, basemap, parcel popup.
9
9
 
10
10
  ## Import
11
11
 
@@ -23,14 +23,17 @@ imports: [GeoMapShellComponent]
23
23
  `geo-map-shell`
24
24
 
25
25
  ## Category
26
- `other`
26
+ `map`
27
27
 
28
28
  ## When to use
29
-
29
+ Public / specialist map portal pages (tra cứu quy hoạch). Prefer this over composing chrome by hand.
30
30
 
31
31
  ## Do not use when
32
-
32
+ Bare map embed without UI chrome use geo-map only.
33
33
 
34
+ ## How to use
35
+
36
+ Shell portal tra cứu: gắn height + layers API; tắt demoSearch trên production. Lắng nghe (search)/(resultSelect)/(parcelExport). Models [(searchOpen)], [(layersOpen)], … để điều khiển panel từ ngoài.
34
37
 
35
38
  ## Binding
36
39
 
@@ -53,7 +56,10 @@ Every supported Input (do not invent others):
53
56
  | `showNav` | `boolean` | `true` | — |
54
57
  | `includeDemoLayers` | `boolean` | `true` | — |
55
58
  | `adminNodes` | `GeoTreeNode[]` | `GEO_MAP_DEMO_ADMIN_NODES` | — |
59
+ | `adminSelectionMode` | `'single' \| 'multi'` | `'multi'` | `single` — chọn đúng 1 xã/phường (BR-06-03); `multi` — checkbox nhiều cấp (mặc định). |
56
60
  | `locationLabel` | `string` | `'Phường 1 — TP Đà Lạt, Lâm Đồng'` | — |
61
+ | `measureDisclaimer` | `string \| null` | `'Giá trị tham khảo trên bản đồ, không có giá trị pháp lý. Diện tích pháp lý của thửa đất lấy theo hồ sơ địa chính.'` | Ghi chú pháp lý hiển thị khi đang đo (BR-10-03). `null` ẩn ghi chú — mặc định giữ nguyên câu chữ đã dùng ở `qh-map-shell`. |
62
+ | `legendCatalogMissing` | `boolean` | `false` | True khi danh mục chú giải không tải được (`ERR_MAP_LEGEND_CATALOG_MISSING`). |
57
63
  | `parcelAudience` | `GeoMapParcelAudience` | `'citizen'` | — |
58
64
  | `provinceExtent` | `readonly [number, number, number, number]` | `GEO_MAP_DEFAULT_PROVINCE_EXTENT_4326` | — |
59
65
  | `demoSearch` | `boolean` | `true` | When true, shell seeds mock search results (Storybook / demos). |
@@ -80,23 +86,60 @@ Every supported Input (do not invent others):
80
86
  |--------|---------|-------------|
81
87
  | `mapReady` | `OutputEmitterRef<GeoMapController>` | — |
82
88
  | `mapClick` | `OutputEmitterRef<GeoMapClickEvent>` | — |
89
+ | `located` | `OutputEmitterRef<[number, number]>` | — |
83
90
  | `locateDenied` | `OutputEmitterRef<void>` | — |
91
+ | `locateError` | `OutputEmitterRef<{ reason: GeoMapLocateErrorReason; message?: string }>` | — |
84
92
  | `actionClick` | `OutputEmitterRef<GeoMapToolbarAction>` | — |
85
93
  | `search` | `OutputEmitterRef<GeoMapSearchQuery>` | — |
86
94
  | `searchReset` | `OutputEmitterRef<void>` | — |
87
95
  | `resultSelect` | `OutputEmitterRef<GeoMapSearchResultItem>` | — |
88
96
  | `parcelExport` | `OutputEmitterRef<GeoMapParcelDetail>` | — |
89
97
  | `adminApply` | `OutputEmitterRef<Array<string \| number>>` | — |
98
+ | `snapshotCaptured` | `OutputEmitterRef<void>` | — |
99
+ | `snapshotError` | `OutputEmitterRef<unknown>` | — |
90
100
 
91
101
 
92
102
  ## Examples
93
103
 
94
- ### Example
104
+ ### Basic portal
95
105
 
96
106
  ```html
97
- <geo-map-shell></geo-map-shell>
107
+ <geo-map-shell
108
+ height="640px"
109
+ [demoSearch]="false"
110
+ parcelAudience="citizen"
111
+ [layers]="layers"
112
+ (mapReady)="ctrl = $event"
113
+ (search)="onSearch($event)"
114
+ ></geo-map-shell>
98
115
  ```
99
116
 
117
+ ### Open search panel
118
+
119
+ ```html
120
+ <geo-map-shell
121
+ height="640px"
122
+ [demoSearch]="false"
123
+ [(searchOpen)]="searchOpen"
124
+ [(searchResults)]="results"
125
+ (search)="runQuery($event)"
126
+ (resultSelect)="onResult($event)"
127
+ ></geo-map-shell>
128
+ ```
129
+
130
+ ## Tips
131
+
132
+ - Ưu tiên geo-map-shell thay vì tự ghép chrome.
133
+ - Peers bắt buộc: ol, proj4.
134
+ - demoSearch=true chỉ cho Storybook/demo — production phải false + API thật.
135
+ - parcelAudience: citizen | specialist.
136
+ - Đọc geo-map.md cho layer types / projections.
137
+ ## Related components
138
+
139
+ - [`geo-map`](./geo-map.md)
140
+ - [`geo-map-search`](./geo-map-search.md)
141
+ - [`geo-map-toolbar`](./geo-map-toolbar.md)
142
+ - [`geo-map-layers-drawer`](./geo-map-layers-drawer.md)
100
143
  ## Package path
101
144
  `node_modules/@geoit/ui/ai/components/geo-map-shell.md`
102
145
 
@@ -5,7 +5,7 @@
5
5
  > Read this file before using the component. Use **only** the Inputs/Outputs listed here.
6
6
 
7
7
  ## Summary
8
- GeoMapSnapshotComponent
8
+ Capture current map canvas to image / download.
9
9
 
10
10
  ## Import
11
11
 
@@ -23,13 +23,13 @@ imports: [GeoMapSnapshotComponent]
23
23
  `geo-map-snapshot`
24
24
 
25
25
  ## Category
26
- `other`
26
+ `map`
27
27
 
28
28
  ## When to use
29
-
29
+ Export screenshot control on map chrome.
30
30
 
31
31
  ## Do not use when
32
-
32
+ Server-side tile export pipelines.
33
33
 
34
34
 
35
35
  ## Binding
@@ -59,7 +59,7 @@ Every supported Input (do not invent others):
59
59
  ### Example
60
60
 
61
61
  ```html
62
- <geo-map-snapshot></geo-map-snapshot>
62
+ <geo-map-snapshot [controller]="ctrl" (captured)="onShot($event)"></geo-map-snapshot>
63
63
  ```
64
64
 
65
65
  ## Package path
@@ -5,7 +5,7 @@
5
5
  > Read this file before using the component. Use **only** the Inputs/Outputs listed here.
6
6
 
7
7
  ## Summary
8
- GeoMapSwipeComponent
8
+ Swipe compare control between two map layers.
9
9
 
10
10
  ## Import
11
11
 
@@ -23,13 +23,13 @@ imports: [GeoMapSwipeComponent]
23
23
  `geo-map-swipe`
24
24
 
25
25
  ## Category
26
- `other`
26
+ `map`
27
27
 
28
28
  ## When to use
29
-
29
+ Before/after planning vs current-use comparison.
30
30
 
31
31
  ## Do not use when
32
-
32
+ Simple opacity blend use geo-map-opacity.
33
33
 
34
34
 
35
35
  ## Binding
@@ -57,7 +57,7 @@ _None_
57
57
  ### Example
58
58
 
59
59
  ```html
60
- <geo-map-swipe></geo-map-swipe>
60
+ <geo-map-swipe [controller]="ctrl" [(active)]="swipeOn" layerId="demo-qhsdd-2020"></geo-map-swipe>
61
61
  ```
62
62
 
63
63
  ## Package path
@@ -5,7 +5,7 @@
5
5
  > Read this file before using the component. Use **only** the Inputs/Outputs listed here.
6
6
 
7
7
  ## Summary
8
- GeoMapToolbarComponent
8
+ Vertical map tool strip (search, pan, measure, layers, …).
9
9
 
10
10
  ## Import
11
11
 
@@ -23,13 +23,13 @@ imports: [GeoMapToolbarComponent]
23
23
  `geo-map-toolbar`
24
24
 
25
25
  ## Category
26
- `other`
26
+ `map`
27
27
 
28
28
  ## When to use
29
-
29
+ Custom map layouts; usually included inside geo-map-shell.
30
30
 
31
31
  ## Do not use when
32
-
32
+ Full portal use geo-map-shell.
33
33
 
34
34
 
35
35
  ## Binding
@@ -60,7 +60,12 @@ Every supported Input (do not invent others):
60
60
  ### Example
61
61
 
62
62
  ```html
63
- <geo-map-toolbar></geo-map-toolbar>
63
+ <geo-map-toolbar
64
+ [controller]="ctrl"
65
+ [actions]="actions"
66
+ [(checkedMap)]="checked"
67
+ (actionClick)="onTool($event)"
68
+ ></geo-map-toolbar>
64
69
  ```
65
70
 
66
71
  ## Package path
@@ -5,7 +5,7 @@
5
5
  > Read this file before using the component. Use **only** the Inputs/Outputs listed here.
6
6
 
7
7
  ## Summary
8
- GeoMapZoomComponent
8
+ Zoom +/- and optional province / home navigation control.
9
9
 
10
10
  ## Import
11
11
 
@@ -23,13 +23,13 @@ imports: [GeoMapZoomComponent]
23
23
  `geo-map-zoom`
24
24
 
25
25
  ## Category
26
- `other`
26
+ `map`
27
27
 
28
28
  ## When to use
29
-
29
+ Custom map chrome; geo-map-shell embeds this.
30
30
 
31
31
  ## Do not use when
32
-
32
+ Relying on OpenLayers built-in zoom alone is fine for bare geo-map.
33
33
 
34
34
 
35
35
  ## Binding
@@ -58,7 +58,7 @@ _None_
58
58
  ### Example
59
59
 
60
60
  ```html
61
- <geo-map-zoom></geo-map-zoom>
61
+ <geo-map-zoom [controller]="ctrl" [showNav]="true"></geo-map-zoom>
62
62
  ```
63
63
 
64
64
  ## Package path
@@ -29,8 +29,11 @@ imports: [GeoMapComponent]
29
29
  Any map viewport (portal quy hoạch, tra cứu thửa). Peers: ol, proj4.
30
30
 
31
31
  ## Do not use when
32
- Non-map charting — use dashboard libs.
32
+ Full portal chrome — prefer geo-map-shell; non-map charts — use geo-chart.
33
33
 
34
+ ## How to use
35
+
36
+ Host OpenLayers thuần. (mapReady) nhận GeoMapController để zoom/fit/addLayer. Layers typed (osm/xyz/wms/wmts/geojson). Projections tùy chỉnh qua [projections] — không invent VN-2000.
34
37
 
35
38
  ## Binding
36
39
 
@@ -180,18 +183,22 @@ export interface GeoMapLayerVisibilityChange {
180
183
 
181
184
  ## Examples
182
185
 
183
- ### Example
186
+ ### Basic
184
187
 
185
188
  ```html
186
- <geo-map
187
- [center]="center"
188
- [zoom]="12"
189
- [layers]="layers"
190
- height="480px"
191
- (mapReady)="ctrl = $event"
192
- ></geo-map>
189
+ <geo-map height="480px" basemap="osm" [center]="[108.45, 11.94]" [zoom]="12" (mapReady)="ctrl = $event"></geo-map>
193
190
  ```
194
191
 
192
+ ## Tips
193
+
194
+ - Portal đầy đủ → geo-map-shell.
195
+ - showZoomControl=false khi dùng geo-map-zoom riêng.
196
+ - Peers: ol, proj4.
197
+ ## Related components
198
+
199
+ - [`geo-map-shell`](./geo-map-shell.md)
200
+ - [`geo-map-zoom`](./geo-map-zoom.md)
201
+ - [`geo-map-toolbar`](./geo-map-toolbar.md)
195
202
  ## Package path
196
203
  `node_modules/@geoit/ui/ai/components/geo-map.md`
197
204
 
@@ -5,7 +5,7 @@
5
5
  > Read this file before using the component. Use **only** the Inputs/Outputs listed here.
6
6
 
7
7
  ## Summary
8
- GeoOverlapResultComponent
8
+ Overlap analysis result list (planning type, area, percent).
9
9
 
10
10
  ## Import
11
11
 
@@ -23,13 +23,13 @@ imports: [GeoOverlapResultComponent]
23
23
  `geo-overlap-result`
24
24
 
25
25
  ## Category
26
- `other`
26
+ `data`
27
27
 
28
28
  ## When to use
29
-
29
+ Show giao cắt quy hoạch vs hiện trạng results.
30
30
 
31
31
  ## Do not use when
32
-
32
+ Generic tables use geo-table.
33
33
 
34
34
 
35
35
  ## Binding
@@ -72,7 +72,7 @@ export interface GeoOverlapResultRow {
72
72
  ### Example
73
73
 
74
74
  ```html
75
- <geo-overlap-result></geo-overlap-result>
75
+ <geo-overlap-result [rows]="rows" (rowClick)="focus($event)"></geo-overlap-result>
76
76
  ```
77
77
 
78
78
  ## Package path
@@ -5,7 +5,7 @@
5
5
  > Read this file before using the component. Use **only** the Inputs/Outputs listed here.
6
6
 
7
7
  ## Summary
8
- GeoPageHeaderComponent
8
+ Compact page header block (title + optional actions slot).
9
9
 
10
10
  ## Import
11
11
 
@@ -23,13 +23,13 @@ imports: [GeoPageHeaderComponent]
23
23
  `geo-page-header`
24
24
 
25
25
  ## Category
26
- `other`
26
+ `display`
27
27
 
28
28
  ## When to use
29
-
29
+ Section headers on dashboard / list pages.
30
30
 
31
31
  ## Do not use when
32
-
32
+ Full page title under breadcrumb prefer geo-page-title.
33
33
 
34
34
 
35
35
  ## Binding
@@ -56,7 +56,7 @@ _None_
56
56
  ### Example
57
57
 
58
58
  ```html
59
- <geo-page-header></geo-page-header>
59
+ <geo-page-header title="Thống kê nhanh"></geo-page-header>
60
60
  ```
61
61
 
62
62
  ## Package path
@@ -26,7 +26,7 @@ imports: [GeoSliderComponent]
26
26
  `forms`
27
27
 
28
28
  ## When to use
29
- Continuous numeric value in a range.
29
+ Continuous numeric value in a range (opacity, percent).
30
30
 
31
31
  ## Do not use when
32
32
  Discrete small sets — use select/radio.
@@ -5,7 +5,7 @@
5
5
  > Read this file before using the component. Use **only** the Inputs/Outputs listed here.
6
6
 
7
7
  ## Summary
8
- GeoStatCardComponent
8
+ KPI stat card (label, value, optional delta / icon).
9
9
 
10
10
  ## Import
11
11
 
@@ -23,13 +23,13 @@ imports: [GeoStatCardComponent]
23
23
  `geo-stat-card`
24
24
 
25
25
  ## Category
26
- `other`
26
+ `data`
27
27
 
28
28
  ## When to use
29
-
29
+ Dashboard summary tiles.
30
30
 
31
31
  ## Do not use when
32
-
32
+ Detailed tables use geo-table.
33
33
 
34
34
 
35
35
  ## Binding
@@ -82,7 +82,7 @@ export interface GeoStatCardItem {
82
82
  ### Example
83
83
 
84
84
  ```html
85
- <geo-stat-card></geo-stat-card>
85
+ <geo-stat-card label="Tổng thửa" [value]="12450" unit="thửa"></geo-stat-card>
86
86
  ```
87
87
 
88
88
  ## Package path
@@ -47,7 +47,9 @@ Every supported Input (do not invent others):
47
47
  |-------|------|---------|-------------|
48
48
  | `nodes` | `GeoTreeNode[]` | `[]` | — |
49
49
  | `checkable` | `boolean` | `false` | — |
50
+ | `selectionMode` | `'single' \| 'multi'` | `'multi'` | `single` — click chọn đúng 1 node (BR-06-03); `multi` — giữ hành vi checkbox hiện có. |
50
51
  | `checkedKeys` | `Array<string \| number>` | `[]` | Two-way `model()` (supports banana binding). |
52
+ | `selectedKeys` | `Array<string \| number>` | `[]` | Two-way `model()` (supports banana binding). |
51
53
  | `expandedKeys` | `Array<string \| number>` | `[]` | Two-way `model()` (supports banana binding). |
52
54
  | `showLine` | `boolean` | `false` | — |
53
55
  | `blockNode` | `boolean` | `false` | — |
package/ai/mockup.html CHANGED
@@ -5,7 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1" />
6
6
  <title>@geoit/ui — Component mockup (design tokens)</title>
7
7
  <!-- Generated by tools/generate-mockup.js — do not edit ai/mockup.html by hand -->
8
- <!-- 2026-08-24T03:07:52.146Z -->
8
+ <!-- 2026-09-04T07:20:22.216Z -->
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com" />
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
11
11
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" />
@@ -685,7 +685,7 @@
685
685
  HTML tĩnh mô phỏng visual của các <code>geo-*</code> trong <code>ai/components</code>,
686
686
  dùng đúng CSS variables từ <code>design-tokens.scss</code>.
687
687
  Tokens được inject tự động khi <code>npm run ai:docs</code> / <code>npm run build</code>.
688
- <br /><span class="typo-caption typo-secondary">Generated 2026-08-24T03:07:52.146Z · source: projects/geo-ui/src/lib/styles/design-tokens.scss · 66 component docs in ai/components</span>
688
+ <br /><span class="typo-caption typo-secondary">Generated 2026-09-04T07:20:22.216Z · source: projects/geo-ui/src/lib/styles/design-tokens.scss · 66 component docs in ai/components</span>
689
689
  </p>
690
690
  </header>
691
691
 
package/ai/recipes.md CHANGED
@@ -194,3 +194,89 @@ Primitives: `geo-stat-card`, `geo-chart` (bar/donut), `geo-page-header`, `geo-em
194
194
  List pages (thống kê tờ/bản đồ, QL người dùng, đồng bộ iLIS, QL bản đồ): `geo-list-page` + `geo-table-toolbar` + `geo-table` + `geo-form-modal`.
195
195
 
196
196
  Storybook: `GEO/Pages/Admin CRUD` (STT 28, TCQH.24, STT 31).
197
+
198
+ ## 13. Map portal (`geo-map-shell`) — recommended
199
+
200
+ Peers: `ol`, `proj4`. Prefer shell over hand-wiring chrome.
201
+
202
+ ```ts
203
+ import {
204
+ GeoMapShellComponent,
205
+ type GeoMapController,
206
+ type GeoMapSearchQuery,
207
+ type GeoMapSearchResultItem,
208
+ } from "@geoit/ui";
209
+ ```
210
+
211
+ ```html
212
+ <geo-map-shell
213
+ height="calc(100vh - 64px)"
214
+ [demoSearch]="false"
215
+ parcelAudience="citizen"
216
+ [includeDemoLayers]="false"
217
+ [layers]="layers"
218
+ [(searchOpen)]="searchOpen"
219
+ (mapReady)="onMapReady($event)"
220
+ (search)="onSearch($event)"
221
+ (resultSelect)="onResult($event)"
222
+ (parcelExport)="onExport($event)"
223
+ ></geo-map-shell>
224
+ ```
225
+
226
+ ```ts
227
+ ctrl: GeoMapController | null = null;
228
+ searchOpen = false;
229
+ layers = []; // GeoMapLayerConfig[] from API
230
+
231
+ onMapReady(c: GeoMapController): void {
232
+ this.ctrl = c;
233
+ }
234
+
235
+ onSearch(q: GeoMapSearchQuery): void {
236
+ // call API → patch shell [(searchResults)] / selectedParcel
237
+ }
238
+
239
+ onResult(item: GeoMapSearchResultItem): void {
240
+ // optional: flyTo via this.ctrl
241
+ }
242
+ ```
243
+
244
+ ### Bare map (no chrome)
245
+
246
+ ```html
247
+ <geo-map
248
+ height="480px"
249
+ [center]="[108.45, 11.94]"
250
+ [zoom]="12"
251
+ basemap="osm"
252
+ [layers]="layers"
253
+ [showZoomControl]="false"
254
+ (mapReady)="ctrl = $event"
255
+ ></geo-map>
256
+ ```
257
+
258
+ ### Map chrome pieces (custom shells only)
259
+
260
+ Use when **not** using `geo-map-shell`: `geo-map-toolbar`, `geo-map-search`, `geo-map-admin-filter`, `geo-map-layers-drawer`, `geo-map-legend`, `geo-map-help`, `geo-map-basemap-switcher`, `geo-map-zoom`, `geo-map-measure`, `geo-map-swipe`, `geo-map-parcel-popup`, `geo-map-location-chip`.
261
+
262
+ Read `ai/components/geo-map-shell.md` and `ai/components/geo-map.md` before composing.
263
+
264
+ ## 14. Date / date range in forms
265
+
266
+ ```html
267
+ <geo-date-picker
268
+ label="Ngày hiệu lực"
269
+ format="dd/MM/yyyy"
270
+ [required]="true"
271
+ [block]="true"
272
+ [(ngModel)]="effectiveDate"
273
+ ></geo-date-picker>
274
+
275
+ <geo-date-range-picker
276
+ label="Khoảng thời gian"
277
+ [block]="true"
278
+ [(ngModel)]="range"
279
+ ></geo-date-range-picker>
280
+ ```
281
+
282
+ App must provide `provideAnimations()` + `provideNzI18n(vi_VN)` for the picker overlay.