@dereekb/dbx-components-mcp 14.9.0 → 14.11.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.
@@ -10,7 +10,7 @@ var __export = (target, all) => {
10
10
  // packages/dbx-components-mcp/package.json
11
11
  var package_default = {
12
12
  name: "@dereekb/dbx-components-mcp",
13
- version: "14.9.0",
13
+ version: "14.11.0",
14
14
  sideEffects: false,
15
15
  type: "module",
16
16
  bin: {
@@ -22,8 +22,8 @@ var package_default = {
22
22
  "ts-morph": "^21.0.0"
23
23
  },
24
24
  peerDependencies: {
25
- "@dereekb/dbx-cli": "14.9.0",
26
- "@dereekb/util": "14.9.0"
25
+ "@dereekb/dbx-cli": "14.11.0",
26
+ "@dereekb/util": "14.11.0"
27
27
  }
28
28
  };
29
29
 
@@ -83,6 +83,31 @@
83
83
  "dbx__ref__dbx-component-patterns"
84
84
  ]
85
85
  },
86
+ {
87
+ "kind": "directive",
88
+ "slug": "map-merge-source",
89
+ "selector": "[dbxFilterMapMergeSource]",
90
+ "className": "DbxFilterMapMergeSourceDirective",
91
+ "module": "@dereekb/dbx-core",
92
+ "description": "Provides a read-only {@link FilterSource} that merges the filters of several keys in an ancestor {@link FilterMap} into one filter. Lets separate filter controls (e.g. a date popover and an attributes popover) each own a key while children consume a single combined filter.\n\nKeys later in the array win when two keys set the same field, and the merged filter has no `preset`. Every key needs a value (e.g. a default filter) before the merged filter emits.",
93
+ "inputs": [
94
+ {
95
+ "name": "dbxFilterMapMergeSource",
96
+ "type": "Maybe<FilterMapKey[]>",
97
+ "description": "The map keys to merge, in priority order."
98
+ }
99
+ ],
100
+ "outputs": [],
101
+ "example": "<div dbxFilterMap>\n <my-date-filter-button [dbxFilterMapSourceConnector]=\"'date'\"></my-date-filter-button>\n <my-attributes-filter-button [dbxFilterMapSourceConnector]=\"'attributes'\"></my-attributes-filter-button>\n <div [dbxFilterMapMergeSource]=\"['date', 'attributes']\">\n <my-filtered-list></my-filtered-list>\n </div>\n</div>",
102
+ "relatedSlugs": [
103
+ "map",
104
+ "map-source",
105
+ "map-source-connector"
106
+ ],
107
+ "skillRefs": [
108
+ "dbx__ref__dbx-component-patterns"
109
+ ]
110
+ },
86
111
  {
87
112
  "kind": "directive",
88
113
  "slug": "map-source",
@@ -107,6 +132,31 @@
107
132
  "dbx__ref__dbx-component-patterns"
108
133
  ]
109
134
  },
135
+ {
136
+ "kind": "directive",
137
+ "slug": "map-storage",
138
+ "selector": "[dbxFilterMapStorage]",
139
+ "className": "DbxFilterMapStorageDirective",
140
+ "module": "@dereekb/dbx-core",
141
+ "description": "Saves the filter of a keyed entry in an ancestor {@link FilterMap} to storage (localStorage by default), and loads it again when the page loads. The saved filter becomes the key's default filter, and every later change to the key is saved.\n\nUse {@link reset} to set the key back to its default filter and remove the saved filter.\n\nRequires {@link provideDbxFilterStorage}.",
142
+ "inputs": [
143
+ {
144
+ "name": "dbxFilterMapStorage",
145
+ "type": "Maybe<DbxFilterMapStorageConfig<F, J>>",
146
+ "description": "The key to save and how to save it."
147
+ }
148
+ ],
149
+ "outputs": [],
150
+ "example": "<div dbxFilterMap>\n <my-filter-button [dbxFilterMapSourceConnector]=\"'list'\" [dbxFilterMapStorage]=\"{ key: 'list', storageKey: 'my.list.filter', defaultFilter: {} }\"></my-filter-button>\n</div>",
151
+ "relatedSlugs": [
152
+ "map",
153
+ "map-source-connector",
154
+ "map-merge-source"
155
+ ],
156
+ "skillRefs": [
157
+ "dbx__ref__dbx-component-patterns"
158
+ ]
159
+ },
110
160
  {
111
161
  "kind": "pattern",
112
162
  "slug": "clickable-preset",
@@ -176,6 +176,27 @@
176
176
  "generic": "<T = unknown>",
177
177
  "configInterface": "DbxForgeComponentFieldConfig<T>"
178
178
  },
179
+ {
180
+ "slug": "radio",
181
+ "factoryName": "dbxForgeRadioField",
182
+ "tier": "field-factory",
183
+ "produces": "T",
184
+ "arrayOutput": "no",
185
+ "description": "Radio button group for picking exactly one value, wrapped in a form-field container. Use for small static option sets where every option should be visible at once.\n\nThe wrapper provides the Material outlined form-field appearance (notched outline with floating label, hint/error subscript), matching the checkbox, toggle, and slider fields.\n\nOptions are passed at the top level of the config, not inside `props`. A `null` option value can represent an \"any\"/\"none\" choice; the form omits the key from its output when that option is selected.\nSet `nullable: true` alongside a `null` option, otherwise a `null` value (including `value: null` as the default) resolves to no selection instead of checking that option.",
186
+ "example": "dbxForgeRadioField<number>({\n key: 'minPay',\n label: 'Minimum Pay Rate',\n layout: 'vertical',\n options: [\n { label: '$120+', value: 120 },\n { label: '$150+', value: 150 }\n ]\n})",
187
+ "properties": [
188
+ {
189
+ "name": "layout",
190
+ "type": "Maybe<DbxForgeRadioFieldLayout>",
191
+ "description": "How the radio buttons are laid out. Defaults to `'horizontal'`.",
192
+ "required": false
193
+ }
194
+ ],
195
+ "wrapperPattern": "material-form-field-wrapped",
196
+ "ngFormType": "radio",
197
+ "generic": "<T = unknown>",
198
+ "configInterface": "DbxForgeRadioFieldConfig<T>"
199
+ },
179
200
  {
180
201
  "slug": "value-selection",
181
202
  "factoryName": "dbxForgeValueSelectionField",
@@ -1066,6 +1066,93 @@
1066
1066
  "--dbx-padding-3"
1067
1067
  ]
1068
1068
  },
