Compare commits

..

9 Commits

Author SHA1 Message Date
unkn0wn 027cec577d feat: updating package to version 1.00.0
Publish to npm / check-and-publish (push) Successful in 22s
2026-06-23 12:36:10 +02:00
unkn0wn 6e077aaeed style: update Navbar and Select component styles for improved consistency and usability 2026-06-23 12:35:23 +02:00
unkn0wn 1d9001705f feat: adding Sidebar and SidebarItem 2026-06-23 12:35:12 +02:00
unkn0wn 1878ec3a0e feat: add Card and Navbar components with styles
- Implemented Card component with cover, title, subtitle, content, and footer slots.
- Added styles for Card component in _card.scss.
- Created Navbar component with brand and links, including styles in _navbar.scss.
- Updated index.astro to include new Card and Navbar components.
2026-06-23 11:40:04 +02:00
unkn0wn b48581b089 feat: implement Modal component with overlay and dialog structure 2026-06-23 11:25:39 +02:00
unkn0wn 3593305512 feat: add Tooltip component and update styles in Button and index page 2026-06-23 11:08:24 +02:00
unkn0wn 6967f3c7cd refactor: reorganize component imports and enhance index page layout
- Grouped component imports into categories for better organization.
- Updated the layout of the index page to include a gallery structure.
- Added new sections for Button, Badge, Selection Controls, TextField, Select, Numeric Stepper, Avatar, Loading Bar, List Item, Link, Tabs, Breadcrumb, Pagination, Notification, Tooltip, Card, Navbar, Sidebar, Modal, and Icons.
- Improved styling for better visual hierarchy and spacing.
- Implemented a theme toggle feature with persistent state using localStorage.
2026-06-23 10:51:40 +02:00
unkn0wn dea517fbe5 feat: adding Badge, Breadcrumb, Checkbox et Radio components 2026-06-23 10:12:04 +02:00
unkn0wn cc54ae46ff style: refactor Button and numericStepper components for improved accessibility and styling 2026-06-23 10:07:39 +02:00
45 changed files with 3122 additions and 785 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "@unkn0wndo3s/nova-design-system", "name": "@unkn0wndo3s/nova-design-system",
"type": "module", "type": "module",
"version": "0.06.1", "version": "1.00.0",
"main": "./src/index.ts", "main": "./src/index.ts",
"description": "Nova Design System — Astro component library", "description": "Nova Design System — Astro component library",
"engines": { "engines": {
+58
View File
@@ -0,0 +1,58 @@
@use "../../styles/tokens/typography" as *;
.badge {
display: inline-flex;
align-items: center;
gap: var(--nds-spacing-2xs);
padding: 3px var(--nds-spacing-xs);
border-radius: var(--nds-radius-full);
@include text-sm;
font-weight: 600;
line-height: 1.2;
width: fit-content;
white-space: nowrap;
&__primary {
--c: var(--nds-primary);
--on: var(--nds-on-primary);
--soft: var(--nds-primary-soft);
}
&__neutral {
--c: var(--nds-neutral);
--on: var(--nds-surface);
--soft: color-mix(in srgb, var(--nds-neutral) 16%, transparent);
}
&__success {
--c: var(--nds-success-medium);
--on: #fff;
--soft: var(--nds-success-low);
}
&__warning {
--c: var(--nds-warning-medium);
--on: #fff;
--soft: var(--nds-warning-low);
}
&__error {
--c: var(--nds-error-medium);
--on: #fff;
--soft: var(--nds-error-low);
}
&__info {
--c: var(--nds-info-medium);
--on: #fff;
--soft: var(--nds-info-low);
}
&--soft {
background-color: var(--soft);
color: var(--c);
}
&--solid {
background-color: var(--c);
color: var(--on);
}
&__dot {
width: 6px;
height: 6px;
border-radius: var(--nds-radius-full);
background-color: currentColor;
}
}
+15
View File
@@ -0,0 +1,15 @@
---
export interface Props {
type?: "primary" | "neutral" | "success" | "warning" | "error" | "info";
variant?: "soft" | "solid";
}
const { type = "primary", variant = "soft" } = Astro.props;
---
<span class={`badge badge__${type} badge--${variant}`}>
<slot />
</span>
<style lang="scss">
@use "./_badge.scss";
</style>
@@ -0,0 +1,27 @@
@use "../../styles/tokens/typography" as *;
.breadcrumb {
display: flex;
align-items: center;
gap: var(--nds-spacing-xs);
@include text-base;
&__item {
text-decoration: none;
color: var(--nds-neutral);
transition: color 120ms ease;
&:hover {
color: var(--nds-text);
}
&:not(:first-child)::before {
content: "/";
color: var(--nds-disabled);
margin-right: var(--nds-spacing-xs);
}
&--current {
color: var(--nds-text);
font-weight: 600;
pointer-events: none;
}
}
}
@@ -0,0 +1,11 @@
---
export interface Props {}
---
<nav class="breadcrumb" aria-label="Breadcrumb">
<slot />
</nav>
<style lang="scss">
@use "./_breadcrumb.scss";
</style>
@@ -0,0 +1,19 @@
---
export interface Props {
href?: string;
current?: boolean;
}
const { href = "#", current = false } = Astro.props;
---
<a
href={href}
class={`breadcrumb__item ${current ? "breadcrumb__item--current" : ""}`}
aria-current={current ? "page" : undefined}
>
<slot />
</a>
<style lang="scss">
@use "./_breadcrumb.scss";
</style>
+78 -21
View File
@@ -1,40 +1,97 @@
@use '../../styles/tokens/typography' as *; @use "../../styles/tokens/typography" as *;
.button { .button {
display: inline-flex;
align-items: center;
justify-content: center;
gap: var(--nds-spacing-xs);
width: fit-content; width: fit-content;
padding: var(--nds-spacing-sm) var(--nds-spacing-md); border: var(--nds-border-width-thin) solid transparent;
border-radius: var(--nds-radius-sm); border-radius: var(--nds-radius-md);
@include text-base; @include text-label;
text-decoration: none;
white-space: nowrap;
cursor: pointer; cursor: pointer;
user-select: none;
transition:
background-color 140ms ease,
border-color 140ms ease,
color 140ms ease,
box-shadow 140ms ease,
transform 80ms ease;
&:focus-visible {
outline: none;
box-shadow: 0 0 0 3px var(--nds-ring);
}
&:active:not(.button--disabled) {
transform: translateY(0.5px);
}
&--sm {
height: 30px;
padding: 0 var(--nds-spacing-sm);
}
&--md {
height: 38px;
padding: 0 var(--nds-spacing-md);
}
&--lg {
height: 46px;
padding: 0 var(--nds-spacing-lg);
font-size: 0.9375rem;
}
&--icon {
padding: 0;
aspect-ratio: 1;
}
&--icon.button--sm {
width: 30px;
}
&--icon.button--md {
width: 38px;
}
&--icon.button--lg {
width: 46px;
}
&__primary { &__primary {
background-color: var(--nds-primary); background-color: var(--nds-primary);
color: var(--nds-text); color: var(--nds-on-primary);
border-color: var(--nds-primary);
&:hover:not(.button--disabled) { &:hover:not(.button--disabled) {
background-color: var(--nds-secondary); background-color: color-mix(in srgb, var(--nds-primary) 88%, #000);
} border-color: color-mix(in srgb, var(--nds-primary) 88%, #000);
&:active:not(.button--disabled) {
background-color: var(--nds-accent);
color: var(--nds-background);
} }
} }
&__secondary { &__secondary {
border: var(--nds-border-width-medium) solid; background-color: transparent;
border-color: var(--nds-primary);
color: var(--nds-primary); color: var(--nds-primary);
border-color: var(--nds-border-strong);
&:hover:not(.button--disabled) { &:hover:not(.button--disabled) {
border-color: var(--nds-secondary); border-color: var(--nds-primary);
background-color: var(--nds-primary-soft);
} }
&:active:not(.button--disabled) { }
border-color: var(--nds-accent); &__ghost {
color: var(--nds-accent); background-color: transparent;
color: var(--nds-text);
border-color: transparent;
&:hover:not(.button--disabled) {
background-color: var(--nds-surface-hover);
}
}
&__danger {
background-color: var(--nds-error-medium);
color: #fff;
border-color: var(--nds-error-medium);
&:hover:not(.button--disabled) {
background-color: color-mix(in srgb, var(--nds-error-medium) 88%, #000);
border-color: color-mix(in srgb, var(--nds-error-medium) 88%, #000);
} }
} }
&--disabled { &--disabled {
cursor: not-allowed; cursor: not-allowed;
background-color: var(--nds-disabled); background-color: var(--nds-disabled);
color: var(--nds-neutral); color: var(--nds-neutral);
border-color: transparent;
box-shadow: none;
} }
&--icon { }
padding: var(--nds-spacing-2xs) var(--nds-spacing-xs);
}
}
+39 -8
View File
@@ -1,16 +1,47 @@
--- ---
export interface Props { export interface Props {
type: 'primary' | 'secondary'; type?: "primary" | "secondary" | "ghost" | "danger";
disabled?: boolean; size?: "sm" | "md" | "lg";
disabled?: boolean;
icon?: boolean; icon?: boolean;
href?: string;
htmlType?: "button" | "submit" | "reset";
} }
const { type, disabled = false, icon = false } = Astro.props; const {
type = "primary",
size = "md",
disabled = false,
icon = false,
href,
htmlType = "button",
...rest
} = Astro.props;
const classes = [
"button",
`button__${type}`,
`button--${size}`,
icon ? "button--icon" : "",
disabled ? "button--disabled" : "",
]
.filter(Boolean)
.join(" ");
const Tag = href ? "a" : "button";
--- ---
<div class={`button button__${type} ${disabled ? 'button--disabled' : ''} ${icon ? 'button--icon' : ''}`}> <Tag
<slot/> class={classes}
</div> href={href}
type={href ? undefined : htmlType}
aria-disabled={disabled ? "true" : undefined}
{...rest}
>
<slot name="icon-left" />
<slot />
<slot name="icon-right" />
</Tag>
<style lang="scss"> <style lang="scss">
@use './_button.scss'; @use "./_button.scss";
</style> </style>
+53
View File
@@ -0,0 +1,53 @@
@use "../../styles/tokens/typography" as *;
.card {
display: flex;
flex-direction: column;
background-color: var(--nds-surface);
border: var(--nds-border-width-thin) solid var(--nds-border);
border-radius: var(--nds-radius-lg);
overflow: hidden;
box-shadow: var(--nds-shadow-sm);
width: fit-content;
transition:
box-shadow 160ms ease,
border-color 160ms ease;
&:hover {
box-shadow: var(--nds-shadow-md);
}
&__cover {
height: 150px;
background-position: center;
background-size: cover;
background-repeat: no-repeat;
}
&__body {
display: flex;
flex-direction: column;
gap: var(--nds-spacing-xs);
padding: var(--nds-spacing-md);
}
&__title {
@include text-xl;
color: var(--nds-text);
margin: 0;
}
&__subtitle {
@include text-base;
color: var(--nds-neutral);
margin: 0;
}
&__content {
@include text-base;
color: var(--nds-text);
&:empty {
display: none;
}
}
&__footer {
margin-top: var(--nds-spacing-2xs);
display: flex;
gap: var(--nds-spacing-xs);
}
}
+33
View File
@@ -0,0 +1,33 @@
---
export interface Props {
title?: string;
subtitle?: string;
cover?: string;
}
const { title, subtitle, cover } = Astro.props;
const hasFooter = Astro.slots.has("footer");
---
<div class="card">
{
cover && (
<div class="card__cover" style={`background-image: url(${cover})`} />
)
}
<div class="card__body">
{title && <p class="card__title">{title}</p>}
{subtitle && <p class="card__subtitle">{subtitle}</p>}
<div class="card__content"><slot /></div>
{
hasFooter && (
<div class="card__footer">
<slot name="footer" />
</div>
)
}
</div>
</div>
<style lang="scss">
@use "./_card.scss";
</style>
+51
View File
@@ -0,0 +1,51 @@
@use "../../styles/tokens/typography" as *;
.checkbox {
display: inline-flex;
align-items: center;
gap: var(--nds-spacing-xs);
cursor: pointer;
@include text-base;
color: var(--nds-text);
&__input {
position: absolute;
opacity: 0;
width: 0;
height: 0;
}
&__box {
width: 18px;
height: 18px;
flex-shrink: 0;
display: inline-flex;
align-items: center;
justify-content: center;
border: var(--nds-border-width-medium) solid var(--nds-border-strong);
border-radius: var(--nds-radius-sm);
background-color: var(--nds-surface);
color: var(--nds-on-primary);
transition: all 130ms ease;
svg {
width: 12px;
height: 12px;
opacity: 0;
transform: scale(0.6);
transition: all 130ms ease;
}
}
&__input:checked + &__box {
background-color: var(--nds-primary);
border-color: var(--nds-primary);
svg {
opacity: 1;
transform: scale(1);
}
}
&__input:focus-visible + &__box {
box-shadow: 0 0 0 3px var(--nds-ring);
}
&--disabled {
cursor: not-allowed;
opacity: 0.5;
}
}
+37
View File
@@ -0,0 +1,37 @@
---
export interface Props {
id: string;
name?: string;
checked?: boolean;
disabled?: boolean;
}
const { id, name, checked = false, disabled = false } = Astro.props;
---
<label class={`checkbox ${disabled ? "checkbox--disabled" : ""}`} for={id}>
<input
type="checkbox"
id={id}
name={name}
checked={checked}
disabled={disabled}
class="checkbox__input"
/>
<span class="checkbox__box" aria-hidden="true">
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="3"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M5 13l4 4L19 7"></path>
</svg>
</span>
<span class="checkbox__label"><slot /></span>
</label>
<style lang="scss">
@use "./_checkbox.scss";
</style>
+23 -25
View File
@@ -1,30 +1,28 @@
@use '../../styles/tokens/typography' as *; @use "../../styles/tokens/typography" as *;
.link { .link__container {
width: fit-content;
display: inline-flex;
align-items: center;
}
.link {
text-decoration: none; text-decoration: none;
color: var(--nds-primary); color: var(--nds-primary);
@include text-base; @include text-base;
&:hover { font-weight: 600;
color: var(--nds-text); display: inline-flex;
opacity: 0.25; align-items: center;
} gap: var(--nds-spacing-3xs);
&:active { border-bottom: 1px solid transparent;
color: var(--nds-text); transition:
opacity: 0.25; border-color 130ms ease,
} color 130ms ease;
&__container { &:hover {
width: fit-content; border-bottom-color: var(--nds-primary);
display: flex;
align-items: center;
justify-content: center;
border-bottom: var(--nds-border-width-medium) dashed var(--nds-secondary);
&:hover {
background-color: var(--nds-secondary);
border-bottom: var(--nds-border-width-medium) dashed var(--nds-accent);
}
&:active {
background-color: var(--nds-primary);
border-bottom: var(--nds-border-width-medium) dashed var(--nds-secondary);
}
} }
} &:focus-visible {
outline: none;
box-shadow: 0 0 0 3px var(--nds-ring);
border-radius: var(--nds-radius-xs);
}
}
+19 -58
View File
@@ -1,70 +1,31 @@
@use '../../styles/tokens/typography' as *; @use "../../styles/tokens/typography" as *;
.list-item { .list-item {
width: 350px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; gap: var(--nds-spacing-sm);
padding: var(--nds-spacing-md); padding: var(--nds-spacing-sm) var(--nds-spacing-md);
border-radius: var(--nds-radius-sm); border-radius: var(--nds-radius-md);
background: var(--nds-background, #040B0B); transition: background-color 120ms ease;
flex-shrink: 0;
position: relative;
cursor: pointer;
&:hover { &:hover {
background: color-mix(in srgb, var(--nds-secondary) 25%, transparent); background-color: var(--nds-surface-hover);
} }
&:active { &__body {
background: color-mix(in srgb, var(--nds-accent) 25%, transparent);
}
&::after {
content: '';
position: absolute;
inset: 0;
border-right: 1px solid;
border-bottom: 1px solid;
border-radius: var(--nds-radius-md);
border-color: transparent;
background:
linear-gradient(var(--nds-background, #040B0B), var(--nds-background, #040B0B)) padding-box,
linear-gradient(
135deg,
transparent 0%,
transparent 20%,
rgba(245, 250, 250, 0.08) 50%,
rgba(245, 250, 250, 0.28) 100%
) border-box;
-webkit-mask:
linear-gradient(#fff 0 0) padding-box,
linear-gradient(#fff 0 0);
-webkit-mask-composite: destination-out;
mask-composite: exclude;
pointer-events: none;
}
&::before {
content: '';
position: absolute;
top: 0;
right: -1px;
width: 1px;
height: 100%;
pointer-events: none;
}
&__content {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: var(--nds-spacing-md); gap: var(--nds-spacing-3xs);
flex: 1;
min-width: 0;
} }
&__subTitle {
@include text-base;
}
&__title { &__title {
@include text-xl; @include text-label;
color: var(--nds-text);
margin: 0;
} }
} &__subtitle {
@include text-sm;
color: var(--nds-neutral);
margin: 0;
}
}
+6 -10
View File
@@ -1,15 +1,11 @@
--- ---
import Arrow2 from "../Icons/Arrow2/Arrow2.astro" export interface Props {}
--- ---
<div class='list-item'>
<div class='list-item__content'> <div class="list-item">
<slot/> <slot />
</div>
<Arrow2
size={24}
orientation='right' />
</div> </div>
<style lang="scss"> <style lang="scss">
@use './listItem'; @use "./_listItem.scss";
</style> </style>
@@ -1,7 +1,11 @@
<div class='list-item__subTitle'> ---
<slot/> export interface Props {}
</div> ---
<p class="list-item__subtitle">
<slot />
</p>
<style lang="scss"> <style lang="scss">
@use './listItem'; @use "./_listItem.scss";
</style> </style>
+9 -5
View File
@@ -1,7 +1,11 @@
<div class='list-item__title'> ---
<slot/> export interface Props {}
</div> ---
<p class="list-item__title">
<slot />
</p>
<style lang="scss"> <style lang="scss">
@use './listItem'; @use "./_listItem.scss";
</style> </style>
+17 -20
View File
@@ -1,37 +1,34 @@
@use '../../styles/tokens/typography' as *; @use "../../styles/tokens/typography" as *;
.loading-bar { .loading-bar {
position: relative; position: relative;
width: 100%; width: 100%;
height: 6px; height: 6px;
background-color: var(--nds-text); background-color: var(--nds-surface-2);
overflow: hidden; overflow: hidden;
border-radius: var(--nds-radius-sm); border-radius: var(--nds-radius-full);
&__progress { &__progress {
height: 100%; height: 100%;
background-color: var(--nds-primary); background-color: var(--nds-primary);
transition: width 0.3s ease; border-radius: var(--nds-radius-full);
border-radius: var(--nds-radius-sm); transition: width 0.35s ease;
} }
&__unknown { &__unknown {
position: absolute; position: absolute;
top: 0; top: 0;
left: -50%; left: 0;
width: 50%; width: 40%;
height: 100%; height: 100%;
background-color: var(--nds-primary); background-color: var(--nds-primary);
border-radius: var(--nds-radius-sm); border-radius: var(--nds-radius-full);
animation: loadingBarIndeterminate 1.5s infinite; animation: nds-lb 1.3s ease-in-out infinite;
} }
}
@keyframes loadingBarIndeterminate { @keyframes nds-lb {
from { 0% {
left: -50%; left: -40%;
}
to {
left: 100%;
}
} }
} 100% {
left: 100%;
}
}
+16 -10
View File
@@ -1,19 +1,25 @@
--- ---
export interface Props { export interface Props {
type: 'known' | 'unknown'; type: "known" | "unknown";
percentage?: number; percentage?: number;
width?: string; width?: string;
} }
const { type, percentage, width } = Astro.props; const { type, percentage, width } = Astro.props;
--- ---
<div class='loading-bar loading-bar--${type}' style={width ? `width: ${width}` : undefined}>
{type === 'known' && percentage !== undefined ? ( <div
<div class='loading-bar__progress' style={`width: ${percentage}%`}></div> class={`loading-bar loading-bar--${type}`}
) : ( style={width ? `width: ${width}` : undefined}
<div class='loading-bar__unknown'></div> >
)} {
type === "known" && percentage !== undefined ? (
<div class="loading-bar__progress" style={`width: ${percentage}%`} />
) : (
<div class="loading-bar__unknown" />
)
}
</div> </div>
<style lang="scss"> <style lang="scss">
@use './loadingBar'; @use "./_loadingBar.scss";
</style> </style>
+78
View File
@@ -0,0 +1,78 @@
@use "../../styles/tokens/typography" as *;
.modal {
&__overlay {
position: fixed;
inset: 0;
background-color: rgba(2, 12, 12, 0.55);
backdrop-filter: blur(3px);
display: none;
align-items: center;
justify-content: center;
z-index: 200;
padding: var(--nds-spacing-md);
}
&__dialog {
width: min(460px, 100%);
background-color: var(--nds-surface);
border: var(--nds-border-width-thin) solid var(--nds-border);
border-radius: var(--nds-radius-xl);
overflow: hidden;
box-shadow: var(--nds-shadow-lg);
animation: nds-modal-in 180ms cubic-bezier(0.2, 0.8, 0.3, 1);
}
&__head {
display: flex;
align-items: center;
justify-content: space-between;
padding: var(--nds-spacing-md) var(--nds-spacing-lg);
border-bottom: var(--nds-border-width-thin) solid var(--nds-border);
}
&__title {
@include text-xl;
color: var(--nds-text);
}
&__close {
background: transparent;
border: none;
color: var(--nds-neutral);
cursor: pointer;
display: flex;
padding: var(--nds-spacing-3xs);
border-radius: var(--nds-radius-sm);
transition:
color 120ms ease,
background-color 120ms ease;
&:hover {
color: var(--nds-text);
background-color: var(--nds-surface-hover);
}
}
&__body {
padding: var(--nds-spacing-lg);
@include text-base;
color: var(--nds-text);
}
&__footer {
display: flex;
justify-content: flex-end;
gap: var(--nds-spacing-xs);
padding: var(--nds-spacing-md) var(--nds-spacing-lg);
border-top: var(--nds-border-width-thin) solid var(--nds-border);
}
}
nds-modal[data-open="true"] .modal__overlay {
display: flex;
}
@keyframes nds-modal-in {
from {
opacity: 0;
transform: translateY(8px) scale(0.98);
}
to {
opacity: 1;
transform: translateY(0) scale(1);
}
}
+84
View File
@@ -0,0 +1,84 @@
---
import { CloseIcon } from "../Icons";
export interface Props {
id: string;
title?: string;
open?: boolean;
}
const { id, title, open = false } = Astro.props;
const hasFooter = Astro.slots.has("footer");
---
<nds-modal id={id} class="modal" data-open={open ? "true" : undefined}>
<div class="modal__overlay" data-modal-close>
<div
class="modal__dialog"
role="dialog"
aria-modal="true"
aria-label={title}
>
<div class="modal__head">
<span class="modal__title">{title}</span>
<button class="modal__close" data-modal-close aria-label="Close">
<CloseIcon size={18} label="Close" />
</button>
</div>
<div class="modal__body"><slot /></div>
{
hasFooter && (
<div class="modal__footer">
<slot name="footer" />
</div>
)
}
</div>
</div>
</nds-modal>
<script>
class NdsModal extends HTMLElement {
connectedCallback() {
this.addEventListener("click", (e) => {
const target = e.target as HTMLElement;
if (
target.closest("[data-modal-close]") ===
target.closest(".modal__dialog")
) {
// clicked dialog interior, ignore
}
if (
target.matches("[data-modal-close]") ||
target.classList.contains("modal__overlay")
) {
this.close();
}
});
document.addEventListener("keydown", (e) => {
if (e.key === "Escape" && this.dataset.open === "true") this.close();
});
}
open() {
this.dataset.open = "true";
this.dispatchEvent(new CustomEvent("nds:open", { bubbles: true }));
}
close() {
delete this.dataset.open;
this.dispatchEvent(new CustomEvent("nds:close", { bubbles: true }));
}
}
customElements.define("nds-modal", NdsModal);
document.addEventListener("click", (e) => {
const trigger = (e.target as HTMLElement).closest<HTMLElement>(
"[data-modal-open]",
);
if (!trigger) return;
const modal = document.getElementById(trigger.dataset.modalOpen!) as any;
modal?.open?.();
});
</script>
<style lang="scss">
@use "./_modal.scss";
</style>
+58
View File
@@ -0,0 +1,58 @@
@use "../../styles/tokens/typography" as *;
.navbar {
display: flex;
align-items: center;
gap: var(--nds-spacing-lg);
height: 60px;
padding: 0 var(--nds-spacing-lg);
background-color: var(--nds-surface);
border-bottom: var(--nds-border-width-thin) solid var(--nds-border);
&__brand {
display: flex;
align-items: center;
gap: var(--nds-spacing-xs);
}
&__mark {
width: 24px;
height: 24px;
border-radius: var(--nds-radius-md);
background: linear-gradient(135deg, var(--nds-primary), var(--nds-accent));
}
&__title {
@include text-xl;
font-size: 1rem;
color: var(--nds-text);
}
&__links {
display: flex;
align-items: center;
gap: var(--nds-spacing-xs);
flex: 1;
:global(.navbar__link) {
padding: var(--nds-spacing-2xs) var(--nds-spacing-sm);
border-radius: var(--nds-radius-md);
@include text-label;
color: var(--nds-text);
text-decoration: none !important;
transition: all 120ms ease;
}
:global(.navbar__link:hover) {
background-color: var(--nds-surface-hover);
}
// On cible la variante active globale séparément
:global(.navbar__link--active) {
color: var(--nds-primary);
}
}
&__right {
display: flex;
align-items: center;
gap: var(--nds-spacing-sm);
}
}
+19
View File
@@ -0,0 +1,19 @@
---
export interface Props {
brand?: string;
}
const { brand = "Nova" } = Astro.props;
---
<header class="navbar">
<div class="navbar__brand">
<span class="navbar__mark"></span>
<span class="navbar__title">{brand}</span>
</div>
<nav class="navbar__links"><slot /></nav>
<div class="navbar__right"><slot name="right" /></div>
</header>
<style lang="scss">
@use "./_navbar.scss";
</style>
+42 -53
View File
@@ -1,61 +1,50 @@
@use '../../styles/tokens/typography' as *; @use "../../styles/tokens/typography" as *;
.notification { .notification {
display: flex; display: flex;
align-items: flex-start;
justify-content: space-between; justify-content: space-between;
align-items: center; gap: var(--nds-spacing-sm);
padding: var(--nds-spacing-sm) var(--nds-spacing-xs) ; padding: var(--nds-spacing-sm) var(--nds-spacing-md);
border-radius: var(--nds-radius-md); border-radius: var(--nds-radius-lg);
@include text-sm; background-color: var(--nds-surface);
&__error { box-shadow: var(--nds-shadow-md);
background-color: var(--nds-error-low); border-left: 3px solid var(--nds-info-medium);
&__close { @include text-base;
background: transparent; max-width: 400px;
border: none;
color: var(--nds-error-medium);
cursor: pointer;
}
&__content {
color: var(--nds-error-high);
}
}
&__success {
background-color: var(--nds-success-low);
&__close {
background: transparent;
border: none;
color: var(--nds-success-medium);
cursor: pointer;
}
&__content {
color: var(--nds-success-high);
}
}
&__warning {
background-color: var(--nds-warning-low);
&__close {
background: transparent;
border: none;
color: var(--nds-warning-medium);
cursor: pointer;
}
&__content {
color: var(--nds-warning-high);
}
}
&__info { &__info {
background-color: var(--nds-info-low); border-left-color: var(--nds-info-medium);
&__close { }
background: transparent; &__success {
border: none; border-left-color: var(--nds-success-medium);
color: var(--nds-info-medium); }
cursor: pointer; &__warning {
} border-left-color: var(--nds-warning-medium);
&__content { }
color: var(--nds-info-high); &__error {
border-left-color: var(--nds-error-medium);
}
&__info__content,
&__success__content,
&__warning__content,
&__error__content {
color: var(--nds-text);
flex: 1;
}
&__info__close,
&__success__close,
&__warning__close,
&__error__close {
background: transparent;
border: none;
cursor: pointer;
display: flex;
color: var(--nds-neutral);
padding: 0;
border-radius: var(--nds-radius-sm);
transition: color 120ms ease;
&:hover {
color: var(--nds-text);
} }
} }
} }
@@ -1,23 +1,30 @@
--- ---
import { CloseIcon } from "../Icons"; import { CloseIcon } from "../Icons";
export interface Props { export interface Props {
type: 'info' | 'success' | 'warning' | 'error'; type: "info" | "success" | "warning" | "error";
} }
const notificationUUID = `notification-${Math.random().toString(36).substr(2, 9)}`; const notificationUUID = `notification-${Math.random().toString(36).slice(2, 11)}`;
const { type } = Astro.props; const { type } = Astro.props;
--- ---
<div class={`notification notification__${type}`} role="alert" id={notificationUUID}> <div
<div class=`notification__${type}__content`> class={`notification notification__${type}`}
role="alert"
id={notificationUUID}
>
<div class={`notification__${type}__content`}>
<slot /> <slot />
</div> </div>
<button class={`notification__${type}__close`} aria-label="Close notification" onclick={`document.getElementById('${notificationUUID}')?.remove()`}> <button
class={`notification__${type}__close`}
aria-label="Close notification"
onclick={`document.getElementById('${notificationUUID}')?.remove()`}
>
<CloseIcon size={16} label="Close notification" /> <CloseIcon size={16} label="Close notification" />
</button> </button>
</div> </div>
<style lang="scss"> <style lang="scss">
@use './_notification.scss'; @use "./_notification.scss";
</style> </style>
+50
View File
@@ -0,0 +1,50 @@
@use "../../styles/tokens/typography" as *;
.radio {
display: inline-flex;
align-items: center;
gap: var(--nds-spacing-xs);
cursor: pointer;
@include text-base;
color: var(--nds-text);
&__input {
position: absolute;
opacity: 0;
width: 0;
height: 0;
}
&__dot {
width: 18px;
height: 18px;
flex-shrink: 0;
display: inline-flex;
align-items: center;
justify-content: center;
border: var(--nds-border-width-medium) solid var(--nds-border-strong);
border-radius: var(--nds-radius-full);
background-color: var(--nds-surface);
transition: border-color 130ms ease;
&::after {
content: "";
width: 8px;
height: 8px;
border-radius: var(--nds-radius-full);
background-color: var(--nds-primary);
transform: scale(0);
transition: transform 130ms cubic-bezier(0.34, 1.4, 0.6, 1);
}
}
&__input:checked + &__dot {
border-color: var(--nds-primary);
&::after {
transform: scale(1);
}
}
&__input:focus-visible + &__dot {
box-shadow: 0 0 0 3px var(--nds-ring);
}
&--disabled {
cursor: not-allowed;
opacity: 0.5;
}
}
+28
View File
@@ -0,0 +1,28 @@
---
export interface Props {
id: string;
name: string;
value?: string;
checked?: boolean;
disabled?: boolean;
}
const { id, name, value, checked = false, disabled = false } = Astro.props;
---
<label class={`radio ${disabled ? "radio--disabled" : ""}`} for={id}>
<input
type="radio"
id={id}
name={name}
value={value}
checked={checked}
disabled={disabled}
class="radio__input"
/>
<span class="radio__dot" aria-hidden="true"></span>
<span class="radio__label"><slot /></span>
</label>
<style lang="scss">
@use "./_radio.scss";
</style>
+63 -44
View File
@@ -1,71 +1,90 @@
@use '../../styles/tokens/typography' as *; @use "../../styles/tokens/typography" as *;
.select { .select {
position: relative; position: relative;
display: inline-flex; display: inline-flex;
flex-direction: column; flex-direction: column;
width: 100%; min-width: 200px;
&__trigger { &__trigger {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
padding: var(--nds-spacing-xs) var(--nds-spacing-md);
background-color: var(--nds-neutral);
color: var(--nds-text);
border: none;
border-radius: var(--nds-radius-sm);
cursor: pointer;
width: 100%;
gap: var(--nds-spacing-xs); gap: var(--nds-spacing-xs);
height: 38px;
padding: 0 var(--nds-spacing-sm);
background-color: var(--nds-surface);
border: var(--nds-border-width-thin) solid var(--nds-border-strong);
border-radius: var(--nds-radius-md);
cursor: pointer;
@include text-base;
color: var(--nds-text);
transition:
border-color 130ms ease,
box-shadow 130ms ease;
&:hover { &:hover {
background-color: color-mix(in srgb, var(--nds-neutral) 85%, var(--nds-text)); border-color: var(--nds-neutral);
}
&:focus-visible {
outline: none;
border-color: var(--nds-primary);
box-shadow: 0 0 0 3px var(--nds-ring);
}
svg {
color: var(--nds-neutral);
transition: transform 160ms ease;
flex-shrink: 0;
} }
} }
&__placeholder {
&__label { color: var(--nds-neutral);
flex: 1;
text-align: left;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
} }
&[data-open="true"] &__trigger {
border-color: var(--nds-primary);
}
&[data-open="true"] &__trigger svg {
transform: rotate(180deg);
}
&__menu {
position: absolute;
top: calc(100% + 6px);
left: 0;
right: 0;
z-index: 40;
background-color: var(--nds-surface);
border: var(--nds-border-width-thin) solid var(--nds-border);
border-radius: var(--nds-radius-md);
box-shadow: var(--nds-shadow-md);
padding: var(--nds-spacing-3xs);
max-height: 240px;
overflow-y: auto;
display: none;
}
&__arrow { &__arrow {
flex-shrink: 0;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center;
&--hidden { &--hidden {
display: none; display: none;
} }
} }
&--disabled {
&__dropdown { cursor: not-allowed;
position: absolute; background-color: var(--nds-surface);
top: calc(100% + var(--nds-spacing-2xs)); color: var(--nds-neutral);
left: 0; border-color: var(--nds-border-strong);
right: 0; opacity: 0.55;
background-color: var(--nds-neutral); & .select__trigger {
border-radius: var(--nds-radius-sm); cursor: not-allowed;
list-style: none; &:hover {
margin: 0; border-color: var(--nds-border-strong);
padding: 0; }
z-index: 100;
overflow: hidden;
&[hidden] {
display: none;
} }
} }
&[data-open="true"] &__menu {
&--disabled { display: block;
opacity: 0.5;
.select__trigger {
background-color: var(--nds-disabled);
cursor: not-allowed;
} }
} }
}
+18 -22
View File
@@ -1,32 +1,28 @@
@use '../../styles/tokens/typography' as *; @use "../../styles/tokens/typography" as *;
.select-option { .select-option {
padding: var(--nds-spacing-xs) var(--nds-spacing-md); display: flex;
align-items: center;
gap: var(--nds-spacing-xs);
padding: var(--nds-spacing-xs) var(--nds-spacing-sm);
cursor: pointer; cursor: pointer;
border-radius: var(--nds-radius-sm);
@include text-base;
color: var(--nds-text); color: var(--nds-text);
background-color: var(--nds-neutral); transition: background-color 110ms ease;
transition: background-color 0.15s ease;
&:hover:not(.select-option__disabled) { &:hover {
background-color: var(--nds-secondary); background-color: var(--nds-surface-hover);
} }
&[aria-selected="true"] {
&:active { color: var(--nds-primary);
background-color: var(--nds-accent); font-weight: 600;
} }
&__disabled {
&__selected { color: var(--nds-disabled);
background-color: var(--nds-primary); cursor: not-allowed;
color: var(--nds-text);
&:hover { &:hover {
background-color: color-mix(in srgb, var(--nds-primary) 85%, var(--nds-background)); background: transparent;
} }
} }
}
&__disabled {
background-color: var(--nds-disabled);
color: color-mix(in srgb, var(--nds-text) 40%, transparent);
cursor: not-allowed;
}
}
+67
View File
@@ -0,0 +1,67 @@
@use "../../styles/tokens/typography" as *;
.sidebar {
display: flex;
flex-direction: column;
width: 240px;
height: 100%;
box-sizing: border-box;
padding: var(--nds-spacing-sm);
background-color: var(--nds-surface);
border-right: var(--nds-border-width-thin) solid var(--nds-border);
&__head {
display: flex;
align-items: center;
gap: var(--nds-spacing-xs);
padding: var(--nds-spacing-xs) var(--nds-spacing-xs) var(--nds-spacing-md);
}
&__mark {
width: 24px;
height: 24px;
border-radius: var(--nds-radius-md);
background: linear-gradient(135deg, var(--nds-primary), var(--nds-accent));
}
&__title {
@include text-xl;
font-size: 1rem;
color: var(--nds-text);
}
&__nav {
display: flex;
flex-direction: column;
gap: var(--nds-spacing-3xs);
flex: 1;
}
&__item {
display: flex;
align-items: center;
gap: var(--nds-spacing-xs);
padding: var(--nds-spacing-xs) var(--nds-spacing-sm);
border-radius: var(--nds-radius-md);
text-decoration: none;
color: var(--nds-text);
@include text-label;
font-weight: 500;
transition:
background-color 120ms ease,
color 120ms ease;
&:hover {
background-color: var(--nds-surface-hover);
}
&--active {
background-color: var(--nds-primary-soft);
color: var(--nds-primary);
font-weight: 600;
}
}
&__item-icon {
display: flex;
flex-shrink: 0;
}
&__footer {
padding-top: var(--nds-spacing-sm);
}
}
+23
View File
@@ -0,0 +1,23 @@
---
export interface Props {
header?: string;
}
const { header = "Nova" } = Astro.props;
---
<aside class="sidebar">
<div class="sidebar__head">
<span class="sidebar__mark"></span>
<span class="sidebar__title">{header}</span>
</div>
<nav class="sidebar__nav">
<slot />
</nav>
<div class="sidebar__footer">
<slot name="footer" />
</div>
</aside>
<style lang="scss">
@use "./_sidebar.scss";
</style>
+23
View File
@@ -0,0 +1,23 @@
---
export interface Props {
href?: string;
active?: boolean;
}
const { href = "#", active = false } = Astro.props;
const hasIcon = Astro.slots.has("icon");
---
<a href={href} class={`sidebar__item ${active ? "sidebar__item--active" : ""}`}>
{
hasIcon && (
<span class="sidebar__item-icon">
<slot name="icon" />
</span>
)
}
<span class="sidebar__item-label"><slot /></span>
</a>
<style lang="scss">
@use "./_sidebar.scss";
</style>
+37 -30
View File
@@ -1,33 +1,40 @@
@use '../../styles/tokens/typography' as *; @use "../../styles/tokens/typography" as *;
.tab { .tab {
display: flex; display: flex;
align-items: flex-start; align-items: stretch;
gap: var(--nds-spacing-xs); gap: var(--nds-spacing-2xs);
justify-content: center; border-bottom: 1px solid var(--nds-border);
width: fit-content; width: fit-content;
&__item {
&__item { display: inline-flex;
display: flex; align-items: center;
flex-direction: column; gap: var(--nds-spacing-2xs);
align-items: center; padding: var(--nds-spacing-xs) var(--nds-spacing-sm);
justify-content: center; cursor: pointer;
height: fit-content; @include text-label;
cursor: pointer; color: var(--nds-neutral);
padding: var(--nds-spacing-2xs); background: transparent;
@include text-base; border: none;
border-bottom: 2px solid transparent;
&--active { margin-bottom: -1px;
color: var(--nds-primary); transition:
color 130ms ease,
&::after { border-color 130ms ease;
content: ''; &:hover {
display: block; color: var(--nds-text);
width: 120%;
height: 1px;
background-color: var(--nds-primary);
border-radius: var(--nds-radius-sm);
}
}
} }
} &--active {
color: var(--nds-text);
border-bottom-color: var(--nds-primary);
}
}
}
.tab__content {
padding-top: var(--nds-spacing-md);
@include text-base;
color: var(--nds-text);
&[hidden] {
display: none;
}
}
+11 -31
View File
@@ -1,33 +1,13 @@
.toggle { .toggle {
background-color: var(--nds-disabled); --w: 44px; --h: 24px; --pad: 3px;
border-radius: var(--nds-radius-full); position: relative; width: var(--w); height: var(--h);
padding: var(--nds-spacing-2xs); background-color: var(--nds-disabled); border-radius: var(--nds-radius-full);
width: 50px; padding: var(--pad); display: flex; align-items: center; cursor: pointer;
height: 25px; transition: background-color 180ms ease;
display: flex; &-switch { width: calc(var(--h) - var(--pad) * 2); height: calc(var(--h) - var(--pad) * 2);
align-items: center; background-color: #fff; border-radius: var(--nds-radius-full); box-shadow: var(--nds-shadow-sm);
justify-content: left; transition: transform 180ms cubic-bezier(.34,1.4,.6,1); }
cursor: pointer; &-active { background-color: var(--nds-primary); }
transition: background-color 160ms ease; &-active .toggle-switch { transform: translateX(calc(var(--w) - var(--h))); }
position: relative;
&-switch {
color: var(--nds-text);
width: 15px;
height: 15px;
background-color: var(--nds-text);
border-radius: var(--nds-radius-full);
position: absolute;
left: var(--nds-spacing-2xs);
top: 50%;
transform: translateY(-50%);
transition: left 160ms ease, background-color 160ms ease, transform 160ms ease;
}
&-active {
display: flex;
justify-content: right;
background-color: var(--nds-primary);
.toggle-switch {
left: calc(100% - var(--nds-spacing-2xs) - 15px);
}
}
} }
toggle-switch:focus-visible .toggle { box-shadow: 0 0 0 3px var(--nds-ring); outline: none; }
+4 -6
View File
@@ -1,8 +1,6 @@
--- ---
import { boolean } from 'astro:schema';
export interface Props { export interface Props {
'data-checked': boolean; 'data-checked'?: boolean | string;
name?: string; name?: string;
id: string; id: string;
} }
@@ -10,7 +8,7 @@ export interface Props {
const { 'data-checked': dataChecked = 'false', name = 'toggle', id } = Astro.props; const { 'data-checked': dataChecked = 'false', name = 'toggle', id } = Astro.props;
--- ---
<toggle-switch data-checked={dataChecked} data-name={name} id={id}> <toggle-switch data-checked={String(dataChecked)} data-name={name} id={id}>
<div class="toggle"> <div class="toggle">
<div class="toggle-switch"></div> <div class="toggle-switch"></div>
</div> </div>
@@ -35,7 +33,7 @@ const { 'data-checked': dataChecked = 'false', name = 'toggle', id } = Astro.pro
this.dispatchEvent(new CustomEvent('change', { this.dispatchEvent(new CustomEvent('change', {
detail: { checked: this._checked, name: this.dataset.name }, detail: { checked: this._checked, name: this.dataset.name },
bubbles: true, bubbles: true,
composed: true, composed: true,
})); }));
} }
@@ -59,4 +57,4 @@ const { 'data-checked': dataChecked = 'false', name = 'toggle', id } = Astro.pro
<style lang="scss"> <style lang="scss">
@use './_toggle.scss'; @use './_toggle.scss';
</style> </style>
+45
View File
@@ -0,0 +1,45 @@
@use "../../styles/tokens/typography" as *;
.tooltip {
position: relative;
display: inline-flex;
&__bubble {
position: absolute;
white-space: nowrap;
padding: var(--nds-spacing-2xs) var(--nds-spacing-xs);
background-color: var(--nds-text);
color: var(--nds-background);
border-radius: var(--nds-radius-sm);
@include text-sm;
font-weight: 500;
box-shadow: var(--nds-shadow-md);
z-index: 100;
opacity: 0;
pointer-events: none;
transition: opacity 130ms ease;
}
&:hover &__bubble,
&:focus-within &__bubble {
opacity: 1;
}
&--top &__bubble {
bottom: 100%;
left: 50%;
transform: translate(-50%, -6px);
}
&--bottom &__bubble {
top: 100%;
left: 50%;
transform: translate(-50%, 6px);
}
&--left &__bubble {
right: 100%;
top: 50%;
transform: translate(-6px, -50%);
}
&--right &__bubble {
left: 100%;
top: 50%;
transform: translate(6px, -50%);
}
}
+16
View File
@@ -0,0 +1,16 @@
---
export interface Props {
label: string;
position?: "top" | "bottom" | "left" | "right";
}
const { label, position = "top" } = Astro.props;
---
<span class={`tooltip tooltip--${position}`}>
<slot />
<span class="tooltip__bubble" role="tooltip">{label}</span>
</span>
<style lang="scss">
@use "./_tooltip.scss";
</style>
@@ -1,14 +1,44 @@
@use '../../styles/tokens/typography' as *; @use "../../styles/tokens/typography" as *;
.numeric-stepper { .numeric-stepper {
display: flex; display: inline-flex;
flex-direction: column;
align-items: center; align-items: center;
gap: var(--nds-spacing-xs); gap: 0;
border: var(--nds-border-width-thin) solid var(--nds-border-strong);
border-radius: var(--nds-radius-md);
background-color: var(--nds-surface);
overflow: hidden;
width: fit-content; width: fit-content;
& p { height: fit-content;
@include text-xl;
margin: 0; &__button {
width: 36px;
height: 36px;
display: inline-flex;
align-items: center;
justify-content: center;
background: transparent;
border: none;
cursor: pointer;
color: var(--nds-text);
transition: background-color 120ms ease;
&:hover:not(:disabled) {
background-color: var(--nds-surface-hover);
}
&:disabled {
color: var(--nds-disabled);
cursor: not-allowed;
}
} }
} &__value {
width: 48px;
text-align: center;
@include text-label;
color: var(--nds-text);
padding: 0;
margin: 0;
border: none;
outline: none;
background: transparent;
}
}
@@ -1,6 +1,6 @@
--- ---
import Button from '../Button/button.astro'; import Button from '../Button/button.astro';
import { Arrow2Icon } from '../Icons'; import { MinusIcon, PlusIcon } from '../Icons';
export interface Props { export interface Props {
id: string; id: string;
@@ -23,16 +23,16 @@ const { id, min, max, value = 0, step = 1 } = Astro.props;
data-step={step} data-step={step}
> >
<span class="numeric-stepper__control" data-action="increment"> <span class="numeric-stepper__control" data-action="increment">
<Button type="secondary" icon={true}> <Button type="ghost" icon={true}>
<Arrow2Icon size={24} orientation="up" /> <MinusIcon size={24} />
</Button> </Button>
</span> </span>
<p class="numeric-stepper__value">{value}</p> <p class="numeric-stepper__value">{value}</p>
<span class="numeric-stepper__control" data-action="decrement"> <span class="numeric-stepper__control" data-action="decrement">
<Button type="secondary" icon={true}> <Button type="ghost" icon={true}>
<Arrow2Icon size={24} orientation="down" /> <PlusIcon size={24} />
</Button> </Button>
</span> </span>
</div> </div>
@@ -113,5 +113,5 @@ const { id, min, max, value = 0, step = 1 } = Astro.props;
</script> </script>
<style lang="scss"> <style lang="scss">
@use './numericStepper'; @use "./numericStepper";
</style> </style>
+5 -4
View File
@@ -1,6 +1,7 @@
@use '../../styles/tokens/typography' as *; @use "../../styles/tokens/typography" as *;
.pagination { .pagination {
display: flex; display: flex;
gap: var(--nds-spacing-sm); align-items: center;
} gap: var(--nds-spacing-2xs);
}
@@ -1,26 +1,30 @@
@use '../../styles/tokens/typography' as *; @use "../../styles/tokens/typography" as *;
.pagination-number { .pagination-number {
width: 30px; min-width: 32px;
height: 30px; height: 32px;
display: flex; padding: 0 var(--nds-spacing-2xs);
display: inline-flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
border-radius: var(--nds-radius-full); border-radius: var(--nds-radius-md);
cursor: pointer;
@include text-label;
color: var(--nds-text);
background: transparent;
border: 1px solid transparent;
transition: all 120ms ease;
user-select: none;
&:hover:not(.pagination-number__disabled):not(.pagination-number__selected) { &:hover:not(.pagination-number__disabled):not(.pagination-number__selected) {
background-color: var(--nds-secondary); border-color: var(--nds-border-strong);
cursor: pointer; background-color: var(--nds-surface-hover);
}
&:active:not(.pagination-number__disabled):not(.pagination-number__selected) {
background-color: var(--nds-accent);
cursor: pointer;
}
&__disabled {
background-color: var(--nds-disabled);
cursor: not-allowed;
} }
&__selected { &__selected {
background-color: var(--nds-primary); background-color: var(--nds-primary);
cursor: pointer; color: var(--nds-on-primary);
} }
} &__disabled {
color: var(--nds-disabled);
cursor: not-allowed;
}
}
+1
View File
@@ -42,6 +42,7 @@
min-height: 84px; min-height: 84px;
padding: var(--nds-spacing-sm); padding: var(--nds-spacing-sm);
resize: vertical; resize: vertical;
width: 100% !important;
line-height: 1.5; line-height: 1.5;
} }
&__charCount { &__charCount {
+12 -24
View File
@@ -1,29 +1,17 @@
--- ---
import '../styles/index.scss'; import '../styles/index.scss';
interface Props { title?: string; }
const { title = 'Nova Design System' } = Astro.props;
--- ---
<!doctype html> <!doctype html>
<html lang="en"> <html lang="en" data-theme="dark">
<head> <head>
<meta charset="UTF-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="/favicon.ico" /> <meta name="generator" content={Astro.generator} />
<meta name="generator" content={Astro.generator} /> <title>{title}</title>
<title>Nova Design System</title> </head>
</head> <body>
<body> <slot />
<slot /> </body>
</body>
</html> </html>
<style>
html,
body {
margin: 0;
width: 100%;
min-height: 100%;
font-family: var(--nds-font-family-base);
background-color: var(--nds-page-low);
color: var(--nds-default);
}
</style>
File diff suppressed because it is too large Load Diff
+690 -366
View File
File diff suppressed because it is too large Load Diff