Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/wicked-eels-call.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@solid-design-system/components': patch
---

Fixed the `sd-datepicker` css properties not showing in Storybook.
114 changes: 114 additions & 0 deletions packages/components/src/components/datepicker/datepicker-converters.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
export const isoDateConverter = {
fromAttribute(value: string | null): string | null {
if (!value) return null;

// normalize all separators to hyphens
const cleaned = value.trim().replace(/[./]/g, '-');

// acccept YYYY-MM-DD only
const match = cleaned.match(/^(\d{4})-(\d{2})-(\d{2})$/);
if (!match) return null;

const iso = `${match[1]}-${match[2]}-${match[3]}`;

// validate date
const d = new Date(+match[1], +match[2] - 1, +match[3]);
if (d.getFullYear() !== +match[1] || d.getMonth() !== +match[2] - 1 || d.getDate() !== +match[3]) {
return null;
}

return iso;
},

toAttribute(value: string | null): string {
return value ?? '';
}
};

export const viewMonthConverter = {
fromAttribute(value: string | null): Date | null {
if (!value) return null;

const cleaned = value.trim().replace(/[./]/g, '-');
let m: RegExpMatchArray | null = cleaned.match(/^(\d{2})-(\d{4})$/);
let month: number;
let year: number;

if (m) {
month = Number(m[1]);
year = Number(m[2]);
} else {
m = cleaned.match(/^(\d{4})-(\d{2})$/);
if (!m) return null;
year = Number(m[1]);
month = Number(m[2]);
}

if (!year || !month || month < 1 || month > 12) return null;

return new Date(year, month - 1, 1);
},

toAttribute(value: Date | null): string {
if (!value) return '';
const year = value.getFullYear();
const month = String(value.getMonth() + 1).padStart(2, '0');
return `${year}-${month}`;
}
};

export const disabledDatesConverter = {
fromAttribute(value: string | null): string[] {
if (!value) return [];

let rawList: string[] = [];

const trimmed = value.trim();

// arrays
if (trimmed.startsWith('[')) {
try {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const parsed = JSON.parse(trimmed);
if (Array.isArray(parsed)) {
rawList = parsed.map(String);
}
} catch {
return [];
}
} else {
// space separated
rawList = trimmed
.split(/[\s,]+/)
.map(v => v.trim())
.filter(Boolean);
}

const result: string[] = [];

for (const raw of rawList) {
// replace all separators with dots
const cleaned = raw.replace(/[-/]/g, '.');
const parts = cleaned.split('.');

if (parts.length !== 3) continue;
const [yyyy, mm, dd] = parts.map(Number);

if (!yyyy || !mm || !dd) continue;

// validate date
const date = new Date(yyyy, mm - 1, dd);
if (date.getFullYear() !== yyyy || date.getMonth() !== mm - 1 || date.getDate() !== dd) continue;

const iso = `${yyyy}-${String(mm).padStart(2, '0')}-${String(dd).padStart(2, '0')}`;

result.push(iso);
}

return result;
},

toAttribute(value: string[] | null): string {
return value ? value.join(',') : '';
}
};
117 changes: 1 addition & 116 deletions packages/components/src/components/datepicker/datepicker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import cx from 'classix';
import SolidElement from '../../internal/solid-element';
import type { SolidFormControl } from '../../internal/solid-element';
import type SdPopup from '../popup/popup';
import { isoDateConverter, viewMonthConverter, disabledDatesConverter } from './datepicker-converters';

/**
* @summary Used to enter or select a date or a range of dates using a calendar view.
Expand Down Expand Up @@ -80,122 +81,6 @@ import type SdPopup from '../popup/popup';
* @cssproperty --sd-datepicker__date-item--current-color-text - The text color for the current date item.
* @cssproperty --sd-datepicker__date-item--selected--hover-color-text - The text color for selected date items in hover state.
*/

const isoDateConverter = {
fromAttribute(value: string | null): string | null {
if (!value) return null;

// normalize all separators to hyphens
const cleaned = value.trim().replace(/[./]/g, '-');

// acccept YYYY-MM-DD only
const match = cleaned.match(/^(\d{4})-(\d{2})-(\d{2})$/);
if (!match) return null;

const iso = `${match[1]}-${match[2]}-${match[3]}`;

// validate date
const d = new Date(+match[1], +match[2] - 1, +match[3]);
if (d.getFullYear() !== +match[1] || d.getMonth() !== +match[2] - 1 || d.getDate() !== +match[3]) {
return null;
}

return iso;
},

toAttribute(value: string | null): string {
return value ?? '';
}
};

const viewMonthConverter = {
fromAttribute(value: string | null): Date | null {
if (!value) return null;

const cleaned = value.trim().replace(/[./]/g, '-');
let m: RegExpMatchArray | null = cleaned.match(/^(\d{2})-(\d{4})$/);
let month: number;
let year: number;

if (m) {
month = Number(m[1]);
year = Number(m[2]);
} else {
m = cleaned.match(/^(\d{4})-(\d{2})$/);
if (!m) return null;
year = Number(m[1]);
month = Number(m[2]);
}

if (!year || !month || month < 1 || month > 12) return null;

return new Date(year, month - 1, 1);
},

toAttribute(value: Date | null): string {
if (!value) return '';
const year = value.getFullYear();
const month = String(value.getMonth() + 1).padStart(2, '0');
return `${year}-${month}`;
}
};

const disabledDatesConverter = {
fromAttribute(value: string | null): string[] {
if (!value) return [];

let rawList: string[] = [];

const trimmed = value.trim();

// arrays
if (trimmed.startsWith('[')) {
try {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const parsed = JSON.parse(trimmed);
if (Array.isArray(parsed)) {
rawList = parsed.map(String);
}
} catch {
return [];
}
} else {
// space separated
rawList = trimmed
.split(/[\s,]+/)
.map(v => v.trim())
.filter(Boolean);
}

const result: string[] = [];

for (const raw of rawList) {
// replace all separators with dots
const cleaned = raw.replace(/[-/]/g, '.');
const parts = cleaned.split('.');

if (parts.length !== 3) continue;
const [yyyy, mm, dd] = parts.map(Number);

if (!yyyy || !mm || !dd) continue;

// validate date
const date = new Date(yyyy, mm - 1, dd);
if (date.getFullYear() !== yyyy || date.getMonth() !== mm - 1 || date.getDate() !== dd) continue;

const iso = `${yyyy}-${String(mm).padStart(2, '0')}-${String(dd).padStart(2, '0')}`;

result.push(iso);
}

return result;
},

toAttribute(value: string[] | null): string {
return value ? value.join(',') : '';
}
};

@customElement('sd-datepicker')
export default class SdDatepicker extends SolidElement implements SolidFormControl {
/** Localize controller used to fetch localized terms/labels. */
Expand Down
Loading