Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

render months by default, simplify basic usage #70

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
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
20 changes: 19 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,15 @@
width: 100%;
text-align: center;
}

#simple::part(slot) {
display: flex;
gap: 1em;
}
#simple2::part(slot) {
display: flex;
gap: 1em;
}
</style>
</head>
<body>
Expand Down Expand Up @@ -89,7 +98,7 @@ <h2>date</h2>

<h2>multi</h2>
<calendar-multi
id="date"
id="multi"
months="2"
show-outside-days
value="2024-05-07 2024-05-09"
Expand All @@ -100,6 +109,15 @@ <h2>multi</h2>
</div>
</calendar-multi>

<h2>Simple date</h2>

<calendar-date id="simple" months="3"></calendar-date>

<calendar-date id="simple2" months="3">
<span slot="previous">&lt;</span>
<span slot="next">&gt;</span>
</calendar-date>

<script type="module">
import "./src/index.ts";

Expand Down
20 changes: 19 additions & 1 deletion src/calendar-base/calendar-base.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { reset, vh } from "../utils/styles.js";
import { toDate, type DaysOfWeek } from "../utils/date.js";
import type { PlainDate } from "../utils/temporal.js";
import type { Pagination } from "./useCalendarBase.js";
import { CalendarMonth } from "../calendar-month/calendar-month.js";

interface CalendarBaseProps {
format: Intl.DateTimeFormat;
Expand All @@ -19,6 +20,17 @@ interface CalendarBaseProps {
onSelect: (e: CustomEvent<PlainDate>) => void;
onFocus: (e: CustomEvent<PlainDate>) => void;
onHover?: (e: CustomEvent<PlainDate>) => void;
months: number;
hasSlotted: boolean;
onSlotChange: (e: Event) => void;
}

function range<T>(max: number, fn: (n: number) => T) {
let output = [];
for (let i = 0; i < max; i++) {
output.push(fn(i));
}
return output;
}

interface CalendarRangeProps extends CalendarBaseProps, CalendarRangeContext {}
Expand Down Expand Up @@ -73,7 +85,13 @@ export function CalendarBase(
onfocusday={props.onFocus}
onhoverday={props.onHover}
>
<slot></slot>
<slot part="slot" onslotchange={props.onSlotChange}>
{props.hasSlotted
? null
: range(props.months, (offset) => (
<CalendarMonth offset={offset} />
))}
</slot>
</CalendarMonthContext>
</div>
);
Expand Down
22 changes: 19 additions & 3 deletions src/calendar-base/useCalendarBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,11 +134,25 @@ export function useCalendarBase({

const host = useHost();
function focus() {
host.current
.querySelectorAll<HTMLElement>("calendar-month")
.forEach((m) => m.focus());
const children =
host.current.querySelectorAll<HTMLElement>("calendar-month");
const months = children.length
? children
: host.current.shadowRoot!.querySelectorAll<HTMLElement>(
"calendar-month"
);

months.forEach((m) => m.focus());
}

const [hasSlotted, setHasSlotted] = useState(false);
const onSlotChange = (e: Event) => {
return setHasSlotted(
(e.target as HTMLSlotElement).assignedElements({ flatten: true }).length >
0
);
};

return {
format: useDateFormatter(formatOptions, locale),
formatVerbose: useDateFormatter(formatVerboseOptions, locale),
Expand All @@ -155,5 +169,7 @@ export function useCalendarBase({
next,
previous,
focus,
hasSlotted,
onSlotChange,
};
}
34 changes: 34 additions & 0 deletions src/calendar-date/calendar-date.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -802,4 +802,38 @@ describe("CalendarDate", () => {
expect(firstJan).to.have.attribute("aria-pressed", "true");
});
});

describe("simple usage", () => {
it("renders its own months if none supplied", async () => {
const calendar = await mount(
<CalendarDate locale="en-GB" months={2} value="2024-11-02" />
);
const months = getMonths(calendar);

expect(months).to.have.lengthOf(2);
expect(getMonthHeading(months[0]!)).to.have.text("November");
expect(getMonthHeading(months[1]!)).to.have.text("December");
});

it("does not render its own month if some are slotted", async () => {
const calendar = await mount(<Fixture value="2024-11-02" />);
expect(
calendar.shadowRoot!.querySelector("slot:not([name])")!.children
).to.have.lengthOf(0);
});

it("behaves correctly when named slots are used", async () => {
const calendar = await mount(
<CalendarDate locale="en-GB" months={2} value="2024-11-02">
<span slot="prev">&lt;</span>
<span slot="next">&gt;</span>
</CalendarDate>
);
const months = getMonths(calendar);

expect(months).to.have.lengthOf(2);
expect(getMonthHeading(months[0]!)).to.have.text("November");
expect(getMonthHeading(months[1]!)).to.have.text("December");
});
});
});
12 changes: 11 additions & 1 deletion src/utils/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,17 @@ export async function click(element: Element) {
}

export function getMonths(calendar: HTMLElement): MonthInstance[] {
return [...calendar.querySelectorAll<MonthInstance>("calendar-month")!];
const children = [
...calendar.querySelectorAll<MonthInstance>("calendar-month"),
];

return children.length
? children
: [
...calendar.shadowRoot!.querySelectorAll<MonthInstance>(
"calendar-month"
),
];
}

export function getMonth(calendar: HTMLElement): MonthInstance {
Expand Down
Loading