@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
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What an interactive card *is*, as one function.
|
|
3
|
+
*
|
|
4
|
+
* `isInteractive` gave a card `role="button"` and `tabindex="0"` with no way
|
|
5
|
+
* off either. That is right for a card that is the only activatable thing in
|
|
6
|
+
* its box, and wrong the moment a card is put inside a link, which is the
|
|
7
|
+
* ordinary way to make a whole card navigate. Measured on one site: every card
|
|
8
|
+
* on it was a `button` inside a `link`, same name, same box. Nested
|
|
9
|
+
* interactive content is invalid HTML, a reader hears the card twice, and a
|
|
10
|
+
* press by coordinate lands on whichever of the two is on top.
|
|
11
|
+
*
|
|
12
|
+
* Three things come out of this, and the first is what fixes the sites without
|
|
13
|
+
* anyone editing a call site. A card is announced as a button when it looks
|
|
14
|
+
* pressable *and has something to press*: `<a href><Card isInteractive /></a>`
|
|
15
|
+
* hands the card no handler, because the anchor is what navigates, so the card
|
|
16
|
+
* stops claiming to be a button and the nesting goes away where it stands.
|
|
17
|
+
* `isInteractive` was doing two jobs at once and only one of them survives
|
|
18
|
+
* inside a link: it is how a card asks for hover and press affordance, which is
|
|
19
|
+
* exactly what a card inside a link wants, and all it wants.
|
|
20
|
+
*
|
|
21
|
+
* The second is `href`: a card that navigates should *be* the anchor rather
|
|
22
|
+
* than sit inside one, exactly as `Button` already does. The third is an
|
|
23
|
+
* explicit `role`, which was accepted and then half-ignored --
|
|
24
|
+
* `role="presentation"` left `tabindex="0"` behind, so the escape hatch
|
|
25
|
+
* produced a presentational element that was still in the tab order and still
|
|
26
|
+
* announced as focusable.
|
|
27
|
+
*
|
|
28
|
+
* A `.layout.tsx` binds free identifiers to props, so the rule lives beside
|
|
29
|
+
* the markup rather than inside it, and the repository's tests are pure.
|
|
30
|
+
*/
|
|
31
|
+
import type { JSX } from "@solidjs/web";
|
|
32
|
+
type RoleAttribute = JSX.HTMLAttributes<HTMLElement>["role"];
|
|
33
|
+
type TabIndexAttribute = JSX.HTMLAttributes<HTMLElement>["tabindex"];
|
|
34
|
+
type Role = Exclude<RoleAttribute, false | undefined>;
|
|
35
|
+
type TabIndex = Exclude<TabIndexAttribute, false | undefined>;
|
|
36
|
+
export type CardSemanticsInput = {
|
|
37
|
+
href?: string | false;
|
|
38
|
+
isInteractive?: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Whether the card has an activation of its own.
|
|
41
|
+
*
|
|
42
|
+
* This is the half that fixes the fleet without anyone editing a call site.
|
|
43
|
+
* `<a href><Card isInteractive /></a>` gives the card no handler: the anchor
|
|
44
|
+
* is what navigates. A card with nothing to activate is not a button, so it
|
|
45
|
+
* stops claiming to be one, and the nesting goes away where it is.
|
|
46
|
+
*
|
|
47
|
+
* `isInteractive` alone was read as "announce this as a button", and it
|
|
48
|
+
* cannot be: it is also how a card asks for hover and press *affordance*,
|
|
49
|
+
* which is exactly what a card inside a link wants and all it wants.
|
|
50
|
+
*/
|
|
51
|
+
hasActivation?: boolean;
|
|
52
|
+
/** An explicit `role` from the call site. Wins outright. */
|
|
53
|
+
role?: RoleAttribute;
|
|
54
|
+
/** An explicit `tabindex` from the call site. Wins outright. */
|
|
55
|
+
tabindex?: TabIndexAttribute;
|
|
56
|
+
};
|
|
57
|
+
export type CardSemantics = {
|
|
58
|
+
element: "a" | "div";
|
|
59
|
+
role: Role | undefined;
|
|
60
|
+
tabindex: TabIndex | undefined;
|
|
61
|
+
/**
|
|
62
|
+
* Whether the card has to implement Enter and Space itself.
|
|
63
|
+
*
|
|
64
|
+
* Only a `div` wearing `role="button"` does. An anchor activates on Enter
|
|
65
|
+
* natively, and a presentational card activates on nothing.
|
|
66
|
+
*/
|
|
67
|
+
handlesKeyboardActivation: boolean;
|
|
68
|
+
};
|
|
69
|
+
export declare const cardSemantics: (input: CardSemanticsInput) => CardSemantics;
|
|
70
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const given = (value)=>false === value || void 0 === value ? void 0 : value;
|
|
2
|
+
const cardSemantics = (input)=>{
|
|
3
|
+
const role = given(input.role);
|
|
4
|
+
const tabindex = given(input.tabindex);
|
|
5
|
+
if ("string" == typeof input.href) return {
|
|
6
|
+
element: "a",
|
|
7
|
+
role,
|
|
8
|
+
tabindex,
|
|
9
|
+
handlesKeyboardActivation: false
|
|
10
|
+
};
|
|
11
|
+
const resolvedRole = role ?? (input.isInteractive && input.hasActivation ? "button" : void 0);
|
|
12
|
+
return {
|
|
13
|
+
element: "div",
|
|
14
|
+
role: resolvedRole,
|
|
15
|
+
tabindex: tabindex ?? ("button" === resolvedRole ? 0 : void 0),
|
|
16
|
+
handlesKeyboardActivation: "button" === resolvedRole
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
export { cardSemantics };
|
|
@@ -50,19 +50,35 @@
|
|
|
50
50
|
transform: rotate(-180deg);
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
/*
|
|
54
|
+
* A closed panel is out of the page, not merely flattened. Same fault and
|
|
55
|
+
* same fix as `.accordion__content`: `keepMounted` is the default, so a
|
|
56
|
+
* closed panel stays in the document carrying `aria-hidden="true"` while
|
|
57
|
+
* everything inside it kept `visibility: visible` and stayed in the tab
|
|
58
|
+
* order. Tab moved focus into a panel nobody can see, inside an
|
|
59
|
+
* `aria-hidden` subtree, which is the one thing `aria-hidden` must never
|
|
60
|
+
* contain.
|
|
61
|
+
*/
|
|
53
62
|
.collapsible__content {
|
|
54
63
|
display: grid;
|
|
55
64
|
grid-template-rows: 0fr;
|
|
56
65
|
opacity: 0;
|
|
57
66
|
overflow: hidden;
|
|
67
|
+
visibility: hidden;
|
|
58
68
|
transition:
|
|
59
69
|
grid-template-rows 200ms ease,
|
|
60
|
-
opacity 200ms ease
|
|
70
|
+
opacity 200ms ease,
|
|
71
|
+
visibility 0s linear 200ms;
|
|
61
72
|
}
|
|
62
73
|
|
|
63
74
|
.collapsible__content[data-expanded="true"] {
|
|
64
75
|
grid-template-rows: 1fr;
|
|
65
76
|
opacity: 1;
|
|
77
|
+
visibility: visible;
|
|
78
|
+
transition:
|
|
79
|
+
grid-template-rows 200ms ease,
|
|
80
|
+
opacity 200ms ease,
|
|
81
|
+
visibility 0s linear 0s;
|
|
66
82
|
}
|
|
67
83
|
|
|
68
84
|
.collapsible__body {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Component as __LayoutComponent } from "solid-js";
|
|
2
2
|
import "./ColorWheelFlower.css";
|
|
3
|
+
import { type ColorValue } from "./ColorUtils";
|
|
3
4
|
import { type ColorWheelFlowerMode } from "./ColorWheelFlower.palette";
|
|
4
5
|
export interface ColorWheelFlowerProps {
|
|
5
6
|
/** Stable base for the flower and each interactive petal. */
|
|
@@ -9,6 +10,13 @@ export interface ColorWheelFlowerProps {
|
|
|
9
10
|
mode?: ColorWheelFlowerMode;
|
|
10
11
|
/** Exactly 31 literal colors, ordered outer ring, middle ring, inner ring, center. */
|
|
11
12
|
palette?: readonly string[];
|
|
13
|
+
/** Controlled selection. A hex, `rgb()` or `hsl()` string, or a parsed value. */
|
|
14
|
+
color?: ColorValue | string;
|
|
15
|
+
/** Initial selection when uncontrolled. */
|
|
16
|
+
defaultColor?: ColorValue | string;
|
|
17
|
+
disabled?: boolean;
|
|
18
|
+
/** The colour a petal was clicked to choose. */
|
|
19
|
+
onChange?: (color: ColorValue) => void;
|
|
12
20
|
}
|
|
13
21
|
declare const ColorWheelFlower: __LayoutComponent<ColorWheelFlowerProps>;
|
|
14
22
|
export default ColorWheelFlower;
|
|
@@ -231,7 +231,20 @@ function buildColors(palette) {
|
|
|
231
231
|
}
|
|
232
232
|
const CENTER_INDEX = LAYOUT.findIndex((l)=>l.isCenter);
|
|
233
233
|
const __solidLayoutColorWheelFlower = (_stable, p)=>{
|
|
234
|
-
const
|
|
234
|
+
const providedContext = useColorPickerContext();
|
|
235
|
+
const toColorValue = (value)=>void 0 === value ? null : "string" == typeof value ? parseColor(value) : value;
|
|
236
|
+
const WHITE = createColorFromHsl(0, 0, 100, 1);
|
|
237
|
+
const [standaloneColor, setStandaloneColor] = createSignal(toColorValue(p.defaultColor) ?? WHITE);
|
|
238
|
+
const context = providedContext ?? {
|
|
239
|
+
color: ()=>toColorValue(p.color) ?? standaloneColor(),
|
|
240
|
+
format: ()=>"hex",
|
|
241
|
+
disabled: ()=>Boolean(p.disabled),
|
|
242
|
+
onChange: (next)=>{
|
|
243
|
+
if (void 0 === p.color) setStandaloneColor(next);
|
|
244
|
+
p.onChange?.(next);
|
|
245
|
+
},
|
|
246
|
+
onFormatChange: ()=>{}
|
|
247
|
+
};
|
|
235
248
|
const [selectedIndex, setSelectedIndex] = createSignal(null);
|
|
236
249
|
const [pulseState, setPulseState] = createSignal(null);
|
|
237
250
|
const [currentTheme, setCurrentTheme] = createSignal("u" > typeof document && "dark" === document.documentElement.getAttribute("data-theme") ? "dark" : "light");
|
|
@@ -7,5 +7,12 @@ export interface ColorPickerContextType {
|
|
|
7
7
|
onChange: (color: ColorValue) => void;
|
|
8
8
|
onFormatChange: (format: ColorFormat) => void;
|
|
9
9
|
}
|
|
10
|
-
export declare const ColorPickerContext: import("solid-js").Context<ColorPickerContextType |
|
|
11
|
-
|
|
10
|
+
export declare const ColorPickerContext: import("solid-js").Context<ColorPickerContextType | null>;
|
|
11
|
+
/**
|
|
12
|
+
* The surrounding picker's state, or `null` when there is no picker.
|
|
13
|
+
*
|
|
14
|
+
* Returning `null` rather than throwing is deliberate: a consumer that can
|
|
15
|
+
* stand alone decides for itself what to do without a provider, and one that
|
|
16
|
+
* genuinely cannot say so in its own words.
|
|
17
|
+
*/
|
|
18
|
+
export declare function useColorPickerContext(): ColorPickerContextType | null;
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { createContext, useContext } from "solid-js";
|
|
2
|
-
const ColorPickerContext = createContext(
|
|
2
|
+
const ColorPickerContext = createContext(null);
|
|
3
3
|
function useColorPickerContext() {
|
|
4
|
-
|
|
5
|
-
if (!context) throw new Error("useColorPickerContext must be used within a ColorPickerContext.Provider");
|
|
6
|
-
return context;
|
|
4
|
+
return useContext(ColorPickerContext);
|
|
7
5
|
}
|
|
8
6
|
export { ColorPickerContext, useColorPickerContext };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Component as __LayoutComponent } from "solid-js";
|
|
2
2
|
import "./DatePicker.css";
|
|
3
3
|
import type { JSX } from "@solidjs/web";
|
|
4
|
-
import { type CalendarWeekdayFormat } from "../calendar";
|
|
4
|
+
import { type CalendarWeekdayFormat, type DateNames } from "../calendar";
|
|
5
5
|
import type { UIBaseProps, State } from "../vocabulary";
|
|
6
6
|
type DatePickerBaseProps = {
|
|
7
7
|
value?: Date;
|
|
@@ -13,6 +13,8 @@ type DatePickerBaseProps = {
|
|
|
13
13
|
name?: string;
|
|
14
14
|
placeholder?: string;
|
|
15
15
|
locale?: string;
|
|
16
|
+
/** Month and weekday names for a language other than English. See `Calendar`. */
|
|
17
|
+
dateNames?: DateNames;
|
|
16
18
|
weekdayFormat?: CalendarWeekdayFormat;
|
|
17
19
|
minValue?: Date;
|
|
18
20
|
maxValue?: Date;
|
|
@@ -3,12 +3,12 @@ import { defineComponent } from "solid-layouts/solid-2/application-boundary";
|
|
|
3
3
|
import "./DatePicker.css";
|
|
4
4
|
import { Show, createMemo, createUniqueId, omit } from "solid-js";
|
|
5
5
|
import { twMerge } from "../../lib/twMerge.js";
|
|
6
|
-
import { formatDate, toISODate, useDateSelection, usePickerOpenState } from "../../hooks/date/index.js";
|
|
6
|
+
import { formatDate, resolveDateNames, toISODate, useDateSelection, usePickerOpenState } from "../../hooks/date/index.js";
|
|
7
7
|
import calendar from "../calendar/index.js";
|
|
8
8
|
import { CLASSES, componentRecipe } from "./DatePicker.recipe.js";
|
|
9
9
|
var _tmpl$ = /*#__PURE__*/ template("<input type=hidden>"), _tmpl$2 = /*#__PURE__*/ template("<div>"), _tmpl$3 = /*#__PURE__*/ template("<div><button><span></span><span><svg><rect x=3 y=4 width=18 height=18 rx=2 ry=2></rect><line x1=16 y1=2 x2=16 y2=6></line><line x1=8 y1=2 x2=8 y2=6></line><line x1=3 y1=10 x2=21 y2=10></line></svg></span></button><!>");
|
|
10
10
|
const __solidLayoutDatePicker = (_stable, p)=>{
|
|
11
|
-
const others = omit(p, "class", "dataTheme", "style", "ref", "value", "defaultValue", "onChange", "open", "defaultOpen", "onOpenChange", "name", "placeholder", "locale", "weekdayFormat", "minValue", "maxValue", "isDateUnavailable", "state", "disabled");
|
|
11
|
+
const others = omit(p, "class", "dataTheme", "style", "ref", "value", "defaultValue", "onChange", "open", "defaultOpen", "onOpenChange", "name", "placeholder", "locale", "dateNames", "weekdayFormat", "minValue", "maxValue", "isDateUnavailable", "state", "disabled");
|
|
12
12
|
const isDisabled = createMemo(()=>Boolean("disabled" === p.state) || Boolean(p.disabled));
|
|
13
13
|
const selection = useDateSelection({
|
|
14
14
|
value: ()=>p.value,
|
|
@@ -21,11 +21,11 @@ const __solidLayoutDatePicker = (_stable, p)=>{
|
|
|
21
21
|
onOpenChange: ()=>p.onOpenChange,
|
|
22
22
|
isDisabled
|
|
23
23
|
});
|
|
24
|
-
const
|
|
24
|
+
const dateNames = createMemo(()=>resolveDateNames(p.locale, p.dateNames).names);
|
|
25
25
|
const displayValue = createMemo(()=>{
|
|
26
26
|
const selectedDate = selection.selectedDate();
|
|
27
27
|
if (!selectedDate) return p.placeholder ?? "Select date";
|
|
28
|
-
return formatDate(selectedDate,
|
|
28
|
+
return formatDate(selectedDate, dateNames());
|
|
29
29
|
});
|
|
30
30
|
const uniqueId = createUniqueId();
|
|
31
31
|
const popoverId = `date-picker-popover-${uniqueId}`;
|
|
@@ -154,7 +154,10 @@ const __solidLayoutDatePicker = (_stable, p)=>{
|
|
|
154
154
|
},
|
|
155
155
|
onChange: handleDateChange,
|
|
156
156
|
get locale () {
|
|
157
|
-
return locale
|
|
157
|
+
return p.locale;
|
|
158
|
+
},
|
|
159
|
+
get dateNames () {
|
|
160
|
+
return p.dateNames;
|
|
158
161
|
},
|
|
159
162
|
get weekdayFormat () {
|
|
160
163
|
return p.weekdayFormat;
|
|
@@ -2,7 +2,7 @@ import type { Component as __LayoutComponent } from "solid-js";
|
|
|
2
2
|
import "./DateRangePicker.css";
|
|
3
3
|
import type { JSX } from "@solidjs/web";
|
|
4
4
|
import { type ControlledDateRangeValue } from "../../hooks/date";
|
|
5
|
-
import { type CalendarWeekdayFormat } from "../calendar";
|
|
5
|
+
import { type CalendarWeekdayFormat, type DateNames } from "../calendar";
|
|
6
6
|
import type { UIBaseProps, State } from "../vocabulary";
|
|
7
7
|
export type DateRangeValue = ControlledDateRangeValue;
|
|
8
8
|
type DateRangePickerBaseProps = {
|
|
@@ -17,6 +17,8 @@ type DateRangePickerBaseProps = {
|
|
|
17
17
|
startPlaceholder?: string;
|
|
18
18
|
endPlaceholder?: string;
|
|
19
19
|
locale?: string;
|
|
20
|
+
/** Month and weekday names for a language other than English. See `Calendar`. */
|
|
21
|
+
dateNames?: DateNames;
|
|
20
22
|
weekdayFormat?: CalendarWeekdayFormat;
|
|
21
23
|
minValue?: Date;
|
|
22
24
|
maxValue?: Date;
|
|
@@ -3,12 +3,12 @@ import { defineComponent } from "solid-layouts/solid-2/application-boundary";
|
|
|
3
3
|
import "./DateRangePicker.css";
|
|
4
4
|
import { Show, createMemo, createTrackedEffect, createUniqueId, omit } from "solid-js";
|
|
5
5
|
import { twMerge } from "../../lib/twMerge.js";
|
|
6
|
-
import { formatDate, toISODate, usePickerOpenState, useRangeSelection } from "../../hooks/date/index.js";
|
|
6
|
+
import { formatDate, resolveDateNames, toISODate, usePickerOpenState, useRangeSelection } from "../../hooks/date/index.js";
|
|
7
7
|
import calendar from "../calendar/index.js";
|
|
8
8
|
import { CLASSES, componentRecipe } from "./DateRangePicker.recipe.js";
|
|
9
9
|
var _tmpl$ = /*#__PURE__*/ template("<input type=hidden>"), _tmpl$2 = /*#__PURE__*/ template("<div>"), _tmpl$3 = /*#__PURE__*/ template("<div><!><button><span></span><span>-</span><span></span><span><svg><rect x=3 y=4 width=18 height=18 rx=2 ry=2></rect><line x1=16 y1=2 x2=16 y2=6></line><line x1=8 y1=2 x2=8 y2=6></line><line x1=3 y1=10 x2=21 y2=10></line></svg></span></button><!>");
|
|
10
10
|
const __solidLayoutDateRangePicker = (_stable, p)=>{
|
|
11
|
-
const others = omit(p, "class", "dataTheme", "style", "ref", "value", "defaultValue", "onChange", "open", "defaultOpen", "onOpenChange", "startName", "endName", "startPlaceholder", "endPlaceholder", "locale", "weekdayFormat", "minValue", "maxValue", "isDateUnavailable", "state", "disabled");
|
|
11
|
+
const others = omit(p, "class", "dataTheme", "style", "ref", "value", "defaultValue", "onChange", "open", "defaultOpen", "onOpenChange", "startName", "endName", "startPlaceholder", "endPlaceholder", "locale", "dateNames", "weekdayFormat", "minValue", "maxValue", "isDateUnavailable", "state", "disabled");
|
|
12
12
|
const isDisabled = createMemo(()=>Boolean("disabled" === p.state) || Boolean(p.disabled));
|
|
13
13
|
const rangeSelection = useRangeSelection({
|
|
14
14
|
value: ()=>p.value,
|
|
@@ -25,17 +25,17 @@ const __solidLayoutDateRangePicker = (_stable, p)=>{
|
|
|
25
25
|
if (openState.isOpen()) return;
|
|
26
26
|
rangeSelection.clearPendingSelection();
|
|
27
27
|
});
|
|
28
|
-
const
|
|
28
|
+
const dateNames = createMemo(()=>resolveDateNames(p.locale, p.dateNames).names);
|
|
29
29
|
const startValue = createMemo(()=>rangeSelection.rangeStart());
|
|
30
30
|
const endValue = createMemo(()=>rangeSelection.rangeEnd());
|
|
31
31
|
const focusDate = createMemo(()=>rangeSelection.focusDate());
|
|
32
32
|
const startDisplay = createMemo(()=>{
|
|
33
33
|
if (!startValue()) return p.startPlaceholder ?? "Start date";
|
|
34
|
-
return formatDate(startValue(),
|
|
34
|
+
return formatDate(startValue(), dateNames());
|
|
35
35
|
});
|
|
36
36
|
const endDisplay = createMemo(()=>{
|
|
37
37
|
if (!endValue()) return p.endPlaceholder ?? "End date";
|
|
38
|
-
return formatDate(endValue(),
|
|
38
|
+
return formatDate(endValue(), dateNames());
|
|
39
39
|
});
|
|
40
40
|
const handleDateSelect = (date)=>{
|
|
41
41
|
const wasSelectingEnd = rangeSelection.isSelectingEnd();
|
|
@@ -208,7 +208,10 @@ const __solidLayoutDateRangePicker = (_stable, p)=>{
|
|
|
208
208
|
return rangeSelection.setHoverDate;
|
|
209
209
|
},
|
|
210
210
|
get locale () {
|
|
211
|
-
return locale
|
|
211
|
+
return p.locale;
|
|
212
|
+
},
|
|
213
|
+
get dateNames () {
|
|
214
|
+
return p.dateNames;
|
|
212
215
|
},
|
|
213
216
|
get weekdayFormat () {
|
|
214
217
|
return p.weekdayFormat;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Component as __LayoutComponent } from "solid-js";
|
|
2
2
|
import "./Drawer.css";
|
|
3
|
+
import { type ValidComponent } from "solid-js";
|
|
3
4
|
import { type JSX } from "@solidjs/web";
|
|
4
5
|
import "../_shared/material.css";
|
|
5
6
|
import type { Material, UIBaseProps } from "../vocabulary";
|
|
@@ -22,6 +23,29 @@ export type DrawerRootProps = Omit<JSX.HTMLAttributes<HTMLDivElement>, "children
|
|
|
22
23
|
};
|
|
23
24
|
export type DrawerTriggerProps = Omit<JSX.ButtonHTMLAttributes<HTMLButtonElement>, "children"> & UIBaseProps & {
|
|
24
25
|
children: JSX.Element;
|
|
26
|
+
/**
|
|
27
|
+
* The component to be the trigger, instead of a bare button.
|
|
28
|
+
*
|
|
29
|
+
* `Drawer.Trigger` renders a `button`, which is right when the trigger is
|
|
30
|
+
* a word or a glyph and wrong when the call site hands it a control:
|
|
31
|
+
* `<Drawer.Trigger><Button>Menu</Button></Drawer.Trigger>` produced a
|
|
32
|
+
* `button` wrapping a `button` at an identical box with an identical name,
|
|
33
|
+
* so every trigger was announced twice and the press by coordinate landed
|
|
34
|
+
* on the outer one rather than on the control that was written. Nested
|
|
35
|
+
* interactive content is also invalid HTML.
|
|
36
|
+
*
|
|
37
|
+
* `as` makes the control *be* the trigger, so there is one element:
|
|
38
|
+
*
|
|
39
|
+
* ```tsx
|
|
40
|
+
* <Drawer.Trigger as={Button} variant="ghost">Menu</Drawer.Trigger>
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* The wiring and anything else written here go to the delegate. The
|
|
44
|
+
* trigger's own class is a button reset and is dropped, because a control
|
|
45
|
+
* does not want one; so is `data-slot="drawer-trigger"`, since the
|
|
46
|
+
* delegate's recipe owns that attribute.
|
|
47
|
+
*/
|
|
48
|
+
as?: ValidComponent;
|
|
25
49
|
};
|
|
26
50
|
export type DrawerBackdropProps = Omit<JSX.HTMLAttributes<HTMLDivElement>, "children"> & UIBaseProps & {
|
|
27
51
|
children: JSX.Element;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Portal, className, createComponent, delegateEvents, effect, insert, memo, mergeProps, ref, spread, template } from "@solidjs/web";
|
|
1
|
+
import { Dynamic, Portal, className, createComponent, delegateEvents, effect, insert, memo, mergeProps, ref, spread, template } from "@solidjs/web";
|
|
2
2
|
import { defineComponent } from "solid-layouts/solid-2/application-boundary";
|
|
3
3
|
import "./Drawer.css";
|
|
4
4
|
import { Show, createSignal, createTrackedEffect, createUniqueId, omit, onCleanup } from "solid-js";
|
|
@@ -179,36 +179,66 @@ const DrawerRoot = defineComponent({
|
|
|
179
179
|
]
|
|
180
180
|
});
|
|
181
181
|
const __solidLayoutDrawerTrigger = (_stable, p)=>{
|
|
182
|
-
const others = omit(p, "children", "class", "dataTheme", "style", "onClick");
|
|
182
|
+
const others = omit(p, "children", "class", "dataTheme", "style", "onClick", "as");
|
|
183
183
|
const ctx = useDrawerContext();
|
|
184
184
|
const handleClick = (event)=>{
|
|
185
185
|
ctx.setIsOpen(true);
|
|
186
186
|
if ("function" == typeof p.onClick) p.onClick(event);
|
|
187
187
|
};
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
get ["class"] () {
|
|
192
|
-
return twMerge(CLASSES.Trigger.base, p.class);
|
|
193
|
-
},
|
|
194
|
-
"data-slot": "drawer-trigger",
|
|
195
|
-
get ["data-theme"] () {
|
|
196
|
-
return p.dataTheme;
|
|
188
|
+
return createComponent(Show, {
|
|
189
|
+
get when () {
|
|
190
|
+
return p.as;
|
|
197
191
|
},
|
|
198
|
-
get
|
|
199
|
-
|
|
192
|
+
get fallback () {
|
|
193
|
+
var _el$2 = _tmpl$2();
|
|
194
|
+
spread(_el$2, mergeProps(others, {
|
|
195
|
+
type: "button",
|
|
196
|
+
get ["class"] () {
|
|
197
|
+
return twMerge(CLASSES.Trigger.base, p.class);
|
|
198
|
+
},
|
|
199
|
+
"data-slot": "drawer-trigger",
|
|
200
|
+
get ["data-theme"] () {
|
|
201
|
+
return p.dataTheme;
|
|
202
|
+
},
|
|
203
|
+
get style () {
|
|
204
|
+
return p.style;
|
|
205
|
+
},
|
|
206
|
+
onClick: handleClick
|
|
207
|
+
}), true);
|
|
208
|
+
insert(_el$2, ()=>p.children);
|
|
209
|
+
return _el$2;
|
|
200
210
|
},
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
211
|
+
get children () {
|
|
212
|
+
return createComponent(Dynamic, mergeProps({
|
|
213
|
+
get component () {
|
|
214
|
+
return p.as;
|
|
215
|
+
}
|
|
216
|
+
}, others, {
|
|
217
|
+
type: "button",
|
|
218
|
+
get ["class"] () {
|
|
219
|
+
return p.class;
|
|
220
|
+
},
|
|
221
|
+
get ["data-theme"] () {
|
|
222
|
+
return p.dataTheme;
|
|
223
|
+
},
|
|
224
|
+
get style () {
|
|
225
|
+
return p.style;
|
|
226
|
+
},
|
|
227
|
+
onClick: handleClick,
|
|
228
|
+
get children () {
|
|
229
|
+
return p.children;
|
|
230
|
+
}
|
|
231
|
+
}));
|
|
232
|
+
}
|
|
233
|
+
});
|
|
205
234
|
};
|
|
206
235
|
const DrawerTrigger = defineComponent({
|
|
207
236
|
recipe: componentRecipe,
|
|
208
237
|
layout: __solidLayoutDrawerTrigger,
|
|
209
238
|
embedded: true,
|
|
210
239
|
behaviour: [
|
|
211
|
-
"children"
|
|
240
|
+
"children",
|
|
241
|
+
"as"
|
|
212
242
|
]
|
|
213
243
|
});
|
|
214
244
|
const __solidLayoutDrawerContent = (_stable, p)=>{
|
|
@@ -19,5 +19,20 @@ export type IconProps = UIBaseProps & {
|
|
|
19
19
|
width?: number;
|
|
20
20
|
height?: number;
|
|
21
21
|
flavor?: Flavor;
|
|
22
|
+
/**
|
|
23
|
+
* What this icon means, for an icon that carries meaning on its own.
|
|
24
|
+
*
|
|
25
|
+
* Most icons sit beside a label that already says it, and repeating it makes
|
|
26
|
+
* a reader hear the same thing twice; those stay hidden, which is the
|
|
27
|
+
* default and stays the default. The ones that need this are the icons that
|
|
28
|
+
* *are* the label: a status glyph in a table cell, a lone mark in a square
|
|
29
|
+
* button, a trend arrow next to a bare number.
|
|
30
|
+
*
|
|
31
|
+
* Setting it swaps `aria-hidden="true"` for `role="img"` and this name. The
|
|
32
|
+
* default was right and there was simply no way off it: `aria-hidden` was
|
|
33
|
+
* written straight into the markup, so it survived any `aria-label` a call
|
|
34
|
+
* site passed through and the icon stayed out of the tree regardless.
|
|
35
|
+
*/
|
|
36
|
+
label?: string;
|
|
22
37
|
};
|
|
23
38
|
export declare const IconLayout: __LayoutComponent<IconProps>;
|
|
@@ -21,7 +21,15 @@ const __solidLayoutIconLayout = (_stable, p)=>(()=>{
|
|
|
21
21
|
get ["data-source"] () {
|
|
22
22
|
return "string" == typeof p.src ? "preload" : "svg";
|
|
23
23
|
},
|
|
24
|
-
|
|
24
|
+
get role () {
|
|
25
|
+
return p.label ? "img" : void 0;
|
|
26
|
+
},
|
|
27
|
+
get ["aria-label"] () {
|
|
28
|
+
return p.label;
|
|
29
|
+
},
|
|
30
|
+
get ["aria-hidden"] () {
|
|
31
|
+
return p.label ? void 0 : "true";
|
|
32
|
+
}
|
|
25
33
|
}), true);
|
|
26
34
|
insert(_el$, createComponent(Show, {
|
|
27
35
|
get when () {
|
|
@@ -53,7 +61,8 @@ const IconLayout = defineComponent({
|
|
|
53
61
|
"src",
|
|
54
62
|
"width",
|
|
55
63
|
"height",
|
|
56
|
-
"flavor"
|
|
64
|
+
"flavor",
|
|
65
|
+
"label"
|
|
57
66
|
]
|
|
58
67
|
});
|
|
59
68
|
export { IconLayout };
|
|
@@ -358,7 +358,7 @@
|
|
|
358
358
|
.immersive-landing-cookie__manage-button {
|
|
359
359
|
border: 0;
|
|
360
360
|
background: transparent;
|
|
361
|
-
color:
|
|
361
|
+
color: var(--color-base-content);
|
|
362
362
|
font-size: 0.875rem;
|
|
363
363
|
text-decoration: underline;
|
|
364
364
|
cursor: pointer;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether a press on the preferences backdrop should dismiss the dialog.
|
|
3
|
+
*
|
|
4
|
+
* The backdrop closes the dialog and is an ancestor of the panel, so every
|
|
5
|
+
* press inside the panel reaches it too. The panel guarded itself the usual
|
|
6
|
+
* way, with `stopPropagation()` on its own click handler, and that guard does
|
|
7
|
+
* not hold in the browser engine the fleet ships: `stopPropagation` is defined
|
|
8
|
+
* there, but event dispatch is deferred, so the host has finished propagating
|
|
9
|
+
* before it calls into the page and the call is a no-op. The engine expresses
|
|
10
|
+
* the same intent as a flag fixed when the listener is registered, which means
|
|
11
|
+
* no runtime call can ever express it. Measured on two sites: pressing
|
|
12
|
+
* Analytics or Marketing closed the whole dialog, so no category could be
|
|
13
|
+
* changed at all.
|
|
14
|
+
*
|
|
15
|
+
* Comparing the press target against the element the handler is bound to needs
|
|
16
|
+
* nothing from the engine beyond the two properties every event already
|
|
17
|
+
* carries. A press that started inside the panel reports the panel, or
|
|
18
|
+
* something under it, as its target, and only a press that landed on the
|
|
19
|
+
* backdrop itself reports the backdrop.
|
|
20
|
+
*/
|
|
21
|
+
export declare const dismissesOnBackdropPress: (event: {
|
|
22
|
+
target: EventTarget | null;
|
|
23
|
+
currentTarget: EventTarget | null;
|
|
24
|
+
}) => boolean;
|