@1001-digital/layers.prose 0.0.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/.editorconfig ADDED
@@ -0,0 +1,12 @@
1
+ root = true
2
+
3
+ [*]
4
+ indent_size = 2
5
+ indent_style = space
6
+ end_of_line = lf
7
+ charset = utf-8
8
+ trim_trailing_whitespace = true
9
+ insert_final_newline = true
10
+
11
+ [*.md]
12
+ trim_trailing_whitespace = false
package/.nuxtrc ADDED
@@ -0,0 +1 @@
1
+ typescript.includeWorkspace = true
@@ -0,0 +1,5 @@
1
+ export default defineAppConfig({
2
+ myLayer: {
3
+ name: 'My amazing Nuxt layer (overwritten)'
4
+ }
5
+ })
@@ -0,0 +1,14 @@
1
+ import { fileURLToPath } from 'node:url'
2
+
3
+ export default defineNuxtConfig({
4
+ // Extends the prose layer (which in turn extends @base/)
5
+ extends: ['..'],
6
+
7
+ modules: ['@nuxt/eslint'],
8
+
9
+ eslint: {
10
+ config: {
11
+ rootDir: fileURLToPath(new URL('..', import.meta.url)),
12
+ },
13
+ },
14
+ })
@@ -0,0 +1,310 @@
1
+ <template>
2
+ <main class="library">
3
+ <header class="library-header">
4
+ <h1>Prose Layer Component Library</h1>
5
+ <nav class="library-nav">
6
+ <a href="#prose">Prose</a>
7
+ <a href="#headings">Headings</a>
8
+ <a href="#text">Text</a>
9
+ <a href="#lists">Lists</a>
10
+ <a href="#quotes">Quotes</a>
11
+ <a href="#code">Code</a>
12
+ <a href="#tables">Tables</a>
13
+ <a href="#images">Images</a>
14
+ </nav>
15
+ </header>
16
+
17
+ <section id="components">
18
+ <h2>Components</h2>
19
+
20
+ <!-- Prose Component -->
21
+ <article id="prose">
22
+ <h3>Prose</h3>
23
+
24
+ <div class="component-demo">
25
+ <h4>Default</h4>
26
+ <Prose>
27
+ <h1>This is a prose container</h1>
28
+ <p>The Prose component wraps content and applies consistent typography styles for long-form text content like articles, blog posts, and documentation.</p>
29
+ <p>It handles spacing, headings, links, lists, and other elements automatically.</p>
30
+ </Prose>
31
+ </div>
32
+
33
+ <div class="component-demo">
34
+ <h4>Centered</h4>
35
+ <Prose centered>
36
+ <h2>Centered Content</h2>
37
+ <p>Use the <code>centered</code> prop to center-align text content.</p>
38
+ </Prose>
39
+ </div>
40
+ </article>
41
+
42
+ <!-- Headings -->
43
+ <article id="headings">
44
+ <h3>Headings</h3>
45
+
46
+ <div class="component-demo">
47
+ <Prose>
48
+ <h1>Heading 1</h1>
49
+ <h2>Heading 2</h2>
50
+ <h3>Heading 3</h3>
51
+ <h4>Heading 4</h4>
52
+ <h5>Heading 5</h5>
53
+ <h6>Heading 6</h6>
54
+ </Prose>
55
+ </div>
56
+
57
+ <div class="component-demo">
58
+ <h4>With Links</h4>
59
+ <Prose>
60
+ <h2><a href="#">Linked Heading</a></h2>
61
+ <p>Headings can contain links that inherit the heading style.</p>
62
+ </Prose>
63
+ </div>
64
+ </article>
65
+
66
+ <!-- Text Content -->
67
+ <article id="text">
68
+ <h3>Text Content</h3>
69
+
70
+ <div class="component-demo">
71
+ <h4>Paragraphs</h4>
72
+ <Prose>
73
+ <p>This is a paragraph with regular text. It demonstrates the default styling applied to prose content including line height and spacing.</p>
74
+ <p>Multiple paragraphs are spaced evenly. Links in paragraphs are <a href="#">styled with underlines</a> to make them visible.</p>
75
+ </Prose>
76
+ </div>
77
+
78
+ <div class="component-demo">
79
+ <h4>Lead Text</h4>
80
+ <Prose>
81
+ <p class="lead">This is lead text, styled slightly larger for introductory content.</p>
82
+ <p>Regular paragraph text follows after the lead.</p>
83
+ </Prose>
84
+ </div>
85
+
86
+ <div class="component-demo">
87
+ <h4>Horizontal Rule</h4>
88
+ <Prose>
89
+ <p>Content above the rule.</p>
90
+ <hr>
91
+ <p>Content below the rule.</p>
92
+ </Prose>
93
+ </div>
94
+ </article>
95
+
96
+ <!-- Lists -->
97
+ <article id="lists">
98
+ <h3>Lists</h3>
99
+
100
+ <div class="component-demo">
101
+ <h4>Unordered List</h4>
102
+ <Prose>
103
+ <ul>
104
+ <li>First item</li>
105
+ <li>Second item</li>
106
+ <li>Third item with a longer description that wraps to multiple lines</li>
107
+ <li>
108
+ Nested list
109
+ <ul>
110
+ <li>Nested item one</li>
111
+ <li>Nested item two</li>
112
+ </ul>
113
+ </li>
114
+ </ul>
115
+ </Prose>
116
+ </div>
117
+
118
+ <div class="component-demo">
119
+ <h4>Ordered List</h4>
120
+ <Prose>
121
+ <ol>
122
+ <li>First step</li>
123
+ <li>Second step</li>
124
+ <li>Third step</li>
125
+ <li>
126
+ Nested steps
127
+ <ol>
128
+ <li>Sub-step one</li>
129
+ <li>Sub-step two</li>
130
+ </ol>
131
+ </li>
132
+ </ol>
133
+ </Prose>
134
+ </div>
135
+ </article>
136
+
137
+ <!-- Blockquotes -->
138
+ <article id="quotes">
139
+ <h3>Blockquotes</h3>
140
+
141
+ <div class="component-demo">
142
+ <h4>Basic Quote</h4>
143
+ <Prose>
144
+ <blockquote>
145
+ <p>This is a blockquote. It's styled with a left border and italic text to distinguish it from regular content.</p>
146
+ </blockquote>
147
+ </Prose>
148
+ </div>
149
+
150
+ <div class="component-demo">
151
+ <h4>With Citation</h4>
152
+ <Prose>
153
+ <blockquote>
154
+ <p>Design is not just what it looks like and feels like. Design is how it works.</p>
155
+ <cite>Steve Jobs</cite>
156
+ </blockquote>
157
+ </Prose>
158
+ </div>
159
+ </article>
160
+
161
+ <!-- Code -->
162
+ <article id="code">
163
+ <h3>Code</h3>
164
+
165
+ <div class="component-demo">
166
+ <h4>Inline Code</h4>
167
+ <Prose>
168
+ <p>Use the <code>Prose</code> component to wrap your content. Set <code>centered</code> for centered text.</p>
169
+ </Prose>
170
+ </div>
171
+
172
+ <div class="component-demo">
173
+ <h4>Code Block</h4>
174
+ <Prose>
175
+ <pre><code>&lt;Prose&gt;
176
+ &lt;h1&gt;Hello World&lt;/h1&gt;
177
+ &lt;p&gt;Your content here.&lt;/p&gt;
178
+ &lt;/Prose&gt;</code></pre>
179
+ </Prose>
180
+ </div>
181
+ </article>
182
+
183
+ <!-- Tables -->
184
+ <article id="tables">
185
+ <h3>Tables</h3>
186
+
187
+ <div class="component-demo">
188
+ <Prose>
189
+ <table>
190
+ <thead>
191
+ <tr>
192
+ <th>Property</th>
193
+ <th>Type</th>
194
+ <th>Default</th>
195
+ </tr>
196
+ </thead>
197
+ <tbody>
198
+ <tr>
199
+ <td>centered</td>
200
+ <td>boolean</td>
201
+ <td>false</td>
202
+ </tr>
203
+ </tbody>
204
+ </table>
205
+ </Prose>
206
+ </div>
207
+ </article>
208
+
209
+ <!-- Images -->
210
+ <article id="images">
211
+ <h3>Images</h3>
212
+
213
+ <div class="component-demo">
214
+ <h4>Basic Image</h4>
215
+ <Prose>
216
+ <p>Images in prose get consistent styling with borders and rounded corners.</p>
217
+ <img src="https://picsum.photos/600/300" alt="Sample image">
218
+ </Prose>
219
+ </div>
220
+
221
+ <div class="component-demo">
222
+ <h4>Figure with Caption</h4>
223
+ <Prose>
224
+ <figure>
225
+ <img src="https://picsum.photos/600/300?random=2" alt="Sample figure">
226
+ <figcaption>Figure caption styled in muted text below the image.</figcaption>
227
+ </figure>
228
+ </Prose>
229
+ </div>
230
+ </article>
231
+ </section>
232
+ </main>
233
+ </template>
234
+
235
+ <script setup lang="ts">
236
+ </script>
237
+
238
+ <style scoped>
239
+ .library {
240
+ max-width: var(--content-width);
241
+ margin: 0 auto;
242
+ padding: var(--spacer-lg);
243
+ display: grid;
244
+ gap: var(--spacer-xl);
245
+ }
246
+
247
+ .library-header {
248
+ border-bottom: var(--border);
249
+ padding-bottom: var(--spacer-lg);
250
+ }
251
+
252
+ .library-header h1 {
253
+ font-size: var(--font-2xl);
254
+ margin-bottom: var(--spacer);
255
+ }
256
+
257
+ .library-nav {
258
+ display: flex;
259
+ gap: var(--spacer);
260
+ flex-wrap: wrap;
261
+ }
262
+
263
+ .library-nav a {
264
+ font-family: var(--font-family);
265
+ font-size: var(--ui-font-size);
266
+ text-transform: var(--ui-text-transform);
267
+ color: var(--muted);
268
+ text-decoration: none;
269
+
270
+ &:hover {
271
+ color: var(--color);
272
+ }
273
+ }
274
+
275
+ section {
276
+ display: grid;
277
+ gap: var(--spacer-lg);
278
+ }
279
+
280
+ section > h2 {
281
+ font-size: var(--font-xl);
282
+ border-bottom: var(--border);
283
+ padding-bottom: var(--spacer-sm);
284
+ }
285
+
286
+ article {
287
+ display: grid;
288
+ gap: var(--spacer);
289
+ }
290
+
291
+ article > h3 {
292
+ font-family: var(--font-family);
293
+ font-size: var(--ui-font-size);
294
+ text-transform: var(--ui-text-transform);
295
+ color: var(--muted);
296
+ }
297
+
298
+ .component-demo {
299
+ display: grid;
300
+ gap: var(--spacer-sm);
301
+ padding: var(--spacer);
302
+ background: var(--gray-z-0);
303
+ border: var(--border);
304
+ }
305
+
306
+ .component-demo h4 {
307
+ font-size: var(--font-sm);
308
+ color: var(--muted);
309
+ }
310
+ </style>
package/AGENTS.md ADDED
@@ -0,0 +1,32 @@
1
+ # AGENTS.md
2
+
3
+ Nuxt layer for content-driven sites with typography and prose styling. Extends `@1001-digital/layers.base`.
4
+
5
+ ## Setup commands
6
+
7
+ - Install deps: `pnpm install`
8
+ - Start dev server: `pnpm dev`
9
+ - Run tests: `pnpm test`
10
+
11
+ ## Styling
12
+
13
+ - Typography styles in `app/assets/styles/layers/prose.css`
14
+ - Uses CSS layer `@layer(components)` for cascade control
15
+ - Inherits CSS variables from base layer
16
+
17
+ ## Components
18
+
19
+ - `Prose.vue` - Main wrapper for prose content, applies typography and spacing
20
+ - Props: `centered` (boolean) for center-aligned text
21
+ - Styled elements within `.prose`: headings, links, blockquotes, lists, code blocks, tables, footnotes
22
+
23
+ ## Key directories
24
+
25
+ ```
26
+ app/
27
+ ├── components/
28
+ │ └── Prose.vue # Main prose container
29
+ ├── assets/styles/
30
+ │ └── layers/
31
+ │ └── prose.css # Typography & content styles
32
+ ```
package/README.md ADDED
@@ -0,0 +1,73 @@
1
+ # Nuxt Layer Starter
2
+
3
+ Create Nuxt extendable layer with this GitHub template.
4
+
5
+ ## Setup
6
+
7
+ Make sure to install the dependencies:
8
+
9
+ ```bash
10
+ pnpm install
11
+ ```
12
+
13
+ ## Working on your layer
14
+
15
+ Your layer is at the root of this repository, it is exactly like a regular Nuxt project, except you can publish it on NPM.
16
+
17
+ The `.playground` directory should help you on trying your layer during development.
18
+
19
+ Running `pnpm dev` will prepare and boot `.playground` directory, which imports your layer itself.
20
+
21
+ ## Distributing your layer
22
+
23
+ Your Nuxt layer is shaped exactly the same as any other Nuxt project, except you can publish it on NPM.
24
+
25
+ To do so, you only have to check if `files` in `package.json` are valid, then run:
26
+
27
+ ```bash
28
+ npm publish --access public
29
+ ```
30
+
31
+ Once done, your users will only have to run:
32
+
33
+ ```bash
34
+ npm install --save your-layer
35
+ ```
36
+
37
+ Then add the dependency to their `extends` in `nuxt.config`:
38
+
39
+ ```ts
40
+ defineNuxtConfig({
41
+ extends: 'your-layer'
42
+ })
43
+ ```
44
+
45
+ ## Development Server
46
+
47
+ Start the development server on http://localhost:3000
48
+
49
+ ```bash
50
+ pnpm dev
51
+ ```
52
+
53
+ ## Production
54
+
55
+ Build the application for production:
56
+
57
+ ```bash
58
+ pnpm build
59
+ ```
60
+
61
+ Or statically generate it with:
62
+
63
+ ```bash
64
+ pnpm generate
65
+ ```
66
+
67
+ Locally preview production build:
68
+
69
+ ```bash
70
+ pnpm preview
71
+ ```
72
+
73
+ Checkout the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information.
package/app/app.vue ADDED
@@ -0,0 +1,3 @@
1
+ <template>
2
+ <NuxtPage />
3
+ </template>
@@ -0,0 +1,6 @@
1
+ /*
2
+ * Prose Layer Styles
3
+ * Extends @base/ layer with prose/typography styling
4
+ */
5
+
6
+ @import './layers/prose.css' layer(components);
@@ -0,0 +1,249 @@
1
+ /*
2
+ * Prose Layer
3
+ * Typography and content styling
4
+ */
5
+
6
+ .prose {
7
+ /* Spacing */
8
+ > * {
9
+ margin: var(--spacer) 0;
10
+ color: var(--color);
11
+
12
+ &:first-child {
13
+ margin-top: 0;
14
+ }
15
+
16
+ &:last-child {
17
+ margin-bottom: 0;
18
+ }
19
+ }
20
+
21
+ /* Headings */
22
+ h1,
23
+ h2,
24
+ h3,
25
+ h4,
26
+ h5,
27
+ h6 {
28
+ width: 100%;
29
+ position: relative;
30
+ margin: var(--spacer) 0;
31
+ color: var(--color);
32
+ font-family: var(--font-family);
33
+ font-weight: var(--font-weight-bold);
34
+ }
35
+
36
+ h1 {
37
+ font-size: var(--font-xl);
38
+ }
39
+
40
+ h2,
41
+ h3,
42
+ h4,
43
+ h5,
44
+ h6,
45
+ .lead {
46
+ font-size: var(--font-lg);
47
+ }
48
+
49
+ hr {
50
+ margin: var(--spacer-lg) 0;
51
+ border-color: var(--gray-z-4, var(--muted));
52
+ }
53
+
54
+ > table {
55
+ margin: var(--spacer) 0;
56
+
57
+ th,
58
+ td {
59
+ padding: calc(var(--spacer-sm) - var(--spacer-xs)) var(--spacer-sm);
60
+ border: var(--border);
61
+ }
62
+ }
63
+
64
+ /* Links */
65
+ a {
66
+ color: var(--primary);
67
+ font-weight: bold;
68
+ transition: all var(--speed);
69
+
70
+ &.muted {
71
+ color: var(--gray-z-9, var(--muted));
72
+ }
73
+ }
74
+
75
+ h1,
76
+ h2,
77
+ h3,
78
+ h4,
79
+ h5,
80
+ h6 {
81
+ > a {
82
+ color: inherit;
83
+ border-bottom: none;
84
+ font-weight: inherit;
85
+ }
86
+ }
87
+
88
+ /* Quotes */
89
+ blockquote {
90
+ padding-left: var(--spacer);
91
+ font-size: var(--font-lg);
92
+ font-family: var(--font-family);
93
+ line-height: var(--line-height-lg);
94
+ border-left: 4px solid var(--primary);
95
+ font-style: italic;
96
+ font-weight: bold;
97
+ color: var(--gray-z-7, var(--muted));
98
+
99
+ cite {
100
+ display: block;
101
+ font-size: var(--font-sm);
102
+ line-height: var(--line-height-sm);
103
+ text-align: right;
104
+ margin: 1em 0 0;
105
+
106
+ &:before {
107
+ content: '\2013';
108
+ margin-right: 0.5em;
109
+ }
110
+ }
111
+ }
112
+
113
+ /* Images */
114
+ figure figcaption,
115
+ p:has(> img) {
116
+ font-size: var(--font-sm);
117
+ line-height: var(--line-height-sm);
118
+ color: var(--gray-z-7, var(--muted));
119
+ }
120
+
121
+ figure > img,
122
+ p > img,
123
+ > img {
124
+ border: var(--image-border);
125
+ border-radius: var(--image-border-radius);
126
+ }
127
+
128
+ figure:has(img),
129
+ > img {
130
+ margin: var(--spacer-md) 0;
131
+ }
132
+
133
+ /* Lists */
134
+ ol {
135
+ list-style: auto;
136
+ }
137
+
138
+ ul {
139
+ list-style: none;
140
+
141
+ > li {
142
+ position: relative;
143
+ }
144
+
145
+ > li:before {
146
+ content: '\2022';
147
+ position: absolute;
148
+ color: var(--gray-z-5, var(--muted));
149
+ font-weight: bold;
150
+ display: inline-block;
151
+ width: 1em;
152
+ margin-left: -1em;
153
+ }
154
+ }
155
+
156
+ ul,
157
+ ol {
158
+ padding-left: 1em;
159
+
160
+ li {
161
+ margin: 0.25em 0;
162
+ }
163
+
164
+ ul,
165
+ ol {
166
+ margin: 0;
167
+
168
+ li {
169
+ margin: 0;
170
+ }
171
+ }
172
+ }
173
+
174
+ /* Footnotes */
175
+ sup a,
176
+ .data-footnote-backref {
177
+ color: var(--gray-z-7, var(--muted));
178
+ padding: 0 0 0 var(--size-0);
179
+
180
+ &:is(:hover, :active, :focus, .active) {
181
+ color: var(--primary);
182
+ }
183
+ }
184
+
185
+ .data-footnote-backref {
186
+ font-size: var(--font-sm);
187
+ }
188
+
189
+ .footnotes {
190
+ font-size: var(--font-sm);
191
+ color: var(--gray-z-7, var(--muted));
192
+ border-top: var(--border);
193
+ margin-top: calc(2 * var(--size-5));
194
+ padding-top: var(--size-5);
195
+ }
196
+
197
+ /* Code */
198
+ pre:has(> code) {
199
+ padding: var(--ui-padding-block) var(--ui-padding-inline);
200
+ background-color: var(--gray-z-1, var(--background));
201
+ border: var(--border);
202
+ border-radius: var(--border-radius);
203
+ font-size: 0.8em;
204
+ overflow: scroll;
205
+
206
+ > code {
207
+ border: 0;
208
+ border-radius: 0;
209
+ padding: 0;
210
+ font-size: 1em;
211
+ }
212
+ }
213
+
214
+ /* Table */
215
+ > table {
216
+ margin: var(--size-4) 0;
217
+ }
218
+
219
+ /* Space */
220
+ > *:first-child,
221
+ > *:first-child > * {
222
+ margin-top: 0;
223
+ }
224
+
225
+ > *:last-child,
226
+ > *:last-child > * {
227
+ margin-bottom: 0;
228
+ }
229
+
230
+ &.centered {
231
+ text-align: center;
232
+ }
233
+
234
+ iframe {
235
+ max-width: 100%;
236
+ }
237
+ }
238
+
239
+ /* General prose rules */
240
+ .prose-title {
241
+ font-size: var(--font-xl);
242
+ }
243
+
244
+ /* Links in paragraphs */
245
+ p {
246
+ a {
247
+ text-decoration: underline;
248
+ }
249
+ }
@@ -0,0 +1,10 @@
1
+ <script setup lang="ts">
2
+ const { myLayer } = useAppConfig()
3
+ </script>
4
+
5
+ <template>
6
+ <div>
7
+ <h1>Hello World!</h1>
8
+ <pre>{{ myLayer }}</pre>
9
+ </div>
10
+ </template>
@@ -0,0 +1,11 @@
1
+ <template>
2
+ <div class="prose" :class="{ centered }">
3
+ <slot />
4
+ </div>
5
+ </template>
6
+
7
+ <script setup lang="ts">
8
+ defineProps<{
9
+ centered?: boolean
10
+ }>()
11
+ </script>
package/app.config.ts ADDED
@@ -0,0 +1,14 @@
1
+ export default defineAppConfig({
2
+ myLayer: {
3
+ name: 'Hello from Nuxt layer'
4
+ }
5
+ })
6
+
7
+ declare module '@nuxt/schema' {
8
+ interface AppConfigInput {
9
+ myLayer?: {
10
+ /** Project name */
11
+ name?: string
12
+ }
13
+ }
14
+ }
@@ -0,0 +1,3 @@
1
+ import withNuxt from './.playground/.nuxt/eslint.config.mjs'
2
+
3
+ export default withNuxt()
package/nuxt.config.ts ADDED
@@ -0,0 +1,15 @@
1
+ import { fileURLToPath } from 'node:url'
2
+ import { dirname, join } from 'node:path'
3
+
4
+ const currentDir = dirname(fileURLToPath(import.meta.url))
5
+
6
+ // https://nuxt.com/docs/api/configuration/nuxt-config
7
+ export default defineNuxtConfig({
8
+ devtools: { enabled: true },
9
+
10
+ extends: ['@1001-digital/layers.base'],
11
+
12
+ css: [
13
+ join(currentDir, './app/assets/styles/index.css'),
14
+ ],
15
+ })
package/package.json ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "@1001-digital/layers.prose",
3
+ "type": "module",
4
+ "version": "0.0.2",
5
+ "main": "./nuxt.config.ts",
6
+ "devDependencies": {
7
+ "@nuxt/eslint": "latest",
8
+ "@types/node": "^24.10.4",
9
+ "eslint": "^9.39.2",
10
+ "nuxt": "^4.2.2",
11
+ "typescript": "^5.9.3",
12
+ "vue": "latest"
13
+ },
14
+ "dependencies": {
15
+ "@1001-digital/layers.base": "0.0.2"
16
+ },
17
+ "scripts": {
18
+ "dev": "nuxi dev .playground",
19
+ "dev:prepare": "nuxt prepare .playground",
20
+ "build": "nuxt build .playground",
21
+ "generate": "nuxt generate .playground",
22
+ "preview": "nuxt preview .playground",
23
+ "lint": "eslint ."
24
+ }
25
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,3 @@
1
+ {
2
+ "extends": "./.playground/.nuxt/tsconfig.json"
3
+ }