Blog #1
@@ -9,12 +9,14 @@ import Figure from '../media/Figure.astro'
|
||||
import Callout from './blocks/general/Callout.astro'
|
||||
import Lead from './blocks/general/Lead.astro'
|
||||
import Quote from './blocks/general/Quote.astro'
|
||||
import Reveal from './blocks/general/Reveal.astro'
|
||||
import TableWrapper from './blocks/general/TableWrapper.astro'
|
||||
|
||||
type Props = { node: RenderableTreeNode | RenderableTreeNode[] }
|
||||
|
||||
const COMPONENTS: Record<string, AstroComponentFactory> = {
|
||||
Callout,
|
||||
Reveal,
|
||||
Figure,
|
||||
TableWrapper,
|
||||
Quote,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
import type { CalloutType } from '@/lib/constants/blocks/notes'
|
||||
import { NOTE_TYPES, type CalloutType } from '@/lib/constants/blocks/notes'
|
||||
|
||||
type Props = {
|
||||
type?: CalloutType
|
||||
@@ -7,11 +7,15 @@ type Props = {
|
||||
}
|
||||
|
||||
const { type = 'default', title } = Astro.props
|
||||
|
||||
const kind = NOTE_TYPES.find((option) => option.value === type)?.label ?? type
|
||||
---
|
||||
|
||||
<aside class:list={['callout', `callout--${type}`]}>
|
||||
{title && <p class="callout__title">{title}</p>}
|
||||
<div class:list={['callout__kind', type !== 'optional' && 'dark']}>{kind}</div>
|
||||
|
||||
<div class="callout__body">
|
||||
{title && <p class="callout__title">{title}</p>}
|
||||
<slot />
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
12
src/components/markdoc/blocks/general/Reveal.astro
Normal file
12
src/components/markdoc/blocks/general/Reveal.astro
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
type Props = { summary?: string }
|
||||
|
||||
const { summary = 'Spoiler' } = Astro.props
|
||||
---
|
||||
|
||||
<details class="reveal">
|
||||
<summary class="reveal__summary">{summary}</summary>
|
||||
<div class="reveal__body">
|
||||
<slot />
|
||||
</div>
|
||||
</details>
|
||||
@@ -67,7 +67,11 @@ All things are poison, and nothing is without poison; the dosage alone makes it
|
||||
|
||||
## Callouts
|
||||
|
||||
{% callout type="default" title="Note" %}
|
||||
{% callout type="default" title="TITA TITLE" %}
|
||||
I AM DONE WITH THIS SHIT! SO COMPLETELY AND TOTALLY DONE!
|
||||
{% /callout %}
|
||||
|
||||
{% callout type="optional" title="Note" %}
|
||||
A default callout with a [link](https://example.com) and `code` inside it.
|
||||
{% /callout %}
|
||||
|
||||
@@ -78,6 +82,10 @@ An example callout containing a list:
|
||||
- two
|
||||
{% /callout %}
|
||||
|
||||
{% reveal summary="Spoiler" %}
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. This first paragraph is the lead, so it should be larger and carry the drop cap. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. A sentence with *emphasis*, **strong text**, `inline code`, ~~struck text~~ and an [external link](https://example.com).
|
||||
{% /reveal %}
|
||||
|
||||
## Code
|
||||
|
||||
```js
|
||||
|
||||
@@ -3,6 +3,7 @@ import { figure } from './figure'
|
||||
import { footnote } from './footnote'
|
||||
import { lead } from './lead'
|
||||
import { quote } from './quote'
|
||||
import { reveal } from './reveal'
|
||||
import { sidenote } from './sidenote'
|
||||
import { tableWrapper } from './table-wrapper'
|
||||
import { xref } from './xref'
|
||||
@@ -15,5 +16,6 @@ export const generalBlocks = (collection: string) => ({
|
||||
sidenote,
|
||||
tableWrapper,
|
||||
quote,
|
||||
reveal,
|
||||
xref: xref(),
|
||||
})
|
||||
|
||||
14
src/keystatic/blocks/general/reveal.ts
Normal file
14
src/keystatic/blocks/general/reveal.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { fields } from '@keystatic/core'
|
||||
import { wrapper } from '@keystatic/core/content-components'
|
||||
|
||||
export const reveal = wrapper({
|
||||
label: 'Reveal',
|
||||
description: 'A spoiler around any content, closed until the reader opens it',
|
||||
schema: {
|
||||
summary: fields.text({
|
||||
label: 'Label',
|
||||
description: 'What the reader sees before opening.',
|
||||
defaultValue: 'Spoiler',
|
||||
}),
|
||||
},
|
||||
})
|
||||
@@ -1,12 +1,16 @@
|
||||
export const NOTE_TYPES = [
|
||||
{
|
||||
label: 'Default',
|
||||
label: 'Note',
|
||||
value: 'default',
|
||||
},
|
||||
{
|
||||
label: 'Example',
|
||||
value: 'example',
|
||||
},
|
||||
{
|
||||
label: 'Optional',
|
||||
value: 'optional',
|
||||
},
|
||||
] as const
|
||||
|
||||
export type CalloutType = (typeof NOTE_TYPES)[number]['value']
|
||||
|
||||
@@ -64,6 +64,7 @@ const generated =
|
||||
figure: 'Figure',
|
||||
tableWrapper: 'TableWrapper',
|
||||
quote: 'Quote',
|
||||
reveal: 'Reveal',
|
||||
},
|
||||
},
|
||||
}).tags ?? {}
|
||||
|
||||
@@ -183,6 +183,7 @@
|
||||
--slot-prose-marker: 1.625rem;
|
||||
--slot-prose-gap: var(--size-6);
|
||||
--slot-prose-bar: var(--size-8);
|
||||
--slot-callout-cell: 8.5rem;
|
||||
|
||||
/* ═══ MOTION ═══ */
|
||||
--motion-fast: 150ms; /* state change: hover, focus, press */
|
||||
|
||||
90
src/styles/components/callout.css
Normal file
90
src/styles/components/callout.css
Normal file
@@ -0,0 +1,90 @@
|
||||
@layer components {
|
||||
.callout {
|
||||
@mixin my var(--space-9);
|
||||
counter-increment: box;
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: var(--slot-callout-cell) minmax(0, 1fr);
|
||||
|
||||
border: var(--border-card) solid var(--color-border-strong);
|
||||
|
||||
background-color: var(--color-surface-elevated-1);
|
||||
box-shadow: var(--shadow-card);
|
||||
}
|
||||
|
||||
.callout__kind {
|
||||
@mixin typo_label;
|
||||
@mixin ma var(--size-0);
|
||||
@mixin py var(--size-6);
|
||||
@mixin px var(--size-7);
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
|
||||
border-inline-end: var(--border-card) solid var(--color-border-strong);
|
||||
|
||||
color: var(--color-text-primary);
|
||||
|
||||
background-color: var(--color-surface-base);
|
||||
|
||||
&::after {
|
||||
content: "Box " counter(sec, upper-roman) "." counter(box);
|
||||
|
||||
font-family: var(--font-mono);
|
||||
font-size: var(--type--3);
|
||||
font-weight: var(--font-weight-body);
|
||||
color: var(--color-text-quarternary);
|
||||
}
|
||||
}
|
||||
|
||||
.callout__title {
|
||||
@mixin typo_heading-4;
|
||||
@mixin mt var(--size-0);
|
||||
@mixin mb var(--size-5);
|
||||
|
||||
font-size: var(--type-0);
|
||||
}
|
||||
|
||||
.callout__body {
|
||||
@mixin py var(--size-6);
|
||||
@mixin px var(--size-8);
|
||||
|
||||
& > :first-child {
|
||||
margin-block-start: var(--size-0);
|
||||
}
|
||||
|
||||
& > :last-child {
|
||||
margin-block-end: var(--size-0);
|
||||
}
|
||||
}
|
||||
|
||||
.callout--example {
|
||||
& .callout__kind {
|
||||
background-color: var(--color-surface-elevated-3);
|
||||
}
|
||||
}
|
||||
|
||||
.callout--optional {
|
||||
border-width: var(--border-hairline);
|
||||
background-color: transparent;
|
||||
box-shadow: none;
|
||||
|
||||
& .callout__kind {
|
||||
border-inline-end: var(--border-hairline) solid var(--color-border-normal);
|
||||
color: var(--color-text-primary);
|
||||
background-color: transparent;
|
||||
|
||||
&::after {
|
||||
color: var(--color-text-quiet);
|
||||
}
|
||||
}
|
||||
|
||||
& .callout__title {
|
||||
@mixin typo_label;
|
||||
|
||||
font-size: var(--type--2);
|
||||
color: var(--color-text-quiet);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
@import url("prose.css");
|
||||
@import url("quote.css");
|
||||
@import url("lead.css");
|
||||
@import url("callout.css");
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
.prose {
|
||||
@mixin typo_body;
|
||||
|
||||
counter-reset: sec sub tbl fig;
|
||||
counter-reset: sec sub tbl fig box;
|
||||
|
||||
& > :first-child {
|
||||
margin-block-start: var(--size-0);
|
||||
@@ -35,7 +35,7 @@
|
||||
@mixin mt var(--space-11);
|
||||
@mixin mb var(--space-8);
|
||||
@mixin ps var(--size-9);
|
||||
counter-set: sub 0 fig 0;
|
||||
counter-set: sub 0 fig 0 box 0;
|
||||
counter-increment: sec;
|
||||
|
||||
clear: both;
|
||||
|
||||
Reference in New Issue
Block a user