@amedia/brick-mcp 0.1.1 → 0.1.2
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/data/components-metadata.json +83 -47
- package/data/tokens-documentation.json +1 -1
- package/data/tokens.json +1 -1
- package/dist/data/components-metadata.json +83 -47
- package/dist/data/tokens-documentation.json +1 -1
- package/dist/data/tokens.json +1 -1
- package/dist/http.js +9 -7
- package/dist/http.js.map +2 -2
- package/dist/index.js +9 -7
- package/dist/index.js.map +2 -2
- package/package.json +38 -1
|
@@ -1,46 +1,57 @@
|
|
|
1
1
|
[
|
|
2
2
|
{
|
|
3
3
|
"name": "brick-alt-teaser",
|
|
4
|
-
"version": "8.0.
|
|
4
|
+
"version": "8.0.70",
|
|
5
5
|
"selector": "brick-alt-teaser-v8",
|
|
6
6
|
"category": "Display",
|
|
7
|
-
"tags": [
|
|
7
|
+
"tags": [
|
|
8
|
+
"display"
|
|
9
|
+
]
|
|
8
10
|
},
|
|
9
11
|
{
|
|
10
12
|
"name": "brick-avatar",
|
|
11
|
-
"version": "0.2.
|
|
13
|
+
"version": "0.2.42",
|
|
12
14
|
"selector": "brick-avatar-v0",
|
|
13
15
|
"description": "brick-avatar component",
|
|
14
16
|
"category": "Display",
|
|
15
|
-
"tags": [
|
|
17
|
+
"tags": [
|
|
18
|
+
"display"
|
|
19
|
+
]
|
|
16
20
|
},
|
|
17
21
|
{
|
|
18
22
|
"name": "brick-button",
|
|
19
|
-
"version": "9.3.
|
|
23
|
+
"version": "9.3.6",
|
|
20
24
|
"selector": "brick-button-v9",
|
|
21
25
|
"category": "Forms",
|
|
22
|
-
"tags": [
|
|
26
|
+
"tags": [
|
|
27
|
+
"forms",
|
|
28
|
+
"interactive"
|
|
29
|
+
]
|
|
23
30
|
},
|
|
24
31
|
{
|
|
25
32
|
"name": "brick-byline",
|
|
26
|
-
"version": "1.0.
|
|
33
|
+
"version": "1.0.2",
|
|
27
34
|
"selector": "brick-byline-v1",
|
|
28
35
|
"description": "brick-byline component"
|
|
29
36
|
},
|
|
30
37
|
{
|
|
31
38
|
"name": "brick-card",
|
|
32
|
-
"version": "7.3.
|
|
39
|
+
"version": "7.3.13",
|
|
33
40
|
"selector": "brick-card-v7",
|
|
34
41
|
"category": "Layout",
|
|
35
|
-
"tags": [
|
|
42
|
+
"tags": [
|
|
43
|
+
"layout"
|
|
44
|
+
]
|
|
36
45
|
},
|
|
37
46
|
{
|
|
38
47
|
"name": "brick-carousel",
|
|
39
|
-
"version": "2.2.
|
|
48
|
+
"version": "2.2.2",
|
|
40
49
|
"selector": "brick-carousel-v2",
|
|
41
50
|
"description": "Simple carousel for any content passed to it.",
|
|
42
51
|
"category": "Display",
|
|
43
|
-
"tags": [
|
|
52
|
+
"tags": [
|
|
53
|
+
"display"
|
|
54
|
+
]
|
|
44
55
|
},
|
|
45
56
|
{
|
|
46
57
|
"name": "brick-classnames",
|
|
@@ -48,25 +59,29 @@
|
|
|
48
59
|
"selector": "brick-classnames-v2",
|
|
49
60
|
"description": "Utility method to create a safe string from a design name",
|
|
50
61
|
"category": "Utilities",
|
|
51
|
-
"tags": [
|
|
62
|
+
"tags": [
|
|
63
|
+
"utilities"
|
|
64
|
+
]
|
|
52
65
|
},
|
|
53
66
|
{
|
|
54
67
|
"name": "brick-countdown",
|
|
55
|
-
"version": "2.0.
|
|
68
|
+
"version": "2.0.14",
|
|
56
69
|
"selector": "brick-countdown-v2",
|
|
57
70
|
"description": "brick-countdown component"
|
|
58
71
|
},
|
|
59
72
|
{
|
|
60
73
|
"name": "brick-dialog",
|
|
61
|
-
"version": "2.0.
|
|
74
|
+
"version": "2.0.18",
|
|
62
75
|
"selector": "brick-dialog-v2",
|
|
63
76
|
"description": "brick-dialog component",
|
|
64
77
|
"category": "Feedback",
|
|
65
|
-
"tags": [
|
|
78
|
+
"tags": [
|
|
79
|
+
"feedback"
|
|
80
|
+
]
|
|
66
81
|
},
|
|
67
82
|
{
|
|
68
83
|
"name": "brick-expand",
|
|
69
|
-
"version": "0.0.
|
|
84
|
+
"version": "0.0.4",
|
|
70
85
|
"selector": "brick-expand-v0",
|
|
71
86
|
"description": "brick-expand component"
|
|
72
87
|
},
|
|
@@ -76,20 +91,24 @@
|
|
|
76
91
|
"selector": "brick-fonts-v2",
|
|
77
92
|
"description": "Distribution of font files",
|
|
78
93
|
"category": "Utilities",
|
|
79
|
-
"tags": [
|
|
94
|
+
"tags": [
|
|
95
|
+
"utilities"
|
|
96
|
+
]
|
|
80
97
|
},
|
|
81
98
|
{
|
|
82
99
|
"name": "brick-helloworld",
|
|
83
|
-
"version": "2.0.
|
|
100
|
+
"version": "2.0.7",
|
|
84
101
|
"selector": "brick-helloworld-v2",
|
|
85
102
|
"description": "Brick Hello World component"
|
|
86
103
|
},
|
|
87
104
|
{
|
|
88
105
|
"name": "brick-icon",
|
|
89
|
-
"version": "2.3.
|
|
106
|
+
"version": "2.3.6",
|
|
90
107
|
"selector": "brick-icon-v2",
|
|
91
108
|
"category": "Display",
|
|
92
|
-
"tags": [
|
|
109
|
+
"tags": [
|
|
110
|
+
"display"
|
|
111
|
+
]
|
|
93
112
|
},
|
|
94
113
|
{
|
|
95
114
|
"name": "brick-illustrations",
|
|
@@ -99,18 +118,23 @@
|
|
|
99
118
|
},
|
|
100
119
|
{
|
|
101
120
|
"name": "brick-image",
|
|
102
|
-
"version": "6.0.
|
|
121
|
+
"version": "6.0.10",
|
|
103
122
|
"selector": "brick-image-v6",
|
|
104
123
|
"category": "Display",
|
|
105
|
-
"tags": [
|
|
124
|
+
"tags": [
|
|
125
|
+
"display"
|
|
126
|
+
]
|
|
106
127
|
},
|
|
107
128
|
{
|
|
108
129
|
"name": "brick-input",
|
|
109
|
-
"version": "3.0.
|
|
130
|
+
"version": "3.0.14",
|
|
110
131
|
"selector": "brick-input-v3",
|
|
111
132
|
"description": "brick-input component",
|
|
112
133
|
"category": "Forms",
|
|
113
|
-
"tags": [
|
|
134
|
+
"tags": [
|
|
135
|
+
"forms",
|
|
136
|
+
"interactive"
|
|
137
|
+
]
|
|
114
138
|
},
|
|
115
139
|
{
|
|
116
140
|
"name": "brick-nifs",
|
|
@@ -120,80 +144,88 @@
|
|
|
120
144
|
},
|
|
121
145
|
{
|
|
122
146
|
"name": "brick-pill",
|
|
123
|
-
"version": "9.0.
|
|
147
|
+
"version": "9.0.7",
|
|
124
148
|
"selector": "brick-pill-v9"
|
|
125
149
|
},
|
|
126
150
|
{
|
|
127
151
|
"name": "brick-player",
|
|
128
|
-
"version": "1.27.
|
|
152
|
+
"version": "1.27.22",
|
|
129
153
|
"selector": "brick-player-v1",
|
|
130
154
|
"description": "Component for playing video and audio files"
|
|
131
155
|
},
|
|
132
156
|
{
|
|
133
157
|
"name": "brick-published",
|
|
134
|
-
"version": "4.0.
|
|
158
|
+
"version": "4.0.6",
|
|
135
159
|
"selector": "brick-published-v4",
|
|
136
160
|
"description": "brick-published"
|
|
137
161
|
},
|
|
138
162
|
{
|
|
139
163
|
"name": "brick-share",
|
|
140
|
-
"version": "0.3.
|
|
164
|
+
"version": "0.3.9",
|
|
141
165
|
"selector": "brick-share-v0",
|
|
142
166
|
"description": "brick-share component"
|
|
143
167
|
},
|
|
144
168
|
{
|
|
145
169
|
"name": "brick-stepper",
|
|
146
|
-
"version": "1.0.
|
|
170
|
+
"version": "1.0.16",
|
|
147
171
|
"selector": "brick-stepper-v1",
|
|
148
172
|
"description": "brick-stepper component"
|
|
149
173
|
},
|
|
150
174
|
{
|
|
151
175
|
"name": "brick-tab",
|
|
152
|
-
"version": "0.1.
|
|
176
|
+
"version": "0.1.13",
|
|
153
177
|
"selector": "brick-tab-v0",
|
|
154
178
|
"description": "brick-tab component"
|
|
155
179
|
},
|
|
156
180
|
{
|
|
157
181
|
"name": "brick-tabs",
|
|
158
|
-
"version": "0.1.
|
|
182
|
+
"version": "0.1.14",
|
|
159
183
|
"selector": "brick-tabs-v0",
|
|
160
184
|
"description": "brick-tabs component handling tablist, tabs and tabpanel",
|
|
161
185
|
"category": "Navigation",
|
|
162
|
-
"tags": [
|
|
186
|
+
"tags": [
|
|
187
|
+
"navigation"
|
|
188
|
+
]
|
|
163
189
|
},
|
|
164
190
|
{
|
|
165
191
|
"name": "brick-tag",
|
|
166
|
-
"version": "0.0.
|
|
192
|
+
"version": "0.0.13",
|
|
167
193
|
"selector": "brick-tag-v0",
|
|
168
194
|
"description": "brick-tag component"
|
|
169
195
|
},
|
|
170
196
|
{
|
|
171
197
|
"name": "brick-teaser",
|
|
172
|
-
"version": "20.0
|
|
198
|
+
"version": "20.1.0",
|
|
173
199
|
"selector": "brick-teaser-v20",
|
|
174
200
|
"description": "Teaser component.",
|
|
175
201
|
"category": "Display",
|
|
176
|
-
"tags": [
|
|
202
|
+
"tags": [
|
|
203
|
+
"display"
|
|
204
|
+
]
|
|
177
205
|
},
|
|
178
206
|
{
|
|
179
207
|
"name": "brick-teaser-player",
|
|
180
|
-
"version": "1.0.
|
|
208
|
+
"version": "1.0.28",
|
|
181
209
|
"selector": "brick-teaser-player-v1",
|
|
182
210
|
"description": "brick-video-teaser component",
|
|
183
211
|
"category": "Display",
|
|
184
|
-
"tags": [
|
|
212
|
+
"tags": [
|
|
213
|
+
"display"
|
|
214
|
+
]
|
|
185
215
|
},
|
|
186
216
|
{
|
|
187
217
|
"name": "brick-teaser-reels",
|
|
188
|
-
"version": "0.4.
|
|
218
|
+
"version": "0.4.2",
|
|
189
219
|
"selector": "brick-teaser-reels-v0",
|
|
190
220
|
"description": "brick-teaser-reels component",
|
|
191
221
|
"category": "Display",
|
|
192
|
-
"tags": [
|
|
222
|
+
"tags": [
|
|
223
|
+
"display"
|
|
224
|
+
]
|
|
193
225
|
},
|
|
194
226
|
{
|
|
195
227
|
"name": "brick-textarea",
|
|
196
|
-
"version": "2.0.
|
|
228
|
+
"version": "2.0.9",
|
|
197
229
|
"selector": "brick-textarea-v2",
|
|
198
230
|
"description": "brick-textarea component"
|
|
199
231
|
},
|
|
@@ -205,30 +237,34 @@
|
|
|
205
237
|
},
|
|
206
238
|
{
|
|
207
239
|
"name": "brick-toast",
|
|
208
|
-
"version": "0.1.
|
|
240
|
+
"version": "0.1.25",
|
|
209
241
|
"selector": "brick-toast-v0",
|
|
210
242
|
"description": "brick-toast component",
|
|
211
243
|
"category": "Feedback",
|
|
212
|
-
"tags": [
|
|
244
|
+
"tags": [
|
|
245
|
+
"feedback"
|
|
246
|
+
]
|
|
213
247
|
},
|
|
214
248
|
{
|
|
215
249
|
"name": "brick-toggle",
|
|
216
|
-
"version": "3.1.
|
|
250
|
+
"version": "3.1.12",
|
|
217
251
|
"selector": "brick-toggle-v3",
|
|
218
252
|
"description": "brick-toggle component"
|
|
219
253
|
},
|
|
220
254
|
{
|
|
221
255
|
"name": "brick-tokens",
|
|
222
|
-
"version": "5.
|
|
256
|
+
"version": "5.21.0",
|
|
223
257
|
"selector": "brick-tokens-v5",
|
|
224
258
|
"description": "Tokens package",
|
|
225
259
|
"category": "Utilities",
|
|
226
|
-
"tags": [
|
|
260
|
+
"tags": [
|
|
261
|
+
"utilities"
|
|
262
|
+
]
|
|
227
263
|
},
|
|
228
264
|
{
|
|
229
265
|
"name": "brick-tooltip",
|
|
230
|
-
"version": "1.0.
|
|
266
|
+
"version": "1.0.15",
|
|
231
267
|
"selector": "brick-tooltip-v1",
|
|
232
268
|
"description": "brick-tooltip component"
|
|
233
269
|
}
|
|
234
|
-
]
|
|
270
|
+
]
|
|
@@ -4,4 +4,4 @@
|
|
|
4
4
|
"naming": "import { Meta, Canvas, Source } from '@storybook/addon-docs/blocks';\nimport { BrickStyle } from './brickStyle.js';\nimport Repo from './assets/repo.svg';\nimport Open from './assets/open.svg';\n\n<Meta title=\"Brick Tokens/Documentation/Naming\" />\n\n<brick-style></brick-style>\n\n# Naming\n\nA design token name in Figma can be transformed into different shapes based on the format.\nSee all the tokens available at the [tokens pages](?path=/story/brick-tokens-tokens--space)\n\n## Naming Conventions and examples\n\nDue to varying naming conventions and requirements across technologies, the naming format in **code** can differ.\n\nBelow are two examples illustrating the transformation of names into different formats:\n\n### Figma names:\n\n- `color.utility.primary.bg`\n- `spacing.x1`\n\n### CSS variable\n\n<Source\n language=\"css\"\n dark=\"true\"\n code={`\ncolor: var(--brick-colors-utilityPrimaryBg);\npadding: var(--brick-spacing-x1);\n `}\n/>\n\n### CSS-in-JS\n\nDeprecated - use css variables instead\n\n<Source\n language=\"javascript\"\n dark=\"true\"\n code={`\nconst heading = css({\n color: '$utilityPrimaryBg', //translates to 'var(--brick-colors-primaryBg)'\n padding:'$x1' //translates to 'var(--brick-spacing-x1)''\n})\n `}\n/>\n\n### For iOS\n\n**Spacing.swift**\n\n<Source\n language=\"other\"\n dark=\"true\"\n code={`\n //Example of name/value in the Spacing.swift file\nstruct Spacing {\n\tstatic let x1 : CGFloat = 5\n }\n `}\n/>\n\n**colors.json**\n\n<Source\n language=\"other\"\n dark=\"true\"\n code={`\n //Example of name/value in the colors.json file\n{\n \"color_utility_primary_fg\": \"#292827\",\n}\n `}\n/>\n\n## The taxonomy behind the names in themes\n\nWe need names that makes it as easy as possible to understand what the token should be used for, and when.\n\nGood names are predictable, unique, and understandable across disciplines.\n\nWhat is semantic to one, might not be semantic to a coworker. We need to agree on a common vocabulary.\n\nIn our themes, the design tokens are made up of semantic attributes that together form the token name. This ensures scalability and consistency. It covers both simple and more complex naming.\n\n<div className=\"token-name-steps\">\n <span className=\"step\">\n <strong>Scope*</strong>\n </span>\n <span>─</span>\n <span className=\"step\">\n <strong>[Context]</strong>\n </span>\n <span>─</span>\n <span className=\"step\">\n <strong>[Prominence]</strong>\n </span>\n <span>─</span>\n <span className=\"step\">\n <strong>[Sentiment]</strong>\n </span>\n <span>─</span>\n <span className=\"step\">\n <strong>[State]</strong>\n </span>\n <span></span>\n <span className=\"step\">\n <strong>Usage*</strong>\n </span>\n</div>\n*required parts. The optional parts are enclosed in brackets [].{' '}\n\n<div class=\"token-name-parts\">\n<div class=\"token-name-part\">\n **Scope**: \"Omfang\" The broadest category of the token, indicating its general\n purpose.\n Definerer hvilket \"navnerom\" tokenet tilhører.\n <ul>\n <li>\n <code>base</code>: General scope.\n </li>\n <li>\n <code>utility</code>: Interaction colors used for status messages and alerts.\n </li>\n <li>\n <code>supportive</code>: Supportive colors used in a theme on different elements\n </li>\n <li>\n <code>button</code>, <code>article</code>, <code>expand</code>:\n Component specific scope.\n </li>\n </ul>\n</div>\n\n<div class=\"token-name-part\">\n **[Context]**: Optional. Further refines the scope by specifying the\n particular area or genre the token applies to.\n <ul>\n <li>\n <code>opinion</code>, <code>reel</code>, <code>finance</code>,\n <code>lifestyle</code>\n </li>\n </ul>\n</div>\n\n<div class=\"token-name-part\">\n **[Prominence]** (Visuell Vekt) Optional. Describes the visual importance or\n emphasis of the element.\n <ul>\n <li>\n <code>primary</code>, <code>secondary</code>, <code>subtle</code>\n </li>\n </ul>\n</div>\n\n<div class=\"token-name-part\">\n **[Sentiment]**[ (Budskap/Status) Optional. Describes the emotional tone or\n status\n <ul>\n <li>\n <code>success</code>, <code>error</code>, <code>warning</code>,\n <code>breaking</code>, <code>live</code>, <code>beta</code>,\n <code>new</code>\n </li>\n </ul>\n</div>\n\n<div class=\"token-name-part\">\n **[State]** (Tilstand) Optional. Describes the interaction state of the\n element.\n <ul>\n <li>\n <code>hover</code>, <code>active</code>, <code>focus</code>,\n <code>disabled</code>\n </li>\n </ul>\n</div>\n\n<div class=\"token-name-part\">\n**Usage** (Bruk) Obligatorisk. Describing what the design decision applies to. If it is a color, it might be \"bg\", but if it is typography it might be \"body-s\" or \"heading-m\", including size to be responsive.\n <ul>\n <li>\n <code>bg</code>, <code>fg</code>, <code>border</code>, <code>body-s</code>, <code>heading-xl</code>\n </li>\n </ul>\n\n</div>\n</div>\n\n<div className=\"token-taxonomy-table\">\n <div>Token Navn</div>\n <div>Scope</div>\n <div>Context</div>\n <div>Prominence</div>\n <div>Sentiment</div>\n <div>State</div>\n <div>Usage</div>\n <div>Forklaring</div>\n\n<div>\n <strong>\n <code>base-page-bg</code>\n </strong>\n</div>\n<div>\n <code>base</code>\n</div>\n<div>-</div>\n<div>-</div>\n<div>-</div>\n<div>-</div>\n<div>\n <code>page-bg</code>\n</div>\n<div>Sidebakgrunn</div>\n\n<div>\n <strong>\n <code>button-primary-bg</code>\n </strong>\n</div>\n<div>\n <code>button</code>\n</div>\n<div>-</div>\n<div>\n <code>primary</code>\n</div>\n<div>-</div>\n<div>-</div>\n<div>\n <code>bg</code>\n</div>\n<div>Bakgrunn på knapp</div>\n\n<div>\n <strong>\n <code>button-primary-fg</code>\n </strong>\n</div>\n<div>\n <code>button</code>\n</div>\n<div>-</div>\n<div>\n <code>primary</code>\n</div>\n<div>-</div>\n<div>-</div>\n<div>\n <code>fg</code>\n</div>\n<div>Tekst/Ikon på knapp</div>\n<div>\n <strong>\n <code>utility-success-fg</code>\n </strong>\n</div>\n<div>\n <code>utility</code>\n</div>\n<div>-</div>\n<div>-</div>\n<div>\n <code>success</code>\n</div>\n<div>-</div>\n<div>\n <code>fg</code>\n</div>\n<div>Tekstfarge for suksess</div>\n\n<div><strong><code>utility-success-hover-bg</code></strong></div>\n<div><code>utility</code></div>\n<div>-</div>\n<div>-</div>\n<div><code>success</code></div>\n<div><code>hover</code></div>\n<div><code>bg</code></div>\n<div>Bakgrunn ved hover</div>{' '}\n<div><strong><code>article-opinion-body-s</code></strong></div>\n <div><code>article</code></div>\n <div><code>opinion</code></div>\n <div>-</div>\n <div>-</div>\n <div>-</div>\n <div><code>body-s</code></div>\n <div>Brødtekst for opinion artikler i liten størrelse for mindre skjermer</div>\n</div>\n",
|
|
5
5
|
"themes": "import { Meta, Canvas, Source } from '@storybook/addon-docs/blocks';\nimport { BrickStyle } from './brickStyle.js';\n\n<Meta title=\"Brick Tokens/Documentation/Themes\" />\n\n<brick-style></brick-style>\n\n## Themes\n\nStyles are themeable using CSS Custom Properties.\n\nBrick ships currently 5 pre-built themes:\n\n- [Alfa](https://assets.acdn.no/pkg/@amedia/brick-tokens/5.7.2/css/theme-alfa.css)\n- [Bravo](https://assets.acdn.no/pkg/@amedia/brick-tokens/5.7.2/css/theme-bravo.css)\n- [Charlie](https://assets.acdn.no/pkg/@amedia/brick-tokens/5.7.2/css/theme-charlie.css)\n- [Nettavisen](https://assets.acdn.no/pkg/@amedia/brick-tokens/5.7.2/css/theme-nettavisen.css)\n- [Alt](https://assets.acdn.no/pkg/@amedia/brick-tokens/5.7.2/css/theme-alt.css)\n\nThemes are collections of design tokens, and the CSS Properties are scoped to a theme class. The design tokens **names** are the same across themes, but the value is unique for each theme.\n\nThis very page is using brick-tokens, and the theme Alfa!\n\n#### Example:\n\n<Source\n language=\"css\"\n dark=\"true\"\n code={`\n//Example\n.themeAlfa {\n --brick-colors-accesibilityFocusOutline:rgb(49, 111, 209);\n --brick-colors-baseBg:rgb(229, 229, 229);\n --brick-colors-baseDivider:rgb(89, 89, 89);\n --brick-colors-baseFg:rgb(41, 40, 39);\n }\n.themeOther {\n --brick-colors-accesibilityFocusOutline:hotpink;\n --brick-colors-baseBg:red;\n --brick-colors-baseDivider:black;\n --brick-colors-baseFg:purple;\n }\n `}\n/>\n\n### Usage\n\nUsing Brick’s themes is pretty straightforward.\n\nTo get started, add one of the following link tags to the `<head>` of your application:\n\n```\n<!-- Alfa theme -->\n<link rel=\"stylesheet\" href=\"https://assets.acdn.no/pkg/@amedia/brick-tokens/5.7.2/css/theme-alfa.css\" crossorigin=\"anonymous\" />\n<!-- Bravo theme -->\n<link rel=\"stylesheet\" href=\"https://assets.acdn.no/pkg/@amedia/brick-tokens/5.7.2/css/theme-bravo.css\" crossorigin=\"anonymous\" />\n<!-- Charlie theme -->\n<link rel=\"stylesheet\" href=\"https://assets.acdn.no/pkg/@amedia/brick-tokens/5.7.2/css/theme-charlie.css\" crossorigin=\"anonymous\" />\n<!-- Nettavisen theme -->\n<link rel=\"stylesheet\" href=\"https://assets.acdn.no/pkg/@amedia/brick-tokens/5.7.2/css/theme-nettavisen.css\" crossorigin=\"anonymous\" />\n<!-- ALT theme -->\n<link rel=\"stylesheet\" href=\"https://assets.acdn.no/pkg/@amedia/brick-tokens/5.7.2/css/theme-alt.css\" crossorigin=\"anonymous\" />\n```\n\n### How does it work?\n\nWhen the theme css file is loaded, you need to set the theme classname on a container, i.e the _body_ tag, since the theme is scoped to a classname.\n\nIt enables the use of multiple themes on the same page, even if there is one main theme for one page.\n\n<iframe\n height=\"300\"\n style={{ width: '100%' }}\n scrolling=\"no\"\n title=\"Untitled\"\n src=\"https://codepen.io/renatewr/embed/preview/MWRemoj?default-tab=html%2Cresult&editable=true\"\n loading=\"lazy\"\n allowtransparency=\"true\"\n allowFullScreen={true}\n>\n See the Pen <a href=\"https://codepen.io/renatewr/pen/MWRemoj\">Untitled</a> by\n Renate Winther Ravnaas (<a href=\"https://codepen.io/renatewr\">@renatewr</a>)\n on <a href=\"https://codepen.io\">CodePen</a>.\n</iframe>\n\n#### How to set correct theme classname?\n\n[brick-classnames](https://github.com/amedia/brick/tree/master/packages/brick-classnames) is a utility module to create CSS-safe strings from design names.\n\n### iOS\n\nFor use in iOS, the correct theme file can be loaded from `https://assets.acdn.no/pkg/@amedia/brick-tokens` for colors,spacing and radii.\nMore details at the [Formats page](?path=/docs/brick-tokens-documentation-formats--documentation#ios)\n",
|
|
6
6
|
"usage": "import { Meta, Canvas, Source } from '@storybook/addon-docs/blocks';\nimport { BrickStyle } from './brickStyle.js';\n\n<Meta title=\"Brick Tokens/Documentation/Usage\" />\n<brick-style></brick-style>\n\n# Usage\n\nUsage may differ between technoloies. The examples below are focusing on web.\n\n#### Existing Brick Components\n\nWhenever possible, leverage or enhance existing brick components within your web app.\n\n#### Use Design Tokens for styling\n\nStyling with this approach facilitates the automatic adaptation of variable values based on the theme.\n\nRead more about the different [formats](?path=/docs/brick-tokens-documentation-formats--documentation), the tokens available at the [tokens pages](?path=/story/brick-tokens-tokens--space), and how to use [themes](?path=/docs/brick-tokens-documentation-themes--documentation).\n\n<div class=\"note\">\n\n#### Need help?\n\nIn a perfect scenario, it is clear wich token names to use.\nIf you find yourself wondering what token to use, reach out at the [#designsystem](https://app.slack.com/client/T02568FUD/C01PVHPQMRN) channel, or at [GitHub discussion](https://github.com/amedia/brick/discussions/new?category=brick-tokens).\nYou'll likely encounter things that don't seem right, or are missing. Please share your experiences, or ideas.\n\n</div>\n\n#### Usage and implementation\n\n- The consuming page of your web app should load the appropriate theme file and apply the corresponding theme class to the container (e.g., the body tag).\n- It is important to note that the variables are scoped to the theme class, ensuring encapsulation and consistency within the designated theme.\n\nThe CSS variables are prefixed with `--brick`, and then the category, i.ei `-colors-`, before the name, i.e. `utilityPrimaryBg`.\n\n#### Example of css variables for theme Alfa:\n\n<Source\n language=\"html\"\n dark=\"true\"\n code={`\n https://assets.acdn.no/pkg/@amedia/brick-tokens/5.7.2/css/theme-alfa.css\n `}\n/>\n\nAn example use case could be that you wish to use spacing tokens to add some spacing:\n\n<Source\n language=\"css\"\n dark=\"true\"\n code={`\n .my-awesome-selector {\n padding: var(--brick-space-x1)\n }\n `}\n/>\n\nAnother use case could be that you need to apply color to an element:\n\n<Source\n language=\"html\"\n dark=\"true\"\n code={`<html>\n <head><link rel=\"stylesheet\" href=\"https://assets.acdn.no/pkg/@amedia/brick-tokens/5.7.2/css/theme-alfa.css\" /></head>\n <style>\n .my-awesome-selector {\n color: var(--brick-colors-baseFg);\n }\n </style>\n\n <body class=\"themeAlfa\">\n <div class=\"my-awesome-selector\">\n The color will be the value of the theme Alfa css variable named '--brick-colors-baseFg'\n </div>\n </body>\n</html>\n\n`}\n/>\n\n<iframe\n height=\"300\"\n style={{ width: '100%' }}\n scrolling=\"no\"\n title=\"Brick theming\"\n src=\"https://codepen.io/renatewr/embed/preview/MWRemoj?default-tab=css%2Cresult&editable=true\"\n loading=\"lazy\"\n allowtransparency=\"true\"\n allowFullScreen={true}\n>\n See the Pen{' '}\n <a href=\"https://codepen.io/renatewr/pen/MWRemoj\">Brick Theming</a> by Renate\n Winther Ravnaas (<a href=\"https://codepen.io/renatewr\">@renatewr</a>) on{' '}\n <a href=\"https://codepen.io\">CodePen</a>.\n</iframe>\n\n### iOS\n\nOn build time, the correct theme file for the specific token category can be loaded.\n\n- Swift files with radii and spacing tokens\n `https://assets.acdn.no/pkg/@amedia/brick-tokens/5.7.2/theme/alfa/ios/Radius.swift`\n `https://assets.acdn.no/pkg/@amedia/brick-tokens/5.7.2/theme/alfa/ios/Spacing.swift`\n\n- JSON files with colors:\n `https://assets.acdn.no/pkg/@amedia/brick-tokens/5.7.2/theme/bravo/ios/colors.json`\n\nhttps://github.com/amedia/brick/tree/master/packages/brick-tokens/build/style-dictionary/alfa/ios\n\n### Javascript/typescript\n\nEx:\n\nhttps://assets.acdn.no/pkg/@amedia/brick-tokens/5.7.2/theme/bravo/web/borderWidths.ts\n\n### CSS-in-JS\n\nbrick-tokens also exports `{css}` for using CSS-in-JS\n\nAt **the time of writing**, brick is using CSS-in-JS with Stitches under the hood.\nThis way you can style your custom components with the confidence that your styles should never clash.\nThere are pros and cons using CSS-in-JS and vanilla CSS, but that is out of scope of this documentation page.\n\n```css-in-js\nconst buttonCss = css({\n background-color: '$buttonPrimaryBackground';\n borderWidth: '1px', //token missing, talk to your designer\n borderStyle: 'solid',\n borderColor: '$buttonPrimaryBorder',\n ..\n '&:hover': {\n backgroundColor: '$buttonPrimaryBackgroundHover',\n color: '$buttonPrimaryTextHover',\n borderColor: '$buttonPrimaryBorderHover',\n },\n variants: {\n version: {\n secondary: {\n backgroundColor: '$buttonSecondaryBackground',\n '&:hover': {\n backgroundColor: '$buttonSecondaryBackgroundHover',\n },\n }\n },\n size: {\n large: {\n fontSize: 'clamp($mainButtonS, 0.4vw + 1rem, $mainButtonL)',\n }\n }\n\n }\n defaultVariants: {\n version: 'secondary',\n size: 'large'\n },\n compoundVariants: [\n {\n variant: 'secondary',\n size: 'small',\n css: {\n backgroundColor: '$someOtherToken',\n },\n },\n ],\n});\n})\n\n\n```\n\n#### Apply the css classname\n\n```css-in-js\n<div class=\"${getThemeByDesign('bravo')}\"> //main container\n...\n<button class=\"${buttonStyle({variant: 'primary'})}\">Primary</button>\n<button class=\"${buttonStyle({variant: 'secondary', outlined: true, size: 'large'})}\">Secondary Outlined</button>\n...\n</div>\n```\n\n#### Utils/shorthands\n\nUtils are like custom CSS properties, but allows us to group certain multiple CSS properties, or make shorthands.\nThe util takes one argument - the designtoken you normally would use on all the properties, excluding the '$' prefix.\n\nExample of the `fontstyle` util:\n\n```js\nconst myElementClass = css({\n fontstyle: 'titleXl',\n});\n```\n\nResult:\n\n```js\nconst myElementClass = css({\n fontFamily: `$titleXl`,\n fontSize: `$titleXl`,\n fontWeight: `$titleXl`,\n lineHeight: `$titleXl`,\n letterSpacing: `$titleXl`,\n }),\n\n```\n\n#### Utility classes\n\n`brick-tokens` have a few utility classes that can be used in any app or component that uses brick-tokens.\nThe purpose of these classes is to have easily accessible, reusable, and consistent naming for styling that would otherwise get repeated in multiple places.\n\nSome of these you can find in the `utility` object in **stitches.ts** and can be used directly through the [css](https://stitches.dev/docs/api#css) method.\nOthers are exported outside this object and needs to be imported alongside css, for example like this: \n`import {css, sroStyle} from '@amedia/brick-tokens'`\n\nAnd you would use it like this: \n`<div class\"${sroStyle()}\"></div> `\n"
|
|
7
|
-
}
|
|
7
|
+
}
|
package/data/tokens.json
CHANGED
|
@@ -1,46 +1,57 @@
|
|
|
1
1
|
[
|
|
2
2
|
{
|
|
3
3
|
"name": "brick-alt-teaser",
|
|
4
|
-
"version": "8.0.
|
|
4
|
+
"version": "8.0.70",
|
|
5
5
|
"selector": "brick-alt-teaser-v8",
|
|
6
6
|
"category": "Display",
|
|
7
|
-
"tags": [
|
|
7
|
+
"tags": [
|
|
8
|
+
"display"
|
|
9
|
+
]
|
|
8
10
|
},
|
|
9
11
|
{
|
|
10
12
|
"name": "brick-avatar",
|
|
11
|
-
"version": "0.2.
|
|
13
|
+
"version": "0.2.42",
|
|
12
14
|
"selector": "brick-avatar-v0",
|
|
13
15
|
"description": "brick-avatar component",
|
|
14
16
|
"category": "Display",
|
|
15
|
-
"tags": [
|
|
17
|
+
"tags": [
|
|
18
|
+
"display"
|
|
19
|
+
]
|
|
16
20
|
},
|
|
17
21
|
{
|
|
18
22
|
"name": "brick-button",
|
|
19
|
-
"version": "9.3.
|
|
23
|
+
"version": "9.3.6",
|
|
20
24
|
"selector": "brick-button-v9",
|
|
21
25
|
"category": "Forms",
|
|
22
|
-
"tags": [
|
|
26
|
+
"tags": [
|
|
27
|
+
"forms",
|
|
28
|
+
"interactive"
|
|
29
|
+
]
|
|
23
30
|
},
|
|
24
31
|
{
|
|
25
32
|
"name": "brick-byline",
|
|
26
|
-
"version": "1.0.
|
|
33
|
+
"version": "1.0.2",
|
|
27
34
|
"selector": "brick-byline-v1",
|
|
28
35
|
"description": "brick-byline component"
|
|
29
36
|
},
|
|
30
37
|
{
|
|
31
38
|
"name": "brick-card",
|
|
32
|
-
"version": "7.3.
|
|
39
|
+
"version": "7.3.13",
|
|
33
40
|
"selector": "brick-card-v7",
|
|
34
41
|
"category": "Layout",
|
|
35
|
-
"tags": [
|
|
42
|
+
"tags": [
|
|
43
|
+
"layout"
|
|
44
|
+
]
|
|
36
45
|
},
|
|
37
46
|
{
|
|
38
47
|
"name": "brick-carousel",
|
|
39
|
-
"version": "2.2.
|
|
48
|
+
"version": "2.2.2",
|
|
40
49
|
"selector": "brick-carousel-v2",
|
|
41
50
|
"description": "Simple carousel for any content passed to it.",
|
|
42
51
|
"category": "Display",
|
|
43
|
-
"tags": [
|
|
52
|
+
"tags": [
|
|
53
|
+
"display"
|
|
54
|
+
]
|
|
44
55
|
},
|
|
45
56
|
{
|
|
46
57
|
"name": "brick-classnames",
|
|
@@ -48,25 +59,29 @@
|
|
|
48
59
|
"selector": "brick-classnames-v2",
|
|
49
60
|
"description": "Utility method to create a safe string from a design name",
|
|
50
61
|
"category": "Utilities",
|
|
51
|
-
"tags": [
|
|
62
|
+
"tags": [
|
|
63
|
+
"utilities"
|
|
64
|
+
]
|
|
52
65
|
},
|
|
53
66
|
{
|
|
54
67
|
"name": "brick-countdown",
|
|
55
|
-
"version": "2.0.
|
|
68
|
+
"version": "2.0.14",
|
|
56
69
|
"selector": "brick-countdown-v2",
|
|
57
70
|
"description": "brick-countdown component"
|
|
58
71
|
},
|
|
59
72
|
{
|
|
60
73
|
"name": "brick-dialog",
|
|
61
|
-
"version": "2.0.
|
|
74
|
+
"version": "2.0.18",
|
|
62
75
|
"selector": "brick-dialog-v2",
|
|
63
76
|
"description": "brick-dialog component",
|
|
64
77
|
"category": "Feedback",
|
|
65
|
-
"tags": [
|
|
78
|
+
"tags": [
|
|
79
|
+
"feedback"
|
|
80
|
+
]
|
|
66
81
|
},
|
|
67
82
|
{
|
|
68
83
|
"name": "brick-expand",
|
|
69
|
-
"version": "0.0.
|
|
84
|
+
"version": "0.0.4",
|
|
70
85
|
"selector": "brick-expand-v0",
|
|
71
86
|
"description": "brick-expand component"
|
|
72
87
|
},
|
|
@@ -76,20 +91,24 @@
|
|
|
76
91
|
"selector": "brick-fonts-v2",
|
|
77
92
|
"description": "Distribution of font files",
|
|
78
93
|
"category": "Utilities",
|
|
79
|
-
"tags": [
|
|
94
|
+
"tags": [
|
|
95
|
+
"utilities"
|
|
96
|
+
]
|
|
80
97
|
},
|
|
81
98
|
{
|
|
82
99
|
"name": "brick-helloworld",
|
|
83
|
-
"version": "2.0.
|
|
100
|
+
"version": "2.0.7",
|
|
84
101
|
"selector": "brick-helloworld-v2",
|
|
85
102
|
"description": "Brick Hello World component"
|
|
86
103
|
},
|
|
87
104
|
{
|
|
88
105
|
"name": "brick-icon",
|
|
89
|
-
"version": "2.3.
|
|
106
|
+
"version": "2.3.6",
|
|
90
107
|
"selector": "brick-icon-v2",
|
|
91
108
|
"category": "Display",
|
|
92
|
-
"tags": [
|
|
109
|
+
"tags": [
|
|
110
|
+
"display"
|
|
111
|
+
]
|
|
93
112
|
},
|
|
94
113
|
{
|
|
95
114
|
"name": "brick-illustrations",
|
|
@@ -99,18 +118,23 @@
|
|
|
99
118
|
},
|
|
100
119
|
{
|
|
101
120
|
"name": "brick-image",
|
|
102
|
-
"version": "6.0.
|
|
121
|
+
"version": "6.0.10",
|
|
103
122
|
"selector": "brick-image-v6",
|
|
104
123
|
"category": "Display",
|
|
105
|
-
"tags": [
|
|
124
|
+
"tags": [
|
|
125
|
+
"display"
|
|
126
|
+
]
|
|
106
127
|
},
|
|
107
128
|
{
|
|
108
129
|
"name": "brick-input",
|
|
109
|
-
"version": "3.0.
|
|
130
|
+
"version": "3.0.14",
|
|
110
131
|
"selector": "brick-input-v3",
|
|
111
132
|
"description": "brick-input component",
|
|
112
133
|
"category": "Forms",
|
|
113
|
-
"tags": [
|
|
134
|
+
"tags": [
|
|
135
|
+
"forms",
|
|
136
|
+
"interactive"
|
|
137
|
+
]
|
|
114
138
|
},
|
|
115
139
|
{
|
|
116
140
|
"name": "brick-nifs",
|
|
@@ -120,80 +144,88 @@
|
|
|
120
144
|
},
|
|
121
145
|
{
|
|
122
146
|
"name": "brick-pill",
|
|
123
|
-
"version": "9.0.
|
|
147
|
+
"version": "9.0.7",
|
|
124
148
|
"selector": "brick-pill-v9"
|
|
125
149
|
},
|
|
126
150
|
{
|
|
127
151
|
"name": "brick-player",
|
|
128
|
-
"version": "1.27.
|
|
152
|
+
"version": "1.27.22",
|
|
129
153
|
"selector": "brick-player-v1",
|
|
130
154
|
"description": "Component for playing video and audio files"
|
|
131
155
|
},
|
|
132
156
|
{
|
|
133
157
|
"name": "brick-published",
|
|
134
|
-
"version": "4.0.
|
|
158
|
+
"version": "4.0.6",
|
|
135
159
|
"selector": "brick-published-v4",
|
|
136
160
|
"description": "brick-published"
|
|
137
161
|
},
|
|
138
162
|
{
|
|
139
163
|
"name": "brick-share",
|
|
140
|
-
"version": "0.3.
|
|
164
|
+
"version": "0.3.9",
|
|
141
165
|
"selector": "brick-share-v0",
|
|
142
166
|
"description": "brick-share component"
|
|
143
167
|
},
|
|
144
168
|
{
|
|
145
169
|
"name": "brick-stepper",
|
|
146
|
-
"version": "1.0.
|
|
170
|
+
"version": "1.0.16",
|
|
147
171
|
"selector": "brick-stepper-v1",
|
|
148
172
|
"description": "brick-stepper component"
|
|
149
173
|
},
|
|
150
174
|
{
|
|
151
175
|
"name": "brick-tab",
|
|
152
|
-
"version": "0.1.
|
|
176
|
+
"version": "0.1.13",
|
|
153
177
|
"selector": "brick-tab-v0",
|
|
154
178
|
"description": "brick-tab component"
|
|
155
179
|
},
|
|
156
180
|
{
|
|
157
181
|
"name": "brick-tabs",
|
|
158
|
-
"version": "0.1.
|
|
182
|
+
"version": "0.1.14",
|
|
159
183
|
"selector": "brick-tabs-v0",
|
|
160
184
|
"description": "brick-tabs component handling tablist, tabs and tabpanel",
|
|
161
185
|
"category": "Navigation",
|
|
162
|
-
"tags": [
|
|
186
|
+
"tags": [
|
|
187
|
+
"navigation"
|
|
188
|
+
]
|
|
163
189
|
},
|
|
164
190
|
{
|
|
165
191
|
"name": "brick-tag",
|
|
166
|
-
"version": "0.0.
|
|
192
|
+
"version": "0.0.13",
|
|
167
193
|
"selector": "brick-tag-v0",
|
|
168
194
|
"description": "brick-tag component"
|
|
169
195
|
},
|
|
170
196
|
{
|
|
171
197
|
"name": "brick-teaser",
|
|
172
|
-
"version": "20.0
|
|
198
|
+
"version": "20.1.0",
|
|
173
199
|
"selector": "brick-teaser-v20",
|
|
174
200
|
"description": "Teaser component.",
|
|
175
201
|
"category": "Display",
|
|
176
|
-
"tags": [
|
|
202
|
+
"tags": [
|
|
203
|
+
"display"
|
|
204
|
+
]
|
|
177
205
|
},
|
|
178
206
|
{
|
|
179
207
|
"name": "brick-teaser-player",
|
|
180
|
-
"version": "1.0.
|
|
208
|
+
"version": "1.0.28",
|
|
181
209
|
"selector": "brick-teaser-player-v1",
|
|
182
210
|
"description": "brick-video-teaser component",
|
|
183
211
|
"category": "Display",
|
|
184
|
-
"tags": [
|
|
212
|
+
"tags": [
|
|
213
|
+
"display"
|
|
214
|
+
]
|
|
185
215
|
},
|
|
186
216
|
{
|
|
187
217
|
"name": "brick-teaser-reels",
|
|
188
|
-
"version": "0.4.
|
|
218
|
+
"version": "0.4.2",
|
|
189
219
|
"selector": "brick-teaser-reels-v0",
|
|
190
220
|
"description": "brick-teaser-reels component",
|
|
191
221
|
"category": "Display",
|
|
192
|
-
"tags": [
|
|
222
|
+
"tags": [
|
|
223
|
+
"display"
|
|
224
|
+
]
|
|
193
225
|
},
|
|
194
226
|
{
|
|
195
227
|
"name": "brick-textarea",
|
|
196
|
-
"version": "2.0.
|
|
228
|
+
"version": "2.0.9",
|
|
197
229
|
"selector": "brick-textarea-v2",
|
|
198
230
|
"description": "brick-textarea component"
|
|
199
231
|
},
|
|
@@ -205,30 +237,34 @@
|
|
|
205
237
|
},
|
|
206
238
|
{
|
|
207
239
|
"name": "brick-toast",
|
|
208
|
-
"version": "0.1.
|
|
240
|
+
"version": "0.1.25",
|
|
209
241
|
"selector": "brick-toast-v0",
|
|
210
242
|
"description": "brick-toast component",
|
|
211
243
|
"category": "Feedback",
|
|
212
|
-
"tags": [
|
|
244
|
+
"tags": [
|
|
245
|
+
"feedback"
|
|
246
|
+
]
|
|
213
247
|
},
|
|
214
248
|
{
|
|
215
249
|
"name": "brick-toggle",
|
|
216
|
-
"version": "3.1.
|
|
250
|
+
"version": "3.1.12",
|
|
217
251
|
"selector": "brick-toggle-v3",
|
|
218
252
|
"description": "brick-toggle component"
|
|
219
253
|
},
|
|
220
254
|
{
|
|
221
255
|
"name": "brick-tokens",
|
|
222
|
-
"version": "5.
|
|
256
|
+
"version": "5.21.0",
|
|
223
257
|
"selector": "brick-tokens-v5",
|
|
224
258
|
"description": "Tokens package",
|
|
225
259
|
"category": "Utilities",
|
|
226
|
-
"tags": [
|
|
260
|
+
"tags": [
|
|
261
|
+
"utilities"
|
|
262
|
+
]
|
|
227
263
|
},
|
|
228
264
|
{
|
|
229
265
|
"name": "brick-tooltip",
|
|
230
|
-
"version": "1.0.
|
|
266
|
+
"version": "1.0.15",
|
|
231
267
|
"selector": "brick-tooltip-v1",
|
|
232
268
|
"description": "brick-tooltip component"
|
|
233
269
|
}
|
|
234
|
-
]
|
|
270
|
+
]
|
|
@@ -4,4 +4,4 @@
|
|
|
4
4
|
"naming": "import { Meta, Canvas, Source } from '@storybook/addon-docs/blocks';\nimport { BrickStyle } from './brickStyle.js';\nimport Repo from './assets/repo.svg';\nimport Open from './assets/open.svg';\n\n<Meta title=\"Brick Tokens/Documentation/Naming\" />\n\n<brick-style></brick-style>\n\n# Naming\n\nA design token name in Figma can be transformed into different shapes based on the format.\nSee all the tokens available at the [tokens pages](?path=/story/brick-tokens-tokens--space)\n\n## Naming Conventions and examples\n\nDue to varying naming conventions and requirements across technologies, the naming format in **code** can differ.\n\nBelow are two examples illustrating the transformation of names into different formats:\n\n### Figma names:\n\n- `color.utility.primary.bg`\n- `spacing.x1`\n\n### CSS variable\n\n<Source\n language=\"css\"\n dark=\"true\"\n code={`\ncolor: var(--brick-colors-utilityPrimaryBg);\npadding: var(--brick-spacing-x1);\n `}\n/>\n\n### CSS-in-JS\n\nDeprecated - use css variables instead\n\n<Source\n language=\"javascript\"\n dark=\"true\"\n code={`\nconst heading = css({\n color: '$utilityPrimaryBg', //translates to 'var(--brick-colors-primaryBg)'\n padding:'$x1' //translates to 'var(--brick-spacing-x1)''\n})\n `}\n/>\n\n### For iOS\n\n**Spacing.swift**\n\n<Source\n language=\"other\"\n dark=\"true\"\n code={`\n //Example of name/value in the Spacing.swift file\nstruct Spacing {\n\tstatic let x1 : CGFloat = 5\n }\n `}\n/>\n\n**colors.json**\n\n<Source\n language=\"other\"\n dark=\"true\"\n code={`\n //Example of name/value in the colors.json file\n{\n \"color_utility_primary_fg\": \"#292827\",\n}\n `}\n/>\n\n## The taxonomy behind the names in themes\n\nWe need names that makes it as easy as possible to understand what the token should be used for, and when.\n\nGood names are predictable, unique, and understandable across disciplines.\n\nWhat is semantic to one, might not be semantic to a coworker. We need to agree on a common vocabulary.\n\nIn our themes, the design tokens are made up of semantic attributes that together form the token name. This ensures scalability and consistency. It covers both simple and more complex naming.\n\n<div className=\"token-name-steps\">\n <span className=\"step\">\n <strong>Scope*</strong>\n </span>\n <span>─</span>\n <span className=\"step\">\n <strong>[Context]</strong>\n </span>\n <span>─</span>\n <span className=\"step\">\n <strong>[Prominence]</strong>\n </span>\n <span>─</span>\n <span className=\"step\">\n <strong>[Sentiment]</strong>\n </span>\n <span>─</span>\n <span className=\"step\">\n <strong>[State]</strong>\n </span>\n <span></span>\n <span className=\"step\">\n <strong>Usage*</strong>\n </span>\n</div>\n*required parts. The optional parts are enclosed in brackets [].{' '}\n\n<div class=\"token-name-parts\">\n<div class=\"token-name-part\">\n **Scope**: \"Omfang\" The broadest category of the token, indicating its general\n purpose.\n Definerer hvilket \"navnerom\" tokenet tilhører.\n <ul>\n <li>\n <code>base</code>: General scope.\n </li>\n <li>\n <code>utility</code>: Interaction colors used for status messages and alerts.\n </li>\n <li>\n <code>supportive</code>: Supportive colors used in a theme on different elements\n </li>\n <li>\n <code>button</code>, <code>article</code>, <code>expand</code>:\n Component specific scope.\n </li>\n </ul>\n</div>\n\n<div class=\"token-name-part\">\n **[Context]**: Optional. Further refines the scope by specifying the\n particular area or genre the token applies to.\n <ul>\n <li>\n <code>opinion</code>, <code>reel</code>, <code>finance</code>,\n <code>lifestyle</code>\n </li>\n </ul>\n</div>\n\n<div class=\"token-name-part\">\n **[Prominence]** (Visuell Vekt) Optional. Describes the visual importance or\n emphasis of the element.\n <ul>\n <li>\n <code>primary</code>, <code>secondary</code>, <code>subtle</code>\n </li>\n </ul>\n</div>\n\n<div class=\"token-name-part\">\n **[Sentiment]**[ (Budskap/Status) Optional. Describes the emotional tone or\n status\n <ul>\n <li>\n <code>success</code>, <code>error</code>, <code>warning</code>,\n <code>breaking</code>, <code>live</code>, <code>beta</code>,\n <code>new</code>\n </li>\n </ul>\n</div>\n\n<div class=\"token-name-part\">\n **[State]** (Tilstand) Optional. Describes the interaction state of the\n element.\n <ul>\n <li>\n <code>hover</code>, <code>active</code>, <code>focus</code>,\n <code>disabled</code>\n </li>\n </ul>\n</div>\n\n<div class=\"token-name-part\">\n**Usage** (Bruk) Obligatorisk. Describing what the design decision applies to. If it is a color, it might be \"bg\", but if it is typography it might be \"body-s\" or \"heading-m\", including size to be responsive.\n <ul>\n <li>\n <code>bg</code>, <code>fg</code>, <code>border</code>, <code>body-s</code>, <code>heading-xl</code>\n </li>\n </ul>\n\n</div>\n</div>\n\n<div className=\"token-taxonomy-table\">\n <div>Token Navn</div>\n <div>Scope</div>\n <div>Context</div>\n <div>Prominence</div>\n <div>Sentiment</div>\n <div>State</div>\n <div>Usage</div>\n <div>Forklaring</div>\n\n<div>\n <strong>\n <code>base-page-bg</code>\n </strong>\n</div>\n<div>\n <code>base</code>\n</div>\n<div>-</div>\n<div>-</div>\n<div>-</div>\n<div>-</div>\n<div>\n <code>page-bg</code>\n</div>\n<div>Sidebakgrunn</div>\n\n<div>\n <strong>\n <code>button-primary-bg</code>\n </strong>\n</div>\n<div>\n <code>button</code>\n</div>\n<div>-</div>\n<div>\n <code>primary</code>\n</div>\n<div>-</div>\n<div>-</div>\n<div>\n <code>bg</code>\n</div>\n<div>Bakgrunn på knapp</div>\n\n<div>\n <strong>\n <code>button-primary-fg</code>\n </strong>\n</div>\n<div>\n <code>button</code>\n</div>\n<div>-</div>\n<div>\n <code>primary</code>\n</div>\n<div>-</div>\n<div>-</div>\n<div>\n <code>fg</code>\n</div>\n<div>Tekst/Ikon på knapp</div>\n<div>\n <strong>\n <code>utility-success-fg</code>\n </strong>\n</div>\n<div>\n <code>utility</code>\n</div>\n<div>-</div>\n<div>-</div>\n<div>\n <code>success</code>\n</div>\n<div>-</div>\n<div>\n <code>fg</code>\n</div>\n<div>Tekstfarge for suksess</div>\n\n<div><strong><code>utility-success-hover-bg</code></strong></div>\n<div><code>utility</code></div>\n<div>-</div>\n<div>-</div>\n<div><code>success</code></div>\n<div><code>hover</code></div>\n<div><code>bg</code></div>\n<div>Bakgrunn ved hover</div>{' '}\n<div><strong><code>article-opinion-body-s</code></strong></div>\n <div><code>article</code></div>\n <div><code>opinion</code></div>\n <div>-</div>\n <div>-</div>\n <div>-</div>\n <div><code>body-s</code></div>\n <div>Brødtekst for opinion artikler i liten størrelse for mindre skjermer</div>\n</div>\n",
|
|
5
5
|
"themes": "import { Meta, Canvas, Source } from '@storybook/addon-docs/blocks';\nimport { BrickStyle } from './brickStyle.js';\n\n<Meta title=\"Brick Tokens/Documentation/Themes\" />\n\n<brick-style></brick-style>\n\n## Themes\n\nStyles are themeable using CSS Custom Properties.\n\nBrick ships currently 5 pre-built themes:\n\n- [Alfa](https://assets.acdn.no/pkg/@amedia/brick-tokens/5.7.2/css/theme-alfa.css)\n- [Bravo](https://assets.acdn.no/pkg/@amedia/brick-tokens/5.7.2/css/theme-bravo.css)\n- [Charlie](https://assets.acdn.no/pkg/@amedia/brick-tokens/5.7.2/css/theme-charlie.css)\n- [Nettavisen](https://assets.acdn.no/pkg/@amedia/brick-tokens/5.7.2/css/theme-nettavisen.css)\n- [Alt](https://assets.acdn.no/pkg/@amedia/brick-tokens/5.7.2/css/theme-alt.css)\n\nThemes are collections of design tokens, and the CSS Properties are scoped to a theme class. The design tokens **names** are the same across themes, but the value is unique for each theme.\n\nThis very page is using brick-tokens, and the theme Alfa!\n\n#### Example:\n\n<Source\n language=\"css\"\n dark=\"true\"\n code={`\n//Example\n.themeAlfa {\n --brick-colors-accesibilityFocusOutline:rgb(49, 111, 209);\n --brick-colors-baseBg:rgb(229, 229, 229);\n --brick-colors-baseDivider:rgb(89, 89, 89);\n --brick-colors-baseFg:rgb(41, 40, 39);\n }\n.themeOther {\n --brick-colors-accesibilityFocusOutline:hotpink;\n --brick-colors-baseBg:red;\n --brick-colors-baseDivider:black;\n --brick-colors-baseFg:purple;\n }\n `}\n/>\n\n### Usage\n\nUsing Brick’s themes is pretty straightforward.\n\nTo get started, add one of the following link tags to the `<head>` of your application:\n\n```\n<!-- Alfa theme -->\n<link rel=\"stylesheet\" href=\"https://assets.acdn.no/pkg/@amedia/brick-tokens/5.7.2/css/theme-alfa.css\" crossorigin=\"anonymous\" />\n<!-- Bravo theme -->\n<link rel=\"stylesheet\" href=\"https://assets.acdn.no/pkg/@amedia/brick-tokens/5.7.2/css/theme-bravo.css\" crossorigin=\"anonymous\" />\n<!-- Charlie theme -->\n<link rel=\"stylesheet\" href=\"https://assets.acdn.no/pkg/@amedia/brick-tokens/5.7.2/css/theme-charlie.css\" crossorigin=\"anonymous\" />\n<!-- Nettavisen theme -->\n<link rel=\"stylesheet\" href=\"https://assets.acdn.no/pkg/@amedia/brick-tokens/5.7.2/css/theme-nettavisen.css\" crossorigin=\"anonymous\" />\n<!-- ALT theme -->\n<link rel=\"stylesheet\" href=\"https://assets.acdn.no/pkg/@amedia/brick-tokens/5.7.2/css/theme-alt.css\" crossorigin=\"anonymous\" />\n```\n\n### How does it work?\n\nWhen the theme css file is loaded, you need to set the theme classname on a container, i.e the _body_ tag, since the theme is scoped to a classname.\n\nIt enables the use of multiple themes on the same page, even if there is one main theme for one page.\n\n<iframe\n height=\"300\"\n style={{ width: '100%' }}\n scrolling=\"no\"\n title=\"Untitled\"\n src=\"https://codepen.io/renatewr/embed/preview/MWRemoj?default-tab=html%2Cresult&editable=true\"\n loading=\"lazy\"\n allowtransparency=\"true\"\n allowFullScreen={true}\n>\n See the Pen <a href=\"https://codepen.io/renatewr/pen/MWRemoj\">Untitled</a> by\n Renate Winther Ravnaas (<a href=\"https://codepen.io/renatewr\">@renatewr</a>)\n on <a href=\"https://codepen.io\">CodePen</a>.\n</iframe>\n\n#### How to set correct theme classname?\n\n[brick-classnames](https://github.com/amedia/brick/tree/master/packages/brick-classnames) is a utility module to create CSS-safe strings from design names.\n\n### iOS\n\nFor use in iOS, the correct theme file can be loaded from `https://assets.acdn.no/pkg/@amedia/brick-tokens` for colors,spacing and radii.\nMore details at the [Formats page](?path=/docs/brick-tokens-documentation-formats--documentation#ios)\n",
|
|
6
6
|
"usage": "import { Meta, Canvas, Source } from '@storybook/addon-docs/blocks';\nimport { BrickStyle } from './brickStyle.js';\n\n<Meta title=\"Brick Tokens/Documentation/Usage\" />\n<brick-style></brick-style>\n\n# Usage\n\nUsage may differ between technoloies. The examples below are focusing on web.\n\n#### Existing Brick Components\n\nWhenever possible, leverage or enhance existing brick components within your web app.\n\n#### Use Design Tokens for styling\n\nStyling with this approach facilitates the automatic adaptation of variable values based on the theme.\n\nRead more about the different [formats](?path=/docs/brick-tokens-documentation-formats--documentation), the tokens available at the [tokens pages](?path=/story/brick-tokens-tokens--space), and how to use [themes](?path=/docs/brick-tokens-documentation-themes--documentation).\n\n<div class=\"note\">\n\n#### Need help?\n\nIn a perfect scenario, it is clear wich token names to use.\nIf you find yourself wondering what token to use, reach out at the [#designsystem](https://app.slack.com/client/T02568FUD/C01PVHPQMRN) channel, or at [GitHub discussion](https://github.com/amedia/brick/discussions/new?category=brick-tokens).\nYou'll likely encounter things that don't seem right, or are missing. Please share your experiences, or ideas.\n\n</div>\n\n#### Usage and implementation\n\n- The consuming page of your web app should load the appropriate theme file and apply the corresponding theme class to the container (e.g., the body tag).\n- It is important to note that the variables are scoped to the theme class, ensuring encapsulation and consistency within the designated theme.\n\nThe CSS variables are prefixed with `--brick`, and then the category, i.ei `-colors-`, before the name, i.e. `utilityPrimaryBg`.\n\n#### Example of css variables for theme Alfa:\n\n<Source\n language=\"html\"\n dark=\"true\"\n code={`\n https://assets.acdn.no/pkg/@amedia/brick-tokens/5.7.2/css/theme-alfa.css\n `}\n/>\n\nAn example use case could be that you wish to use spacing tokens to add some spacing:\n\n<Source\n language=\"css\"\n dark=\"true\"\n code={`\n .my-awesome-selector {\n padding: var(--brick-space-x1)\n }\n `}\n/>\n\nAnother use case could be that you need to apply color to an element:\n\n<Source\n language=\"html\"\n dark=\"true\"\n code={`<html>\n <head><link rel=\"stylesheet\" href=\"https://assets.acdn.no/pkg/@amedia/brick-tokens/5.7.2/css/theme-alfa.css\" /></head>\n <style>\n .my-awesome-selector {\n color: var(--brick-colors-baseFg);\n }\n </style>\n\n <body class=\"themeAlfa\">\n <div class=\"my-awesome-selector\">\n The color will be the value of the theme Alfa css variable named '--brick-colors-baseFg'\n </div>\n </body>\n</html>\n\n`}\n/>\n\n<iframe\n height=\"300\"\n style={{ width: '100%' }}\n scrolling=\"no\"\n title=\"Brick theming\"\n src=\"https://codepen.io/renatewr/embed/preview/MWRemoj?default-tab=css%2Cresult&editable=true\"\n loading=\"lazy\"\n allowtransparency=\"true\"\n allowFullScreen={true}\n>\n See the Pen{' '}\n <a href=\"https://codepen.io/renatewr/pen/MWRemoj\">Brick Theming</a> by Renate\n Winther Ravnaas (<a href=\"https://codepen.io/renatewr\">@renatewr</a>) on{' '}\n <a href=\"https://codepen.io\">CodePen</a>.\n</iframe>\n\n### iOS\n\nOn build time, the correct theme file for the specific token category can be loaded.\n\n- Swift files with radii and spacing tokens\n `https://assets.acdn.no/pkg/@amedia/brick-tokens/5.7.2/theme/alfa/ios/Radius.swift`\n `https://assets.acdn.no/pkg/@amedia/brick-tokens/5.7.2/theme/alfa/ios/Spacing.swift`\n\n- JSON files with colors:\n `https://assets.acdn.no/pkg/@amedia/brick-tokens/5.7.2/theme/bravo/ios/colors.json`\n\nhttps://github.com/amedia/brick/tree/master/packages/brick-tokens/build/style-dictionary/alfa/ios\n\n### Javascript/typescript\n\nEx:\n\nhttps://assets.acdn.no/pkg/@amedia/brick-tokens/5.7.2/theme/bravo/web/borderWidths.ts\n\n### CSS-in-JS\n\nbrick-tokens also exports `{css}` for using CSS-in-JS\n\nAt **the time of writing**, brick is using CSS-in-JS with Stitches under the hood.\nThis way you can style your custom components with the confidence that your styles should never clash.\nThere are pros and cons using CSS-in-JS and vanilla CSS, but that is out of scope of this documentation page.\n\n```css-in-js\nconst buttonCss = css({\n background-color: '$buttonPrimaryBackground';\n borderWidth: '1px', //token missing, talk to your designer\n borderStyle: 'solid',\n borderColor: '$buttonPrimaryBorder',\n ..\n '&:hover': {\n backgroundColor: '$buttonPrimaryBackgroundHover',\n color: '$buttonPrimaryTextHover',\n borderColor: '$buttonPrimaryBorderHover',\n },\n variants: {\n version: {\n secondary: {\n backgroundColor: '$buttonSecondaryBackground',\n '&:hover': {\n backgroundColor: '$buttonSecondaryBackgroundHover',\n },\n }\n },\n size: {\n large: {\n fontSize: 'clamp($mainButtonS, 0.4vw + 1rem, $mainButtonL)',\n }\n }\n\n }\n defaultVariants: {\n version: 'secondary',\n size: 'large'\n },\n compoundVariants: [\n {\n variant: 'secondary',\n size: 'small',\n css: {\n backgroundColor: '$someOtherToken',\n },\n },\n ],\n});\n})\n\n\n```\n\n#### Apply the css classname\n\n```css-in-js\n<div class=\"${getThemeByDesign('bravo')}\"> //main container\n...\n<button class=\"${buttonStyle({variant: 'primary'})}\">Primary</button>\n<button class=\"${buttonStyle({variant: 'secondary', outlined: true, size: 'large'})}\">Secondary Outlined</button>\n...\n</div>\n```\n\n#### Utils/shorthands\n\nUtils are like custom CSS properties, but allows us to group certain multiple CSS properties, or make shorthands.\nThe util takes one argument - the designtoken you normally would use on all the properties, excluding the '$' prefix.\n\nExample of the `fontstyle` util:\n\n```js\nconst myElementClass = css({\n fontstyle: 'titleXl',\n});\n```\n\nResult:\n\n```js\nconst myElementClass = css({\n fontFamily: `$titleXl`,\n fontSize: `$titleXl`,\n fontWeight: `$titleXl`,\n lineHeight: `$titleXl`,\n letterSpacing: `$titleXl`,\n }),\n\n```\n\n#### Utility classes\n\n`brick-tokens` have a few utility classes that can be used in any app or component that uses brick-tokens.\nThe purpose of these classes is to have easily accessible, reusable, and consistent naming for styling that would otherwise get repeated in multiple places.\n\nSome of these you can find in the `utility` object in **stitches.ts** and can be used directly through the [css](https://stitches.dev/docs/api#css) method.\nOthers are exported outside this object and needs to be imported alongside css, for example like this: \n`import {css, sroStyle} from '@amedia/brick-tokens'`\n\nAnd you would use it like this: \n`<div class\"${sroStyle()}\"></div> `\n"
|
|
7
|
-
}
|
|
7
|
+
}
|
package/dist/data/tokens.json
CHANGED
package/dist/http.js
CHANGED
|
@@ -195,9 +195,9 @@ function createServer() {
|
|
|
195
195
|
{
|
|
196
196
|
title: "List Brick Components",
|
|
197
197
|
description: "List all available Brick components with metadata. Optionally filter by category, tag, or name.",
|
|
198
|
-
inputSchema: {
|
|
198
|
+
inputSchema: z.object({
|
|
199
199
|
filter: z.string().optional().describe("Optional filter by category, tag, or name")
|
|
200
|
-
}
|
|
200
|
+
})
|
|
201
201
|
},
|
|
202
202
|
async ({ filter }) => {
|
|
203
203
|
const result = await listComponents({ filter });
|
|
@@ -216,11 +216,11 @@ function createServer() {
|
|
|
216
216
|
{
|
|
217
217
|
title: "Get Component Documentation",
|
|
218
218
|
description: "Retrieve detailed documentation for specific Brick component(s) including props, events, examples, and accessibility information.",
|
|
219
|
-
inputSchema: {
|
|
219
|
+
inputSchema: z.object({
|
|
220
220
|
components: z.array(z.string()).describe(
|
|
221
221
|
'Array of component names (e.g., ["brick-button", "brick-modal"])'
|
|
222
222
|
)
|
|
223
|
-
}
|
|
223
|
+
})
|
|
224
224
|
},
|
|
225
225
|
async ({ components }) => {
|
|
226
226
|
const result = await getComponentDocs({ components });
|
|
@@ -239,11 +239,13 @@ function createServer() {
|
|
|
239
239
|
{
|
|
240
240
|
title: "Get Design Tokens",
|
|
241
241
|
description: "Access design tokens from brick-tokens. Optionally filter by category (colors, spacing, typography, shadows, borders).",
|
|
242
|
-
inputSchema: {
|
|
242
|
+
inputSchema: z.object({
|
|
243
243
|
category: z.enum(["colors", "spacing", "typography", "shadows", "borders"]).optional().describe("Filter tokens by category")
|
|
244
|
-
}
|
|
244
|
+
})
|
|
245
245
|
},
|
|
246
|
-
async ({
|
|
246
|
+
async ({
|
|
247
|
+
category
|
|
248
|
+
}) => {
|
|
247
249
|
const result = await getDesignTokens({ category });
|
|
248
250
|
return {
|
|
249
251
|
content: [
|
package/dist/http.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/http.ts", "../src/server.ts", "../src/tools/getComponentDocs.ts", "../src/utils/dataPath.ts", "../src/extractors/packageScanner.ts", "../src/tools/getDesignTokens.ts", "../src/tools/listComponents.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * HTTP server entry point for local development only\n * Uses Fastify and SSE transport for MCP communication\n */\n\nimport cors from '@fastify/cors';\nimport { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';\nimport Fastify from 'fastify';\n\nimport { createServer } from './server.ts';\n\nconst PORT = 3000;\nconst HOST = 'localhost';\n\nconst fastify = Fastify({\n logger: {\n level: 'info',\n },\n});\n\n// Store active transports and servers by sessionId\nconst activeTransports = new Map<string, SSEServerTransport>();\nconst activeMcpServers = new Map<string, ReturnType<typeof createServer>>();\n\n// Enable CORS for local development\nawait fastify.register(cors, {\n origin: true,\n credentials: true,\n});\n\n// Health check endpoint\nfastify.get('/health', async () => {\n return { status: 'ok' };\n});\n\n// SSE endpoint for MCP communication\nfastify.get('/sse', async (_request, reply) => {\n // Prevent Fastify from automatically sending a response\n reply.hijack();\n\n // Create a new MCP server instance for this connection\n const mcpServer = createServer();\n\n // Create SSE transport (this will handle headers internally)\n const transport = new SSEServerTransport('/message', reply.raw);\n\n // Handle the SSE connection (this calls transport.start() which writes headers)\n await mcpServer.connect(transport);\n\n // Store the transport and server by sessionId for POST message handling\n // The sessionId is available after the transport starts via the public getter\n const sessionId = transport.sessionId;\n activeTransports.set(sessionId, transport);\n activeMcpServers.set(sessionId, mcpServer);\n\n // Clean up when the connection closes\n reply.raw.on('close', async () => {\n activeTransports.delete(sessionId);\n const server = activeMcpServers.get(sessionId);\n if (server) {\n await server.close();\n activeMcpServers.delete(sessionId);\n }\n });\n});\n\n// POST endpoint for messages\nfastify.post<{\n Querystring: { sessionId: string };\n}>('/message', async (request, reply) => {\n // Prevent Fastify from automatically sending a response\n reply.hijack();\n\n // Extract sessionId from query parameters (now properly typed)\n const { sessionId } = request.query;\n\n // Find the transport for this session\n const transport = activeTransports.get(sessionId);\n\n if (!transport) {\n reply.raw.writeHead(404, { 'Content-Type': 'application/json' });\n reply.raw.end(JSON.stringify({ error: 'Session not found' }));\n return;\n }\n\n // Let the transport handle the POST message\n await transport.handlePostMessage(request.raw, reply.raw, request.body);\n});\n\n// Start the server\ntry {\n await fastify.listen({ port: PORT, host: HOST });\n console.log(`Brick MCP HTTP server listening on http://${HOST}:${PORT}`);\n console.log(`SSE endpoint: http://${HOST}:${PORT}/sse`);\n} catch (err) {\n fastify.log.error(err);\n process.exit(1);\n}\n", "/**\n * MCP server setup and registration\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\n\nimport { getComponentDocs } from './tools/getComponentDocs.ts';\nimport { getDesignTokens } from './tools/getDesignTokens.ts';\nimport { listComponents } from './tools/listComponents.ts';\n\n/**\n * Create and configure the MCP server\n */\nexport function createServer(): McpServer {\n // Create an MCP server\n const server = new McpServer({\n name: 'brick-design-system',\n version: '1.0.0',\n });\n\n // Register list-components tool\n server.registerTool(\n 'list-components',\n {\n title: 'List Brick Components',\n description:\n 'List all available Brick components with metadata. Optionally filter by category, tag, or name.',\n inputSchema: {\n filter: z\n .string()\n .optional()\n .describe('Optional filter by category, tag, or name'),\n },\n },\n async ({ filter }) => {\n const result = await listComponents({ filter });\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n }\n );\n\n // Register get-component-docs tool\n server.registerTool(\n 'get-component-docs',\n {\n title: 'Get Component Documentation',\n description:\n 'Retrieve detailed documentation for specific Brick component(s) including props, events, examples, and accessibility information.',\n inputSchema: {\n components: z\n .array(z.string())\n .describe(\n 'Array of component names (e.g., [\"brick-button\", \"brick-modal\"])'\n ),\n },\n },\n async ({ components }) => {\n const result = await getComponentDocs({ components });\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n }\n );\n\n // Register get-design-tokens tool\n server.registerTool(\n 'get-design-tokens',\n {\n title: 'Get Design Tokens',\n description:\n 'Access design tokens from brick-tokens. Optionally filter by category (colors, spacing, typography, shadows, borders).',\n inputSchema: {\n category: z\n .enum(['colors', 'spacing', 'typography', 'shadows', 'borders'])\n .optional()\n .describe('Filter tokens by category'),\n },\n },\n async ({ category }) => {\n const result = await getDesignTokens({ category });\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n }\n );\n\n return server;\n}\n", "/**\n * Get Component Docs tool implementation\n */\n\nimport { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\n\nimport { getDataPath } from '../utils/dataPath.ts';\nimport { loadComponentData } from '../extractors/packageScanner.ts';\n\nexport interface GetComponentDocsInput {\n components: string[]; // e.g., [\"brick-button\", \"brick-modal\"]\n}\n\nexport interface GetComponentDocsOutput {\n docs: string[];\n}\n\n/**\n * Load markdown documentation for a component\n */\nasync function loadComponentMarkdown(\n componentName: string\n): Promise<string | undefined> {\n try {\n const markdownPath = join(\n getDataPath(),\n 'components',\n `${componentName}.md`\n );\n const content = await readFile(markdownPath, 'utf-8');\n return content;\n } catch (error) {\n console.error(`Error loading markdown for ${componentName}:`, error);\n return undefined;\n }\n}\n\n/**\n * Get detailed documentation for specific component(s)\n */\nexport async function getComponentDocs(\n input: GetComponentDocsInput\n): Promise<GetComponentDocsOutput> {\n // Load markdown documentation for each requested component\n const docsPromises = input.components.map(async (componentName) => {\n const md = await loadComponentMarkdown(componentName);\n if (!md) {\n const json = await loadComponentData(componentName);\n return json ? JSON.stringify(json) : undefined;\n }\n return md;\n });\n\n const docsResults = await Promise.all(docsPromises);\n\n // Filter out any components that failed to load\n const docs = docsResults.filter((doc): doc is string => doc !== undefined);\n\n return { docs };\n}\n", "/**\n * Utility for finding the data directory path\n * Works both in development (from src/) and production (from dist/)\n */\n\nimport { accessSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n/**\n * Get the path to the data directory\n * When running from dist/, looks for dist/data\n * When running from src/, looks for package root data\n */\nexport function getDataPath(): string {\n const currentFilePath = fileURLToPath(import.meta.url);\n let dir = dirname(currentFilePath);\n\n // First check if there's a data directory in the same parent as the current file\n // This handles the dist/data case when running from dist/\n const localDataPath = join(dir, 'data');\n try {\n accessSync(localDataPath);\n return localDataPath;\n } catch {\n // Continue to package root search\n }\n\n // Walk up the directory tree to find package root (where package.json exists)\n for (let i = 0; i < 5; i++) {\n try {\n const testPath = join(dir, 'package.json');\n accessSync(testPath);\n return join(dir, 'data');\n } catch {\n // Go up one level\n const parent = dirname(dir);\n if (parent === dir) break; // Reached filesystem root\n dir = parent;\n }\n }\n\n return join(dirname(currentFilePath), '..', '..', 'data');\n}\n", "/**\n * Package scanner for discovering Brick components\n */\n\nimport { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\n\nimport { type BrickComponent, type BrickComponentMetadata } from '../types.ts';\nimport { getDataPath } from '../utils/dataPath.ts';\n\n/**\n * Load all component metadata (lightweight, for listing)\n */\nexport async function scanAllPackages(): Promise<BrickComponentMetadata[]> {\n try {\n const metadataPath = join(getDataPath(), 'components-metadata.json');\n const content = await readFile(metadataPath, 'utf-8');\n const metadata: BrickComponentMetadata[] = JSON.parse(content);\n return metadata;\n } catch (error) {\n console.error('Error loading component metadata:', error);\n return [];\n }\n}\n\n/**\n * Load full component data for a specific component\n */\nexport async function loadComponentData(\n componentName: string\n): Promise<BrickComponent | undefined> {\n try {\n const componentPath = join(\n getDataPath(),\n 'components',\n `${componentName}.json`\n );\n const content = await readFile(componentPath, 'utf-8');\n const component: BrickComponent = JSON.parse(content);\n return component;\n } catch (error) {\n console.error(`Error loading component data for ${componentName}:`, error);\n return undefined;\n }\n}\n\n/**\n * Filter components by category or tag\n */\nexport function filterComponents(\n components: BrickComponentMetadata[],\n filter?: string\n): BrickComponentMetadata[] {\n if (!filter) {\n return components;\n }\n\n const filterLower = filter.toLowerCase();\n\n return components.filter((component) => {\n // Match against name\n if (component.name.toLowerCase().includes(filterLower)) {\n return true;\n }\n\n // Match against category\n if (component.category?.toLowerCase().includes(filterLower)) {\n return true;\n }\n\n // Match against tags\n if (\n component.tags?.some((tag) => tag.toLowerCase().includes(filterLower))\n ) {\n return true;\n }\n\n return false;\n });\n}\n", "/**\n * Get Design Tokens tool implementation\n */\n\nimport { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\n\nimport { getDataPath } from '../utils/dataPath.ts';\n\nexport interface DesignToken {\n path: string;\n name: string;\n type: string;\n value: string;\n description?: string;\n cssVariable: string;\n}\n\nexport interface GetDesignTokensInput {\n category?: 'colors' | 'spacing' | 'typography' | 'shadows' | 'borders';\n}\n\nexport interface TokensDocumentation {\n anOverview?: string;\n formats?: string;\n naming?: string;\n usage?: string;\n}\n\nexport interface GetDesignTokensOutput {\n tokens: DesignToken[];\n documentation: TokensDocumentation;\n note?: string;\n}\n\n/**\n * Get the path to the bundled tokens data\n */\nfunction getTokensDataPath(): string {\n return join(getDataPath(), 'tokens.json');\n}\n\n/**\n * Get the path to the bundled documentation data\n */\nfunction getDocumentationDataPath(): string {\n return join(getDataPath(), 'tokens-documentation.json');\n}\n\n/**\n * Load all tokens from bundled JSON data\n */\nasync function loadAllTokens(): Promise<DesignToken[]> {\n try {\n const dataPath = getTokensDataPath();\n const content = await readFile(dataPath, 'utf-8');\n return JSON.parse(content);\n } catch (error) {\n console.error('Error loading tokens data:', error);\n return [];\n }\n}\n\n/**\n * Load documentation from bundled JSON data\n */\nasync function loadDocumentation(): Promise<TokensDocumentation> {\n try {\n const dataPath = getDocumentationDataPath();\n const content = await readFile(dataPath, 'utf-8');\n return JSON.parse(content);\n } catch (error) {\n console.error('Error loading documentation data:', error);\n return {};\n }\n}\n\n/**\n * Get design tokens with optional filtering\n */\nexport async function getDesignTokens(\n input: GetDesignTokensInput\n): Promise<GetDesignTokensOutput> {\n const allTokens = await loadAllTokens();\n const documentation = await loadDocumentation();\n\n let filteredTokens = allTokens;\n\n // Filter by category if specified\n if (input.category) {\n filteredTokens = filteredTokens.filter((token) => {\n // Filter based on the path field which contains category information\n const path = token.path.toLowerCase();\n\n switch (input.category) {\n case 'colors':\n return path.startsWith('color.');\n case 'spacing':\n return path.startsWith('spacing.');\n case 'typography':\n return path.startsWith('typography.');\n case 'shadows':\n return path.startsWith('box-shadow.');\n case 'borders':\n return (\n path.startsWith('border-width.') ||\n path.startsWith('border-radius.') ||\n path.startsWith('border.')\n );\n default:\n return false;\n }\n });\n }\n\n return {\n tokens: filteredTokens,\n documentation,\n note: 'The \"value\" field shows example values from one theme. Actual values vary across different themes (alfa, bravo, charlie, nettavisen, alt). Use the \"cssVariable\" field for theme-aware styling.',\n };\n}\n", "/**\n * List Components tool implementation\n */\n\nimport {\n filterComponents,\n scanAllPackages,\n} from '../extractors/packageScanner.ts';\nimport type { BrickComponentMetadata } from '../types.ts';\n\nexport interface ListComponentsInput {\n filter?: string;\n}\n\nexport interface ListComponentsOutput {\n components: BrickComponentMetadata[];\n}\n\n/**\n * List all available Brick components with optional filtering\n */\nexport async function listComponents(\n input: ListComponentsInput\n): Promise<ListComponentsOutput> {\n // Scan all packages in the monorepo (returns lightweight metadata)\n const allComponents = await scanAllPackages();\n\n // Apply filter if provided\n const components = filterComponents(allComponents, input.filter);\n\n return {\n components,\n };\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["/**\n * HTTP server entry point for local development only\n * Uses Fastify and SSE transport for MCP communication\n */\n\nimport cors from '@fastify/cors';\nimport { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';\nimport Fastify from 'fastify';\n\nimport { createServer } from './server.ts';\n\nconst PORT = 3000;\nconst HOST = 'localhost';\n\nconst fastify = Fastify({\n logger: {\n level: 'info',\n },\n});\n\n// Store active transports and servers by sessionId\nconst activeTransports = new Map<string, SSEServerTransport>();\nconst activeMcpServers = new Map<string, ReturnType<typeof createServer>>();\n\n// Enable CORS for local development\nawait fastify.register(cors, {\n origin: true,\n credentials: true,\n});\n\n// Health check endpoint\nfastify.get('/health', async () => {\n return { status: 'ok' };\n});\n\n// SSE endpoint for MCP communication\nfastify.get('/sse', async (_request, reply) => {\n // Prevent Fastify from automatically sending a response\n reply.hijack();\n\n // Create a new MCP server instance for this connection\n const mcpServer = createServer();\n\n // Create SSE transport (this will handle headers internally)\n const transport = new SSEServerTransport('/message', reply.raw);\n\n // Handle the SSE connection (this calls transport.start() which writes headers)\n await mcpServer.connect(transport);\n\n // Store the transport and server by sessionId for POST message handling\n // The sessionId is available after the transport starts via the public getter\n const sessionId = transport.sessionId;\n activeTransports.set(sessionId, transport);\n activeMcpServers.set(sessionId, mcpServer);\n\n // Clean up when the connection closes\n reply.raw.on('close', async () => {\n activeTransports.delete(sessionId);\n const server = activeMcpServers.get(sessionId);\n if (server) {\n await server.close();\n activeMcpServers.delete(sessionId);\n }\n });\n});\n\n// POST endpoint for messages\nfastify.post<{\n Querystring: { sessionId: string };\n}>('/message', async (request, reply) => {\n // Prevent Fastify from automatically sending a response\n reply.hijack();\n\n // Extract sessionId from query parameters (now properly typed)\n const { sessionId } = request.query;\n\n // Find the transport for this session\n const transport = activeTransports.get(sessionId);\n\n if (!transport) {\n reply.raw.writeHead(404, { 'Content-Type': 'application/json' });\n reply.raw.end(JSON.stringify({ error: 'Session not found' }));\n return;\n }\n\n // Let the transport handle the POST message\n await transport.handlePostMessage(request.raw, reply.raw, request.body);\n});\n\n// Start the server\ntry {\n await fastify.listen({ port: PORT, host: HOST });\n console.log(`Brick MCP HTTP server listening on http://${HOST}:${PORT}`);\n console.log(`SSE endpoint: http://${HOST}:${PORT}/sse`);\n} catch (err) {\n fastify.log.error(err);\n process.exit(1);\n}\n", "/**\n * MCP server setup and registration\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\n\nimport { getComponentDocs } from './tools/getComponentDocs.ts';\nimport { getDesignTokens } from './tools/getDesignTokens.ts';\nimport { listComponents } from './tools/listComponents.ts';\n\n/**\n * Create and configure the MCP server\n */\nexport function createServer(): McpServer {\n // Create an MCP server\n const server = new McpServer({\n name: 'brick-design-system',\n version: '1.0.0',\n });\n\n // Register list-components tool\n server.registerTool(\n 'list-components',\n {\n title: 'List Brick Components',\n description:\n 'List all available Brick components with metadata. Optionally filter by category, tag, or name.',\n inputSchema: z.object({\n filter: z\n .string()\n .optional()\n .describe('Optional filter by category, tag, or name'),\n }),\n } as const,\n async ({ filter }: { filter?: string }) => {\n const result = await listComponents({ filter });\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n }\n );\n\n // Register get-component-docs tool\n server.registerTool(\n 'get-component-docs',\n {\n title: 'Get Component Documentation',\n description:\n 'Retrieve detailed documentation for specific Brick component(s) including props, events, examples, and accessibility information.',\n inputSchema: z.object({\n components: z\n .array(z.string())\n .describe(\n 'Array of component names (e.g., [\"brick-button\", \"brick-modal\"])'\n ),\n }),\n } as const,\n async ({ components }: { components: string[] }) => {\n const result = await getComponentDocs({ components });\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n }\n );\n\n // Register get-design-tokens tool\n server.registerTool(\n 'get-design-tokens',\n {\n title: 'Get Design Tokens',\n description:\n 'Access design tokens from brick-tokens. Optionally filter by category (colors, spacing, typography, shadows, borders).',\n inputSchema: z.object({\n category: z\n .enum(['colors', 'spacing', 'typography', 'shadows', 'borders'])\n .optional()\n .describe('Filter tokens by category'),\n }),\n } as const,\n async ({\n category,\n }: {\n category?: 'colors' | 'spacing' | 'typography' | 'shadows' | 'borders';\n }) => {\n const result = await getDesignTokens({ category });\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n }\n );\n\n return server;\n}\n", "/**\n * Get Component Docs tool implementation\n */\n\nimport { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\n\nimport { getDataPath } from '../utils/dataPath.ts';\nimport { loadComponentData } from '../extractors/packageScanner.ts';\n\nexport interface GetComponentDocsInput {\n components: string[]; // e.g., [\"brick-button\", \"brick-modal\"]\n}\n\nexport interface GetComponentDocsOutput {\n docs: string[];\n}\n\n/**\n * Load markdown documentation for a component\n */\nasync function loadComponentMarkdown(\n componentName: string\n): Promise<string | undefined> {\n try {\n const markdownPath = join(\n getDataPath(),\n 'components',\n `${componentName}.md`\n );\n const content = await readFile(markdownPath, 'utf-8');\n return content;\n } catch (error) {\n console.error(`Error loading markdown for ${componentName}:`, error);\n return undefined;\n }\n}\n\n/**\n * Get detailed documentation for specific component(s)\n */\nexport async function getComponentDocs(\n input: GetComponentDocsInput\n): Promise<GetComponentDocsOutput> {\n // Load markdown documentation for each requested component\n const docsPromises = input.components.map(async (componentName) => {\n const md = await loadComponentMarkdown(componentName);\n if (!md) {\n const json = await loadComponentData(componentName);\n return json ? JSON.stringify(json) : undefined;\n }\n return md;\n });\n\n const docsResults = await Promise.all(docsPromises);\n\n // Filter out any components that failed to load\n const docs = docsResults.filter((doc): doc is string => doc !== undefined);\n\n return { docs };\n}\n", "/**\n * Utility for finding the data directory path\n * Works both in development (from src/) and production (from dist/)\n */\n\nimport { accessSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n/**\n * Get the path to the data directory\n * When running from dist/, looks for dist/data\n * When running from src/, looks for package root data\n */\nexport function getDataPath(): string {\n const currentFilePath = fileURLToPath(import.meta.url);\n let dir = dirname(currentFilePath);\n\n // First check if there's a data directory in the same parent as the current file\n // This handles the dist/data case when running from dist/\n const localDataPath = join(dir, 'data');\n try {\n accessSync(localDataPath);\n return localDataPath;\n } catch {\n // Continue to package root search\n }\n\n // Walk up the directory tree to find package root (where package.json exists)\n for (let i = 0; i < 5; i++) {\n try {\n const testPath = join(dir, 'package.json');\n accessSync(testPath);\n return join(dir, 'data');\n } catch {\n // Go up one level\n const parent = dirname(dir);\n if (parent === dir) break; // Reached filesystem root\n dir = parent;\n }\n }\n\n return join(dirname(currentFilePath), '..', '..', 'data');\n}\n", "/**\n * Package scanner for discovering Brick components\n */\n\nimport { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\n\nimport { type BrickComponent, type BrickComponentMetadata } from '../types.ts';\nimport { getDataPath } from '../utils/dataPath.ts';\n\n/**\n * Load all component metadata (lightweight, for listing)\n */\nexport async function scanAllPackages(): Promise<BrickComponentMetadata[]> {\n try {\n const metadataPath = join(getDataPath(), 'components-metadata.json');\n const content = await readFile(metadataPath, 'utf-8');\n const metadata: BrickComponentMetadata[] = JSON.parse(content);\n return metadata;\n } catch (error) {\n console.error('Error loading component metadata:', error);\n return [];\n }\n}\n\n/**\n * Load full component data for a specific component\n */\nexport async function loadComponentData(\n componentName: string\n): Promise<BrickComponent | undefined> {\n try {\n const componentPath = join(\n getDataPath(),\n 'components',\n `${componentName}.json`\n );\n const content = await readFile(componentPath, 'utf-8');\n const component: BrickComponent = JSON.parse(content);\n return component;\n } catch (error) {\n console.error(`Error loading component data for ${componentName}:`, error);\n return undefined;\n }\n}\n\n/**\n * Filter components by category or tag\n */\nexport function filterComponents(\n components: BrickComponentMetadata[],\n filter?: string\n): BrickComponentMetadata[] {\n if (!filter) {\n return components;\n }\n\n const filterLower = filter.toLowerCase();\n\n return components.filter((component) => {\n // Match against name\n if (component.name.toLowerCase().includes(filterLower)) {\n return true;\n }\n\n // Match against category\n if (component.category?.toLowerCase().includes(filterLower)) {\n return true;\n }\n\n // Match against tags\n if (\n component.tags?.some((tag) => tag.toLowerCase().includes(filterLower))\n ) {\n return true;\n }\n\n return false;\n });\n}\n", "/**\n * Get Design Tokens tool implementation\n */\n\nimport { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\n\nimport { getDataPath } from '../utils/dataPath.ts';\n\nexport interface DesignToken {\n path: string;\n name: string;\n type: string;\n value: string;\n description?: string;\n cssVariable: string;\n}\n\nexport interface GetDesignTokensInput {\n category?: 'colors' | 'spacing' | 'typography' | 'shadows' | 'borders';\n}\n\nexport interface TokensDocumentation {\n anOverview?: string;\n formats?: string;\n naming?: string;\n usage?: string;\n}\n\nexport interface GetDesignTokensOutput {\n tokens: DesignToken[];\n documentation: TokensDocumentation;\n note?: string;\n}\n\n/**\n * Get the path to the bundled tokens data\n */\nfunction getTokensDataPath(): string {\n return join(getDataPath(), 'tokens.json');\n}\n\n/**\n * Get the path to the bundled documentation data\n */\nfunction getDocumentationDataPath(): string {\n return join(getDataPath(), 'tokens-documentation.json');\n}\n\n/**\n * Load all tokens from bundled JSON data\n */\nasync function loadAllTokens(): Promise<DesignToken[]> {\n try {\n const dataPath = getTokensDataPath();\n const content = await readFile(dataPath, 'utf-8');\n return JSON.parse(content);\n } catch (error) {\n console.error('Error loading tokens data:', error);\n return [];\n }\n}\n\n/**\n * Load documentation from bundled JSON data\n */\nasync function loadDocumentation(): Promise<TokensDocumentation> {\n try {\n const dataPath = getDocumentationDataPath();\n const content = await readFile(dataPath, 'utf-8');\n return JSON.parse(content);\n } catch (error) {\n console.error('Error loading documentation data:', error);\n return {};\n }\n}\n\n/**\n * Get design tokens with optional filtering\n */\nexport async function getDesignTokens(\n input: GetDesignTokensInput\n): Promise<GetDesignTokensOutput> {\n const allTokens = await loadAllTokens();\n const documentation = await loadDocumentation();\n\n let filteredTokens = allTokens;\n\n // Filter by category if specified\n if (input.category) {\n filteredTokens = filteredTokens.filter((token) => {\n // Filter based on the path field which contains category information\n const path = token.path.toLowerCase();\n\n switch (input.category) {\n case 'colors':\n return path.startsWith('color.');\n case 'spacing':\n return path.startsWith('spacing.');\n case 'typography':\n return path.startsWith('typography.');\n case 'shadows':\n return path.startsWith('box-shadow.');\n case 'borders':\n return (\n path.startsWith('border-width.') ||\n path.startsWith('border-radius.') ||\n path.startsWith('border.')\n );\n default:\n return false;\n }\n });\n }\n\n return {\n tokens: filteredTokens,\n documentation,\n note: 'The \"value\" field shows example values from one theme. Actual values vary across different themes (alfa, bravo, charlie, nettavisen, alt). Use the \"cssVariable\" field for theme-aware styling.',\n };\n}\n", "/**\n * List Components tool implementation\n */\n\nimport {\n filterComponents,\n scanAllPackages,\n} from '../extractors/packageScanner.ts';\nimport type { BrickComponentMetadata } from '../types.ts';\n\nexport interface ListComponentsInput {\n filter?: string;\n}\n\nexport interface ListComponentsOutput {\n components: BrickComponentMetadata[];\n}\n\n/**\n * List all available Brick components with optional filtering\n */\nexport async function listComponents(\n input: ListComponentsInput\n): Promise<ListComponentsOutput> {\n // Scan all packages in the monorepo (returns lightweight metadata)\n const allComponents = await scanAllPackages();\n\n // Apply filter if provided\n const components = filterComponents(allComponents, input.filter);\n\n return {\n components,\n };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["readFile", "join", "join", "join", "join", "readFile", "readFile", "join", "join", "readFile"]
|
|
7
7
|
}
|
package/dist/index.js
CHANGED
|
@@ -194,9 +194,9 @@ function createServer() {
|
|
|
194
194
|
{
|
|
195
195
|
title: "List Brick Components",
|
|
196
196
|
description: "List all available Brick components with metadata. Optionally filter by category, tag, or name.",
|
|
197
|
-
inputSchema: {
|
|
197
|
+
inputSchema: z.object({
|
|
198
198
|
filter: z.string().optional().describe("Optional filter by category, tag, or name")
|
|
199
|
-
}
|
|
199
|
+
})
|
|
200
200
|
},
|
|
201
201
|
async ({ filter }) => {
|
|
202
202
|
const result = await listComponents({ filter });
|
|
@@ -215,11 +215,11 @@ function createServer() {
|
|
|
215
215
|
{
|
|
216
216
|
title: "Get Component Documentation",
|
|
217
217
|
description: "Retrieve detailed documentation for specific Brick component(s) including props, events, examples, and accessibility information.",
|
|
218
|
-
inputSchema: {
|
|
218
|
+
inputSchema: z.object({
|
|
219
219
|
components: z.array(z.string()).describe(
|
|
220
220
|
'Array of component names (e.g., ["brick-button", "brick-modal"])'
|
|
221
221
|
)
|
|
222
|
-
}
|
|
222
|
+
})
|
|
223
223
|
},
|
|
224
224
|
async ({ components }) => {
|
|
225
225
|
const result = await getComponentDocs({ components });
|
|
@@ -238,11 +238,13 @@ function createServer() {
|
|
|
238
238
|
{
|
|
239
239
|
title: "Get Design Tokens",
|
|
240
240
|
description: "Access design tokens from brick-tokens. Optionally filter by category (colors, spacing, typography, shadows, borders).",
|
|
241
|
-
inputSchema: {
|
|
241
|
+
inputSchema: z.object({
|
|
242
242
|
category: z.enum(["colors", "spacing", "typography", "shadows", "borders"]).optional().describe("Filter tokens by category")
|
|
243
|
-
}
|
|
243
|
+
})
|
|
244
244
|
},
|
|
245
|
-
async ({
|
|
245
|
+
async ({
|
|
246
|
+
category
|
|
247
|
+
}) => {
|
|
246
248
|
const result = await getDesignTokens({ category });
|
|
247
249
|
return {
|
|
248
250
|
content: [
|
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.ts", "../src/server.ts", "../src/tools/getComponentDocs.ts", "../src/utils/dataPath.ts", "../src/extractors/packageScanner.ts", "../src/tools/getDesignTokens.ts", "../src/tools/listComponents.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Main MCP server entry point\n */\n\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\n\nimport { createServer } from './server.ts';\n\n// Create and start the server\nconst server = createServer();\n\n// Start receiving messages on stdin and sending messages on stdout\nconst transport = new StdioServerTransport();\nawait server.connect(transport);\n", "/**\n * MCP server setup and registration\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\n\nimport { getComponentDocs } from './tools/getComponentDocs.ts';\nimport { getDesignTokens } from './tools/getDesignTokens.ts';\nimport { listComponents } from './tools/listComponents.ts';\n\n/**\n * Create and configure the MCP server\n */\nexport function createServer(): McpServer {\n // Create an MCP server\n const server = new McpServer({\n name: 'brick-design-system',\n version: '1.0.0',\n });\n\n // Register list-components tool\n server.registerTool(\n 'list-components',\n {\n title: 'List Brick Components',\n description:\n 'List all available Brick components with metadata. Optionally filter by category, tag, or name.',\n inputSchema: {\n filter: z\n .string()\n .optional()\n .describe('Optional filter by category, tag, or name'),\n },\n },\n async ({ filter }) => {\n const result = await listComponents({ filter });\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n }\n );\n\n // Register get-component-docs tool\n server.registerTool(\n 'get-component-docs',\n {\n title: 'Get Component Documentation',\n description:\n 'Retrieve detailed documentation for specific Brick component(s) including props, events, examples, and accessibility information.',\n inputSchema: {\n components: z\n .array(z.string())\n .describe(\n 'Array of component names (e.g., [\"brick-button\", \"brick-modal\"])'\n ),\n },\n },\n async ({ components }) => {\n const result = await getComponentDocs({ components });\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n }\n );\n\n // Register get-design-tokens tool\n server.registerTool(\n 'get-design-tokens',\n {\n title: 'Get Design Tokens',\n description:\n 'Access design tokens from brick-tokens. Optionally filter by category (colors, spacing, typography, shadows, borders).',\n inputSchema: {\n category: z\n .enum(['colors', 'spacing', 'typography', 'shadows', 'borders'])\n .optional()\n .describe('Filter tokens by category'),\n },\n },\n async ({ category }) => {\n const result = await getDesignTokens({ category });\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n }\n );\n\n return server;\n}\n", "/**\n * Get Component Docs tool implementation\n */\n\nimport { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\n\nimport { getDataPath } from '../utils/dataPath.ts';\nimport { loadComponentData } from '../extractors/packageScanner.ts';\n\nexport interface GetComponentDocsInput {\n components: string[]; // e.g., [\"brick-button\", \"brick-modal\"]\n}\n\nexport interface GetComponentDocsOutput {\n docs: string[];\n}\n\n/**\n * Load markdown documentation for a component\n */\nasync function loadComponentMarkdown(\n componentName: string\n): Promise<string | undefined> {\n try {\n const markdownPath = join(\n getDataPath(),\n 'components',\n `${componentName}.md`\n );\n const content = await readFile(markdownPath, 'utf-8');\n return content;\n } catch (error) {\n console.error(`Error loading markdown for ${componentName}:`, error);\n return undefined;\n }\n}\n\n/**\n * Get detailed documentation for specific component(s)\n */\nexport async function getComponentDocs(\n input: GetComponentDocsInput\n): Promise<GetComponentDocsOutput> {\n // Load markdown documentation for each requested component\n const docsPromises = input.components.map(async (componentName) => {\n const md = await loadComponentMarkdown(componentName);\n if (!md) {\n const json = await loadComponentData(componentName);\n return json ? JSON.stringify(json) : undefined;\n }\n return md;\n });\n\n const docsResults = await Promise.all(docsPromises);\n\n // Filter out any components that failed to load\n const docs = docsResults.filter((doc): doc is string => doc !== undefined);\n\n return { docs };\n}\n", "/**\n * Utility for finding the data directory path\n * Works both in development (from src/) and production (from dist/)\n */\n\nimport { accessSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n/**\n * Get the path to the data directory\n * When running from dist/, looks for dist/data\n * When running from src/, looks for package root data\n */\nexport function getDataPath(): string {\n const currentFilePath = fileURLToPath(import.meta.url);\n let dir = dirname(currentFilePath);\n\n // First check if there's a data directory in the same parent as the current file\n // This handles the dist/data case when running from dist/\n const localDataPath = join(dir, 'data');\n try {\n accessSync(localDataPath);\n return localDataPath;\n } catch {\n // Continue to package root search\n }\n\n // Walk up the directory tree to find package root (where package.json exists)\n for (let i = 0; i < 5; i++) {\n try {\n const testPath = join(dir, 'package.json');\n accessSync(testPath);\n return join(dir, 'data');\n } catch {\n // Go up one level\n const parent = dirname(dir);\n if (parent === dir) break; // Reached filesystem root\n dir = parent;\n }\n }\n\n return join(dirname(currentFilePath), '..', '..', 'data');\n}\n", "/**\n * Package scanner for discovering Brick components\n */\n\nimport { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\n\nimport { type BrickComponent, type BrickComponentMetadata } from '../types.ts';\nimport { getDataPath } from '../utils/dataPath.ts';\n\n/**\n * Load all component metadata (lightweight, for listing)\n */\nexport async function scanAllPackages(): Promise<BrickComponentMetadata[]> {\n try {\n const metadataPath = join(getDataPath(), 'components-metadata.json');\n const content = await readFile(metadataPath, 'utf-8');\n const metadata: BrickComponentMetadata[] = JSON.parse(content);\n return metadata;\n } catch (error) {\n console.error('Error loading component metadata:', error);\n return [];\n }\n}\n\n/**\n * Load full component data for a specific component\n */\nexport async function loadComponentData(\n componentName: string\n): Promise<BrickComponent | undefined> {\n try {\n const componentPath = join(\n getDataPath(),\n 'components',\n `${componentName}.json`\n );\n const content = await readFile(componentPath, 'utf-8');\n const component: BrickComponent = JSON.parse(content);\n return component;\n } catch (error) {\n console.error(`Error loading component data for ${componentName}:`, error);\n return undefined;\n }\n}\n\n/**\n * Filter components by category or tag\n */\nexport function filterComponents(\n components: BrickComponentMetadata[],\n filter?: string\n): BrickComponentMetadata[] {\n if (!filter) {\n return components;\n }\n\n const filterLower = filter.toLowerCase();\n\n return components.filter((component) => {\n // Match against name\n if (component.name.toLowerCase().includes(filterLower)) {\n return true;\n }\n\n // Match against category\n if (component.category?.toLowerCase().includes(filterLower)) {\n return true;\n }\n\n // Match against tags\n if (\n component.tags?.some((tag) => tag.toLowerCase().includes(filterLower))\n ) {\n return true;\n }\n\n return false;\n });\n}\n", "/**\n * Get Design Tokens tool implementation\n */\n\nimport { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\n\nimport { getDataPath } from '../utils/dataPath.ts';\n\nexport interface DesignToken {\n path: string;\n name: string;\n type: string;\n value: string;\n description?: string;\n cssVariable: string;\n}\n\nexport interface GetDesignTokensInput {\n category?: 'colors' | 'spacing' | 'typography' | 'shadows' | 'borders';\n}\n\nexport interface TokensDocumentation {\n anOverview?: string;\n formats?: string;\n naming?: string;\n usage?: string;\n}\n\nexport interface GetDesignTokensOutput {\n tokens: DesignToken[];\n documentation: TokensDocumentation;\n note?: string;\n}\n\n/**\n * Get the path to the bundled tokens data\n */\nfunction getTokensDataPath(): string {\n return join(getDataPath(), 'tokens.json');\n}\n\n/**\n * Get the path to the bundled documentation data\n */\nfunction getDocumentationDataPath(): string {\n return join(getDataPath(), 'tokens-documentation.json');\n}\n\n/**\n * Load all tokens from bundled JSON data\n */\nasync function loadAllTokens(): Promise<DesignToken[]> {\n try {\n const dataPath = getTokensDataPath();\n const content = await readFile(dataPath, 'utf-8');\n return JSON.parse(content);\n } catch (error) {\n console.error('Error loading tokens data:', error);\n return [];\n }\n}\n\n/**\n * Load documentation from bundled JSON data\n */\nasync function loadDocumentation(): Promise<TokensDocumentation> {\n try {\n const dataPath = getDocumentationDataPath();\n const content = await readFile(dataPath, 'utf-8');\n return JSON.parse(content);\n } catch (error) {\n console.error('Error loading documentation data:', error);\n return {};\n }\n}\n\n/**\n * Get design tokens with optional filtering\n */\nexport async function getDesignTokens(\n input: GetDesignTokensInput\n): Promise<GetDesignTokensOutput> {\n const allTokens = await loadAllTokens();\n const documentation = await loadDocumentation();\n\n let filteredTokens = allTokens;\n\n // Filter by category if specified\n if (input.category) {\n filteredTokens = filteredTokens.filter((token) => {\n // Filter based on the path field which contains category information\n const path = token.path.toLowerCase();\n\n switch (input.category) {\n case 'colors':\n return path.startsWith('color.');\n case 'spacing':\n return path.startsWith('spacing.');\n case 'typography':\n return path.startsWith('typography.');\n case 'shadows':\n return path.startsWith('box-shadow.');\n case 'borders':\n return (\n path.startsWith('border-width.') ||\n path.startsWith('border-radius.') ||\n path.startsWith('border.')\n );\n default:\n return false;\n }\n });\n }\n\n return {\n tokens: filteredTokens,\n documentation,\n note: 'The \"value\" field shows example values from one theme. Actual values vary across different themes (alfa, bravo, charlie, nettavisen, alt). Use the \"cssVariable\" field for theme-aware styling.',\n };\n}\n", "/**\n * List Components tool implementation\n */\n\nimport {\n filterComponents,\n scanAllPackages,\n} from '../extractors/packageScanner.ts';\nimport type { BrickComponentMetadata } from '../types.ts';\n\nexport interface ListComponentsInput {\n filter?: string;\n}\n\nexport interface ListComponentsOutput {\n components: BrickComponentMetadata[];\n}\n\n/**\n * List all available Brick components with optional filtering\n */\nexport async function listComponents(\n input: ListComponentsInput\n): Promise<ListComponentsOutput> {\n // Scan all packages in the monorepo (returns lightweight metadata)\n const allComponents = await scanAllPackages();\n\n // Apply filter if provided\n const components = filterComponents(allComponents, input.filter);\n\n return {\n components,\n };\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["/**\n * Main MCP server entry point\n */\n\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\n\nimport { createServer } from './server.ts';\n\n// Create and start the server\nconst server = createServer();\n\n// Start receiving messages on stdin and sending messages on stdout\nconst transport = new StdioServerTransport();\nawait server.connect(transport);\n", "/**\n * MCP server setup and registration\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\n\nimport { getComponentDocs } from './tools/getComponentDocs.ts';\nimport { getDesignTokens } from './tools/getDesignTokens.ts';\nimport { listComponents } from './tools/listComponents.ts';\n\n/**\n * Create and configure the MCP server\n */\nexport function createServer(): McpServer {\n // Create an MCP server\n const server = new McpServer({\n name: 'brick-design-system',\n version: '1.0.0',\n });\n\n // Register list-components tool\n server.registerTool(\n 'list-components',\n {\n title: 'List Brick Components',\n description:\n 'List all available Brick components with metadata. Optionally filter by category, tag, or name.',\n inputSchema: z.object({\n filter: z\n .string()\n .optional()\n .describe('Optional filter by category, tag, or name'),\n }),\n } as const,\n async ({ filter }: { filter?: string }) => {\n const result = await listComponents({ filter });\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n }\n );\n\n // Register get-component-docs tool\n server.registerTool(\n 'get-component-docs',\n {\n title: 'Get Component Documentation',\n description:\n 'Retrieve detailed documentation for specific Brick component(s) including props, events, examples, and accessibility information.',\n inputSchema: z.object({\n components: z\n .array(z.string())\n .describe(\n 'Array of component names (e.g., [\"brick-button\", \"brick-modal\"])'\n ),\n }),\n } as const,\n async ({ components }: { components: string[] }) => {\n const result = await getComponentDocs({ components });\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n }\n );\n\n // Register get-design-tokens tool\n server.registerTool(\n 'get-design-tokens',\n {\n title: 'Get Design Tokens',\n description:\n 'Access design tokens from brick-tokens. Optionally filter by category (colors, spacing, typography, shadows, borders).',\n inputSchema: z.object({\n category: z\n .enum(['colors', 'spacing', 'typography', 'shadows', 'borders'])\n .optional()\n .describe('Filter tokens by category'),\n }),\n } as const,\n async ({\n category,\n }: {\n category?: 'colors' | 'spacing' | 'typography' | 'shadows' | 'borders';\n }) => {\n const result = await getDesignTokens({ category });\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n }\n );\n\n return server;\n}\n", "/**\n * Get Component Docs tool implementation\n */\n\nimport { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\n\nimport { getDataPath } from '../utils/dataPath.ts';\nimport { loadComponentData } from '../extractors/packageScanner.ts';\n\nexport interface GetComponentDocsInput {\n components: string[]; // e.g., [\"brick-button\", \"brick-modal\"]\n}\n\nexport interface GetComponentDocsOutput {\n docs: string[];\n}\n\n/**\n * Load markdown documentation for a component\n */\nasync function loadComponentMarkdown(\n componentName: string\n): Promise<string | undefined> {\n try {\n const markdownPath = join(\n getDataPath(),\n 'components',\n `${componentName}.md`\n );\n const content = await readFile(markdownPath, 'utf-8');\n return content;\n } catch (error) {\n console.error(`Error loading markdown for ${componentName}:`, error);\n return undefined;\n }\n}\n\n/**\n * Get detailed documentation for specific component(s)\n */\nexport async function getComponentDocs(\n input: GetComponentDocsInput\n): Promise<GetComponentDocsOutput> {\n // Load markdown documentation for each requested component\n const docsPromises = input.components.map(async (componentName) => {\n const md = await loadComponentMarkdown(componentName);\n if (!md) {\n const json = await loadComponentData(componentName);\n return json ? JSON.stringify(json) : undefined;\n }\n return md;\n });\n\n const docsResults = await Promise.all(docsPromises);\n\n // Filter out any components that failed to load\n const docs = docsResults.filter((doc): doc is string => doc !== undefined);\n\n return { docs };\n}\n", "/**\n * Utility for finding the data directory path\n * Works both in development (from src/) and production (from dist/)\n */\n\nimport { accessSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n/**\n * Get the path to the data directory\n * When running from dist/, looks for dist/data\n * When running from src/, looks for package root data\n */\nexport function getDataPath(): string {\n const currentFilePath = fileURLToPath(import.meta.url);\n let dir = dirname(currentFilePath);\n\n // First check if there's a data directory in the same parent as the current file\n // This handles the dist/data case when running from dist/\n const localDataPath = join(dir, 'data');\n try {\n accessSync(localDataPath);\n return localDataPath;\n } catch {\n // Continue to package root search\n }\n\n // Walk up the directory tree to find package root (where package.json exists)\n for (let i = 0; i < 5; i++) {\n try {\n const testPath = join(dir, 'package.json');\n accessSync(testPath);\n return join(dir, 'data');\n } catch {\n // Go up one level\n const parent = dirname(dir);\n if (parent === dir) break; // Reached filesystem root\n dir = parent;\n }\n }\n\n return join(dirname(currentFilePath), '..', '..', 'data');\n}\n", "/**\n * Package scanner for discovering Brick components\n */\n\nimport { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\n\nimport { type BrickComponent, type BrickComponentMetadata } from '../types.ts';\nimport { getDataPath } from '../utils/dataPath.ts';\n\n/**\n * Load all component metadata (lightweight, for listing)\n */\nexport async function scanAllPackages(): Promise<BrickComponentMetadata[]> {\n try {\n const metadataPath = join(getDataPath(), 'components-metadata.json');\n const content = await readFile(metadataPath, 'utf-8');\n const metadata: BrickComponentMetadata[] = JSON.parse(content);\n return metadata;\n } catch (error) {\n console.error('Error loading component metadata:', error);\n return [];\n }\n}\n\n/**\n * Load full component data for a specific component\n */\nexport async function loadComponentData(\n componentName: string\n): Promise<BrickComponent | undefined> {\n try {\n const componentPath = join(\n getDataPath(),\n 'components',\n `${componentName}.json`\n );\n const content = await readFile(componentPath, 'utf-8');\n const component: BrickComponent = JSON.parse(content);\n return component;\n } catch (error) {\n console.error(`Error loading component data for ${componentName}:`, error);\n return undefined;\n }\n}\n\n/**\n * Filter components by category or tag\n */\nexport function filterComponents(\n components: BrickComponentMetadata[],\n filter?: string\n): BrickComponentMetadata[] {\n if (!filter) {\n return components;\n }\n\n const filterLower = filter.toLowerCase();\n\n return components.filter((component) => {\n // Match against name\n if (component.name.toLowerCase().includes(filterLower)) {\n return true;\n }\n\n // Match against category\n if (component.category?.toLowerCase().includes(filterLower)) {\n return true;\n }\n\n // Match against tags\n if (\n component.tags?.some((tag) => tag.toLowerCase().includes(filterLower))\n ) {\n return true;\n }\n\n return false;\n });\n}\n", "/**\n * Get Design Tokens tool implementation\n */\n\nimport { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\n\nimport { getDataPath } from '../utils/dataPath.ts';\n\nexport interface DesignToken {\n path: string;\n name: string;\n type: string;\n value: string;\n description?: string;\n cssVariable: string;\n}\n\nexport interface GetDesignTokensInput {\n category?: 'colors' | 'spacing' | 'typography' | 'shadows' | 'borders';\n}\n\nexport interface TokensDocumentation {\n anOverview?: string;\n formats?: string;\n naming?: string;\n usage?: string;\n}\n\nexport interface GetDesignTokensOutput {\n tokens: DesignToken[];\n documentation: TokensDocumentation;\n note?: string;\n}\n\n/**\n * Get the path to the bundled tokens data\n */\nfunction getTokensDataPath(): string {\n return join(getDataPath(), 'tokens.json');\n}\n\n/**\n * Get the path to the bundled documentation data\n */\nfunction getDocumentationDataPath(): string {\n return join(getDataPath(), 'tokens-documentation.json');\n}\n\n/**\n * Load all tokens from bundled JSON data\n */\nasync function loadAllTokens(): Promise<DesignToken[]> {\n try {\n const dataPath = getTokensDataPath();\n const content = await readFile(dataPath, 'utf-8');\n return JSON.parse(content);\n } catch (error) {\n console.error('Error loading tokens data:', error);\n return [];\n }\n}\n\n/**\n * Load documentation from bundled JSON data\n */\nasync function loadDocumentation(): Promise<TokensDocumentation> {\n try {\n const dataPath = getDocumentationDataPath();\n const content = await readFile(dataPath, 'utf-8');\n return JSON.parse(content);\n } catch (error) {\n console.error('Error loading documentation data:', error);\n return {};\n }\n}\n\n/**\n * Get design tokens with optional filtering\n */\nexport async function getDesignTokens(\n input: GetDesignTokensInput\n): Promise<GetDesignTokensOutput> {\n const allTokens = await loadAllTokens();\n const documentation = await loadDocumentation();\n\n let filteredTokens = allTokens;\n\n // Filter by category if specified\n if (input.category) {\n filteredTokens = filteredTokens.filter((token) => {\n // Filter based on the path field which contains category information\n const path = token.path.toLowerCase();\n\n switch (input.category) {\n case 'colors':\n return path.startsWith('color.');\n case 'spacing':\n return path.startsWith('spacing.');\n case 'typography':\n return path.startsWith('typography.');\n case 'shadows':\n return path.startsWith('box-shadow.');\n case 'borders':\n return (\n path.startsWith('border-width.') ||\n path.startsWith('border-radius.') ||\n path.startsWith('border.')\n );\n default:\n return false;\n }\n });\n }\n\n return {\n tokens: filteredTokens,\n documentation,\n note: 'The \"value\" field shows example values from one theme. Actual values vary across different themes (alfa, bravo, charlie, nettavisen, alt). Use the \"cssVariable\" field for theme-aware styling.',\n };\n}\n", "/**\n * List Components tool implementation\n */\n\nimport {\n filterComponents,\n scanAllPackages,\n} from '../extractors/packageScanner.ts';\nimport type { BrickComponentMetadata } from '../types.ts';\n\nexport interface ListComponentsInput {\n filter?: string;\n}\n\nexport interface ListComponentsOutput {\n components: BrickComponentMetadata[];\n}\n\n/**\n * List all available Brick components with optional filtering\n */\nexport async function listComponents(\n input: ListComponentsInput\n): Promise<ListComponentsOutput> {\n // Scan all packages in the monorepo (returns lightweight metadata)\n const allComponents = await scanAllPackages();\n\n // Apply filter if provided\n const components = filterComponents(allComponents, input.filter);\n\n return {\n components,\n };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["readFile", "join", "join", "join", "join", "readFile", "readFile", "join", "join", "readFile", "server"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@amedia/brick-mcp",
|
|
3
3
|
"homepage": "https://github.com/amedia/brick.git",
|
|
4
4
|
"author": "Amedia",
|
|
5
|
-
"version": "0.1.
|
|
5
|
+
"version": "0.1.2",
|
|
6
6
|
"description": "This is a MCP server for Brick",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"type": "module",
|
|
@@ -36,6 +36,43 @@
|
|
|
36
36
|
"zod": "3.25.76",
|
|
37
37
|
"zod-to-json-schema": "3.24.6"
|
|
38
38
|
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@amedia/brick-alt-teaser": "*",
|
|
41
|
+
"@amedia/brick-avatar": "*",
|
|
42
|
+
"@amedia/brick-button": "*",
|
|
43
|
+
"@amedia/brick-byline": "*",
|
|
44
|
+
"@amedia/brick-card": "*",
|
|
45
|
+
"@amedia/brick-carousel": "*",
|
|
46
|
+
"@amedia/brick-classnames": "*",
|
|
47
|
+
"@amedia/brick-countdown": "*",
|
|
48
|
+
"@amedia/brick-dialog": "*",
|
|
49
|
+
"@amedia/brick-expand": "*",
|
|
50
|
+
"@amedia/brick-fonts": "*",
|
|
51
|
+
"@amedia/brick-helloworld": "*",
|
|
52
|
+
"@amedia/brick-icon": "*",
|
|
53
|
+
"@amedia/brick-icons": "*",
|
|
54
|
+
"@amedia/brick-illustrations": "*",
|
|
55
|
+
"@amedia/brick-image": "*",
|
|
56
|
+
"@amedia/brick-input": "*",
|
|
57
|
+
"@amedia/brick-pill": "*",
|
|
58
|
+
"@amedia/brick-player": "*",
|
|
59
|
+
"@amedia/brick-published": "*",
|
|
60
|
+
"@amedia/brick-share": "*",
|
|
61
|
+
"@amedia/brick-stepper": "*",
|
|
62
|
+
"@amedia/brick-tab": "*",
|
|
63
|
+
"@amedia/brick-tabs": "*",
|
|
64
|
+
"@amedia/brick-tag": "*",
|
|
65
|
+
"@amedia/brick-teaser": "*",
|
|
66
|
+
"@amedia/brick-teaser-player": "*",
|
|
67
|
+
"@amedia/brick-teaser-reels": "*",
|
|
68
|
+
"@amedia/brick-template": "*",
|
|
69
|
+
"@amedia/brick-textarea": "*",
|
|
70
|
+
"@amedia/brick-themes": "*",
|
|
71
|
+
"@amedia/brick-toast": "*",
|
|
72
|
+
"@amedia/brick-toggle": "*",
|
|
73
|
+
"@amedia/brick-tokens": "*",
|
|
74
|
+
"@amedia/brick-tooltip": "*"
|
|
75
|
+
},
|
|
39
76
|
"eik": {
|
|
40
77
|
"server": "https://assets.acdn.no",
|
|
41
78
|
"files": {
|