Compare commits

...

3 Commits

9 changed files with 211 additions and 4 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.05.0", "version": "0.06.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": {
+4 -3
View File
@@ -1,5 +1,3 @@
// Auto-generated by scripts/generate-barrel.mjs — do not edit manually.
export * from './Icons/index.ts'; export * from './Icons/index.ts';
export { default as Notification } from './Notifications/notification.astro'; export { default as Notification } from './Notifications/notification.astro';
export { default as Toggle } from './Toggle/toggle.astro'; export { default as Toggle } from './Toggle/toggle.astro';
@@ -15,4 +13,7 @@ export { default as LoadingBar } from './LoadingBar/loadingBar.astro';
export { default as NumericStepper } from './numericStepper/numericStepper.astro'; export { default as NumericStepper } from './numericStepper/numericStepper.astro';
export { default as Avatar } from './Avatar/avatar.astro'; export { default as Avatar } from './Avatar/avatar.astro';
export { default as Select } from './Select/select.astro'; export { default as Select } from './Select/select.astro';
export { default as SelectOption } from './Select/selectOption.astro'; export { default as SelectOption } from './Select/selectOption.astro';
export { default as TextField } from './textField/textField.astro';
export { default as Pagination } from './pagination/pagination.astro';
export { default as PaginationNumber } from './pagination/paginationNumber.astro';
@@ -0,0 +1,6 @@
@use '../../styles/tokens/typography' as *;
.pagination {
display: flex;
gap: var(--nds-spacing-sm);
}
@@ -0,0 +1,26 @@
@use '../../styles/tokens/typography' as *;
.pagination-number {
width: 30px;
height: 30px;
display: flex;
align-items: center;
justify-content: center;
border-radius: var(--nds-radius-full);
&:hover:not(.pagination-number__disabled):not(.pagination-number__selected) {
background-color: var(--nds-secondary);
cursor: pointer;
}
&: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 {
background-color: var(--nds-primary);
cursor: pointer;
}
}
@@ -0,0 +1,36 @@
---
export interface Props {
defaultPage?: number;
}
const { defaultPage = 1 } = Astro.props;
---
<div class="pagination" data-current={defaultPage}>
<slot/>
</div>
<script>
const pagination = document.querySelector('.pagination');
const numbers = pagination?.querySelectorAll('.pagination-number');
numbers?.forEach((el) => {
if (
!el.classList.contains('pagination-number__disabled') &&
el.textContent?.trim() === pagination?.getAttribute('data-current')
) {
el.classList.add('pagination-number__selected');
}
el.addEventListener('click', () => {
if (el.classList.contains('pagination-number__disabled')) return;
numbers.forEach(n => n.classList.remove('pagination-number__selected'));
el.classList.add('pagination-number__selected');
pagination?.setAttribute('data-current', el.textContent?.trim() ?? '');
});
});
</script>
<style lang="scss">
@use './pagination';
</style>
@@ -0,0 +1,20 @@
---
export interface Props {
disabled?: boolean;
}
const { disabled } = Astro.props;
const classes = [
'pagination-number',
disabled ? 'pagination-number__disabled' : ''
].filter(Boolean).join(' ');
---
<div class={classes}>
<slot/>
</div>
<style lang="scss">
@use './paginationNumber';
</style>
+30
View File
@@ -0,0 +1,30 @@
@use '../../styles/tokens/typography' as *;
.textField {
display: flex;
flex-direction: column;
gap: var(--nds-spacing-xs);
&__textarea {
background-color: var(--nds-color-background);
border: var(--nds-border-width-thin) solid var(--nds-text);
border-radius: var(--nds-radius-sm);
padding: var(--nds-spacing-sm) var(--nds-spacing-xs) ;
@include text-base;
color: var(--nds-text);
min-height: 50px;
max-width: 100%;
}
&__charCount {
@include text-sm;
color: var(--nds-text-muted);
text-align: left;
}
&__input {
background-color: var(--nds-color-background);
border: var(--nds-border-width-thin) solid var(--nds-text);
border-radius: var(--nds-radius-sm);
padding: var(--nds-spacing-sm) var(--nds-spacing-xs) ;
@include text-base;
color: var(--nds-text);
}
}
+65
View File
@@ -0,0 +1,65 @@
---
export interface Props {
id?: string;
label?: string;
type?: 'text' | 'email' | 'password' | 'textarea';
placeholder?: string;
min?: number;
max?: number;
value?: number;
step?: number;
}
const { id, label, type = 'text', placeholder, min, max, value, step } = Astro.props;
const charCounter = 0;
---
<div
class="textField"
id={id}
>
{label && <label for={id}>{label}</label>}
{type === 'textarea' ? (
<div>
<textarea
id={id}
placeholder={placeholder}
maxlength={max}
class="textField__textarea"
></textarea>
{max && (
<div class="textField__charCount">
<span id={`${id}-charCount`}>{charCounter}</span> / {max}
</div>
)}
</div>
) : (
<input
id={id}
type={type}
placeholder={placeholder}
min={min}
max={max}
value={value}
step={step}
class="textField__input"
/>
)}
</div>
<script>
document.querySelectorAll<HTMLElement>('.textField').forEach((field) => {
const textarea = field.querySelector<HTMLTextAreaElement>('.textField__textarea');
const counter = field.querySelector<HTMLElement>('[id$="-charCount"]');
if (!textarea || !counter) return;
textarea.addEventListener('input', () => {
counter.textContent = String(textarea.value.length);
});
});
</script>
<style lang="scss">
@use './textField';
</style>
+23
View File
@@ -15,6 +15,9 @@ import NumericStepper from '../components/numericStepper/numericStepper.astro';
import Avatar from '../components/Avatar/avatar.astro'; import Avatar from '../components/Avatar/avatar.astro';
import Select from '../components/Select/select.astro'; import Select from '../components/Select/select.astro';
import SelectOption from '../components/Select/selectOption.astro'; import SelectOption from '../components/Select/selectOption.astro';
import TextField from '../components/textField/textField.astro';
import Pagination from '../components/pagination/pagination.astro';
import PaginationNumber from '../components/pagination/paginationNumber.astro';
import { import {
Arrow2Icon, BinIcon, BurgerIcon, CalendarIcon, CheckIcon, CloseIcon, Arrow2Icon, BinIcon, BurgerIcon, CalendarIcon, CheckIcon, CloseIcon,
CodeIcon, CubeIcon, DownloadIcon, FilterIcon, HelpIcon, HomeIcon, CodeIcon, CubeIcon, DownloadIcon, FilterIcon, HelpIcon, HomeIcon,
@@ -29,6 +32,26 @@ const initialChecked = true;
<Layout> <Layout>
<main> <main>
<h1>Nova Design System</h1> <h1>Nova Design System</h1>
<section>
<h2>Pagination</h2>
<div style="display: flex; flex-direction: column; gap: var(--nds-spacing-md);">
<Pagination defaultPage={3}>
<PaginationNumber>1</PaginationNumber>
<PaginationNumber>2</PaginationNumber>
<PaginationNumber>3</PaginationNumber>
<PaginationNumber>4</PaginationNumber>
<PaginationNumber disabled>5</PaginationNumber>
</Pagination>
</div>
</section>
<section>
<h2>TextField</h2>
<div style="display: flex; flex-direction: column; gap: var(--nds-spacing-md);">
<TextField label="Email" type="email" placeholder="Enter your email" />
<TextField label="Password" type="password" placeholder="Enter your password" />
<TextField label="Textarea" type="textarea" placeholder="Enter your message" max={100} />
</div>
</section>
<section> <section>
<h2>Select</h2> <h2>Select</h2>
<div style="display: flex; flex-direction: column; gap: var(--nds-spacing-md);"> <div style="display: flex; flex-direction: column; gap: var(--nds-spacing-md);">