@pathscale/ui 3.1.0 → 3.2.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/README.md +13 -2
- package/dist/components/accordion/Accordion.css +24 -1
- package/dist/components/alert/Alert.css +11 -1
- package/dist/components/button/Button.css +33 -6
- package/dist/components/calendar/Calendar.generated.d.ts +19 -2
- package/dist/components/calendar/Calendar.generated.js +30 -23
- package/dist/components/calendar/index.d.ts +1 -1
- package/dist/components/card/Card.generated.d.ts +17 -0
- package/dist/components/card/Card.generated.js +99 -45
- package/dist/components/card/Card.interactions.d.ts +70 -0
- package/dist/components/card/Card.interactions.js +19 -0
- package/dist/components/collapsible/Collapsible.css +17 -1
- package/dist/components/color-wheel-flower/ColorWheelFlower.generated.d.ts +8 -0
- package/dist/components/color-wheel-flower/ColorWheelFlower.generated.js +14 -1
- package/dist/components/color-wheel-flower/colorWheelFlowerContext.d.ts +9 -2
- package/dist/components/color-wheel-flower/colorWheelFlowerContext.js +2 -4
- package/dist/components/date-picker/DatePicker.generated.d.ts +3 -1
- package/dist/components/date-picker/DatePicker.generated.js +8 -5
- package/dist/components/date-range-picker/DateRangePicker.generated.d.ts +3 -1
- package/dist/components/date-range-picker/DateRangePicker.generated.js +9 -6
- package/dist/components/drawer/Drawer.generated.d.ts +24 -0
- package/dist/components/drawer/Drawer.generated.js +48 -18
- package/dist/components/icon/Icon.generated.d.ts +15 -0
- package/dist/components/icon/Icon.generated.js +11 -2
- package/dist/components/immersive-landing/ImmersiveLanding.css +1 -1
- package/dist/components/immersive-landing/components/CookieConsent.interactions.d.ts +24 -0
- package/dist/components/immersive-landing/components/CookieConsent.interactions.js +2 -0
- package/dist/components/immersive-landing/components/CookieConsent.js +52 -47
- package/dist/components/immersive-landing/components/FirefoxPWABanner.js +10 -10
- package/dist/components/immersive-landing/types.d.ts +15 -0
- package/dist/components/language-switcher/LanguageSwitcher.generated.js +1 -1
- package/dist/components/live-chat/LiveChatPanel.generated.js +2 -6
- package/dist/components/live-chat/LiveChatPanel.interactions.d.ts +21 -0
- package/dist/components/live-chat/LiveChatPanel.interactions.js +10 -0
- package/dist/components/popover/Popover.a11y.d.ts +47 -0
- package/dist/components/popover/Popover.a11y.js +19 -0
- package/dist/components/popover/Popover.generated.d.ts +26 -0
- package/dist/components/popover/Popover.generated.js +105 -35
- package/dist/components/range-calendar/RangeCalendar.generated.d.ts +3 -1
- package/dist/components/range-calendar/RangeCalendar.generated.js +4 -1
- package/dist/components/table/MobileListView.generated.js +1 -1
- package/dist/components/text/Text.generated.d.ts +26 -1
- package/dist/components/text/Text.generated.js +13 -8
- package/dist/components/text/index.d.ts +1 -1
- package/dist/components/theme-color-picker/ThemeColorPicker.generated.js +1 -1
- package/dist/hooks/date/date.names.d.ts +107 -0
- package/dist/hooks/date/date.names.js +74 -0
- package/dist/hooks/date/date.utils.d.ts +11 -1
- package/dist/hooks/date/date.utils.js +3 -6
- package/dist/hooks/date/index.d.ts +1 -0
- package/dist/hooks/date/index.js +1 -0
- package/dist/hooks/date/useCalendarState.d.ts +12 -5
- package/dist/hooks/date/useCalendarState.js +7 -19
- package/dist/hooks/form/createForm.d.ts +4 -4
- package/dist/hooks/form/createForm.js +7 -9
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -1
- package/dist/layouts.manifest.json +4 -1
- package/dist/responsive-classes.txt +450 -0
- package/package.json +10 -5
package/README.md
CHANGED
|
@@ -28,7 +28,7 @@ yarn add @pathscale/ui solid-layouts && yarn add -D rsbuild-plugin-solid-layouts
|
|
|
28
28
|
|
|
29
29
|
## Setup
|
|
30
30
|
|
|
31
|
-
`@pathscale/ui`
|
|
31
|
+
`@pathscale/ui` 3.x is a compiled Layout bundle. Configure the application compiler before
|
|
32
32
|
Solid transforms JSX:
|
|
33
33
|
|
|
34
34
|
```ts
|
|
@@ -58,11 +58,22 @@ import "@pathscale/ui/index.css";
|
|
|
58
58
|
|
|
59
59
|
export const Example = () => (
|
|
60
60
|
<Flex direction="col" gap="sm">
|
|
61
|
-
<Button variant="primary" size="md">Primary</Button>
|
|
61
|
+
<Button variant="solid" flavor="primary" size="md">Primary</Button>
|
|
62
62
|
</Flex>
|
|
63
63
|
);
|
|
64
64
|
```
|
|
65
65
|
|
|
66
|
+
In the application's Tailwind v4 stylesheet, register the package as a source
|
|
67
|
+
(adjust the relative path from that stylesheet):
|
|
68
|
+
|
|
69
|
+
```css
|
|
70
|
+
@source "../node_modules/@pathscale/ui";
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
This includes the published `dist/responsive-classes.txt` scanner input. Grid and
|
|
74
|
+
Flex compose responsive classes at runtime, so scanning only the compiled JavaScript
|
|
75
|
+
misses utilities such as `md:grid-cols-3`.
|
|
76
|
+
|
|
66
77
|
## Theming
|
|
67
78
|
|
|
68
79
|
Two themes ship with the library: `light` (the default when no attribute is set) and `dark`.
|
|
@@ -93,19 +93,42 @@
|
|
|
93
93
|
transform: rotate(-180deg);
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
+
/*
|
|
97
|
+
* A closed panel is out of the page, not merely flattened.
|
|
98
|
+
*
|
|
99
|
+
* `keepMounted` is the default, so a closed panel stays in the document, and
|
|
100
|
+
* it carried `aria-hidden="true"` while its contents kept `visibility:
|
|
101
|
+
* visible`. Nothing under `grid-template-rows: 0fr` and `opacity: 0` is
|
|
102
|
+
* display:none, so every link and button inside a closed panel was still in
|
|
103
|
+
* the tab order: Tab moved focus into a panel nobody can see, into an
|
|
104
|
+
* `aria-hidden` subtree, which is the one thing `aria-hidden` must never
|
|
105
|
+
* contain.
|
|
106
|
+
*
|
|
107
|
+
* `visibility: hidden` is what takes the descendants out of both the tab
|
|
108
|
+
* order and the accessibility tree, and it is delayed by the length of the
|
|
109
|
+
* collapse so the animation still plays before the panel disappears. Opening
|
|
110
|
+
* drops the delay, so the panel is visible for the whole of the expansion.
|
|
111
|
+
*/
|
|
96
112
|
.accordion__content {
|
|
97
113
|
display: grid;
|
|
98
114
|
grid-template-rows: 0fr;
|
|
99
115
|
opacity: 0;
|
|
100
116
|
overflow: hidden;
|
|
117
|
+
visibility: hidden;
|
|
101
118
|
transition:
|
|
102
119
|
grid-template-rows 200ms ease,
|
|
103
|
-
opacity 200ms ease
|
|
120
|
+
opacity 200ms ease,
|
|
121
|
+
visibility 0s linear 200ms;
|
|
104
122
|
}
|
|
105
123
|
|
|
106
124
|
.accordion__content--expanded {
|
|
107
125
|
grid-template-rows: 1fr;
|
|
108
126
|
opacity: 1;
|
|
127
|
+
visibility: visible;
|
|
128
|
+
transition:
|
|
129
|
+
grid-template-rows 200ms ease,
|
|
130
|
+
opacity 200ms ease,
|
|
131
|
+
visibility 0s linear 0s;
|
|
109
132
|
}
|
|
110
133
|
|
|
111
134
|
.accordion__body {
|
|
@@ -5,6 +5,14 @@
|
|
|
5
5
|
* Same shape as Button: flavor or state picks --alert-accent and the
|
|
6
6
|
* variant decides how it is spent. State is declared second so it wins on
|
|
7
7
|
* source order — a reported condition outranks a styling preference.
|
|
8
|
+
*
|
|
9
|
+
* --alert-accent-ink carries the same split Button needed: the accent as a
|
|
10
|
+
* surface and the accent as ink are not the same colour when the flavor is
|
|
11
|
+
* `neutral`, whose accent is --color-base-300, the page one step darker.
|
|
12
|
+
* `plain` is the variant that writes the accent straight onto the page, so
|
|
13
|
+
* `variant="plain" flavor="neutral"` was unreadable for exactly the reason a
|
|
14
|
+
* neutral outline Button was invisible. Ink defaults to the accent, so only
|
|
15
|
+
* `neutral` overrides it.
|
|
8
16
|
* --------------------------------------------------------------------- */
|
|
9
17
|
.alert {
|
|
10
18
|
display: flex;
|
|
@@ -20,6 +28,7 @@
|
|
|
20
28
|
|
|
21
29
|
--alert-accent: var(--color-base-300);
|
|
22
30
|
--alert-accent-fg: var(--color-base-content);
|
|
31
|
+
--alert-accent-ink: var(--alert-accent);
|
|
23
32
|
--alert-bg: var(--color-base-200);
|
|
24
33
|
--alert-fg: var(--color-base-content);
|
|
25
34
|
--alert-border: transparent;
|
|
@@ -33,6 +42,7 @@
|
|
|
33
42
|
.alert--flavor-neutral {
|
|
34
43
|
--alert-accent: var(--color-base-300);
|
|
35
44
|
--alert-accent-fg: var(--color-base-content);
|
|
45
|
+
--alert-accent-ink: var(--color-base-content);
|
|
36
46
|
}
|
|
37
47
|
.alert--flavor-primary {
|
|
38
48
|
--alert-accent: var(--color-primary);
|
|
@@ -96,7 +106,7 @@
|
|
|
96
106
|
|
|
97
107
|
.alert--plain {
|
|
98
108
|
--alert-bg: transparent;
|
|
99
|
-
--alert-fg: var(--alert-accent);
|
|
109
|
+
--alert-fg: var(--alert-accent-ink);
|
|
100
110
|
--alert-border: transparent;
|
|
101
111
|
padding: 0;
|
|
102
112
|
}
|
|
@@ -2,10 +2,31 @@
|
|
|
2
2
|
/* -----------------------------------------------------------------------
|
|
3
3
|
* Root
|
|
4
4
|
*
|
|
5
|
-
*
|
|
5
|
+
* Three custom properties carry the whole state x variant cross product:
|
|
6
6
|
* a state sets --button-accent (and its readable foreground), and a variant
|
|
7
7
|
* decides how that accent is spent. 8 states + 5 variants = 13 rules
|
|
8
8
|
* instead of 40 combinations.
|
|
9
|
+
*
|
|
10
|
+
* The third is --button-accent-ink, and it exists because the accent is two
|
|
11
|
+
* different things depending on how a variant spends it. `solid` paints the
|
|
12
|
+
* accent as a *surface* and writes on it with --button-accent-fg; `outline`,
|
|
13
|
+
* `soft` and `plain` paint the accent as *ink*, on the page's own surface.
|
|
14
|
+
* Seven flavors set an accent that works either way. `neutral` sets
|
|
15
|
+
* --color-base-300, which is a surface token by construction: it is the page
|
|
16
|
+
* one step darker.
|
|
17
|
+
*
|
|
18
|
+
* So `variant="outline" flavor="neutral"` resolved label and border alike to
|
|
19
|
+
* base-300 and rendered a completely invisible control: correct role, correct
|
|
20
|
+
* name, correct 46x28 box, clickable, and 0 of its 1288 pixels different from
|
|
21
|
+
* the background behind it. Measured at #e6e4e3 on a #f5f5f4 page, the label
|
|
22
|
+
* was at 1.16:1. The focus ring had the same fault for the same reason: a
|
|
23
|
+
* neutral button's focus ring was drawn in the surface colour.
|
|
24
|
+
*
|
|
25
|
+
* --button-accent-ink is therefore what the accent means when it is ink. It
|
|
26
|
+
* defaults to the accent, so the seven flavors that already worked are
|
|
27
|
+
* untouched and a theme defining its own flavor needs to set nothing; only
|
|
28
|
+
* `neutral` overrides it, to the content colour that is readable on the page
|
|
29
|
+
* by definition.
|
|
9
30
|
* --------------------------------------------------------------------- */
|
|
10
31
|
.button {
|
|
11
32
|
position: relative;
|
|
@@ -36,6 +57,7 @@
|
|
|
36
57
|
|
|
37
58
|
--button-accent: var(--color-base-300);
|
|
38
59
|
--button-accent-fg: var(--color-base-content);
|
|
60
|
+
--button-accent-ink: var(--button-accent);
|
|
39
61
|
--button-bg: transparent;
|
|
40
62
|
--button-bg-hover: var(--button-bg);
|
|
41
63
|
--button-bg-pressed: var(--button-bg-hover);
|
|
@@ -49,7 +71,7 @@
|
|
|
49
71
|
|
|
50
72
|
.button:focus-visible,
|
|
51
73
|
.button[data-focus-visible="true"] {
|
|
52
|
-
outline: var(--focus-ring-width, 2px) solid var(--button-accent);
|
|
74
|
+
outline: var(--focus-ring-width, 2px) solid var(--button-accent-ink);
|
|
53
75
|
outline-offset: var(--focus-ring-offset, 2px);
|
|
54
76
|
}
|
|
55
77
|
|
|
@@ -84,9 +106,14 @@
|
|
|
84
106
|
/* -----------------------------------------------------------------------
|
|
85
107
|
* Flavor — a styling preference: which palette slot to wear
|
|
86
108
|
* --------------------------------------------------------------------- */
|
|
109
|
+
/*
|
|
110
|
+
* The one flavor whose accent is a surface. `outline`, `soft` and `plain`
|
|
111
|
+
* would otherwise draw the label in it, on the page it is one step away from.
|
|
112
|
+
*/
|
|
87
113
|
.button--flavor-neutral {
|
|
88
114
|
--button-accent: var(--color-base-300);
|
|
89
115
|
--button-accent-fg: var(--color-base-content);
|
|
116
|
+
--button-accent-ink: var(--color-base-content);
|
|
90
117
|
}
|
|
91
118
|
.button--flavor-primary {
|
|
92
119
|
--button-accent: var(--color-primary);
|
|
@@ -177,7 +204,7 @@
|
|
|
177
204
|
var(--button-accent),
|
|
178
205
|
var(--color-base-100) 74%
|
|
179
206
|
);
|
|
180
|
-
--button-fg: var(--button-accent);
|
|
207
|
+
--button-fg: var(--button-accent-ink);
|
|
181
208
|
--button-border: transparent;
|
|
182
209
|
}
|
|
183
210
|
|
|
@@ -193,8 +220,8 @@
|
|
|
193
220
|
var(--button-accent),
|
|
194
221
|
transparent 80%
|
|
195
222
|
);
|
|
196
|
-
--button-fg: var(--button-accent);
|
|
197
|
-
--button-border: var(--button-accent);
|
|
223
|
+
--button-fg: var(--button-accent-ink);
|
|
224
|
+
--button-border: var(--button-accent-ink);
|
|
198
225
|
}
|
|
199
226
|
|
|
200
227
|
/* Ghost keeps body text colour: it is chrome, not an accent surface. */
|
|
@@ -210,7 +237,7 @@
|
|
|
210
237
|
--button-bg: transparent;
|
|
211
238
|
--button-bg-hover: transparent;
|
|
212
239
|
--button-bg-pressed: transparent;
|
|
213
|
-
--button-fg: var(--button-accent);
|
|
240
|
+
--button-fg: var(--button-accent-ink);
|
|
214
241
|
--button-border: transparent;
|
|
215
242
|
height: auto;
|
|
216
243
|
padding-inline: 0;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { Component as __LayoutComponent } from "solid-js";
|
|
2
2
|
import "./Calendar.css";
|
|
3
3
|
import type { JSX } from "@solidjs/web";
|
|
4
|
-
import { type CalendarSelectionMode } from "../../hooks/date";
|
|
4
|
+
import { type CalendarSelectionMode, type DateNames } from "../../hooks/date";
|
|
5
5
|
import type { UIBaseProps, State } from "../vocabulary";
|
|
6
6
|
export type CalendarWeekdayFormat = "narrow" | "short" | "long";
|
|
7
|
-
export type { CalendarSelectionMode };
|
|
7
|
+
export type { CalendarSelectionMode, DateNames };
|
|
8
8
|
export type CalendarDaySelectHandler = (date: Date) => void;
|
|
9
9
|
export type CalendarDayHoverHandler = (date?: Date) => void;
|
|
10
10
|
type CalendarBaseProps = {
|
|
@@ -20,7 +20,24 @@ type CalendarBaseProps = {
|
|
|
20
20
|
minValue?: Date;
|
|
21
21
|
maxValue?: Date;
|
|
22
22
|
isDateUnavailable?: (date: Date) => boolean;
|
|
23
|
+
/**
|
|
24
|
+
* The language to render in. Honoured only when `dateNames` supplies the
|
|
25
|
+
* names to back it; on its own it cannot change what is on screen, because
|
|
26
|
+
* the library carries no locale data beyond `en-US`. Whatever is actually
|
|
27
|
+
* rendered is reported on the root element's `lang`.
|
|
28
|
+
*/
|
|
23
29
|
locale?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Month and weekday names for a language other than English.
|
|
32
|
+
*
|
|
33
|
+
* The library ships one table, `en-US`, and no way to derive another: `Intl`
|
|
34
|
+
* is unavailable in the chuzz browser and ICU data is deliberately not
|
|
35
|
+
* shipped. A translated site passes its own names here, from the same i18n
|
|
36
|
+
* catalogue it already uses for the rest of its strings. All five arrays are
|
|
37
|
+
* required. Omit this and the calendar renders English and says `lang="en-US"`
|
|
38
|
+
* regardless of `locale`.
|
|
39
|
+
*/
|
|
40
|
+
dateNames?: DateNames;
|
|
24
41
|
weekdayFormat?: CalendarWeekdayFormat;
|
|
25
42
|
showOutsideDays?: boolean;
|
|
26
43
|
state?: State;
|
|
@@ -3,11 +3,11 @@ import { defineComponent } from "solid-layouts/solid-2/application-boundary";
|
|
|
3
3
|
import "./Calendar.css";
|
|
4
4
|
import { For, Show, createMemo, createTrackedEffect, createUniqueId, omit } from "solid-js";
|
|
5
5
|
import { twMerge } from "../../lib/twMerge.js";
|
|
6
|
-
import { DAYS_PER_WEEK, addDays, compareDates, getToday, normalizeDate, parseDate, shiftDateByMonths, toISODate, useCalendarNavigation, useCalendarState, useDateSelection } from "../../hooks/date/index.js";
|
|
6
|
+
import { DAYS_PER_WEEK, addDays, compareDates, getToday, normalizeDate, parseDate, resolveDateNames, shiftDateByMonths, toISODate, useCalendarNavigation, useCalendarState, useDateSelection } from "../../hooks/date/index.js";
|
|
7
7
|
import { CLASSES, componentRecipe } from "./Calendar.recipe.js";
|
|
8
8
|
var _tmpl$ = /*#__PURE__*/ template('<div><div><div><button><svg><path d="m15 18-6-6 6-6"></path></svg></button></div><div></div><div><button><svg><path d="m9 18 6-6-6-6"></path></svg></button></div></div><div><div><div></div></div><div>'), _tmpl$2 = /*#__PURE__*/ template("<span>"), _tmpl$3 = /*#__PURE__*/ template("<div>"), _tmpl$4 = /*#__PURE__*/ template("<button><span>");
|
|
9
9
|
const __solidLayoutCalendar = (_stable, p)=>{
|
|
10
|
-
const others = omit(p, "class", "dataTheme", "style", "ref", "selectionMode", "value", "defaultValue", "onChange", "rangeStart", "rangeEnd", "rangePreview", "onDaySelect", "onDayHover", "minValue", "maxValue", "isDateUnavailable", "locale", "weekdayFormat", "showOutsideDays", "state", "disabled");
|
|
10
|
+
const others = omit(p, "class", "dataTheme", "style", "ref", "selectionMode", "value", "defaultValue", "onChange", "rangeStart", "rangeEnd", "rangePreview", "onDaySelect", "onDayHover", "minValue", "maxValue", "isDateUnavailable", "locale", "dateNames", "weekdayFormat", "showOutsideDays", "state", "disabled");
|
|
11
11
|
const selectionMode = createMemo(()=>p.selectionMode ?? "single");
|
|
12
12
|
const dateSelection = useDateSelection({
|
|
13
13
|
value: ()=>p.value,
|
|
@@ -22,7 +22,9 @@ const __solidLayoutCalendar = (_stable, p)=>{
|
|
|
22
22
|
const focusReferenceDate = createMemo(()=>selectedDate() ?? rangeEnd() ?? rangeStart() ?? normalizeDate(p.value) ?? defaultReferenceDate());
|
|
23
23
|
const minDate = createMemo(()=>normalizeDate(p.minValue));
|
|
24
24
|
const maxDate = createMemo(()=>normalizeDate(p.maxValue));
|
|
25
|
-
const
|
|
25
|
+
const resolvedNames = createMemo(()=>resolveDateNames(p.locale, p.dateNames));
|
|
26
|
+
const dateNames = createMemo(()=>resolvedNames().names);
|
|
27
|
+
const renderedLocale = createMemo(()=>resolvedNames().locale);
|
|
26
28
|
const weekdayFormat = createMemo(()=>p.weekdayFormat ?? "short");
|
|
27
29
|
const showOutsideDays = createMemo(()=>p.showOutsideDays ?? true);
|
|
28
30
|
const isCalendarDisabled = createMemo(()=>Boolean("disabled" === p.state) || Boolean(p.disabled));
|
|
@@ -46,7 +48,7 @@ const __solidLayoutCalendar = (_stable, p)=>{
|
|
|
46
48
|
});
|
|
47
49
|
const calendarState = useCalendarState({
|
|
48
50
|
selectionMode: ()=>selectionMode(),
|
|
49
|
-
|
|
51
|
+
dateNames,
|
|
50
52
|
weekdayFormat,
|
|
51
53
|
visibleMonth: navigation.visibleMonth,
|
|
52
54
|
focusedDate: navigation.focusedDate,
|
|
@@ -146,6 +148,9 @@ const __solidLayoutCalendar = (_stable, p)=>{
|
|
|
146
148
|
get ["data-disabled"] () {
|
|
147
149
|
return isCalendarDisabled() ? "true" : "false";
|
|
148
150
|
},
|
|
151
|
+
get lang () {
|
|
152
|
+
return renderedLocale();
|
|
153
|
+
},
|
|
149
154
|
get ["data-theme"] () {
|
|
150
155
|
return p.dataTheme;
|
|
151
156
|
},
|
|
@@ -199,9 +204,11 @@ const __solidLayoutCalendar = (_stable, p)=>{
|
|
|
199
204
|
class: CLASSES.Heading.base
|
|
200
205
|
}), {
|
|
201
206
|
"data-slot": "calendar-heading",
|
|
207
|
+
role: "heading",
|
|
208
|
+
"aria-level": "2",
|
|
202
209
|
"aria-live": "polite"
|
|
203
210
|
}), true);
|
|
204
|
-
insert(_el$6, ()=>calendarState.
|
|
211
|
+
insert(_el$6, ()=>calendarState.monthLabel());
|
|
205
212
|
spread(_el$7, mergeProps(()=>({
|
|
206
213
|
class: CLASSES.Nav.base
|
|
207
214
|
}), {
|
|
@@ -294,7 +301,7 @@ const __solidLayoutCalendar = (_stable, p)=>{
|
|
|
294
301
|
insert(_el$13, createComponent(For, {
|
|
295
302
|
each: week,
|
|
296
303
|
children: (date)=>{
|
|
297
|
-
const cellState = calendarState.getCellState(date);
|
|
304
|
+
const cellState = createMemo(()=>calendarState.getCellState(date));
|
|
298
305
|
const isoDate = toISODate(date);
|
|
299
306
|
var _el$14 = _tmpl$3();
|
|
300
307
|
spread(_el$14, mergeProps(()=>({
|
|
@@ -305,7 +312,7 @@ const __solidLayoutCalendar = (_stable, p)=>{
|
|
|
305
312
|
}), true);
|
|
306
313
|
insert(_el$14, createComponent(Show, {
|
|
307
314
|
get when () {
|
|
308
|
-
return showOutsideDays() || !cellState.isOutsideMonth;
|
|
315
|
+
return showOutsideDays() || !cellState().isOutsideMonth;
|
|
309
316
|
},
|
|
310
317
|
get fallback () {
|
|
311
318
|
var _el$17 = _tmpl$2();
|
|
@@ -322,57 +329,57 @@ const __solidLayoutCalendar = (_stable, p)=>{
|
|
|
322
329
|
spread(_el$15, mergeProps({
|
|
323
330
|
type: "button"
|
|
324
331
|
}, ()=>({
|
|
325
|
-
class: twMerge(CLASSES.Cell.base, cellState.isSelected && CLASSES.Cell.flag.selected, cellState.isRangeStart && CLASSES.Cell.flag.rangeStart, cellState.isRangeEnd && CLASSES.Cell.flag.rangeEnd, cellState.isInCommittedRange && CLASSES.Cell.flag.inRange, cellState.isInPreviewRange && !cellState.isInCommittedRange && CLASSES.Cell.flag.inPreviewRange, cellState.isToday && CLASSES.Cell.flag.today, cellState.isOutsideMonth && CLASSES.Cell.flag.outsideMonth, cellState.isDisabled && CLASSES.Cell.flag.disabled, cellState.isUnavailable && CLASSES.Cell.flag.unavailable, cellState.isFocused && CLASSES.Cell.flag.focused)
|
|
332
|
+
class: twMerge(CLASSES.Cell.base, cellState().isSelected && CLASSES.Cell.flag.selected, cellState().isRangeStart && CLASSES.Cell.flag.rangeStart, cellState().isRangeEnd && CLASSES.Cell.flag.rangeEnd, cellState().isInCommittedRange && CLASSES.Cell.flag.inRange, cellState().isInPreviewRange && !cellState().isInCommittedRange && CLASSES.Cell.flag.inPreviewRange, cellState().isToday && CLASSES.Cell.flag.today, cellState().isOutsideMonth && CLASSES.Cell.flag.outsideMonth, cellState().isDisabled && CLASSES.Cell.flag.disabled, cellState().isUnavailable && CLASSES.Cell.flag.unavailable, cellState().isFocused && CLASSES.Cell.flag.focused)
|
|
326
333
|
}), {
|
|
327
334
|
"data-slot": "calendar-cell",
|
|
328
335
|
"data-date": isoDate,
|
|
329
336
|
get ["data-selected"] () {
|
|
330
|
-
return cellState.isSelected ? "true" : "false";
|
|
337
|
+
return cellState().isSelected ? "true" : "false";
|
|
331
338
|
},
|
|
332
339
|
get ["data-range-start"] () {
|
|
333
|
-
return cellState.isRangeStart ? "true" : "false";
|
|
340
|
+
return cellState().isRangeStart ? "true" : "false";
|
|
334
341
|
},
|
|
335
342
|
get ["data-range-end"] () {
|
|
336
|
-
return cellState.isRangeEnd ? "true" : "false";
|
|
343
|
+
return cellState().isRangeEnd ? "true" : "false";
|
|
337
344
|
},
|
|
338
345
|
get ["data-in-range"] () {
|
|
339
|
-
return cellState.isInCommittedRange ? "true" : "false";
|
|
346
|
+
return cellState().isInCommittedRange ? "true" : "false";
|
|
340
347
|
},
|
|
341
348
|
get ["data-in-preview-range"] () {
|
|
342
|
-
return cellState.isInPreviewRange ? "true" : "false";
|
|
349
|
+
return cellState().isInPreviewRange ? "true" : "false";
|
|
343
350
|
},
|
|
344
351
|
get ["data-today"] () {
|
|
345
|
-
return cellState.isToday ? "true" : "false";
|
|
352
|
+
return cellState().isToday ? "true" : "false";
|
|
346
353
|
},
|
|
347
354
|
get ["data-outside-month"] () {
|
|
348
|
-
return cellState.isOutsideMonth ? "true" : "false";
|
|
355
|
+
return cellState().isOutsideMonth ? "true" : "false";
|
|
349
356
|
},
|
|
350
357
|
get ["data-disabled"] () {
|
|
351
|
-
return cellState.isDisabled ? "true" : "false";
|
|
358
|
+
return cellState().isDisabled ? "true" : "false";
|
|
352
359
|
},
|
|
353
360
|
get ["data-unavailable"] () {
|
|
354
|
-
return cellState.isUnavailable ? "true" : "false";
|
|
361
|
+
return cellState().isUnavailable ? "true" : "false";
|
|
355
362
|
},
|
|
356
363
|
role: "gridcell",
|
|
357
364
|
get ["aria-label"] () {
|
|
358
|
-
return calendarState.
|
|
365
|
+
return calendarState.formatDayLabel(date);
|
|
359
366
|
},
|
|
360
367
|
get ["aria-selected"] () {
|
|
361
|
-
return cellState.isAriaSelected ? "true" : "false";
|
|
368
|
+
return cellState().isAriaSelected ? "true" : "false";
|
|
362
369
|
},
|
|
363
370
|
get ["aria-disabled"] () {
|
|
364
|
-
return cellState.isDisabled ? "true" : "false";
|
|
371
|
+
return cellState().isDisabled ? "true" : "false";
|
|
365
372
|
},
|
|
366
373
|
get disabled () {
|
|
367
|
-
return cellState.isDisabled;
|
|
374
|
+
return cellState().isDisabled;
|
|
368
375
|
},
|
|
369
376
|
get tabindex () {
|
|
370
|
-
return cellState.isFocused ? 0 : -1;
|
|
377
|
+
return cellState().isFocused ? 0 : -1;
|
|
371
378
|
},
|
|
372
379
|
onClick: ()=>selectDate(date),
|
|
373
380
|
onFocus: ()=>navigation.setFocusedDate(date),
|
|
374
381
|
onMouseEnter: ()=>{
|
|
375
|
-
if (cellState.isDisabled) return;
|
|
382
|
+
if (cellState().isDisabled) return;
|
|
376
383
|
p.onDayHover?.(date);
|
|
377
384
|
},
|
|
378
385
|
onKeyDown: handleCellKeyDown
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { type CalendarDayHoverHandler, type CalendarDaySelectHandler, type CalendarProps, type CalendarSelectionMode, type CalendarWeekdayFormat, default, } from "./Calendar.generated";
|
|
1
|
+
export { type CalendarDayHoverHandler, type CalendarDaySelectHandler, type CalendarProps, type CalendarSelectionMode, type CalendarWeekdayFormat, type DateNames, default, } from "./Calendar.generated";
|
|
@@ -39,6 +39,23 @@ export type CardProps = Omit<JSX.HTMLAttributes<HTMLDivElement>, "children"> & U
|
|
|
39
39
|
radius?: Radius;
|
|
40
40
|
/** Replaces isHoverable and isPressable, which had one call site each across 330. */
|
|
41
41
|
isInteractive?: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Renders the card as an anchor, and navigates.
|
|
44
|
+
*
|
|
45
|
+
* A whole card that navigates is the common shape, and the way it was
|
|
46
|
+
* written was `<a href><Card isInteractive /></a>`, which put a `button`
|
|
47
|
+
* inside a `link` with the same name and the same box. That is invalid
|
|
48
|
+
* HTML, it announces the card twice, and a press by coordinate lands on
|
|
49
|
+
* whichever of the two happens to be on top.
|
|
50
|
+
*
|
|
51
|
+
* A card that navigates should be the anchor rather than sit inside one,
|
|
52
|
+
* which is what `Button` already does. Middle-click, right-click,
|
|
53
|
+
* open-in-new-tab and "copy link address" all work, which a `div` with a
|
|
54
|
+
* click handler takes away.
|
|
55
|
+
*/
|
|
56
|
+
href?: string;
|
|
57
|
+
target?: JSX.AnchorHTMLAttributes<HTMLAnchorElement>["target"];
|
|
58
|
+
rel?: string;
|
|
42
59
|
header?: JSX.Element;
|
|
43
60
|
footer?: JSX.Element;
|
|
44
61
|
children: JSX.Element;
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { createComponent, insert, mergeProps, spread, template } from "@solidjs/web";
|
|
1
|
+
import { claimElement, createComponent, insert, mergeProps, spread, template } from "@solidjs/web";
|
|
2
2
|
import { defineComponent } from "solid-layouts/solid-2/application-boundary";
|
|
3
3
|
import "../_shared/material.css";
|
|
4
4
|
import "./Card.css";
|
|
5
5
|
import { Show } from "solid-js";
|
|
6
|
+
import { buttonHref, buttonRel } from "../button/Button.interactions.js";
|
|
7
|
+
import { cardSemantics } from "./Card.interactions.js";
|
|
6
8
|
import { card, cardBody, cardFooter, cardHeader } from "./Card.recipe.js";
|
|
7
|
-
var _tmpl$ = /*#__PURE__*/ template("<div>"), _tmpl$2 = /*#__PURE__*/ template("<
|
|
9
|
+
var _tmpl$ = /*#__PURE__*/ template("<div>"), _tmpl$2 = /*#__PURE__*/ template("<a>");
|
|
8
10
|
const __solidLayoutCardHeaderLayout = (_stable, p)=>(()=>{
|
|
9
11
|
var _el$ = _tmpl$();
|
|
10
12
|
spread(_el$, mergeProps(()=>_stable.slot.root), true);
|
|
@@ -48,62 +50,111 @@ const CardFooterLayout = defineComponent({
|
|
|
48
50
|
]
|
|
49
51
|
});
|
|
50
52
|
const __solidLayoutCardLayout = (_stable, p)=>{
|
|
53
|
+
const semantics = ()=>cardSemantics({
|
|
54
|
+
href: p.href,
|
|
55
|
+
isInteractive: p.isInteractive,
|
|
56
|
+
hasActivation: null != p.onClick,
|
|
57
|
+
role: p.role,
|
|
58
|
+
tabindex: p.tabindex
|
|
59
|
+
});
|
|
51
60
|
const handleKeyDown = (event)=>{
|
|
52
|
-
if (!
|
|
61
|
+
if (!semantics().handlesKeyboardActivation) return;
|
|
53
62
|
if ("Enter" !== event.key && " " !== event.key) return;
|
|
54
63
|
if (event.target !== event.currentTarget) return;
|
|
55
64
|
event.preventDefault();
|
|
56
65
|
event.currentTarget.click();
|
|
57
66
|
};
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
return p.role ?? (p.isInteractive ? "button" : void 0);
|
|
62
|
-
},
|
|
63
|
-
get tabindex () {
|
|
64
|
-
return p.tabindex ?? (p.isInteractive ? 0 : void 0);
|
|
65
|
-
},
|
|
66
|
-
onKeyDown: handleKeyDown,
|
|
67
|
-
get ["data-flavor"] () {
|
|
68
|
-
return p.flavor ?? "neutral";
|
|
69
|
-
},
|
|
70
|
-
get ["data-material"] () {
|
|
71
|
-
return p.material ?? "solid";
|
|
72
|
-
},
|
|
73
|
-
get ["data-material-explicit"] () {
|
|
74
|
-
return p.material ? "" : void 0;
|
|
75
|
-
}
|
|
76
|
-
}), true);
|
|
77
|
-
insert(_el$4, createComponent(Show, {
|
|
78
|
-
get when () {
|
|
79
|
-
return p.header;
|
|
80
|
-
},
|
|
81
|
-
get children () {
|
|
82
|
-
return createComponent(CardHeaderLayout, {
|
|
83
|
-
get children () {
|
|
67
|
+
const body = ()=>[
|
|
68
|
+
createComponent(Show, {
|
|
69
|
+
get when () {
|
|
84
70
|
return p.header;
|
|
71
|
+
},
|
|
72
|
+
get children () {
|
|
73
|
+
return createComponent(CardHeaderLayout, {
|
|
74
|
+
get children () {
|
|
75
|
+
return p.header;
|
|
76
|
+
}
|
|
77
|
+
});
|
|
85
78
|
}
|
|
86
|
-
})
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
79
|
+
}),
|
|
80
|
+
createComponent(CardBodyLayout, {
|
|
81
|
+
get children () {
|
|
82
|
+
return _stable.children;
|
|
83
|
+
}
|
|
84
|
+
}),
|
|
85
|
+
createComponent(Show, {
|
|
86
|
+
get when () {
|
|
87
|
+
return p.footer;
|
|
88
|
+
},
|
|
89
|
+
get children () {
|
|
90
|
+
return createComponent(CardFooterLayout, {
|
|
91
|
+
get children () {
|
|
92
|
+
return p.footer;
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
})
|
|
97
|
+
];
|
|
98
|
+
return createComponent(Show, {
|
|
95
99
|
get when () {
|
|
96
|
-
return
|
|
100
|
+
return "a" === semantics().element;
|
|
101
|
+
},
|
|
102
|
+
get fallback () {
|
|
103
|
+
var _el$5 = _tmpl$();
|
|
104
|
+
spread(_el$5, mergeProps(()=>_stable.slot.root, {
|
|
105
|
+
get role () {
|
|
106
|
+
return semantics().role;
|
|
107
|
+
},
|
|
108
|
+
get tabindex () {
|
|
109
|
+
return semantics().tabindex;
|
|
110
|
+
},
|
|
111
|
+
onKeyDown: handleKeyDown,
|
|
112
|
+
get ["data-flavor"] () {
|
|
113
|
+
return p.flavor ?? "neutral";
|
|
114
|
+
},
|
|
115
|
+
get ["data-material"] () {
|
|
116
|
+
return p.material ?? "solid";
|
|
117
|
+
},
|
|
118
|
+
get ["data-material-explicit"] () {
|
|
119
|
+
return p.material ? "" : void 0;
|
|
120
|
+
}
|
|
121
|
+
}), true);
|
|
122
|
+
insert(_el$5, body);
|
|
123
|
+
return _el$5;
|
|
97
124
|
},
|
|
98
125
|
get children () {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
126
|
+
var _el$4 = _tmpl$2();
|
|
127
|
+
claimElement(_el$4);
|
|
128
|
+
spread(_el$4, mergeProps(()=>_stable.slot.root, {
|
|
129
|
+
get href () {
|
|
130
|
+
return buttonHref(p.href, false);
|
|
131
|
+
},
|
|
132
|
+
get target () {
|
|
133
|
+
return p.target;
|
|
134
|
+
},
|
|
135
|
+
get rel () {
|
|
136
|
+
return buttonRel(p.rel, p.target);
|
|
137
|
+
},
|
|
138
|
+
get role () {
|
|
139
|
+
return semantics().role;
|
|
140
|
+
},
|
|
141
|
+
get tabindex () {
|
|
142
|
+
return semantics().tabindex;
|
|
143
|
+
},
|
|
144
|
+
get ["data-flavor"] () {
|
|
145
|
+
return p.flavor ?? "neutral";
|
|
146
|
+
},
|
|
147
|
+
get ["data-material"] () {
|
|
148
|
+
return p.material ?? "solid";
|
|
149
|
+
},
|
|
150
|
+
get ["data-material-explicit"] () {
|
|
151
|
+
return p.material ? "" : void 0;
|
|
102
152
|
}
|
|
103
|
-
});
|
|
153
|
+
}), true);
|
|
154
|
+
insert(_el$4, body);
|
|
155
|
+
return _el$4;
|
|
104
156
|
}
|
|
105
|
-
})
|
|
106
|
-
return _el$4;
|
|
157
|
+
});
|
|
107
158
|
};
|
|
108
159
|
const CardLayout = defineComponent({
|
|
109
160
|
recipe: card,
|
|
@@ -118,6 +169,9 @@ const CardLayout = defineComponent({
|
|
|
118
169
|
"padding",
|
|
119
170
|
"radius",
|
|
120
171
|
"isInteractive",
|
|
172
|
+
"href",
|
|
173
|
+
"target",
|
|
174
|
+
"rel",
|
|
121
175
|
"header",
|
|
122
176
|
"footer",
|
|
123
177
|
"children"
|