1069
+ {
1070
+ "slug": "card-image-caption",
1071
+ "selector": ".dbx-card-image-captioned",
1072
+ "source": "@dereekb/dbx-web",
1073
+ "module": "@dereekb/dbx-web",
1074
+ "file": "src/lib/layout/card/_card.scss",
1075
+ "line": 301,
1076
+ "declarations": [
1077
+ {
1078
+ "property": "position",
1079
+ "value": "absolute"
1080
+ },
1081
+ {
1082
+ "property": "left",
1083
+ "value": "0"
1084
+ },
1085
+ {
1086
+ "property": "right",
1087
+ "value": "0"
1088
+ },
1089
+ {
1090
+ "property": "bottom",
1091
+ "value": "0"
1092
+ },
1093
+ {
1094
+ "property": "padding",
1095
+ "value": "var(--dbx-padding-2) var(--dbx-padding-4)"
1096
+ },
1097
+ {
1098
+ "property": "color",
1099
+ "value": "white"
1100
+ },
1101
+ {
1102
+ "property": "background",
1103
+ "value": "color-mix(in srgb, var(--mat-sys-scrim, black) 55%, transparent)"
1104
+ },
1105
+ {
1106
+ "property": "white-space",
1107
+ "value": "nowrap"
1108
+ },
1109
+ {
1110
+ "property": "overflow",
1111
+ "value": "hidden"
1112
+ },
1113
+ {
1114
+ "property": "text-overflow",
1115
+ "value": "ellipsis"
1116
+ }
1117
+ ],
1118
+ "role": "layout",
1119
+ "intent": "single-line caption strip across the bottom of a `.dbx-card-image-captioned` image — light text on a translucent `--mat-sys-scrim` wash that stays readable over any picture in light and dark themes; long text ellipsizes. Pair with a type role utility such as `.dbx-text-title-small`.",
1120
+ "seeAlso": [
1121
+ "card-image-captioned",
1122
+ "text-title-small"
1123
+ ],
1124
+ "parent": "card-image-captioned",
1125
+ "selectorContext": ".dbx-card-image-captioned > .dbx-card-image-caption",
1126
+ "tokensRead": [
1127
+ "--dbx-padding-2",
1128
+ "--dbx-padding-4",
1129
+ "--mat-sys-scrim"
1130
+ ]
1131
+ },
1132
+ {
1133
+ "slug": "card-image-captioned",
1134
+ "selector": ".dbx-card-image-captioned",
1135
+ "source": "@dereekb/dbx-web",
1136
+ "module": "@dereekb/dbx-web",
1137
+ "file": "src/lib/layout/card/_card.scss",
1138
+ "line": 285,
1139
+ "declarations": [
1140
+ {
1141
+ "property": "position",
1142
+ "value": "relative"
1143
+ },
1144
+ {
1145
+ "property": "overflow",
1146
+ "value": "hidden"
1147
+ }
1148
+ ],
1149
+ "role": "layout",
1150
+ "intent": "`mat-card-image` wrapper that overlays a `.dbx-card-image-caption` strip on the bottom of its `<img>` (e.g. a place name over a map popup hero) — put `mat-card-image` on this wrapper `<div>` instead of the `<img>`, so the wrapper keeps mat-card's rounded top corners and clips the image to them.",
1151
+ "seeAlso": [
1152
+ "card-image-caption",
1153
+ "text-title-small"
1154
+ ]
1155
+ },
1069
1156
  {
1070
1157
  "slug": "card-select",
1071
1158
  "selector": ".dbx-card-select",
@@ -2607,7 +2694,7 @@
2607
2694
  "source": "@dereekb/dbx-web",
2608
2695
  "module": "@dereekb/dbx-web",
2609
2696
  "file": "src/lib/layout/list/_list.scss",
2610
- "line": 467,
2697
+ "line": 632,
2611
2698
  "declarations": [
2612
2699
  {
2613
2700
  "property": "height",
@@ -2628,7 +2715,7 @@
2628
2715
  "source": "@dereekb/dbx-web",
2629
2716
  "module": "@dereekb/dbx-web",
2630
2717
  "file": "src/lib/layout/list/_list.scss",
2631
- "line": 335,
2718
+ "line": 338,
2632
2719
  "declarations": [
2633
2720
  {
2634
2721
  "property": "--dbx-list-card-items-list-gap",
@@ -2651,13 +2738,259 @@
2651
2738
  "--dbx-list-card-items-list-gap"
2652
2739
  ]
2653
2740
  },
2741
+ {
2742
+ "slug": "list-detail-item",
2743
+ "selector": ".dbx-list-detail-item",
2744
+ "source": "@dereekb/dbx-web",
2745
+ "module": "@dereekb/dbx-web",
2746
+ "file": "src/lib/layout/list/_list.scss",
2747
+ "line": 467,
2748
+ "declarations": [
2749
+ {
2750
+ "property": "--dbx-list-detail-item-padding-resolved",
2751
+ "value": "var(--dbx-list-detail-item-padding, var(--dbx-padding-3))"
2752
+ },
2753
+ {
2754
+ "property": "display",
2755
+ "value": "flex"
2756
+ },
2757
+ {
2758
+ "property": "flex-direction",
2759
+ "value": "row"
2760
+ },
2761
+ {
2762
+ "property": "align-items",
2763
+ "value": "stretch"
2764
+ },
2765
+ {
2766
+ "property": "gap",
2767
+ "value": "var(--dbx-list-detail-item-gap, var(--dbx-padding-3))"
2768
+ },
2769
+ {
2770
+ "property": "min-width",
2771
+ "value": "0"
2772
+ },
2773
+ {
2774
+ "property": "padding",
2775
+ "value": "var(--dbx-list-detail-item-padding-resolved)"
2776
+ },
2777
+ {
2778
+ "property": "box-sizing",
2779
+ "value": "border-box"
2780
+ }
2781
+ ],
2782
+ "role": "layout",
2783
+ "intent": "detail list-row layout — flex row of a leading slot, a content column (bold `.item-title` + `.item-line` rows with optional leading icons) and a trailing slot, paired with nested `.item-leading` / `.item-leading-block` / `.item-content` / `.item-title` / `.item-line` / `.item-trailing` / `.item-trailing-divided` helpers; the row pads itself, so pair with `dbx-list-item-p0` on the view",
2784
+ "seeAlso": [
2785
+ "dbx-list-two-line-item",
2786
+ "dbx-list-item-p0",
2787
+ "dbx-list-detail-item-highlight"
2788
+ ],
2789
+ "tokensRead": [
2790
+ "--dbx-list-detail-item-gap",
2791
+ "--dbx-list-detail-item-line-gap",
2792
+ "--dbx-list-detail-item-line-icon-size",
2793
+ "--dbx-list-detail-item-padding",
2794
+ "--dbx-list-detail-item-padding-resolved",
2795
+ "--dbx-padding-1",
2796
+ "--dbx-padding-3",
2797
+ "--mat-sys-body-medium",
2798
+ "--mat-sys-on-surface",
2799
+ "--mat-sys-on-surface-variant",
2800
+ "--mat-sys-title-medium"
2801
+ ],
2802
+ "tokensSet": [
2803
+ "--dbx-list-detail-item-padding-resolved"
2804
+ ]
2805
+ },
2806
+ {
2807
+ "slug": "list-detail-item-gap",
2808
+ "selector": ".dbx-list-detail-item-gap",
2809
+ "source": "@dereekb/dbx-web",
2810
+ "module": "@dereekb/dbx-web",
2811
+ "file": "src/lib/layout/list/_list.scss",
2812
+ "line": 564,
2813
+ "declarations": [
2814
+ {
2815
+ "property": "display",
2816
+ "value": "flex"
2817
+ },
2818
+ {
2819
+ "property": "align-items",
2820
+ "value": "center"
2821
+ },
2822
+ {
2823
+ "property": "gap",
2824
+ "value": "var(--dbx-list-detail-item-gap, var(--dbx-padding-3))"
2825
+ },
2826
+ {
2827
+ "property": "padding",
2828
+ "value": "var(--dbx-list-detail-item-gap-marker-padding, var(--dbx-padding-3)) 0"
2829
+ },
2830
+ {
2831
+ "property": "font",
2832
+ "value": "var(--mat-sys-label-medium)"
2833
+ },
2834
+ {
2835
+ "property": "color",
2836
+ "value": "var(--mat-sys-on-surface-variant)"
2837
+ }
2838
+ ],
2839
+ "role": "layout",
2840
+ "intent": "non-interactive \"…\" gap marker between runs of `.dbx-list-detail-item` rows (e.g. non-consecutive dates) — a compact muted row whose `.item-leading` column lines up with `.item-leading-block`; render it as the separator component of a list view's `separatorConfig` so it sits between rows without row styling",
2841
+ "seeAlso": [
2842
+ "dbx-list-detail-item",
2843
+ "dbx-list-detail-item-leading-block"
2844
+ ],
2845
+ "parent": "list-detail-item",
2846
+ "tokensRead": [
2847
+ "--dbx-list-detail-item-gap",
2848
+ "--dbx-list-detail-item-gap-marker-padding",
2849
+ "--dbx-list-detail-item-leading-block-width",
2850
+ "--dbx-padding-3",
2851
+ "--mat-sys-label-medium",
2852
+ "--mat-sys-on-surface-variant"
2853
+ ]
2854
+ },
2855
+ {
2856
+ "slug": "list-detail-item-highlight",
2857
+ "selector": ".dbx-list-detail-item-highlight",
2858
+ "source": "@dereekb/dbx-web",
2859
+ "module": "@dereekb/dbx-web",
2860
+ "file": "src/lib/layout/list/_list.scss",
2861
+ "line": 586,
2862
+ "declarations": [
2863
+ {
2864
+ "property": "background",
2865
+ "value": "color-mix(in srgb, var(--dbx-list-detail-item-highlight-color, var(--dbx-notice-color)) var(--dbx-list-detail-item-highlight-tone, 14%), transparent)"
2866
+ },
2867
+ {
2868
+ "property": "border-radius",
2869
+ "value": "var(--mat-sys-corner-medium, 12px)"
2870
+ }
2871
+ ],
2872
+ "role": "state",
2873
+ "intent": "flag a `.dbx-list-detail-item` row as urgent — a rounded tonal wash of `--dbx-list-detail-item-highlight-color` (default `--dbx-notice-color`) at `--dbx-list-detail-item-highlight-tone` (default 14%); inside a `.dbx-list` the hosting list row paints the wash instead, so it also spans the view's built-in meta slot (e.g. the chevron)",
2874
+ "seeAlso": [
2875
+ "dbx-list-detail-item"
2876
+ ],
2877
+ "parent": "list-detail-item",
2878
+ "tokensRead": [
2879
+ "--dbx-list-detail-item-highlight-color",
2880
+ "--dbx-list-detail-item-highlight-tone",
2881
+ "--dbx-notice-color",
2882
+ "--mat-sys-corner-medium"
2883
+ ]
2884
+ },
2885
+ {
2886
+ "slug": "list-detail-item-leading-block",
2887
+ "selector": ".dbx-list-detail-item",
2888
+ "source": "@dereekb/dbx-web",
2889
+ "module": "@dereekb/dbx-web",
2890
+ "file": "src/lib/layout/list/_list.scss",
2891
+ "line": 525,
2892
+ "declarations": [
2893
+ {
2894
+ "property": "display",
2895
+ "value": "flex"
2896
+ },
2897
+ {
2898
+ "property": "flex-direction",
2899
+ "value": "column"
2900
+ },
2901
+ {
2902
+ "property": "justify-content",
2903
+ "value": "center"
2904
+ },
2905
+ {
2906
+ "property": "align-items",
2907
+ "value": "flex-start"
2908
+ },
2909
+ {
2910
+ "property": "align-self",
2911
+ "value": "stretch"
2912
+ },
2913
+ {
2914
+ "property": "gap",
2915
+ "value": "var(--dbx-padding-1)"
2916
+ },
2917
+ {
2918
+ "property": "flex",
2919
+ "value": "none"
2920
+ },
2921
+ {
2922
+ "property": "min-width",
2923
+ "value": "var(--dbx-list-detail-item-leading-block-width, 112px)"
2924
+ },
2925
+ {
2926
+ "property": "margin",
2927
+ "value": "calc(-1 * var(--dbx-list-detail-item-padding-resolved)) 0 calc(-1 * var(--dbx-list-detail-item-padding-resolved)) calc(-1 * var(--dbx-list-detail-item-padding-resolved))"
2928
+ },
2929
+ {
2930
+ "property": "padding",
2931
+ "value": "var(--dbx-list-detail-item-padding-resolved)"
2932
+ },
2933
+ {
2934
+ "property": "box-sizing",
2935
+ "value": "border-box"
2936
+ }
2937
+ ],
2938
+ "role": "layout",
2939
+ "intent": "full-height leading column for a `.dbx-list-detail-item` (e.g. a weekday / date / status block) — bleeds out to the row's top, bottom and start edges so a `[dbxColor]` + `.dbx-color-bg` wash fills the row edge; never shrinks below `--dbx-list-detail-item-leading-block-width` (112px), so every row's block stays the same width and only grows when its own content is wider",
2940
+ "seeAlso": [
2941
+ "dbx-list-detail-item",
2942
+ "dbx-color-bg"
2943
+ ],
2944
+ "parent": "list-detail-item",
2945
+ "selectorContext": ".dbx-list-detail-item .item-leading-block",
2946
+ "tokensRead": [
2947
+ "--dbx-list-detail-item-leading-block-width",
2948
+ "--dbx-list-detail-item-padding-resolved",
2949
+ "--dbx-padding-1"
2950
+ ]
2951
+ },
2952
+ {
2953
+ "slug": "list-detail-item-trailing-divided",
2954
+ "selector": ".dbx-list-detail-item",
2955
+ "source": "@dereekb/dbx-web",
2956
+ "module": "@dereekb/dbx-web",
2957
+ "file": "src/lib/layout/list/_list.scss",
2958
+ "line": 546,
2959
+ "declarations": [
2960
+ {
2961
+ "property": "align-self",
2962
+ "value": "stretch"
2963
+ },
2964
+ {
2965
+ "property": "padding-left",
2966
+ "value": "var(--dbx-list-detail-item-gap, var(--dbx-padding-3))"
2967
+ },
2968
+ {
2969
+ "property": "border-left",
2970
+ "value": "1px solid var(--dbx-list-detail-item-divider-color, var(--mat-sys-outline-variant))"
2971
+ }
2972
+ ],
2973
+ "role": "layout",
2974
+ "intent": "trailing slot of a `.dbx-list-detail-item` set off from the content by a hairline start border — for a trailing button column; recolor via `--dbx-list-detail-item-divider-color`",
2975
+ "seeAlso": [
2976
+ "dbx-list-detail-item"
2977
+ ],
2978
+ "parent": "list-detail-item",
2979
+ "selectorContext": ".dbx-list-detail-item .item-trailing-divided",
2980
+ "tokensRead": [
2981
+ "--dbx-list-detail-item-divider-color",
2982
+ "--dbx-list-detail-item-gap",
2983
+ "--dbx-padding-3",
2984
+ "--mat-sys-outline-variant"
2985
+ ]
2986
+ },
2654
2987
  {
2655
2988
  "slug": "list-item-p0",
2656
2989
  "selector": ".dbx-list-item-p0",
2657
2990
  "source": "@dereekb/dbx-web",
2658
2991
  "module": "@dereekb/dbx-web",
2659
2992
  "file": "src/lib/layout/list/_list.scss",
2660
- "line": 482,
2993
+ "line": 647,
2661
2994
  "declarations": [
2662
2995
  {
2663
2996
  "property": "padding",
@@ -2677,7 +3010,7 @@
2677
3010
  "source": "@dereekb/dbx-web",
2678
3011
  "module": "@dereekb/dbx-web",
2679
3012
  "file": "src/lib/layout/list/_list.scss",
2680
- "line": 297,
3013
+ "line": 300,
2681
3014
  "declarations": [
2682
3015
  {
2683
3016
  "property": "min-height",
@@ -2706,7 +3039,7 @@
2706
3039
  "source": "@dereekb/dbx-web",
2707
3040
  "module": "@dereekb/dbx-web",
2708
3041
  "file": "src/lib/layout/list/_list.scss",
2709
- "line": 306,
3042
+ "line": 309,
2710
3043
  "declarations": [
2711
3044
  {
2712
3045
  "property": "min-height",
@@ -2732,7 +3065,7 @@
2732
3065
  "source": "@dereekb/dbx-web",
2733
3066
  "module": "@dereekb/dbx-web",
2734
3067
  "file": "src/lib/layout/list/_list.scss",
2735
- "line": 442,
3068
+ "line": 607,
2736
3069
  "declarations": [
2737
3070
  {
2738
3071
  "property": "cursor",
@@ -2749,7 +3082,7 @@
2749
3082
  "source": "@dereekb/dbx-web",
2750
3083
  "module": "@dereekb/dbx-web",
2751
3084
  "file": "src/lib/layout/list/_list.scss",
2752
- "line": 454,
3085
+ "line": 619,
2753
3086
  "declarations": [
2754
3087
  {
2755
3088
  "property": "padding",
@@ -2769,7 +3102,7 @@
2769
3102
  "source": "@dereekb/dbx-web",
2770
3103
  "module": "@dereekb/dbx-web",
2771
3104
  "file": "src/lib/layout/list/_list.scss",
2772
- "line": 381,
3105
+ "line": 392,
2773
3106
  "declarations": [
2774
3107
  {
2775
3108
  "property": "--dbx-list-item-border-radius",
@@ -2796,7 +3129,7 @@
2796
3129
  "source": "@dereekb/dbx-web",
2797
3130
  "module": "@dereekb/dbx-web",
2798
3131
  "file": "src/lib/layout/list/_list.scss",
2799
- "line": 278,
3132
+ "line": 281,
2800
3133
  "declarations": [],
2801
3134
  "role": "state",
2802
3135
  "intent": "pin `.dbx-list-view-group-header` rows to the top of the list while scrolling"
@@ -2807,7 +3140,7 @@
2807
3140
  "source": "@dereekb/dbx-web",
2808
3141
  "module": "@dereekb/dbx-web",
2809
3142
  "file": "src/lib/layout/list/_list.scss",
2810
- "line": 398,
3143
+ "line": 409,
2811
3144
  "declarations": [
2812
3145
  {
2813
3146
  "property": "display",
@@ -2834,7 +3167,7 @@
2834
3167
  "source": "@dereekb/dbx-web",
2835
3168
  "module": "@dereekb/dbx-web",
2836
3169
  "file": "src/lib/layout/list/_list.scss",
2837
- "line": 255,
3170
+ "line": 258,
2838
3171
  "declarations": [],
2839
3172
  "role": "spacing",
2840
3173
  "intent": "strip the leading + trailing padding around `mdc-list-item--with-trailing-meta` rows so meta-only items hug their container"
@@ -1453,6 +1453,154 @@
1453
1453
  },
1454
1454
  "componentScope": "list"
1455
1455
  },
1456
+ {
1457
+ "cssVariable": "--dbx-list-content-max-height",
1458
+ "source": "dbx-web",
1459
+ "role": "size",
1460
+ "intents": [
1461
+ "list content max height"
1462
+ ],
1463
+ "description": "Component-scoped override point (`list`) read in `packages/dbx-web/src/lib/layout/list/_list.scss` — set it (from an app, or via the owning dbx directive where one exists) to override; unset, it falls back to `100%`.",
1464
+ "defaults": {
1465
+ "light": "100%"
1466
+ },
1467
+ "componentScope": "list"
1468
+ },
1469
+ {
1470
+ "cssVariable": "--dbx-list-detail-item-divider-color",
1471
+ "source": "dbx-web",
1472
+ "role": "color",
1473
+ "intents": [
1474
+ "list detail item divider color"
1475
+ ],
1476
+ "description": "Component-scoped override point (`list`) read in `packages/dbx-web/src/lib/layout/list/_list.scss` — set it (from an app, or via the owning dbx directive where one exists) to override; unset, it falls back to `var(--mat-sys-outline-variant)`.",
1477
+ "defaults": {
1478
+ "light": "var(--mat-sys-outline-variant)"
1479
+ },
1480
+ "componentScope": "list"
1481
+ },
1482
+ {
1483
+ "cssVariable": "--dbx-list-detail-item-gap",
1484
+ "source": "dbx-web",
1485
+ "role": "spacing",
1486
+ "intents": [
1487
+ "list detail item gap",
1488
+ "list detail item gap spacing"
1489
+ ],
1490
+ "description": "Component-scoped override point (`list`) read in `packages/dbx-web/src/lib/layout/list/_list.scss` — set it (from an app, or via the owning dbx directive where one exists) to override; unset, it falls back to `var(--dbx-padding-3)`.",
1491
+ "defaults": {
1492
+ "light": "var(--dbx-padding-3)"
1493
+ },
1494
+ "componentScope": "list"
1495
+ },
1496
+ {
1497
+ "cssVariable": "--dbx-list-detail-item-gap-marker-padding",
1498
+ "source": "dbx-web",
1499
+ "role": "spacing",
1500
+ "intents": [
1501
+ "list detail item gap marker padding",
1502
+ "list detail item gap marker padding spacing"
1503
+ ],
1504
+ "description": "Component-scoped override point (`list`) read in `packages/dbx-web/src/lib/layout/list/_list.scss` — set it (from an app, or via the owning dbx directive where one exists) to override; unset, it falls back to `var(--dbx-padding-3)`.",
1505
+ "defaults": {
1506
+ "light": "var(--dbx-padding-3)"
1507
+ },
1508
+ "componentScope": "list"
1509
+ },
1510
+ {
1511
+ "cssVariable": "--dbx-list-detail-item-highlight-color",
1512
+ "source": "dbx-web",
1513
+ "role": "color",
1514
+ "intents": [
1515
+ "list detail item highlight color"
1516
+ ],
1517
+ "description": "Component-scoped override point (`list`) read in `packages/dbx-web/src/lib/layout/list/_list.scss` — set it (from an app, or via the owning dbx directive where one exists) to override; unset, it falls back to `var(--dbx-notice-color)`.",
1518
+ "defaults": {
1519
+ "light": "var(--dbx-notice-color)"
1520
+ },
1521
+ "componentScope": "list"
1522
+ },
1523
+ {
1524
+ "cssVariable": "--dbx-list-detail-item-highlight-tone",
1525
+ "source": "dbx-web",
1526
+ "role": "misc",
1527
+ "intents": [
1528
+ "list detail item highlight tone"
1529
+ ],
1530
+ "description": "Component-scoped override point (`list`) read in `packages/dbx-web/src/lib/layout/list/_list.scss` — set it (from an app, or via the owning dbx directive where one exists) to override; unset, it falls back to `14%`.",
1531
+ "defaults": {
1532
+ "light": "14%"
1533
+ },
1534
+ "componentScope": "list"
1535
+ },
1536
+ {
1537
+ "cssVariable": "--dbx-list-detail-item-leading-block-width",
1538
+ "source": "dbx-web",
1539
+ "role": "size",
1540
+ "intents": [
1541
+ "list detail item leading block width"
1542
+ ],
1543
+ "description": "Component-scoped override point (`list`) read in `packages/dbx-web/src/lib/layout/list/_list.scss` — set it (from an app, or via the owning dbx directive where one exists) to override; unset, it falls back to `112px`.",
1544
+ "defaults": {
1545
+ "light": "112px"
1546
+ },
1547
+ "componentScope": "list"
1548
+ },
1549
+ {
1550
+ "cssVariable": "--dbx-list-detail-item-line-gap",
1551
+ "source": "dbx-web",
1552
+ "role": "spacing",
1553
+ "intents": [
1554
+ "list detail item line gap",
1555
+ "list detail item line gap spacing"
1556
+ ],
1557
+ "description": "Component-scoped override point (`list`) read in `packages/dbx-web/src/lib/layout/list/_list.scss` — set it (from an app, or via the owning dbx directive where one exists) to override; unset, it falls back to `2px`.",
1558
+ "defaults": {
1559
+ "light": "2px"
1560
+ },
1561
+ "componentScope": "list"
1562
+ },
1563
+ {
1564
+ "cssVariable": "--dbx-list-detail-item-line-icon-size",
1565
+ "source": "dbx-web",
1566
+ "role": "size",
1567
+ "intents": [
1568
+ "list detail item line icon size"
1569
+ ],
1570
+ "description": "Component-scoped override point (`list`) read in `packages/dbx-web/src/lib/layout/list/_list.scss` — set it (from an app, or via the owning dbx directive where one exists) to override; unset, it falls back to `18px`.",
1571
+ "defaults": {
1572
+ "light": "18px"
1573
+ },
1574
+ "componentScope": "list"
1575
+ },
1576
+ {
1577
+ "cssVariable": "--dbx-list-detail-item-padding",
1578
+ "source": "dbx-web",
1579
+ "role": "spacing",
1580
+ "intents": [
1581
+ "list detail item padding",
1582
+ "list detail item padding spacing"
1583
+ ],
1584
+ "description": "Component-scoped override point (`list`) read in `packages/dbx-web/src/lib/layout/list/_list.scss` — set it (from an app, or via the owning dbx directive where one exists) to override; unset, it falls back to `var(--dbx-padding-3)`.",
1585
+ "defaults": {
1586
+ "light": "var(--dbx-padding-3)"
1587
+ },
1588
+ "componentScope": "list"
1589
+ },
1590
+ {
1591
+ "cssVariable": "--dbx-list-detail-item-padding-resolved",
1592
+ "source": "dbx-web",
1593
+ "role": "spacing",
1594
+ "intents": [
1595
+ "list detail item padding resolved",
1596
+ "list detail item padding resolved spacing"
1597
+ ],
1598
+ "description": "Component-scoped token (`list`) declared in `packages/dbx-web/src/lib/layout/list/_list.scss`. Add a sassdoc `///` block above the declaration for richer guidance.",
1599
+ "defaults": {
1600
+ "light": "var(--dbx-list-detail-item-padding, var(--dbx-padding-3))"
1601
+ },
1602
+ "componentScope": "list"
1603
+ },
1456
1604
  {
1457
1605
  "cssVariable": "--dbx-list-empty-content-padding",
1458
1606
  "source": "dbx-web",
@@ -1628,6 +1776,32 @@
1628
1776
  },
1629
1777
  "componentScope": "list"
1630
1778
  },
1779
+ {
1780
+ "cssVariable": "--dbx-mapbox-popup-tip-color",
1781
+ "source": "dbx-web",
1782
+ "role": "color",
1783
+ "intents": [
1784
+ "mapbox popup tip color"
1785
+ ],
1786
+ "description": "Component-scoped override point (`mapbox`) read in `packages/dbx-web/src/lib/extension/mapbox/_mapbox.scss` — set it (from an app, or via the owning dbx directive where one exists) to override; unset, it falls back to `var(--mat-card-elevated-container-color, var(--mat-sys-surface-container-low))`.",
1787
+ "defaults": {
1788
+ "light": "var(--mat-card-elevated-container-color, var(--mat-sys-surface-container-low))"
1789
+ },
1790
+ "componentScope": "mapbox"
1791
+ },
1792
+ {
1793
+ "cssVariable": "--dbx-mapbox-popup-width",
1794
+ "source": "dbx-web",
1795
+ "role": "size",
1796
+ "intents": [
1797
+ "mapbox popup width"
1798
+ ],
1799
+ "description": "Component-scoped override point (`mapbox`) read in `packages/dbx-web/src/lib/extension/mapbox/_mapbox.scss` — set it (from an app, or via the owning dbx directive where one exists) to override; unset, it falls back to `340px`.",
1800
+ "defaults": {
1801
+ "light": "340px"
1802
+ },
1803
+ "componentScope": "mapbox"
1804
+ },
1631
1805
  {
1632
1806
  "cssVariable": "--dbx-navbar-item-border-radius",
1633
1807
  "source": "dbx-web",
@@ -808,6 +808,52 @@
808
808
  "example": "<dbx-progress-spinner-button [config]=\"cfg\" (btnClick)=\"onClick()\"></dbx-progress-spinner-button>",
809
809
  "minimalExample": "<dbx-progress-spinner-button [config]=\"cfg\"></dbx-progress-spinner-button>"
810
810
  },
811
+ {
812
+ "slug": "browser-agent-view",
813
+ "category": "misc",
814
+ "kind": "component",
815
+ "selector": "dbx-browser-agent-view",
816
+ "className": "DbxBrowserAgentViewComponent",
817
+ "module": "@dereekb/dbx-web",
818
+ "description": "Renders the component of the first {@link DbxBrowserAgentViewEntry} whose match matches the current browser agent (OS, browser, and device), falling back to the config's default entry.\n\nAn optional override button lets the user pick another entry. Injected components can inject {@link DbxBrowserAgentViewContext} to read the detected agent or to switch entries.",
819
+ "inputs": [
820
+ {
821
+ "name": "config",
822
+ "type": "Maybe<DbxBrowserAgentViewConfig>",
823
+ "description": "",
824
+ "required": false
825
+ },
826
+ {
827
+ "name": "showOverrideButton",
828
+ "type": "Maybe<boolean>",
829
+ "description": "",
830
+ "required": false
831
+ }
832
+ ],
833
+ "outputs": [],
834
+ "relatedSlugs": [
835
+ "widget",
836
+ "browser-agent-view-override-button"
837
+ ],
838
+ "example": "readonly config = makeDbxBrowserAgentViewConfigFromOsMap({\n ios: { componentClass: IosInstructionsComponent },\n android: { componentClass: AndroidInstructionsComponent },\n default: { componentClass: BookmarkInstructionsComponent },\n showOverrideButton: true\n});\n```\n\n```html\n<dbx-browser-agent-view [config]=\"config\" [(overrideKey)]=\"savedDeviceKey\"></dbx-browser-agent-view>",
839
+ "minimalExample": "<dbx-browser-agent-view [config]=\"config\"></dbx-browser-agent-view>"
840
+ },
841
+ {
842
+ "slug": "browser-agent-view-override-button",
843
+ "category": "misc",
844
+ "kind": "component",
845
+ "selector": "dbx-browser-agent-view-override-button",
846
+ "className": "DbxBrowserAgentViewOverrideButtonComponent",
847
+ "module": "@dereekb/dbx-web",
848
+ "description": "Button that opens a menu to manually select an entry of the parent {@link DbxBrowserAgentViewComponent}, or to return to the auto-detected entry.\n\nRendered by the view when `showOverrideButton` is enabled, but can also be placed inside the injected content to position it manually.",
849
+ "inputs": [],
850
+ "outputs": [],
851
+ "relatedSlugs": [
852
+ "browser-agent-view"
853
+ ],
854
+ "example": "<!-- inside a component injected by dbx-browser-agent-view -->\n<p>Follow these steps to add the app to your home screen.</p>\n<dbx-browser-agent-view-override-button></dbx-browser-agent-view-override-button>",
855
+ "minimalExample": "<dbx-browser-agent-view-override-button></dbx-browser-agent-view-override-button>"
856
+ },
811
857
  {
812
858
  "slug": "page-title-info",
813
859
  "category": "navigation",
@@ -315,6 +315,95 @@
315
315
  }
316
316
  ]
317
317
  },
318
+ {
319
+ "slug": "list-detail-item-schedule-todo",
320
+ "category": "list",
321
+ "summary": "Shared .dbx-list-detail-item row (bold title + lines between leading/trailing slots) rendering a hover-free, button-only Schedule list with a full-height date block and \"…\" separatorConfig gap markers between non-consecutive days, and a row-clickable To Do list with the built-in chevron, an urgent highlight, and an empty state.",
322
+ "header": ".dbx-list-detail-item Schedule + To Do Lists",
323
+ "className": "DocListDetailItemExampleComponent",
324
+ "selector": "doc-list-detail-item-example",
325
+ "module": "apps/demo",
326
+ "appRef": "apps/demo",
327
+ "hint": "One shared row utility — bold title + lines between leading/trailing slots — powering a hover-free, button-only schedule list and a row-clickable to do list.",
328
+ "relatedSlugs": [
329
+ "dbx-list",
330
+ "dbx-list-detail-item",
331
+ "dbx-list-no-hover-effects",
332
+ "dbx-list-card-items-list",
333
+ "dbx-list-empty-content",
334
+ "dbx-list-detail-item-gap",
335
+ "dbx-anchor",
336
+ "dbx-button",
337
+ "dbx-chip",
338
+ "dbx-icon-tile",
339
+ "dbx-color"
340
+ ],
341
+ "info": "<p>\n Both panels render\n <code>.dbx-list-detail-item</code>\n rows: an\n <code>.item-content</code>\n column of one bold\n <code>.item-title</code>\n followed by any number of\n <code>.item-line</code>\n rows (a leading\n <code>&lt;mat-icon&gt;</code>\n is sized for you), framed by an\n <code>.item-leading</code>\n and an\n <code>.item-trailing</code>\n slot. The row pads itself, so each view sets\n <code>dbx-list-item-p0</code>\n on its host.\n</p>\n<p>\n <strong>Your Schedule</strong>\n is hover-free and button-only. The wrapper host applies\n <code>dbx-list-no-hover-effects dbx-list-card-items-list</code>\n , and the view's\n <code>mapValuesToItemValues</code>\n drops\n <code>anchor</code>\n so the row is never a click target and the list turns its ripple off — only the\n <code>&lt;dbx-anchor&gt;</code>\n -wrapped button inside the\n <code>.item-trailing-divided</code>\n slot reacts. The date column is an\n <code>.item-leading-block</code>\n that bleeds to the row's edges, painted by\n <code>[dbxColor]</code>\n +\n <code>[dbxColorTone]</code>\n +\n <code>.dbx-color-bg</code>\n .\n</p>\n<p>\n When a day doesn't follow the previous one, a \"…\"\n <code>.dbx-list-detail-item-gap</code>\n marker sits between them. The view config sets a\n <code>separatorConfig</code>\n : a separator component plus a\n <code>showSeparator(previous, next)</code>\n function that returns true when the next day isn't the following calendar day. The list calls it for each pair of neighbouring rows (and once before the first and after the last row, with the missing side undefined), and injects the component through\n <code>dbx-injection</code>\n wherever it returns true. The component reads both rows from\n <code>DBX_VALUE_LIST_VIEW_ITEM_SEPARATOR</code>\n to label the gap. Separators sit outside the list rows, so the marker picks up no row hover, ripple or card styling, and its icon column shares the date block's width so it lines up underneath.\n</p>\n<p>\n <strong>To Do</strong>\n keeps the default hover and ripple, and the whole row is the click target (the view keeps\n <code>anchor</code>\n ). The view's\n <code>metaConfig: DbxListViewMetaIconComponent.metaConfig('chevron_right')</code>\n adds the built-in chevron, so the rows need no\n <code>.item-trailing</code>\n slot. The urgent row adds\n <code>.dbx-list-detail-item-highlight</code>\n , which paints the hosting list row through\n <code>:has()</code>\n so the wash also covers the chevron (tune it with\n <code>--dbx-list-detail-item-highlight-color</code>\n /\n <code>--dbx-list-detail-item-highlight-tone</code>\n ). With no items the list shows its projected\n <code>&lt;dbx-list-empty-content empty&gt;</code>\n .\n</p>\n<p>\n Both lists size to their rows and cap their height with\n <code>--dbx-list-content-max-height</code>\n set on the wrapper host, so\n <code>.dbx-list-content</code>\n — the list's own scroll container — scrolls past the limit instead of the card growing (and a paged list's load-more keeps working).\n</p>\n<p>\n Last clicked:\n <code>{{ clickedKey() ?? '(none)' }}</code>\n</p>",
342
+ "snippet": "<div class=\"dbx-button-wrap-group dbx-mb3\">\n @for (option of todoPresentationOptions; track option.presentation) {\n <button mat-stroked-button (click)=\"todoPresentationSignal.set(option.presentation)\" [disabled]=\"todoPresentationSignal() === option.presentation\">{{ option.label }}</button>\n }\n</div>\n<div gdColumns=\"7fr 5fr\" gdColumns.lt-md=\"1fr\" gdGap=\"var(--dbx-padding-3)\">\n <mat-card appearance=\"outlined\">\n <mat-card-content>\n <h3 class=\"dbx-text-headline-small dbx-m0\">Your Schedule</h3>\n <p class=\"dbx-hint dbx-mb3\">{{ bookedCount }} upcoming weekdays booked</p>\n <doc-schedule-day-item-list class=\"doc-list-detail-item-list\" [state]=\"scheduleState\"></doc-schedule-day-item-list>\n </mat-card-content>\n </mat-card>\n <mat-card appearance=\"outlined\">\n <mat-card-content>\n <h3 class=\"dbx-text-headline-small dbx-m0\">To Do</h3>\n @if (todoCountLabelSignal(); as todoCountLabel) {\n <p class=\"dbx-hint dbx-mb3\">{{ todoCountLabel }}</p>\n }\n <doc-todo-item-list class=\"doc-list-detail-item-list\" [state]=\"todoStateSignal()\">\n <dbx-list-empty-content empty>\n <div class=\"dbx-flex-column dbx-flex-center dbx-text-center dbx-pv4\">\n <dbx-icon-tile class=\"dbx-mb3\" icon=\"task_alt\" [round]=\"true\" dbxColor=\"primary\" [dbxColorTone]=\"18\"></dbx-icon-tile>\n <div class=\"dbx-text-title-medium\">You're all caught up</div>\n <div class=\"dbx-hint\">No action items right now. We'll let you know if something needs your attention.</div>\n </div>\n </dbx-list-empty-content>\n </doc-todo-item-list>\n </mat-card-content>\n </mat-card>\n</div>",
343
+ "uses": [
344
+ {
345
+ "kind": "component",
346
+ "className": "DocScheduleDayItemListComponent",
347
+ "role": "list",
348
+ "selector": "doc-schedule-day-item-list",
349
+ "classSource": "@Component({\n selector: 'doc-schedule-day-item-list',\n template: DEFAULT_LIST_WRAPPER_COMPONENT_CONFIGURATION_TEMPLATE,\n imports: [DbxListWrapperComponentImportsModule],\n host: {\n class: 'dbx-list-no-hover-effects dbx-list-card-items-list'\n }\n})\nexport class DocScheduleDayItemListComponent extends AbstractDbxSelectionListWrapperDirective<ScheduleDayItemValue> {\n constructor() {\n super({\n componentClass: DocScheduleDayItemListViewComponent,\n defaultSelectionMode: 'view'\n });\n }\n}"
350
+ },
351
+ {
352
+ "kind": "component",
353
+ "className": "DocScheduleDayItemListViewComponent",
354
+ "role": "view",
355
+ "selector": "doc-schedule-day-item-list-view",
356
+ "classSource": "@Component({\n selector: 'doc-schedule-day-item-list-view',\n template: DEFAULT_DBX_SELECTION_VALUE_LIST_COMPONENT_CONFIGURATION_TEMPLATE,\n imports: [DbxSelectionValueListViewComponentImportsModule],\n providers: provideDbxListView(DocScheduleDayItemListViewComponent),\n host: {\n class: 'dbx-list-item-p0'\n }\n})\nexport class DocScheduleDayItemListViewComponent extends AbstractDbxSelectionListViewDirective<ScheduleDayItemValue> {\n // Drop `anchor` (the trailing button owns it; the row stays non-clickable and ripple-free).\n // Separate two days with a \"…\" gap whenever the next day isn't the following calendar day.\n readonly config: DbxSelectionValueListViewConfig<ScheduleDayItemValueWithSelection> = {\n componentClass: DocScheduleDayItemListViewItemComponent,\n mapValuesToItemValues: (values) => of(values.map((value) => ({ ...value, itemValue: value, anchor: undefined }))),\n separatorConfig: {\n componentClass: DocScheduleDayGapComponent,\n showSeparator: dbxValueListItemSeparatorDecisionFunction<ScheduleDayItemValue>((previous, next) => previous != null && next != null && skippedDaysBetweenScheduleDays(previous.day, next.day) > 0)\n }\n };\n}"
357
+ },
358
+ {
359
+ "kind": "component",
360
+ "className": "DocScheduleDayItemListViewItemComponent",
361
+ "role": "item",
362
+ "selector": "doc-schedule-day-item-list-view-item",
363
+ "classSource": "@Component({\n selector: 'doc-schedule-day-item-list-view-item',\n template: `\n <div class=\"dbx-list-detail-item\">\n <div class=\"item-leading-block dbx-color-bg\" [dbxColor]=\"stateColor\" [dbxColorTone]=\"14\">\n <span class=\"dbx-text-label-medium dbx-uppercase dbx-tracked-wide\">{{ dayLabel }}</span>\n <span class=\"dbx-text-title-large\">{{ dateLabel }}</span>\n @if (session) {\n <dbx-chip [color]=\"stateColor\" [tone]=\"100\" [small]=\"true\">BOOKED</dbx-chip>\n } @else {\n <dbx-chip [color]=\"stateColor\" [small]=\"true\">\n <span class=\"dbx-dot\"></span>\n <span class=\"dbx-pl1\">OPEN</span>\n </dbx-chip>\n }\n </div>\n <div class=\"item-content\">\n @if (session; as session) {\n <span class=\"item-title\">{{ session.title }}</span>\n <span class=\"item-line\">\n <mat-icon>location_on</mat-icon>\n {{ session.locationName }}\n </span>\n <span class=\"item-line\">\n <mat-icon>calendar_today</mat-icon>\n {{ session.dateRange }}\n </span>\n <span class=\"item-line\">\n <mat-icon>schedule</mat-icon>\n {{ session.timeRange }}\n </span>\n } @else {\n <span class=\"item-title\">Nothing booked</span>\n <span class=\"item-line\">This day is still free.</span>\n }\n </div>\n <div class=\"item-trailing item-trailing-divided\">\n <dbx-anchor [anchor]=\"anchor\">\n @if (session) {\n <dbx-button class=\"dbx-nowrap\" [stroked]=\"true\" text=\"View Details\"></dbx-button>\n } @else {\n <dbx-button class=\"dbx-nowrap\" [tonal]=\"true\" color=\"primary\" text=\"Browse sessions\"></dbx-button>\n }\n </dbx-anchor>\n </div>\n </div>\n `,\n imports: [MatIconModule, DbxAnchorComponent, DbxButtonComponent, DbxChipDirective, DbxColorDirective]\n})\nexport class DocScheduleDayItemListViewItemComponent extends AbstractDbxValueListViewItemComponent<ScheduleDayItemValue> {\n get dayLabel(): string {\n return this.itemValue.dayLabel;\n }\n\n get dateLabel(): string {\n return this.itemValue.dateLabel;\n }\n\n get session(): Maybe<ScheduleDaySession> {\n return this.itemValue.session;\n }\n\n get stateColor(): DbxThemeColor {\n return this.itemValue.state === 'booked' ? 'success' : 'notice';\n }\n\n get anchor(): ClickableAnchor {\n return this.itemValue.anchor;\n }\n}"
364
+ },
365
+ {
366
+ "kind": "component",
367
+ "className": "DocScheduleDayGapComponent",
368
+ "role": "separator",
369
+ "selector": "doc-schedule-day-gap",
370
+ "classSource": "@Component({\n selector: 'doc-schedule-day-gap',\n template: `\n <div class=\"dbx-list-detail-item-gap\">\n <span class=\"item-leading\"><mat-icon>more_vert</mat-icon></span>\n <span>{{ label }}</span>\n </div>\n `,\n imports: [MatIconModule]\n})\nexport class DocScheduleDayGapComponent {\n readonly separator = inject<DbxValueListItemSeparatorContext<ScheduleDayItemValue>>(DBX_VALUE_LIST_VIEW_ITEM_SEPARATOR);\n\n get label(): string {\n const { previous, next } = this.separator;\n const skippedDays = previous && next ? skippedDaysBetweenScheduleDays(previous.itemValue.day, next.itemValue.day) : 0;\n return `${skippedDays} ${skippedDays === 1 ? 'day' : 'days'} skipped`;\n }\n}"
371
+ },
372
+ {
373
+ "kind": "interface",
374
+ "className": "ScheduleDayItemValue",
375
+ "role": "data",
376
+ "classSource": "export interface ScheduleDayItemValue {\n readonly key: string;\n /**\n * The schedule day. Days are weekdays, sorted ascending.\n */\n readonly day: ISO8601DayString;\n /**\n * Short weekday label, e.g. `Fri`.\n */\n readonly dayLabel: string;\n /**\n * Short date label, e.g. `Sep 25`.\n */\n readonly dateLabel: string;\n readonly state: ScheduleDayItemState;\n /**\n * The booked session. Only set when {@link state} is `'booked'`.\n */\n readonly session?: Maybe<ScheduleDaySession>;\n /**\n * Fired by the row's trailing button — \"View Details\" for a booked day, \"Browse sessions\" for an open day.\n */\n readonly anchor: ClickableAnchor;\n}"
377
+ },
378
+ {
379
+ "kind": "component",
380
+ "className": "DocTodoItemListComponent",
381
+ "role": "list",
382
+ "selector": "doc-todo-item-list",
383
+ "classSource": "@Component({\n selector: 'doc-todo-item-list',\n template: DEFAULT_LIST_WRAPPER_COMPONENT_CONFIGURATION_TEMPLATE,\n imports: [DbxListWrapperComponentImportsModule],\n host: {\n class: 'dbx-list-auto-height'\n }\n})\nexport class DocTodoItemListComponent extends AbstractDbxSelectionListWrapperDirective<TodoItemValue> {\n constructor() {\n super({\n componentClass: DocTodoItemListViewComponent,\n defaultSelectionMode: 'view'\n });\n }\n}"
384
+ },
385
+ {
386
+ "kind": "component",
387
+ "className": "DocTodoItemListViewComponent",
388
+ "role": "view",
389
+ "selector": "doc-todo-item-list-view",
390
+ "classSource": "@Component({\n selector: 'doc-todo-item-list-view',\n template: DEFAULT_DBX_SELECTION_VALUE_LIST_COMPONENT_CONFIGURATION_TEMPLATE,\n imports: [DbxSelectionValueListViewComponentImportsModule],\n providers: provideDbxListView(DocTodoItemListViewComponent),\n host: {\n class: 'dbx-list-item-p0'\n }\n})\nexport class DocTodoItemListViewComponent extends AbstractDbxSelectionListViewDirective<TodoItemValue> {\n // Drop `icon` (template paints its own tile); keep `anchor` so the whole row is the click target.\n readonly config: DbxSelectionValueListViewConfig<TodoItemValueWithSelection> = {\n componentClass: DocTodoItemListViewItemComponent,\n metaConfig: DbxListViewMetaIconComponent.metaConfig('chevron_right'),\n mapValuesToItemValues: (values) => of(values.map((value) => ({ ...value, itemValue: value, icon: undefined })))\n };\n}"
391
+ },
392
+ {
393
+ "kind": "component",
394
+ "className": "DocTodoItemListViewItemComponent",
395
+ "role": "item",
396
+ "selector": "doc-todo-item-list-view-item",
397
+ "classSource": "@Component({\n selector: 'doc-todo-item-list-view-item',\n template: `\n <div class=\"dbx-list-detail-item\" [class.dbx-list-detail-item-highlight]=\"highlight\">\n <dbx-icon-tile class=\"item-leading\" [icon]=\"icon\" [round]=\"true\" [dbxColor]=\"highlight ? 'notice' : 'grey'\" [dbxColorTone]=\"18\"></dbx-icon-tile>\n <div class=\"item-content\">\n <span class=\"item-title\">{{ title }}</span>\n <span class=\"item-line\">{{ detail }}</span>\n @if (chip; as chip) {\n <span class=\"item-line dbx-pt1\">\n <dbx-chip [color]=\"chip.color\" [small]=\"true\">{{ chip.text }}</dbx-chip>\n </span>\n }\n </div>\n </div>\n `,\n imports: [DbxChipDirective, DbxColorDirective, DbxIconTileComponent]\n})\nexport class DocTodoItemListViewItemComponent extends AbstractDbxValueListViewItemComponent<TodoItemValue> {\n get icon(): string {\n return this.itemValue.icon;\n }\n\n get title(): string {\n return this.itemValue.title;\n }\n\n get detail(): string {\n return this.itemValue.detail;\n }\n\n get chip(): Maybe<TodoItemChip> {\n return this.itemValue.chip;\n }\n\n get highlight(): boolean {\n return this.itemValue.highlight === true;\n }\n}"
398
+ },
399
+ {
400
+ "kind": "interface",
401
+ "className": "TodoItemValue",
402
+ "role": "data",
403
+ "classSource": "export interface TodoItemValue {\n readonly key: string;\n readonly icon: string;\n readonly title: string;\n readonly detail: string;\n readonly chip?: Maybe<TodoItemChip>;\n /**\n * Whether to paint the row with the urgent `.dbx-list-detail-item-highlight` wash.\n */\n readonly highlight?: Maybe<boolean>;\n /**\n * Whole-row click target.\n */\n readonly anchor: ClickableAnchor;\n}"
404
+ }
405
+ ]
406
+ },
318
407
  {
319
408
  "slug": "list-progress-with-button",
320
409
  "category": "list",
@@ -804,6 +804,54 @@
804
804
  }
805
805
  ]
806
806
  },
807
+ {
808
+ "slug": "notifications-newest-first-query",
809
+ "name": "notificationsNewestFirstQuery",
810
+ "module": "@dereekb/firebase",
811
+ "subpath": "model/notification/notification.query",
812
+ "signature": "notificationsNewestFirstQuery(): FirestoreQueryConstraint[]",
813
+ "description": "Query constraints for listing the {@link Notification} documents in one {@link NotificationBox}, newest first.\n\nRun against a single box's notification collection — this is how an admin finds the notifications sent to a\nmodel (e.g. every notification for a profile) when their ids are auto-generated and not otherwise known. Pair it\nwith a limit; a busy box can hold many notifications between cleanup sweeps.",
814
+ "model": "Notification",
815
+ "collection": "nbn",
816
+ "isNested": true,
817
+ "scope": "COLLECTION",
818
+ "manual": false,
819
+ "skip": false,
820
+ "category": "lookup",
821
+ "params": [],
822
+ "returns": "Array of Firestore query constraints ordering notifications by creation date, newest first.",
823
+ "tags": [
824
+ "lookup",
825
+ "notification",
826
+ "notifications",
827
+ "newest",
828
+ "first",
829
+ "query",
830
+ "notificationsnewestfirstquery",
831
+ "constraints",
832
+ "listing",
833
+ "link",
834
+ "documents",
835
+ "one",
836
+ "notificationbox",
837
+ "run",
838
+ "against"
839
+ ],
840
+ "constraintSequences": [
841
+ {
842
+ "pathLabel": "all",
843
+ "entries": [
844
+ {
845
+ "kind": "orderBy",
846
+ "fieldPath": "cat",
847
+ "direction": "desc"
848
+ }
849
+ ]
850
+ }
851
+ ],
852
+ "derivedComposites": [],
853
+ "derivedFieldOverrides": []
854
+ },
807
855
  {
808
856
  "slug": "notification-logged-event-days-older-than-query",
809
857
  "name": "notificationLoggedEventDaysOlderThanQuery",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dereekb/dbx-components-mcp",
3
- "version": "14.9.0",
3
+ "version": "14.11.0",
4
4
  "sideEffects": false,
5
5
  "type": "module",
6
6
  "bin": {
@@ -12,7 +12,7 @@
12
12
  "ts-morph": "^21.0.0"
13
13
  },
14
14
  "peerDependencies": {
15
- "@dereekb/dbx-cli": "14.9.0",
16
- "@dereekb/util": "14.9.0"
15
+ "@dereekb/dbx-cli": "14.11.0",
16
+ "@dereekb/util": "14.11.0"
17
17
  }
18
18
  }