@sarimarcus/content-sites-ui 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
All packages in the platform release in lockstep; entries are per release version.
|
|
4
4
|
|
|
5
|
+
## 0.5.0 (2026-09-29)
|
|
6
|
+
|
|
7
|
+
- Stable release of 0.5.0-rc.0, unchanged: adopted on all three sites with every page identical outside class attributes and every class change a declared brand→role pair; screenshots unchanged (SLA-2821).
|
|
8
|
+
|
|
9
|
+
## 0.5.0-rc.0 (2026-09-29)
|
|
10
|
+
|
|
11
|
+
- `./primitives`: `ArrowLabel`, `SectionDivider` and `LinkArrow` (`color` is a theme role: `primary`, `secondary`, `accent`, `onImage`; external hrefs open in a new tab unless `target`/`rel` are given) (SLA-2821).
|
|
12
|
+
|
|
5
13
|
## 0.4.0 (2026-09-29)
|
|
6
14
|
|
|
7
15
|
- Stable release of 0.4.0-rc.0, unchanged: adopted on all three sites with every page identical through the class-alias oracle and screenshots unchanged (SLA-2821).
|
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ text arrives through props and slots.
|
|
|
11
11
|
## Primitives
|
|
12
12
|
|
|
13
13
|
```ts
|
|
14
|
-
import { Icon, Badge, Chip, PILL_BASE, isBadgeLength, PRICE_LABEL_MAX } from '@sarimarcus/content-sites-ui/primitives';
|
|
14
|
+
import { Icon, Badge, Chip, ArrowLabel, SectionDivider, LinkArrow, PILL_BASE, isBadgeLength, PRICE_LABEL_MAX } from '@sarimarcus/content-sites-ui/primitives';
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
- `Icon`: any Lucide icon by kebab-case name.
|
|
@@ -22,6 +22,13 @@ import { Icon, Badge, Chip, PILL_BASE, isBadgeLength, PRICE_LABEL_MAX } from '@s
|
|
|
22
22
|
focus colour (`primary` (default), `secondary`, `accent`, `neutral`). `active` emits `data-active="true"|"false"`
|
|
23
23
|
only when set; scripts must write `dataset.active = 'true'|'false'`, never add or remove the attribute. Other
|
|
24
24
|
attributes pass through last, so markers such as `data-section-link` reach the element.
|
|
25
|
+
- `ArrowLabel`: a label followed by an arrow that shifts right on `group-hover`. It carries no colour: the caller's
|
|
26
|
+
`class` sets it; `arrowClass` sizes the arrow (default `h-4 w-4`).
|
|
27
|
+
- `SectionDivider`: a break between sections. `variant` is `dots` (default), `line`, or `quote` (with `quote` and
|
|
28
|
+
an optional `source`).
|
|
29
|
+
- `LinkArrow`: a text link with a trailing arrow. `color` is `primary` (default), `secondary`, `accent` or `onImage`;
|
|
30
|
+
`size` is `sm` (default) or `base`. An `http(s)` href opens in a new tab with `rel="noopener noreferrer"`; an
|
|
31
|
+
explicit `target` (`_blank` or `_self`) or `rel` overrides that. Attributes render as `href target rel class`.
|
|
25
32
|
- `PILL_BASE`: the shared pill geometry. `isBadgeLength`, `BADGE_MAX_CHARS`, `PRICE_LABEL_MAX`: the label-length
|
|
26
33
|
limits a call site branches on (pill or prose); a price-range schema `.max()` must equal `PRICE_LABEL_MAX`.
|
|
27
34
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sarimarcus/content-sites-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Universal Astro UI components, layout shell and design tokens shared by the content sites.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -42,6 +42,6 @@
|
|
|
42
42
|
"@lucide/astro": "^1.23.0",
|
|
43
43
|
"astro": "^7.0.6",
|
|
44
44
|
"tailwindcss": "^4.1.18",
|
|
45
|
-
"@sarimarcus/content-sites-core": "0.
|
|
45
|
+
"@sarimarcus/content-sites-core": "0.5.0"
|
|
46
46
|
}
|
|
47
47
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
interface Props {
|
|
3
|
+
class?: string;
|
|
4
|
+
arrowClass?: string;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
const { class: className = '', arrowClass = 'h-4 w-4' } = Astro.props;
|
|
8
|
+
---
|
|
9
|
+
<span class:list={['inline-flex items-center gap-2', className]}>
|
|
10
|
+
<slot />
|
|
11
|
+
<svg
|
|
12
|
+
class:list={[arrowClass, 'shrink-0 transition-transform group-hover:translate-x-1']}
|
|
13
|
+
viewBox="0 0 24 24"
|
|
14
|
+
fill="none"
|
|
15
|
+
stroke="currentColor"
|
|
16
|
+
stroke-width="2"
|
|
17
|
+
stroke-linecap="round"
|
|
18
|
+
stroke-linejoin="round"
|
|
19
|
+
aria-hidden="true"
|
|
20
|
+
>
|
|
21
|
+
<path d="M5 12h14" />
|
|
22
|
+
<path d="m12 5 7 7-7 7" />
|
|
23
|
+
</svg>
|
|
24
|
+
</span>
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
interface Props {
|
|
3
|
+
href: string;
|
|
4
|
+
size?: 'sm' | 'base';
|
|
5
|
+
color?: 'primary' | 'secondary' | 'accent' | 'onImage';
|
|
6
|
+
/** Overrides the http(s) detection: '_blank' on any href, '_self' to keep an off-site link in the tab. */
|
|
7
|
+
target?: '_blank' | '_self';
|
|
8
|
+
/** Defaults to 'noopener noreferrer' whenever the link opens a new tab. */
|
|
9
|
+
rel?: string;
|
|
10
|
+
class?: string;
|
|
11
|
+
}
|
|
12
|
+
const { href, size = 'sm', color = 'primary', target: targetProp, rel: relProp, class: className = '' } = Astro.props;
|
|
13
|
+
|
|
14
|
+
const isExternal = href.startsWith('http://') || href.startsWith('https://');
|
|
15
|
+
const target = targetProp ?? (isExternal ? '_blank' : undefined);
|
|
16
|
+
const rel = relProp ?? (target === '_blank' ? 'noopener noreferrer' : undefined);
|
|
17
|
+
|
|
18
|
+
const sizeClass = size === 'base' ? 'text-base font-medium' : 'text-sm font-medium';
|
|
19
|
+
const colorClass = {
|
|
20
|
+
primary: 'text-primary hover:text-primary-strong',
|
|
21
|
+
secondary: 'text-secondary hover:text-secondary-strong',
|
|
22
|
+
accent: 'text-accent-strong hover:text-accent',
|
|
23
|
+
onImage: 'text-overlay-foreground/90 hover:text-overlay-foreground',
|
|
24
|
+
}[color];
|
|
25
|
+
---
|
|
26
|
+
<a
|
|
27
|
+
href={href}
|
|
28
|
+
target={target}
|
|
29
|
+
rel={rel}
|
|
30
|
+
class:list={[
|
|
31
|
+
"group inline-flex items-center gap-2 transition-colors",
|
|
32
|
+
sizeClass,
|
|
33
|
+
colorClass,
|
|
34
|
+
className
|
|
35
|
+
]}
|
|
36
|
+
>
|
|
37
|
+
<slot />
|
|
38
|
+
<svg
|
|
39
|
+
class="w-4 h-4 transition-transform group-hover:translate-x-1"
|
|
40
|
+
viewBox="0 0 24 24"
|
|
41
|
+
fill="none"
|
|
42
|
+
stroke="currentColor"
|
|
43
|
+
stroke-width="2"
|
|
44
|
+
stroke-linecap="round"
|
|
45
|
+
stroke-linejoin="round"
|
|
46
|
+
aria-hidden="true"
|
|
47
|
+
>
|
|
48
|
+
<path d="M5 12h14" /><path d="m12 5 7 7-7 7" />
|
|
49
|
+
</svg>
|
|
50
|
+
</a>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
// Rhythm breaker between content sections: dots (the default), a thin rule, or a pull quote.
|
|
3
|
+
interface Props {
|
|
4
|
+
variant?: 'dots' | 'line' | 'quote';
|
|
5
|
+
quote?: string;
|
|
6
|
+
source?: string;
|
|
7
|
+
class?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const {
|
|
11
|
+
variant = 'dots',
|
|
12
|
+
quote,
|
|
13
|
+
source,
|
|
14
|
+
class: className = '',
|
|
15
|
+
} = Astro.props;
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
{variant === 'dots' && (
|
|
19
|
+
<div class:list={['flex items-center justify-center gap-2 py-8', className]} aria-hidden="true">
|
|
20
|
+
<span class="w-1.5 h-1.5 rounded-full bg-primary/40"></span>
|
|
21
|
+
<span class="w-1.5 h-1.5 rounded-full bg-accent/50"></span>
|
|
22
|
+
<span class="w-1.5 h-1.5 rounded-full bg-primary/40"></span>
|
|
23
|
+
</div>
|
|
24
|
+
)}
|
|
25
|
+
|
|
26
|
+
{variant === 'line' && (
|
|
27
|
+
<div class:list={['py-8', className]} aria-hidden="true">
|
|
28
|
+
<hr class="border-0 h-px bg-gradient-to-r from-transparent via-border to-transparent" />
|
|
29
|
+
</div>
|
|
30
|
+
)}
|
|
31
|
+
|
|
32
|
+
{variant === 'quote' && quote && (
|
|
33
|
+
<figure class:list={['py-10 px-6 sm:px-10 my-8 border border-primary/40 bg-primary/5 rounded-xl', className]}>
|
|
34
|
+
<blockquote class="text-lg sm:text-xl italic text-foreground/80 leading-relaxed font-display">
|
|
35
|
+
“{quote}”
|
|
36
|
+
</blockquote>
|
|
37
|
+
{source && (
|
|
38
|
+
<figcaption class="mt-3 text-sm text-muted-foreground">
|
|
39
|
+
— {source}
|
|
40
|
+
</figcaption>
|
|
41
|
+
)}
|
|
42
|
+
</figure>
|
|
43
|
+
)}
|
package/src/primitives/index.ts
CHANGED
|
@@ -2,5 +2,8 @@
|
|
|
2
2
|
export { default as Icon } from './Icon.astro';
|
|
3
3
|
export { default as Badge } from './Badge.astro';
|
|
4
4
|
export { default as Chip } from './Chip.astro';
|
|
5
|
+
export { default as ArrowLabel } from './ArrowLabel.astro';
|
|
6
|
+
export { default as SectionDivider } from './SectionDivider.astro';
|
|
7
|
+
export { default as LinkArrow } from './LinkArrow.astro';
|
|
5
8
|
export { PILL_BASE } from './pillRecipe';
|
|
6
9
|
export { BADGE_MAX_CHARS, PRICE_LABEL_MAX, isBadgeLength } from './badgeText';
|