@vettvangur/design-system 0.0.1
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/LICENSE +11 -0
- package/README.md +18 -0
- package/dist/generate-astro-AcegHzWG.js +476 -0
- package/dist/generate-astro-B225JTMY.js +534 -0
- package/dist/generate-astro-Btr2jiyr.js +389 -0
- package/dist/generate-astro-CpNCOn_3.js +475 -0
- package/dist/generate-astro-CqXZcTfi.js +820 -0
- package/dist/generate-astro-D-FcwrAx.js +819 -0
- package/dist/generate-astro-DfaWTEF_.js +539 -0
- package/dist/generate-astro-DwBkft4p.js +820 -0
- package/dist/generate-razor--hJCWG13.js +454 -0
- package/dist/generate-razor-B0Pid10L.js +441 -0
- package/dist/generate-razor-B0n9FUR8.js +441 -0
- package/dist/generate-razor-B3a_-uDf.js +441 -0
- package/dist/generate-razor-BLNML3CC.js +441 -0
- package/dist/generate-razor-CABSDQok.js +454 -0
- package/dist/generate-razor-CGhqwpRL.js +413 -0
- package/dist/generate-razor-DcAkNKya.js +9 -0
- package/dist/generate-razor-DwXDvSTP.js +332 -0
- package/dist/generate-razor-IGs8o9fx.js +441 -0
- package/dist/generate-razor-nGTa0EVW.js +335 -0
- package/dist/generate-tailwind-16Mayr2z.js +1050 -0
- package/dist/generate-tailwind-BR1-fpNI.js +1056 -0
- package/dist/generate-tailwind-BVpI-hUx.js +1057 -0
- package/dist/generate-tailwind-Bd3ltCQR.js +1084 -0
- package/dist/generate-tailwind-BljcUYMa.js +1051 -0
- package/dist/generate-tailwind-BqZCEvj5.js +1049 -0
- package/dist/generate-tailwind-CGwQarzK.js +1059 -0
- package/dist/generate-tailwind-Cpb8YNNz.js +1050 -0
- package/dist/generate-tailwind-CtUsHnBd.js +1060 -0
- package/dist/generate-tailwind-DL0GEqR6.js +1050 -0
- package/dist/generate-tailwind-Dr3KLBMD.js +1045 -0
- package/dist/generate-tailwind-KzRHwyMG.js +1049 -0
- package/dist/generate-tailwind-VnkcDTZP.js +1049 -0
- package/dist/index.esm.js +58 -0
- package/dist/inputs-CQVgm9Do.js +439 -0
- package/package.json +35 -0
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { promises } from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import 'node:url';
|
|
5
|
+
import { p as parseColors, a as parseTypography, b as parseButtons, i as inputsSpec } from './inputs-CQVgm9Do.js';
|
|
6
|
+
import 'node:process';
|
|
7
|
+
|
|
8
|
+
// core/razor/generate-razor.mjs
|
|
9
|
+
const CWD = process.cwd();
|
|
10
|
+
|
|
11
|
+
// Target folder for partials (cwd = vettvangur-styleguide)
|
|
12
|
+
const OUT_DIR = path.resolve(CWD, '../Vettvangur.Site/Views/Partials/Styleguide');
|
|
13
|
+
const FILE_COLORS = path.join(OUT_DIR, 'StyleguideColors.cshtml');
|
|
14
|
+
const FILE_TYPO = path.join(OUT_DIR, 'StyleguideTypography.cshtml');
|
|
15
|
+
const FILE_BUTTONS = path.join(OUT_DIR, 'StyleguideButtons.cshtml');
|
|
16
|
+
const FILE_INPUTS = path.join(OUT_DIR, 'StyleguideInputs.cshtml');
|
|
17
|
+
async function generateRazor() {
|
|
18
|
+
await promises.mkdir(OUT_DIR, {
|
|
19
|
+
recursive: true
|
|
20
|
+
});
|
|
21
|
+
const [colors, typography, buttons] = await Promise.all([parseColors(),
|
|
22
|
+
// [{ title, color, class }]
|
|
23
|
+
parseTypography(),
|
|
24
|
+
// { bodies: [...], headlines: [...] }
|
|
25
|
+
parseButtons() // [{ title, class, text }]
|
|
26
|
+
]);
|
|
27
|
+
|
|
28
|
+
// Colors
|
|
29
|
+
if (colors?.length) {
|
|
30
|
+
await promises.writeFile(FILE_COLORS, renderColors(colors), 'utf8');
|
|
31
|
+
log(FILE_COLORS, colors.length);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Typography (one file: headlines + bodies)
|
|
35
|
+
if ((typography?.headlines?.length ?? 0) + (typography?.bodies?.length ?? 0) > 0) {
|
|
36
|
+
await promises.writeFile(FILE_TYPO, renderTypography(typography), 'utf8');
|
|
37
|
+
log(FILE_TYPO, (typography.headlines?.length ?? 0) + (typography.bodies?.length ?? 0));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Buttons
|
|
41
|
+
if (buttons?.length) {
|
|
42
|
+
await promises.writeFile(FILE_BUTTONS, renderButtons(buttons), 'utf8');
|
|
43
|
+
log(FILE_BUTTONS, buttons.length);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Inputs
|
|
47
|
+
const hasAnyInputs = Object.values(inputsSpec).some(v => Array.isArray(v) && v.length);
|
|
48
|
+
if (hasAnyInputs) {
|
|
49
|
+
await promises.writeFile(FILE_INPUTS, renderInputs(inputsSpec), 'utf8');
|
|
50
|
+
log(FILE_INPUTS, countInputs(inputsSpec));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/* -------------------- RENDERERS -------------------- */
|
|
55
|
+
|
|
56
|
+
// Colors
|
|
57
|
+
function renderColors(colors) {
|
|
58
|
+
const items = colors.map(({
|
|
59
|
+
title,
|
|
60
|
+
color
|
|
61
|
+
}) => `
|
|
62
|
+
<div class="styleguide-color">
|
|
63
|
+
<span class="styleguide-color__label label">${h(title)}</span>
|
|
64
|
+
<div class="styleguide-color__swatch" style="background: ${a(color)};"></div>
|
|
65
|
+
<div class="styleguide-color__info">
|
|
66
|
+
<span class="styleguide-color__info-hex label">${h(color)}</span>
|
|
67
|
+
</div>
|
|
68
|
+
</div>`).join('\n');
|
|
69
|
+
return `@* Auto-generated — do not edit by hand *@
|
|
70
|
+
<section class="styleguide-colors styleguide-spacing">
|
|
71
|
+
<div class="container">
|
|
72
|
+
\t\t<partial name="Cerebrum/Components/Headline" view-data="@(new ViewDataDictionary(ViewData)
|
|
73
|
+
\t\t{{ "headlineData", new Headline {
|
|
74
|
+
\t\t\tIdentifier = "styleguide__headline",
|
|
75
|
+
\t\t\tModifier = "headline1",
|
|
76
|
+
\t\t\tText = "Colors"
|
|
77
|
+
\t\t}}})" />
|
|
78
|
+
|
|
79
|
+
<div class="styleguide-colors-grid grid grid--gap">
|
|
80
|
+
${items}
|
|
81
|
+
</div>
|
|
82
|
+
</div>
|
|
83
|
+
</section>
|
|
84
|
+
`;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Typography (headlines + bodies)
|
|
88
|
+
function renderTypography({
|
|
89
|
+
headlines = [],
|
|
90
|
+
bodies = []
|
|
91
|
+
}) {
|
|
92
|
+
const headlineItems = headlines.map(hItem => {
|
|
93
|
+
const mod = classToModifier(hItem.class, 'headline'); // "headline-3" -> "headline3"
|
|
94
|
+
const info = infoBlocks(hItem); // text with desktop/mobile pairs
|
|
95
|
+
return `
|
|
96
|
+
<div class="styleguide-typography__item grid grid--gap">
|
|
97
|
+
<span class="styleguide-typography__item-name">${hItem.title}</span>
|
|
98
|
+
|
|
99
|
+
<partial name="Cerebrum/Components/Headline" view-data="@(new ViewDataDictionary(ViewData)
|
|
100
|
+
{{ "headlineData", new Headline {
|
|
101
|
+
Identifier = "styleguide-typography__item-example",
|
|
102
|
+
Modifier = "${a(mod)}",
|
|
103
|
+
Text = "${a(hItem.title)}"
|
|
104
|
+
}}})" />
|
|
105
|
+
|
|
106
|
+
${info ? renderInfo(info) : ''}
|
|
107
|
+
</div>`;
|
|
108
|
+
}).join('\n');
|
|
109
|
+
const bodyItems = bodies.map(b => {
|
|
110
|
+
const info = infoBlocks(b);
|
|
111
|
+
return `
|
|
112
|
+
<div class="styleguide-typography__item grid grid--gap">
|
|
113
|
+
<span class="styleguide-typography__item-name">${h(b.title)}</span>
|
|
114
|
+
<p class="${a(b.class)} styleguide-typography__item-example">
|
|
115
|
+
The quick brown fox jumps over the lazy dog.
|
|
116
|
+
</p>
|
|
117
|
+
${info ? renderInfo(info) : ''}
|
|
118
|
+
</div>`;
|
|
119
|
+
}).join('\n');
|
|
120
|
+
return `@* Auto-generated — do not edit by hand *@
|
|
121
|
+
<section class="styleguide-typography styleguide-spacing">
|
|
122
|
+
<div class="container">
|
|
123
|
+
<partial name="Cerebrum/Components/Headline" view-data="@(new ViewDataDictionary(ViewData)
|
|
124
|
+
{{ "headlineData", new Headline {
|
|
125
|
+
Identifier = "styleguide__headline",
|
|
126
|
+
Modifier = "headline1",
|
|
127
|
+
Text = "Typography"
|
|
128
|
+
}}})" />
|
|
129
|
+
${headlineItems}
|
|
130
|
+
${bodyItems}
|
|
131
|
+
</div>
|
|
132
|
+
</section>
|
|
133
|
+
`;
|
|
134
|
+
}
|
|
135
|
+
function renderInfo(info) {
|
|
136
|
+
const {
|
|
137
|
+
base,
|
|
138
|
+
desktop,
|
|
139
|
+
mobile
|
|
140
|
+
} = info;
|
|
141
|
+
return `
|
|
142
|
+
<div class="styleguide-typography__info">
|
|
143
|
+
${base ? `
|
|
144
|
+
<div class="styleguide-typography__info-item">
|
|
145
|
+
<span>Base</span>
|
|
146
|
+
<span><strong>${h(base)}</strong></span>
|
|
147
|
+
</div>` : ''}
|
|
148
|
+
${desktop ? `
|
|
149
|
+
<div class="styleguide-typography__info-item">
|
|
150
|
+
<span>Desktop</span>
|
|
151
|
+
<span><strong>${h(desktop)}</strong></span>
|
|
152
|
+
</div>` : ''}
|
|
153
|
+
${mobile ? `
|
|
154
|
+
<div class="styleguide-typography__info-item">
|
|
155
|
+
<span>Mobile</span>
|
|
156
|
+
<span><strong>${h(mobile)}</strong></span>
|
|
157
|
+
</div>` : ''}
|
|
158
|
+
</div>`;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Buttons (using your Button partial)
|
|
162
|
+
function renderButtons(buttons) {
|
|
163
|
+
const items = buttons.map(b => {
|
|
164
|
+
// Map our utility classes directly into Modifier (your partial handles class string)
|
|
165
|
+
const modifier = b.class;
|
|
166
|
+
return `
|
|
167
|
+
<div class="styleguide__button-wrap">
|
|
168
|
+
<partial name="Cerebrum/Components/Button" view-data="@(new ViewDataDictionary(ViewData)
|
|
169
|
+
{{ "buttonData", new Button {
|
|
170
|
+
Modifier = "${a(modifier)}",
|
|
171
|
+
Type = ButtonType.Button,
|
|
172
|
+
Text = "${a(b.text || b.title)}"
|
|
173
|
+
}}})" />
|
|
174
|
+
</div>`;
|
|
175
|
+
}).join('\n');
|
|
176
|
+
return `@* Auto-generated — do not edit by hand *@
|
|
177
|
+
<section class="styleguide-buttons styleguide-spacing">
|
|
178
|
+
<div class="container">
|
|
179
|
+
\t\t<partial name="Cerebrum/Components/Headline" view-data="@(new ViewDataDictionary(ViewData)
|
|
180
|
+
\t\t{{ "headlineData", new Headline {
|
|
181
|
+
\t\t\tIdentifier = "styleguide__headline",
|
|
182
|
+
\t\t\tModifier = "headline1",
|
|
183
|
+
\t\t\tText = "Buttons"
|
|
184
|
+
\t\t}}})" />
|
|
185
|
+
|
|
186
|
+
<div class="grid grid--gap">
|
|
187
|
+
${items}
|
|
188
|
+
</div>
|
|
189
|
+
</div>
|
|
190
|
+
</section>
|
|
191
|
+
`;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Inputs (using your MVC partials exactly like your example)
|
|
195
|
+
function renderInputs(spec) {
|
|
196
|
+
const {
|
|
197
|
+
inputs = [],
|
|
198
|
+
selects = [],
|
|
199
|
+
checkboxes = [],
|
|
200
|
+
radios = [],
|
|
201
|
+
textareas = []
|
|
202
|
+
} = spec;
|
|
203
|
+
const inputsPartials = inputs.map(i => `
|
|
204
|
+
\t\t\t<partial name="Cerebrum/Components/Inputs/Input" view-data="@(new ViewDataDictionary(ViewData)
|
|
205
|
+
\t\t\t{{ "inputData", new Input {
|
|
206
|
+
\t\t\t\tId = "${a(i.id || '')}",
|
|
207
|
+
\t\t\t\tLabel = "${a(i.Label ?? i.label ?? 'Input')}",
|
|
208
|
+
\t\t\t\tPlaceholder = "${a(i.placeholder ?? 'Input placeholder')}",
|
|
209
|
+
\t\t\t\tIsDisabled = ${bool(i.isDisabled)},
|
|
210
|
+
\t\t\t\tIsReadOnly = ${bool(i.isReadOnly)},
|
|
211
|
+
\t\t\t\tIsError = ${bool(i.isError)}
|
|
212
|
+
\t\t\t}}})" />`).join('\n');
|
|
213
|
+
const selectsPartials = selects.map(s => `
|
|
214
|
+
\t\t\t<partial name="Cerebrum/Components/Inputs/Select" view-data="@(new ViewDataDictionary(ViewData)
|
|
215
|
+
\t\t\t{{ "selectData", new Select {
|
|
216
|
+
\t\t\t\tId = "${a(s.id || '')}",
|
|
217
|
+
\t\t\t\tLabel = "${a(s.Label ?? 'Select')}",
|
|
218
|
+
\t\t\t\tOptions = selectOptions,
|
|
219
|
+
\t\t\t\tIsDisabled = ${bool(s.isDisabled)},
|
|
220
|
+
\t\t\t\tIsReadOnly = ${bool(s.isReadOnly)},
|
|
221
|
+
\t\t\t\tIsError = ${bool(s.isError)}
|
|
222
|
+
\t\t\t}}})" />`).join('\n');
|
|
223
|
+
const checkboxRows = checkboxes.map(c => `
|
|
224
|
+
\t\t\t<div class="input-group">
|
|
225
|
+
\t\t\t\t<partial name="Cerebrum/Components/Inputs/Selection" view-data="@(new ViewDataDictionary(ViewData)
|
|
226
|
+
\t\t\t\t{{ "selectionData", new Selection {
|
|
227
|
+
\t\t\t\t\tId = "${a(c.id || '')}",
|
|
228
|
+
\t\t\t\t\tLabel = "${a(c.Label ?? c.label ?? 'Checkbox')}",
|
|
229
|
+
\t\t\t\t\tType = "checkbox",
|
|
230
|
+
\t\t\t\t\tIsDisabled = ${bool(c.isDisabled)},
|
|
231
|
+
\t\t\t\t\tIsError = ${bool(c.isError)}
|
|
232
|
+
\t\t\t\t}}})" />
|
|
233
|
+
\t\t\t</div>`).join('\n');
|
|
234
|
+
const radioRows = radios.map(r => `
|
|
235
|
+
\t\t\t<div class="input-group">
|
|
236
|
+
\t\t\t\t<partial name="Cerebrum/Components/Inputs/Selection" view-data="@(new ViewDataDictionary(ViewData)
|
|
237
|
+
\t\t\t\t{{ "selectionData", new Selection {
|
|
238
|
+
\t\t\t\t\tId = "${a(r.id || '')}",
|
|
239
|
+
\t\t\t\t\tType = "radio",
|
|
240
|
+
\t\t\t\t\tName = "${a(r.Name ?? r.name ?? 'prettyradio')}",
|
|
241
|
+
\t\t\t\t\tLabel = "${a(r.Label ?? r.label ?? 'Radio')}",
|
|
242
|
+
\t\t\t\t\tIsDisabled = ${bool(r.isDisabled)},
|
|
243
|
+
\t\t\t\t\tIsError = ${bool(r.isError)}
|
|
244
|
+
\t\t\t\t}}})" />
|
|
245
|
+
\t\t\t</div>`).join('\n');
|
|
246
|
+
const textareasPartials = textareas.map(t => `
|
|
247
|
+
\t\t\t<partial name="Cerebrum/Components/Inputs/Textarea" view-data="@(new ViewDataDictionary(ViewData)
|
|
248
|
+
\t\t\t{{ "textareaData", new Textarea {
|
|
249
|
+
\t\t\t\tId = "${a(t.id || '')}",
|
|
250
|
+
\t\t\t\tLabel = "${a(t.Label ?? 'Textarea')}",
|
|
251
|
+
\t\t\t\tPlaceholder = "${a(t.placeholder ?? 'Textarea placeholder')}",
|
|
252
|
+
\t\t\t\tIsDisabled = ${bool(t.isDisabled)},
|
|
253
|
+
\t\t\t\tIsReadOnly = ${bool(t.isReadOnly)},
|
|
254
|
+
\t\t\t\tIsError = ${bool(t.isError)}
|
|
255
|
+
\t\t\t}}})" />`).join('\n');
|
|
256
|
+
return `@* Auto-generated — do not edit by hand *@
|
|
257
|
+
@{
|
|
258
|
+
var selectOptions = new Dictionary<string, string>() {
|
|
259
|
+
{ "option1", "Option value" },
|
|
260
|
+
{ "option2", "Option value" },
|
|
261
|
+
{ "option3", "Option value" },
|
|
262
|
+
{ "option4", "Option value" },
|
|
263
|
+
{ "option5", "Option value" },
|
|
264
|
+
{ "option6", "Option value" },
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
<section class="styleguide-inputs styleguide-spacing">
|
|
269
|
+
<div class="container">
|
|
270
|
+
\t\t<partial name="Cerebrum/Components/Headline" view-data="@(new ViewDataDictionary(ViewData)
|
|
271
|
+
\t\t{{ "headlineData", new Headline {
|
|
272
|
+
\t\t\tIdentifier = "styleguide__headline",
|
|
273
|
+
\t\t\tModifier = "headline1",
|
|
274
|
+
\t\t\tText = "Inputs"
|
|
275
|
+
\t\t}}})" />
|
|
276
|
+
|
|
277
|
+
<div class="styleguide-inputs__scrollitem grid grid--gap grid--align-start">
|
|
278
|
+
${inputsPartials}
|
|
279
|
+
${selectsPartials}
|
|
280
|
+
${checkboxRows}
|
|
281
|
+
${radioRows}
|
|
282
|
+
${textareasPartials}
|
|
283
|
+
</div>
|
|
284
|
+
</div>
|
|
285
|
+
</section>
|
|
286
|
+
`;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/* -------------------- HELPERS -------------------- */
|
|
290
|
+
|
|
291
|
+
function infoBlocks(item) {
|
|
292
|
+
const base = pair(item.size, item.lineheight);
|
|
293
|
+
const desktop = item?.config?.desktop ? pair(item.config.desktop.size, item.config.desktop.lineHeight) : '';
|
|
294
|
+
const mobile = item?.config?.mobile ? pair(item.config.mobile.size, item.config.mobile.lineHeight) : '';
|
|
295
|
+
if (!base && !desktop && !mobile) {
|
|
296
|
+
return '';
|
|
297
|
+
}
|
|
298
|
+
return {
|
|
299
|
+
base,
|
|
300
|
+
desktop,
|
|
301
|
+
mobile
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
function pair(size, lh) {
|
|
305
|
+
if (!size && !lh) {
|
|
306
|
+
return '';
|
|
307
|
+
}
|
|
308
|
+
return `Size: ${size ?? '-'} / Line height: ${lh ?? '-'}`;
|
|
309
|
+
}
|
|
310
|
+
function classToModifier(cls = '', prefix = 'headline') {
|
|
311
|
+
// "headline-3" -> "headline3", "headline-10" -> "headline10"
|
|
312
|
+
const m = new RegExp(`^${prefix}[-_]?(\\d+)$`).exec(cls);
|
|
313
|
+
if (m) {
|
|
314
|
+
return `${prefix}${m[1]}`;
|
|
315
|
+
}
|
|
316
|
+
// fallback: strip dashes (so "body-1" becomes "body1" if you ever need it)
|
|
317
|
+
return cls.replaceAll('-', '');
|
|
318
|
+
}
|
|
319
|
+
function countInputs(spec) {
|
|
320
|
+
return ['inputs', 'selects', 'checkboxes', 'radios', 'textareas'].reduce((sum, k) => sum + (spec[k]?.length || 0), 0);
|
|
321
|
+
}
|
|
322
|
+
function a(s = '') {
|
|
323
|
+
return String(s).replaceAll('"', '"');
|
|
324
|
+
}
|
|
325
|
+
function h(s = '') {
|
|
326
|
+
return String(s).replaceAll('&', '&').replaceAll('<', '<').replaceAll('>', '>');
|
|
327
|
+
}
|
|
328
|
+
function bool(v) {
|
|
329
|
+
return v ? 'true' : 'false';
|
|
330
|
+
} // ← add this
|
|
331
|
+
function log(file, n) {
|
|
332
|
+
console.log(`✓ Wrote ${path.relative(process.cwd(), file)} (${n})`);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
export { generateRazor as default };
|