@react-md/core 7.0.1 → 7.0.2
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/dist/_base.scss +10 -4
- package/dist/form/utils.js +1 -1
- package/dist/form/utils.js.map +1 -1
- package/dist/icon/_icon.scss +19 -0
- package/dist/icon/configureMaterialSymbols.d.ts +1 -0
- package/dist/icon/configureMaterialSymbols.js +64 -0
- package/dist/icon/configureMaterialSymbols.js.map +1 -0
- package/dist/icon/getMaterialSymbolOption.d.ts +6 -0
- package/dist/icon/getMaterialSymbolOption.js +14 -0
- package/dist/icon/getMaterialSymbolOption.js.map +1 -0
- package/dist/icon/getMaterialSymbolsUrl.d.ts +58 -0
- package/dist/icon/getMaterialSymbolsUrl.js +32 -0
- package/dist/icon/getMaterialSymbolsUrl.js.map +1 -0
- package/dist/icon/symbols.d.ts +4 -0
- package/dist/icon/symbols.js +25 -0
- package/dist/icon/symbols.js.map +1 -0
- package/dist/layout/useExpandableLayout.d.ts +2 -2
- package/dist/layout/useExpandableLayout.js.map +1 -1
- package/dist/menu/MenuItemButton.js +1 -0
- package/dist/menu/MenuItemButton.js.map +1 -1
- package/dist/menu/MenuItemFileInput.js +1 -2
- package/dist/menu/MenuItemFileInput.js.map +1 -1
- package/dist/menu/MenuItemInputToggle.js +1 -1
- package/dist/menu/MenuItemInputToggle.js.map +1 -1
- package/dist/positioning/utils.js +0 -4
- package/dist/positioning/utils.js.map +1 -1
- package/dist/theme/_theme.scss +42 -3
- package/dist/transition/useMaxWidthTransition.d.ts +1 -1
- package/dist/transition/useMaxWidthTransition.js.map +1 -1
- package/dist/types.d.ts +5 -0
- package/dist/types.js.map +1 -1
- package/dist/window-splitter/styles.d.ts +2 -2
- package/dist/window-splitter/styles.js.map +1 -1
- package/package.json +45 -36
- package/src/form/utils.ts +1 -1
- package/src/icon/configureMaterialSymbols.tsx +25 -0
- package/src/icon/getMaterialSymbolOption.ts +20 -0
- package/src/icon/getMaterialSymbolsUrl.ts +112 -0
- package/src/icon/symbols.ts +26 -0
- package/src/layout/useExpandableLayout.ts +6 -2
- package/src/menu/MenuItemButton.tsx +1 -0
- package/src/menu/MenuItemFileInput.tsx +1 -2
- package/src/menu/MenuItemInputToggle.tsx +1 -1
- package/src/positioning/utils.ts +0 -4
- package/src/transition/useMaxWidthTransition.ts +1 -1
- package/src/types.ts +6 -0
- package/src/window-splitter/styles.ts +2 -2
package/dist/_base.scss
CHANGED
|
@@ -330,8 +330,10 @@ $_layer-order: (
|
|
|
330
330
|
/// @include use-light-theme;
|
|
331
331
|
/// }
|
|
332
332
|
///
|
|
333
|
-
@
|
|
334
|
-
|
|
333
|
+
/// @param {Boolean} $disable-color-scheme-var [false] - Set to `true` to
|
|
334
|
+
/// disable setting the color-scheme var
|
|
335
|
+
@mixin use-light-theme($disable-color-scheme-var: false) {
|
|
336
|
+
@include theme.use-light-theme-colors($disable-color-scheme-var);
|
|
335
337
|
@include interaction.use-light-surface;
|
|
336
338
|
@include transition.transition-use-light-theme;
|
|
337
339
|
@include icon.use-light-theme;
|
|
@@ -355,8 +357,11 @@ $_layer-order: (
|
|
|
355
357
|
/// @include use-dark-theme;
|
|
356
358
|
/// }
|
|
357
359
|
///
|
|
358
|
-
|
|
359
|
-
|
|
360
|
+
///
|
|
361
|
+
/// @param {Boolean} $disable-color-scheme-var [false] - Set to `true` to
|
|
362
|
+
/// disable setting the color-scheme var
|
|
363
|
+
@mixin use-dark-theme($disable-color-scheme-var: false) {
|
|
364
|
+
@include theme.use-dark-theme-colors($disable-color-scheme-var);
|
|
360
365
|
@include interaction.use-dark-surface;
|
|
361
366
|
@include transition.transition-use-dark-theme;
|
|
362
367
|
@include icon.use-dark-theme;
|
|
@@ -514,6 +519,7 @@ $_layer-order: (
|
|
|
514
519
|
|
|
515
520
|
@if not theme.$disable-default-root-theme {
|
|
516
521
|
:root {
|
|
522
|
+
@include theme.default-color-scheme;
|
|
517
523
|
@include variables;
|
|
518
524
|
|
|
519
525
|
@if theme.$color-scheme == system {
|
package/dist/form/utils.js
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* @since 6.0.0 Uses `form.requestSubmit` instead of clicking the submit button
|
|
22
22
|
*/ export function tryToSubmitRelatedForm(event, formId) {
|
|
23
23
|
const { currentTarget } = event;
|
|
24
|
-
let form
|
|
24
|
+
let form;
|
|
25
25
|
if (formId) {
|
|
26
26
|
form = document.getElementById(formId);
|
|
27
27
|
} else {
|
package/dist/form/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/form/utils.ts"],"sourcesContent":["import { type KeyboardEvent } from \"react\";\n\n/**\n * This util should be used to implement the native \"Enter\" keypress behavior\n * for \"fake\" form components to submit the form if exists.\n *\n * The way this will work will be:\n * - attempt to find a form by querying for a parent form element. if no parent\n * form element can be found, try to use the `formId` in a\n * `document.getElementById`\n * - if a form element is found, find the submit button within the form. If\n * there are no submit buttons within the form, try to find a submit button in\n * the document that is linked to this form by `form={formId}`\n * - if the submit button was found, click it to trigger the form submit\n * behavior\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/requestSubmit\n * @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/submit\n * @internal\n * @since 2.7.0\n * @since 6.0.0 No longer returns a boolean, added the `formId` parameter, and\n * moved into the form package.\n * @since 6.0.0 Uses `form.requestSubmit` instead of clicking the submit button\n */\nexport function tryToSubmitRelatedForm<E extends HTMLElement>(\n event: KeyboardEvent<E>,\n formId: string | undefined\n): void {\n const { currentTarget } = event;\n let form: HTMLElement | null
|
|
1
|
+
{"version":3,"sources":["../../src/form/utils.ts"],"sourcesContent":["import { type KeyboardEvent } from \"react\";\n\n/**\n * This util should be used to implement the native \"Enter\" keypress behavior\n * for \"fake\" form components to submit the form if exists.\n *\n * The way this will work will be:\n * - attempt to find a form by querying for a parent form element. if no parent\n * form element can be found, try to use the `formId` in a\n * `document.getElementById`\n * - if a form element is found, find the submit button within the form. If\n * there are no submit buttons within the form, try to find a submit button in\n * the document that is linked to this form by `form={formId}`\n * - if the submit button was found, click it to trigger the form submit\n * behavior\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/requestSubmit\n * @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/submit\n * @internal\n * @since 2.7.0\n * @since 6.0.0 No longer returns a boolean, added the `formId` parameter, and\n * moved into the form package.\n * @since 6.0.0 Uses `form.requestSubmit` instead of clicking the submit button\n */\nexport function tryToSubmitRelatedForm<E extends HTMLElement>(\n event: KeyboardEvent<E>,\n formId: string | undefined\n): void {\n const { currentTarget } = event;\n let form: HTMLElement | null;\n if (formId) {\n form = document.getElementById(formId);\n } else {\n form = currentTarget.closest(\"form\");\n }\n\n if (!form || !(form instanceof HTMLFormElement)) {\n return;\n }\n\n // eslint-disable-next-line no-param-reassign\n formId = formId || form.id;\n let submit = form.querySelector<HTMLButtonElement>('[type=\"submit\"]');\n if (!submit && formId) {\n submit = document.querySelector<HTMLButtonElement>(\n `[type=\"submit\"][form=\"${formId}\"]`\n );\n }\n\n form.requestSubmit(submit);\n}\n\n/**\n * @internal\n * @since 6.0.0\n */\nexport type EditableHTMLElement = HTMLInputElement | HTMLTextAreaElement;\n\n/**\n * @internal\n * @since 6.0.0\n */\nexport type ChangeableHTMLElement = EditableHTMLElement | HTMLSelectElement;\n\n/**\n * @internal\n * @since 6.0.0\n */\nexport function isChangeableHTMLElement(\n element: Element | null\n): element is ChangeableHTMLElement {\n return !!element && \"value\" in element;\n}\n\n/**\n * This is used to trigger a change event for a form element.\n *\n * @internal\n * @see https://stackoverflow.com/a/46012210\n * @since 6.0.0\n */\nexport function triggerManualChangeEvent(\n element: ChangeableHTMLElement | null,\n value: string | number\n): void {\n if (!element) {\n return;\n }\n\n const prototype = Object.getPrototypeOf(element);\n const setter = Object.getOwnPropertyDescriptor(prototype, \"value\")?.set;\n if (!setter) {\n return;\n }\n\n setter.call(element, value);\n const event = new Event(\"input\", { bubbles: true });\n element.dispatchEvent(event);\n}\n"],"names":["tryToSubmitRelatedForm","event","formId","currentTarget","form","document","getElementById","closest","HTMLFormElement","id","submit","querySelector","requestSubmit","isChangeableHTMLElement","element","triggerManualChangeEvent","value","prototype","Object","getPrototypeOf","setter","getOwnPropertyDescriptor","set","call","Event","bubbles","dispatchEvent"],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;CAqBC,GACD,OAAO,SAASA,uBACdC,KAAuB,EACvBC,MAA0B;IAE1B,MAAM,EAAEC,aAAa,EAAE,GAAGF;IAC1B,IAAIG;IACJ,IAAIF,QAAQ;QACVE,OAAOC,SAASC,cAAc,CAACJ;IACjC,OAAO;QACLE,OAAOD,cAAcI,OAAO,CAAC;IAC/B;IAEA,IAAI,CAACH,QAAQ,CAAEA,CAAAA,gBAAgBI,eAAc,GAAI;QAC/C;IACF;IAEA,6CAA6C;IAC7CN,SAASA,UAAUE,KAAKK,EAAE;IAC1B,IAAIC,SAASN,KAAKO,aAAa,CAAoB;IACnD,IAAI,CAACD,UAAUR,QAAQ;QACrBQ,SAASL,SAASM,aAAa,CAC7B,CAAC,sBAAsB,EAAET,OAAO,EAAE,CAAC;IAEvC;IAEAE,KAAKQ,aAAa,CAACF;AACrB;AAcA;;;CAGC,GACD,OAAO,SAASG,wBACdC,OAAuB;IAEvB,OAAO,CAAC,CAACA,WAAW,WAAWA;AACjC;AAEA;;;;;;CAMC,GACD,OAAO,SAASC,yBACdD,OAAqC,EACrCE,KAAsB;IAEtB,IAAI,CAACF,SAAS;QACZ;IACF;IAEA,MAAMG,YAAYC,OAAOC,cAAc,CAACL;IACxC,MAAMM,SAASF,OAAOG,wBAAwB,CAACJ,WAAW,UAAUK;IACpE,IAAI,CAACF,QAAQ;QACX;IACF;IAEAA,OAAOG,IAAI,CAACT,SAASE;IACrB,MAAMf,QAAQ,IAAIuB,MAAM,SAAS;QAAEC,SAAS;IAAK;IACjDX,QAAQY,aAAa,CAACzB;AACxB"}
|
package/dist/icon/_icon.scss
CHANGED
|
@@ -44,6 +44,19 @@ $disable-svg: false !default;
|
|
|
44
44
|
/// @type Boolean
|
|
45
45
|
$disable-symbol: false !default;
|
|
46
46
|
|
|
47
|
+
/// Set to `true` if not using the material symbols or material icon fonts.
|
|
48
|
+
/// When this is false, the following code will be added to override the
|
|
49
|
+
/// default stylesheet:
|
|
50
|
+
///
|
|
51
|
+
/// ```scss
|
|
52
|
+
/// .rmd-icon[class*="material-"] {
|
|
53
|
+
/// @include use-var(font-size, size);
|
|
54
|
+
/// }
|
|
55
|
+
/// ```
|
|
56
|
+
///
|
|
57
|
+
/// @type Boolean
|
|
58
|
+
$disable-material-icons-font-fix: false !default;
|
|
59
|
+
|
|
47
60
|
/// Set to `true` to disable the dense icon sizes
|
|
48
61
|
/// @type Boolean
|
|
49
62
|
$disable-dense: false !default;
|
|
@@ -271,6 +284,12 @@ $_disable-icons: $disable-font and $disable-svg and $disable-symbol;
|
|
|
271
284
|
/// layer behavior
|
|
272
285
|
@mixin styles($disable-layer: false) {
|
|
273
286
|
@if not $_disable-icons {
|
|
287
|
+
@if not $disable-material-icons-font-fix {
|
|
288
|
+
.rmd-icon[class*="material-"] {
|
|
289
|
+
@include use-var(font-size, size);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
274
293
|
@include utils.optional-layer(icon, $disable-layer) {
|
|
275
294
|
@include theme.default-system-theme {
|
|
276
295
|
@include use-dark-theme;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/** @since 7.1.0 */ import { MaterialSymbol } from "./MaterialSymbol.js";
|
|
3
|
+
import { configureIcons } from "./config.js";
|
|
4
|
+
configureIcons({
|
|
5
|
+
back: /*#__PURE__*/ _jsx(MaterialSymbol, {
|
|
6
|
+
name: "keyboard_arrow_left"
|
|
7
|
+
}),
|
|
8
|
+
clear: /*#__PURE__*/ _jsx(MaterialSymbol, {
|
|
9
|
+
name: "close_small"
|
|
10
|
+
}),
|
|
11
|
+
close: /*#__PURE__*/ _jsx(MaterialSymbol, {
|
|
12
|
+
name: "close"
|
|
13
|
+
}),
|
|
14
|
+
checkbox: /*#__PURE__*/ _jsx(MaterialSymbol, {
|
|
15
|
+
name: "check_box_outline_blank"
|
|
16
|
+
}),
|
|
17
|
+
checkboxChecked: /*#__PURE__*/ _jsx(MaterialSymbol, {
|
|
18
|
+
name: "check_box"
|
|
19
|
+
}),
|
|
20
|
+
checkboxIndeterminate: /*#__PURE__*/ _jsx(MaterialSymbol, {
|
|
21
|
+
name: "indeterminate_check_box"
|
|
22
|
+
}),
|
|
23
|
+
dropdown: /*#__PURE__*/ _jsx(MaterialSymbol, {
|
|
24
|
+
name: "arrow_drop_down"
|
|
25
|
+
}),
|
|
26
|
+
error: /*#__PURE__*/ _jsx(MaterialSymbol, {
|
|
27
|
+
name: "error"
|
|
28
|
+
}),
|
|
29
|
+
expander: /*#__PURE__*/ _jsx(MaterialSymbol, {
|
|
30
|
+
name: "keyboard_arrow_down"
|
|
31
|
+
}),
|
|
32
|
+
forward: /*#__PURE__*/ _jsx(MaterialSymbol, {
|
|
33
|
+
name: "keyboard_arrow_right"
|
|
34
|
+
}),
|
|
35
|
+
menu: /*#__PURE__*/ _jsx(MaterialSymbol, {
|
|
36
|
+
name: "menu"
|
|
37
|
+
}),
|
|
38
|
+
notification: /*#__PURE__*/ _jsx(MaterialSymbol, {
|
|
39
|
+
name: "notifications"
|
|
40
|
+
}),
|
|
41
|
+
password: /*#__PURE__*/ _jsx(MaterialSymbol, {
|
|
42
|
+
name: "visibility"
|
|
43
|
+
}),
|
|
44
|
+
radio: /*#__PURE__*/ _jsx(MaterialSymbol, {
|
|
45
|
+
name: "radio_button_unchecked"
|
|
46
|
+
}),
|
|
47
|
+
radioChecked: /*#__PURE__*/ _jsx(MaterialSymbol, {
|
|
48
|
+
name: "radio_button_checked"
|
|
49
|
+
}),
|
|
50
|
+
remove: /*#__PURE__*/ _jsx(MaterialSymbol, {
|
|
51
|
+
name: "cancel"
|
|
52
|
+
}),
|
|
53
|
+
selected: /*#__PURE__*/ _jsx(MaterialSymbol, {
|
|
54
|
+
name: "check"
|
|
55
|
+
}),
|
|
56
|
+
sort: /*#__PURE__*/ _jsx(MaterialSymbol, {
|
|
57
|
+
name: "arrow_upward"
|
|
58
|
+
}),
|
|
59
|
+
upload: /*#__PURE__*/ _jsx(MaterialSymbol, {
|
|
60
|
+
name: "upload"
|
|
61
|
+
})
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
//# sourceMappingURL=configureMaterialSymbols.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/icon/configureMaterialSymbols.tsx"],"sourcesContent":["/** @since 7.1.0 */\nimport { MaterialSymbol } from \"./MaterialSymbol.js\";\nimport { configureIcons } from \"./config.js\";\n\nconfigureIcons({\n back: <MaterialSymbol name=\"keyboard_arrow_left\" />,\n clear: <MaterialSymbol name=\"close_small\" />,\n close: <MaterialSymbol name=\"close\" />,\n checkbox: <MaterialSymbol name=\"check_box_outline_blank\" />,\n checkboxChecked: <MaterialSymbol name=\"check_box\" />,\n checkboxIndeterminate: <MaterialSymbol name=\"indeterminate_check_box\" />,\n dropdown: <MaterialSymbol name=\"arrow_drop_down\" />,\n error: <MaterialSymbol name=\"error\" />,\n expander: <MaterialSymbol name=\"keyboard_arrow_down\" />,\n forward: <MaterialSymbol name=\"keyboard_arrow_right\" />,\n menu: <MaterialSymbol name=\"menu\" />,\n notification: <MaterialSymbol name=\"notifications\" />,\n password: <MaterialSymbol name=\"visibility\" />,\n radio: <MaterialSymbol name=\"radio_button_unchecked\" />,\n radioChecked: <MaterialSymbol name=\"radio_button_checked\" />,\n remove: <MaterialSymbol name=\"cancel\" />,\n selected: <MaterialSymbol name=\"check\" />,\n sort: <MaterialSymbol name=\"arrow_upward\" />,\n upload: <MaterialSymbol name=\"upload\" />,\n});\n"],"names":["MaterialSymbol","configureIcons","back","name","clear","close","checkbox","checkboxChecked","checkboxIndeterminate","dropdown","error","expander","forward","menu","notification","password","radio","radioChecked","remove","selected","sort","upload"],"mappings":";AAAA,iBAAiB,GACjB,SAASA,cAAc,QAAQ,sBAAsB;AACrD,SAASC,cAAc,QAAQ,cAAc;AAE7CA,eAAe;IACbC,oBAAM,KAACF;QAAeG,MAAK;;IAC3BC,qBAAO,KAACJ;QAAeG,MAAK;;IAC5BE,qBAAO,KAACL;QAAeG,MAAK;;IAC5BG,wBAAU,KAACN;QAAeG,MAAK;;IAC/BI,+BAAiB,KAACP;QAAeG,MAAK;;IACtCK,qCAAuB,KAACR;QAAeG,MAAK;;IAC5CM,wBAAU,KAACT;QAAeG,MAAK;;IAC/BO,qBAAO,KAACV;QAAeG,MAAK;;IAC5BQ,wBAAU,KAACX;QAAeG,MAAK;;IAC/BS,uBAAS,KAACZ;QAAeG,MAAK;;IAC9BU,oBAAM,KAACb;QAAeG,MAAK;;IAC3BW,4BAAc,KAACd;QAAeG,MAAK;;IACnCY,wBAAU,KAACf;QAAeG,MAAK;;IAC/Ba,qBAAO,KAAChB;QAAeG,MAAK;;IAC5Bc,4BAAc,KAACjB;QAAeG,MAAK;;IACnCe,sBAAQ,KAAClB;QAAeG,MAAK;;IAC7BgB,wBAAU,KAACnB;QAAeG,MAAK;;IAC/BiB,oBAAM,KAACpB;QAAeG,MAAK;;IAC3BkB,sBAAQ,KAACrB;QAAeG,MAAK;;AAC/B"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @internal
|
|
3
|
+
* @since 7.1.0
|
|
4
|
+
*/ export function getMaterialSymbolOption(value, fallback) {
|
|
5
|
+
if (!value) {
|
|
6
|
+
return `${fallback}`;
|
|
7
|
+
}
|
|
8
|
+
if (typeof value === "number") {
|
|
9
|
+
return `${value}`;
|
|
10
|
+
}
|
|
11
|
+
return `${value.min}..${value.max}`;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
//# sourceMappingURL=getMaterialSymbolOption.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/icon/getMaterialSymbolOption.ts"],"sourcesContent":["import { type GoogleFontsAPIValueOrRange } from \"./getMaterialSymbolsUrl.js\";\n\n/**\n * @internal\n * @since 7.1.0\n */\nexport function getMaterialSymbolOption<T extends number>(\n value: GoogleFontsAPIValueOrRange<T> | undefined,\n fallback: T\n): string {\n if (!value) {\n return `${fallback}`;\n }\n\n if (typeof value === \"number\") {\n return `${value}`;\n }\n\n return `${value.min}..${value.max}`;\n}\n"],"names":["getMaterialSymbolOption","value","fallback","min","max"],"mappings":"AAEA;;;CAGC,GACD,OAAO,SAASA,wBACdC,KAAgD,EAChDC,QAAW;IAEX,IAAI,CAACD,OAAO;QACV,OAAO,GAAGC,UAAU;IACtB;IAEA,IAAI,OAAOD,UAAU,UAAU;QAC7B,OAAO,GAAGA,OAAO;IACnB;IAEA,OAAO,GAAGA,MAAME,GAAG,CAAC,EAAE,EAAEF,MAAMG,GAAG,EAAE;AACrC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { type MaterialSymbolFamily, type MaterialSymbolName } from "./material.js";
|
|
2
|
+
import { type MaterialSymbolFill, type MaterialSymbolGrade, type MaterialSymbolOpticalSize, type MaterialSymbolWeight } from "./materialConfig.js";
|
|
3
|
+
/**
|
|
4
|
+
* @since 7.1.0
|
|
5
|
+
*/
|
|
6
|
+
export type GoogleFontsAPIValueOrRange<T extends number> = T | {
|
|
7
|
+
min: T;
|
|
8
|
+
max: T;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* @since 7.1.0
|
|
12
|
+
*/
|
|
13
|
+
export interface MaterialSymbolsGoogleFontUrlOptions {
|
|
14
|
+
/**
|
|
15
|
+
* Provide this value if the `MATERIAL_CONFIG.family` is not the default.
|
|
16
|
+
*
|
|
17
|
+
* @defaultValue `"outlined"`
|
|
18
|
+
*/
|
|
19
|
+
family?: MaterialSymbolFamily | readonly MaterialSymbolFamily[];
|
|
20
|
+
/**
|
|
21
|
+
* Provide this value if the `MATERIAL_CONFIG.fill` is not the default.
|
|
22
|
+
*
|
|
23
|
+
* @defaultValue `0`
|
|
24
|
+
*/
|
|
25
|
+
fill?: GoogleFontsAPIValueOrRange<MaterialSymbolFill>;
|
|
26
|
+
/**
|
|
27
|
+
* Provide this value if the `MATERIAL_CONFIG.grade` is not the default.
|
|
28
|
+
*
|
|
29
|
+
* @defaultValue `0`
|
|
30
|
+
*/
|
|
31
|
+
grade?: GoogleFontsAPIValueOrRange<MaterialSymbolGrade>;
|
|
32
|
+
/**
|
|
33
|
+
* Provide this value if the `MATERIAL_CONFIG.weight` is not the default.
|
|
34
|
+
*
|
|
35
|
+
* @defaultValue `400`
|
|
36
|
+
*/
|
|
37
|
+
weight?: GoogleFontsAPIValueOrRange<MaterialSymbolWeight>;
|
|
38
|
+
/**
|
|
39
|
+
* Provide this value if the `MATERIAL_CONFIG.opticalSize` is not the default.
|
|
40
|
+
*
|
|
41
|
+
* @defaultValue `48`
|
|
42
|
+
*/
|
|
43
|
+
opticalSize?: GoogleFontsAPIValueOrRange<MaterialSymbolOpticalSize>;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* @since 7.1.0
|
|
47
|
+
*/
|
|
48
|
+
export interface MaterialSymbolsUrlOptions extends MaterialSymbolsGoogleFontUrlOptions {
|
|
49
|
+
/**
|
|
50
|
+
* @see {@link DEFAULT_MATERIAL_SYMBOL_NAMES}
|
|
51
|
+
* @defaultValue `DEFAULT_MATERIAL_SYMBOL_NAMES`
|
|
52
|
+
*/
|
|
53
|
+
names?: readonly MaterialSymbolName[];
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* @since 7.1.0
|
|
57
|
+
*/
|
|
58
|
+
export declare function getMaterialSymbolsUrl(options?: MaterialSymbolsUrlOptions): string;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { alphaNumericSort } from "../utils/alphaNumericSort.js";
|
|
2
|
+
import { getMaterialSymbolOption } from "./getMaterialSymbolOption.js";
|
|
3
|
+
import { MATERIAL_CONFIG } from "./materialConfig.js";
|
|
4
|
+
import { DEFAULT_MATERIAL_SYMBOL_NAMES } from "./symbols.js";
|
|
5
|
+
/**
|
|
6
|
+
* @since 7.1.0
|
|
7
|
+
*/ export function getMaterialSymbolsUrl(options = {}) {
|
|
8
|
+
// the names have to be sorted for the google fonts api
|
|
9
|
+
const names = alphaNumericSort([
|
|
10
|
+
...new Set(options.names ?? DEFAULT_MATERIAL_SYMBOL_NAMES)
|
|
11
|
+
]);
|
|
12
|
+
const fill = getMaterialSymbolOption(options.fill, MATERIAL_CONFIG.fill);
|
|
13
|
+
const grade = getMaterialSymbolOption(options.grade, MATERIAL_CONFIG.grade);
|
|
14
|
+
const weight = getMaterialSymbolOption(options.weight, MATERIAL_CONFIG.weight);
|
|
15
|
+
const opticalSize = getMaterialSymbolOption(options.opticalSize, MATERIAL_CONFIG.opticalSize);
|
|
16
|
+
const specs = `:opsz,wght,FILL,GRAD@${opticalSize},${weight},${fill},${grade}`;
|
|
17
|
+
const families = typeof options.family === "string" || options.family === undefined ? [
|
|
18
|
+
options.family ?? MATERIAL_CONFIG.family
|
|
19
|
+
] : options.family;
|
|
20
|
+
let familiesQs = "";
|
|
21
|
+
for (const [i, family] of families.entries()){
|
|
22
|
+
const variant = family.charAt(0).toUpperCase() + family.slice(1);
|
|
23
|
+
familiesQs += (i === 0 ? "" : "&") + "family=Material+Symbols+" + variant;
|
|
24
|
+
}
|
|
25
|
+
let iconNames = "";
|
|
26
|
+
if (names.length > 0) {
|
|
27
|
+
iconNames = `&icon_names=${names.join(",")}`;
|
|
28
|
+
}
|
|
29
|
+
return `https://fonts.googleapis.com/css2?${familiesQs}${specs}${iconNames}`;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
//# sourceMappingURL=getMaterialSymbolsUrl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/icon/getMaterialSymbolsUrl.ts"],"sourcesContent":["import { alphaNumericSort } from \"../utils/alphaNumericSort.js\";\nimport { getMaterialSymbolOption } from \"./getMaterialSymbolOption.js\";\nimport {\n type MaterialSymbolFamily,\n type MaterialSymbolName,\n} from \"./material.js\";\nimport {\n MATERIAL_CONFIG,\n type MaterialSymbolFill,\n type MaterialSymbolGrade,\n type MaterialSymbolOpticalSize,\n type MaterialSymbolWeight,\n} from \"./materialConfig.js\";\nimport { DEFAULT_MATERIAL_SYMBOL_NAMES } from \"./symbols.js\";\n\n/**\n * @since 7.1.0\n */\nexport type GoogleFontsAPIValueOrRange<T extends number> =\n | T\n | { min: T; max: T };\n\n/**\n * @since 7.1.0\n */\nexport interface MaterialSymbolsGoogleFontUrlOptions {\n /**\n * Provide this value if the `MATERIAL_CONFIG.family` is not the default.\n *\n * @defaultValue `\"outlined\"`\n */\n family?: MaterialSymbolFamily | readonly MaterialSymbolFamily[];\n\n /**\n * Provide this value if the `MATERIAL_CONFIG.fill` is not the default.\n *\n * @defaultValue `0`\n */\n fill?: GoogleFontsAPIValueOrRange<MaterialSymbolFill>;\n\n /**\n * Provide this value if the `MATERIAL_CONFIG.grade` is not the default.\n *\n * @defaultValue `0`\n */\n grade?: GoogleFontsAPIValueOrRange<MaterialSymbolGrade>;\n\n /**\n * Provide this value if the `MATERIAL_CONFIG.weight` is not the default.\n *\n * @defaultValue `400`\n */\n weight?: GoogleFontsAPIValueOrRange<MaterialSymbolWeight>;\n\n /**\n * Provide this value if the `MATERIAL_CONFIG.opticalSize` is not the default.\n *\n * @defaultValue `48`\n */\n opticalSize?: GoogleFontsAPIValueOrRange<MaterialSymbolOpticalSize>;\n}\n\n/**\n * @since 7.1.0\n */\nexport interface MaterialSymbolsUrlOptions extends MaterialSymbolsGoogleFontUrlOptions {\n /**\n * @see {@link DEFAULT_MATERIAL_SYMBOL_NAMES}\n * @defaultValue `DEFAULT_MATERIAL_SYMBOL_NAMES`\n */\n names?: readonly MaterialSymbolName[];\n}\n\n/**\n * @since 7.1.0\n */\nexport function getMaterialSymbolsUrl(\n options: MaterialSymbolsUrlOptions = {}\n): string {\n // the names have to be sorted for the google fonts api\n const names = alphaNumericSort([\n ...new Set(options.names ?? DEFAULT_MATERIAL_SYMBOL_NAMES),\n ]);\n const fill = getMaterialSymbolOption(options.fill, MATERIAL_CONFIG.fill);\n const grade = getMaterialSymbolOption(options.grade, MATERIAL_CONFIG.grade);\n const weight = getMaterialSymbolOption(\n options.weight,\n MATERIAL_CONFIG.weight\n );\n const opticalSize = getMaterialSymbolOption(\n options.opticalSize,\n MATERIAL_CONFIG.opticalSize\n );\n const specs = `:opsz,wght,FILL,GRAD@${opticalSize},${weight},${fill},${grade}`;\n\n const families =\n typeof options.family === \"string\" || options.family === undefined\n ? [options.family ?? MATERIAL_CONFIG.family]\n : options.family;\n let familiesQs = \"\";\n for (const [i, family] of families.entries()) {\n const variant = family.charAt(0).toUpperCase() + family.slice(1);\n familiesQs += (i === 0 ? \"\" : \"&\") + \"family=Material+Symbols+\" + variant;\n }\n\n let iconNames = \"\";\n if (names.length > 0) {\n iconNames = `&icon_names=${names.join(\",\")}`;\n }\n\n return `https://fonts.googleapis.com/css2?${familiesQs}${specs}${iconNames}`;\n}\n"],"names":["alphaNumericSort","getMaterialSymbolOption","MATERIAL_CONFIG","DEFAULT_MATERIAL_SYMBOL_NAMES","getMaterialSymbolsUrl","options","names","Set","fill","grade","weight","opticalSize","specs","families","family","undefined","familiesQs","i","entries","variant","charAt","toUpperCase","slice","iconNames","length","join"],"mappings":"AAAA,SAASA,gBAAgB,QAAQ,+BAA+B;AAChE,SAASC,uBAAuB,QAAQ,+BAA+B;AAKvE,SACEC,eAAe,QAKV,sBAAsB;AAC7B,SAASC,6BAA6B,QAAQ,eAAe;AA4D7D;;CAEC,GACD,OAAO,SAASC,sBACdC,UAAqC,CAAC,CAAC;IAEvC,uDAAuD;IACvD,MAAMC,QAAQN,iBAAiB;WAC1B,IAAIO,IAAIF,QAAQC,KAAK,IAAIH;KAC7B;IACD,MAAMK,OAAOP,wBAAwBI,QAAQG,IAAI,EAAEN,gBAAgBM,IAAI;IACvE,MAAMC,QAAQR,wBAAwBI,QAAQI,KAAK,EAAEP,gBAAgBO,KAAK;IAC1E,MAAMC,SAAST,wBACbI,QAAQK,MAAM,EACdR,gBAAgBQ,MAAM;IAExB,MAAMC,cAAcV,wBAClBI,QAAQM,WAAW,EACnBT,gBAAgBS,WAAW;IAE7B,MAAMC,QAAQ,CAAC,qBAAqB,EAAED,YAAY,CAAC,EAAED,OAAO,CAAC,EAAEF,KAAK,CAAC,EAAEC,OAAO;IAE9E,MAAMI,WACJ,OAAOR,QAAQS,MAAM,KAAK,YAAYT,QAAQS,MAAM,KAAKC,YACrD;QAACV,QAAQS,MAAM,IAAIZ,gBAAgBY,MAAM;KAAC,GAC1CT,QAAQS,MAAM;IACpB,IAAIE,aAAa;IACjB,KAAK,MAAM,CAACC,GAAGH,OAAO,IAAID,SAASK,OAAO,GAAI;QAC5C,MAAMC,UAAUL,OAAOM,MAAM,CAAC,GAAGC,WAAW,KAAKP,OAAOQ,KAAK,CAAC;QAC9DN,cAAc,AAACC,CAAAA,MAAM,IAAI,KAAK,GAAE,IAAK,6BAA6BE;IACpE;IAEA,IAAII,YAAY;IAChB,IAAIjB,MAAMkB,MAAM,GAAG,GAAG;QACpBD,YAAY,CAAC,YAAY,EAAEjB,MAAMmB,IAAI,CAAC,MAAM;IAC9C;IAEA,OAAO,CAAC,kCAAkC,EAAET,aAAaJ,QAAQW,WAAW;AAC9E"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since 7.1.0
|
|
3
|
+
*/
|
|
4
|
+
export declare const DEFAULT_MATERIAL_SYMBOL_NAMES: ("error" | "cancel" | "close" | "visibility" | "menu" | "arrow_drop_down" | "arrow_upward" | "check" | "check_box" | "check_box_outline_blank" | "indeterminate_check_box" | "keyboard_arrow_down" | "keyboard_arrow_left" | "keyboard_arrow_right" | "notifications" | "radio_button_checked" | "radio_button_unchecked" | "upload" | "close_small")[];
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since 7.1.0
|
|
3
|
+
*/ export const DEFAULT_MATERIAL_SYMBOL_NAMES = [
|
|
4
|
+
"keyboard_arrow_left",
|
|
5
|
+
"close_small",
|
|
6
|
+
"close",
|
|
7
|
+
"check_box_outline_blank",
|
|
8
|
+
"check_box",
|
|
9
|
+
"indeterminate_check_box",
|
|
10
|
+
"arrow_drop_down",
|
|
11
|
+
"error",
|
|
12
|
+
"keyboard_arrow_down",
|
|
13
|
+
"keyboard_arrow_right",
|
|
14
|
+
"menu",
|
|
15
|
+
"notifications",
|
|
16
|
+
"visibility",
|
|
17
|
+
"radio_button_unchecked",
|
|
18
|
+
"radio_button_checked",
|
|
19
|
+
"cancel",
|
|
20
|
+
"check",
|
|
21
|
+
"arrow_upward",
|
|
22
|
+
"upload"
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
//# sourceMappingURL=symbols.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/icon/symbols.ts"],"sourcesContent":["import { type MaterialSymbolName } from \"./material.js\";\n\n/**\n * @since 7.1.0\n */\nexport const DEFAULT_MATERIAL_SYMBOL_NAMES = [\n \"keyboard_arrow_left\",\n \"close_small\",\n \"close\",\n \"check_box_outline_blank\",\n \"check_box\",\n \"indeterminate_check_box\",\n \"arrow_drop_down\",\n \"error\",\n \"keyboard_arrow_down\",\n \"keyboard_arrow_right\",\n \"menu\",\n \"notifications\",\n \"visibility\",\n \"radio_button_unchecked\",\n \"radio_button_checked\",\n \"cancel\",\n \"check\",\n \"arrow_upward\",\n \"upload\",\n] satisfies readonly MaterialSymbolName[];\n"],"names":["DEFAULT_MATERIAL_SYMBOL_NAMES"],"mappings":"AAEA;;CAEC,GACD,OAAO,MAAMA,gCAAgC;IAC3C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;CACD,CAAyC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type CSSTransitionElementProps } from "../transition/types.js";
|
|
2
|
-
import { type CssPosition, type UseStateInitializer } from "../types.js";
|
|
2
|
+
import { type CssPosition, type LiteralStringUnion, type UseStateInitializer } from "../types.js";
|
|
3
3
|
import { type LayoutNavProps } from "./LayoutNav.js";
|
|
4
4
|
import { type HorizontalLayoutTransitionOptions } from "./useHorizontalLayoutTransition.js";
|
|
5
5
|
import { type ProvidedLayoutNavToggleProps, type ProvidedTemporaryLayoutAppBarProps, type ProvidedTemporaryLayoutMainProps, type TemporaryLayoutImplementation, type TemporaryLayoutOptions } from "./useTemporaryLayout.js";
|
|
@@ -44,7 +44,7 @@ export interface ExpandableLayoutOptions extends TemporaryLayoutOptions {
|
|
|
44
44
|
*
|
|
45
45
|
* @defaultValue `"tablet"`
|
|
46
46
|
*/
|
|
47
|
-
temporaryUntil?: "tablet" | "desktop"
|
|
47
|
+
temporaryUntil?: LiteralStringUnion<"tablet" | "desktop">;
|
|
48
48
|
}
|
|
49
49
|
/**
|
|
50
50
|
* @since 6.0.0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/layout/useExpandableLayout.ts"],"sourcesContent":["\"use client\";\n\nimport { cnb } from \"cnbuilder\";\n\nimport { useSsr } from \"../SsrProvider.js\";\nimport { useAppSize } from \"../media-queries/AppSizeProvider.js\";\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport { type AppSize } from \"../media-queries/appSize.js\";\nimport { MEDIA_QUERY_CONFIG } from \"../media-queries/config.js\";\nimport { useMediaQuery } from \"../media-queries/useMediaQuery.js\";\nimport { type CSSTransitionElementProps } from \"../transition/types.js\";\nimport { type CssPosition, type UseStateInitializer } from \"../types.js\";\nimport { useToggle } from \"../useToggle.js\";\nimport { useDevEffect } from \"../utils/useDevEffect.js\";\nimport { type LayoutNavProps } from \"./LayoutNav.js\";\nimport {\n type HorizontalLayoutTransitionOptions,\n useHorizontalLayoutTransition,\n} from \"./useHorizontalLayoutTransition.js\";\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport { type useResizableLayout } from \"./useResizableLayout.js\";\nimport {\n type ProvidedLayoutNavToggleProps,\n type ProvidedTemporaryLayoutAppBarProps,\n type ProvidedTemporaryLayoutMainProps,\n type TemporaryLayoutImplementation,\n type TemporaryLayoutOptions,\n useTemporaryLayout,\n} from \"./useTemporaryLayout.js\";\n\nlet loggedOnce = false;\n\n/**\n * @since 6.0.0\n */\nexport interface ExpandableLayoutOptions extends TemporaryLayoutOptions {\n /** @defaultValue `\"fixed\"` */\n appBarPosition?: CssPosition;\n\n /** @defaultValue `false` */\n defaultExpanded?: UseStateInitializer<boolean>;\n\n /**\n * Set this to `true` if the expandable navigation should be the full height\n * of the screen. This will also update the app bar so that it is not covered\n * by the navigation. The default behavior is to place the navigation below\n * the fixed header.\n *\n * Set this to `\"static\"` to make the navigation span the full height of the\n * screen and hide the button until the screen shrinks to the temporary\n * layout type.\n *\n * @defaultValue `false`\n */\n fullHeightNav?: boolean | \"static\";\n\n /** @see {@link HorizontalLayoutTransitionOptions} */\n transitionProps?: Omit<HorizontalLayoutTransitionOptions, \"transitionIn\">;\n\n /**\n * The default behavior is to use the temporary layout until the\n * {@link AppSize.isTablet} is `true`. Set this to `\"desktop\"` to use the\n * temporary layout until {@link AppSize.isDesktop} is `true`. Otherwise,\n * provide a media query string to use the temporary layout until the media\n * query matches\n *\n * @example Custom Media Query\n * ```tsx\n * useExpandableLayout({\n * ...options,\n * // display the expandable layout once the min-width is at least 1201px\n * temporaryUntil: \"screen and (min-width: 1201px)\",\n * });\n * ```\n *\n * @defaultValue `\"tablet\"`\n */\n temporaryUntil?: \"tablet\" | \"desktop\" | (string & {});\n}\n\n/**\n * @since 6.0.0\n */\nexport interface ProvidedLayoutMainProps\n extends\n ProvidedTemporaryLayoutMainProps,\n CSSTransitionElementProps<HTMLElement> {}\n\n/**\n * @since 6.0.0\n */\nexport type ProvidedLayoutNavProps = Pick<\n LayoutNavProps,\n \"expanded\" | \"appBarOffset\"\n>;\n\n/**\n * @since 6.0.0\n */\nexport type ProvidedLayoutAppBarProps = ProvidedTemporaryLayoutAppBarProps &\n Partial<CSSTransitionElementProps<HTMLElement>>;\n\n/**\n * @since 6.0.0\n */\nexport interface ProvidedExpandableLayoutNavToggleProps extends ProvidedLayoutNavToggleProps {\n className: string;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface ExpandableLayoutImplementation extends TemporaryLayoutImplementation {\n temporary: boolean;\n persistent: boolean;\n expanded: boolean;\n expandNavigation: () => void;\n collapseNavigation: () => void;\n toggleNavigation: () => void;\n appBarProps: ProvidedLayoutAppBarProps;\n mainProps: ProvidedLayoutMainProps;\n navToggleProps: ProvidedExpandableLayoutNavToggleProps;\n expandableNavProps: ProvidedLayoutNavProps;\n}\n\n/**\n * @example Main Usage\n * ```tsx\n * import { AppBarTitle } from \"@react-md/core/app-bar/AppBarTitle\";\n * import { Button } from \"@react-md/core/button/Button\";\n * import { LayoutAppBar } from \"@react-md/core/layout/LayoutAppBar\";\n * import { LayoutNav } from \"@react-md/core/layout/LayoutNav\";\n * import { Main } from \"@react-md/core/layout/Main\";\n * import { useExpandableLayout } from \"@react-md/core/layout/useExpandableLayout\";\n * import { Sheet } from \"@react-md/core/sheet/Sheet\";\n * import { type ReactElement, type ReactNode } from \"react\";\n *\n * import { CustomNavigation } from \"./CustomNavigation\";\n *\n * export interface LayoutProps {\n * children: ReactNode;\n * }\n *\n * export function Layout(props: LayoutProps): ReactElement {\n * const { children } = props;\n *\n * // choose whichever one for your app\n * // nextjs app dir\n * const pathname = usePathname();\n * // nextjs pages\n * const { pathname } = useRouter();\n * // react router\n * const { pathname } = useHistory();\n *\n * const {\n * temporary,\n * appBarProps,\n * expandableNavProps,\n * mainProps,\n * navToggleProps,\n * temporaryNavProps,\n * windowSplitterProps,\n * } = useExpandableLayout({ pathname });\n *\n * return (\n * <>\n * <LayoutAppBar {...appBarProps}>\n * <Button {...navToggleProps} />\n * <AppBarTitle>Hello, world!</AppBarTitle>\n * </LayoutAppBar>\n * <LayoutNav {...expandableNavProps}>\n * <CustomNavigation />\n * </LayoutNav>\n * {temporary && (\n * <Sheet {...temporaryNavProps}>\n * <CustomNavigation />\n * </Sheet>\n * )}\n * <Main {...mainProps}>{children}</Main>\n * </>\n * );\n * }\n * ```\n *\n * If you have a large navigation panel, you can conditionally render the\n * `LayoutNav` with the `persistent` boolean returned by the hook which will\n * ensure that the DOM has rehydrated before unmounting to prevent SSR errors.\n *\n * @example Safely Conditionally Rendering\n * ```diff\n * const {\n * temporary,\n * + persistent,\n * appBarProps,\n * expandableNavProps,\n * mainProps,\n * navToggleProps,\n * temporaryNavProps,\n * windowSplitterProps,\n * } = useExpandableLayout({ pathname });\n *\n * return (\n * <>\n * <LayoutAppBar {...appBarProps}>\n * <Button {...navToggleProps} />\n * <AppBarTitle>Hello, world!</AppBarTitle>\n * </LayoutAppBar>\n * - <LayoutNav {...expandableNavProps}>\n * - <CustomNavigation />\n * - </LayoutNav>\n * + {persistent && (\n * + <LayoutNav {...expandableNavProps}>\n * + <CustomNavigation />\n * + </LayoutNav>\n * + )}\n * {temporary && (\n * <Sheet {...temporaryNavProps}>\n * <CustomNavigation />\n * </Sheet>\n * )}\n * <Main {...mainProps}>{children}</Main>\n * </>\n * );\n * ```\n *\n * @see {@link https://react-md.dev/getting-started/layout | Layout Demos}\n * @since 6.0.0\n * @see {@link useResizableLayout}\n */\nexport function useExpandableLayout(\n options: ExpandableLayoutOptions\n): ExpandableLayoutImplementation {\n const {\n fullHeightNav = false,\n temporaryUntil = \"tablet\",\n transitionProps,\n defaultExpanded = fullHeightNav === \"static\",\n ...temporaryOptions\n } = options;\n\n const ssr = useSsr();\n const {\n appBarProps,\n mainProps,\n navToggleProps,\n temporaryNavProps,\n hideTemporaryNav,\n showTemporaryNav,\n visible,\n } = useTemporaryLayout(temporaryOptions);\n\n const {\n toggled: expanded,\n enable: expandNavigation,\n disable: collapseNavigation,\n toggle: toggleNavigation,\n } = useToggle(defaultExpanded);\n const { elementProps } = useHorizontalLayoutTransition({\n ...transitionProps,\n transitionIn: expanded,\n });\n const { isPhone, isDesktop } = useAppSize();\n const isAppSizeMatch =\n temporaryUntil === \"tablet\" || temporaryUntil === \"desktop\";\n const matches = useMediaQuery(temporaryUntil, isAppSizeMatch);\n const temporary = isAppSizeMatch\n ? isPhone || (temporaryUntil === \"desktop\" && !isDesktop)\n : !matches;\n\n useDevEffect(() => {\n if (process.env.NODE_ENV === \"test\") {\n return;\n }\n\n let query: string;\n if (temporaryUntil === \"tablet\" || temporaryUntil === \"desktop\") {\n const minWidth =\n temporaryUntil === \"tablet\"\n ? MEDIA_QUERY_CONFIG.tabletMinWidth\n : MEDIA_QUERY_CONFIG.desktopMinWidth;\n query = `screen and (min-width: ${minWidth})`;\n } else {\n query = temporaryUntil;\n }\n\n const timeout = globalThis.setTimeout(() => {\n let found = false;\n for (let i = 0; i < document.styleSheets.length; i++) {\n const sheet = document.styleSheets[i];\n\n try {\n const rules = sheet.cssRules;\n for (const rule of rules) {\n if (\n rule.cssText.includes(\".rmd-layout\") &&\n rule.cssText.includes(`@media ${query}`)\n ) {\n found = true;\n return;\n }\n }\n } catch {\n //\n }\n }\n\n if (!found && !loggedOnce) {\n loggedOnce = true;\n // eslint-disable-next-line no-console\n console.error(\n `The react-md expandable layout has set \\`temporaryUntil: \"${temporaryUntil}\"\\` but the corresponding styles have not been found.` +\n \" This usually means the `$layout-navigation-breakpoint` or `temporaryUntil` value should be updated match.\\n\\n\" +\n \"See https://react-md.dev/getting-started/layout#updating-the-layout-to-be-temporary-until-a-specific-breakpoint-optional \" +\n \"for more information.\"\n );\n }\n }, 3000);\n\n return () => {\n globalThis.clearTimeout(timeout);\n };\n }, [temporaryUntil]);\n\n return {\n visible,\n temporary,\n persistent: ssr || !temporary,\n hideTemporaryNav,\n showTemporaryNav,\n expanded,\n expandNavigation,\n collapseNavigation,\n toggleNavigation,\n appBarProps: {\n ...appBarProps,\n ...(fullHeightNav ? elementProps : {}),\n },\n mainProps: {\n ...mainProps,\n ...elementProps,\n },\n temporaryNavProps,\n expandableNavProps: {\n expanded,\n appBarOffset: !fullHeightNav,\n },\n navToggleProps: {\n ...navToggleProps,\n onClick() {\n if (temporary) {\n showTemporaryNav();\n } else {\n toggleNavigation();\n }\n },\n className: cnb(fullHeightNav === \"static\" && \"rmd-layout-nav-toggle\"),\n },\n };\n}\n"],"names":["cnb","useSsr","useAppSize","MEDIA_QUERY_CONFIG","useMediaQuery","useToggle","useDevEffect","useHorizontalLayoutTransition","useTemporaryLayout","loggedOnce","useExpandableLayout","options","fullHeightNav","temporaryUntil","transitionProps","defaultExpanded","temporaryOptions","ssr","appBarProps","mainProps","navToggleProps","temporaryNavProps","hideTemporaryNav","showTemporaryNav","visible","toggled","expanded","enable","expandNavigation","disable","collapseNavigation","toggle","toggleNavigation","elementProps","transitionIn","isPhone","isDesktop","isAppSizeMatch","matches","temporary","process","env","NODE_ENV","query","minWidth","tabletMinWidth","desktopMinWidth","timeout","globalThis","setTimeout","found","i","document","styleSheets","length","sheet","rules","cssRules","rule","cssText","includes","console","error","clearTimeout","persistent","expandableNavProps","appBarOffset","onClick","className"],"mappings":"AAAA;AAEA,SAASA,GAAG,QAAQ,YAAY;AAEhC,SAASC,MAAM,QAAQ,oBAAoB;AAC3C,SAASC,UAAU,QAAQ,sCAAsC;AAGjE,SAASC,kBAAkB,QAAQ,6BAA6B;AAChE,SAASC,aAAa,QAAQ,oCAAoC;AAGlE,SAASC,SAAS,QAAQ,kBAAkB;AAC5C,SAASC,YAAY,QAAQ,2BAA2B;AAExD,SAEEC,6BAA6B,QACxB,qCAAqC;AAG5C,SAMEC,kBAAkB,QACb,0BAA0B;AAEjC,IAAIC,aAAa;AA+FjB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuGC,GACD,OAAO,SAASC,oBACdC,OAAgC;IAEhC,MAAM,EACJC,gBAAgB,KAAK,EACrBC,iBAAiB,QAAQ,EACzBC,eAAe,EACfC,kBAAkBH,kBAAkB,QAAQ,EAC5C,GAAGI,kBACJ,GAAGL;IAEJ,MAAMM,MAAMhB;IACZ,MAAM,EACJiB,WAAW,EACXC,SAAS,EACTC,cAAc,EACdC,iBAAiB,EACjBC,gBAAgB,EAChBC,gBAAgB,EAChBC,OAAO,EACR,GAAGhB,mBAAmBQ;IAEvB,MAAM,EACJS,SAASC,QAAQ,EACjBC,QAAQC,gBAAgB,EACxBC,SAASC,kBAAkB,EAC3BC,QAAQC,gBAAgB,EACzB,GAAG3B,UAAUU;IACd,MAAM,EAAEkB,YAAY,EAAE,GAAG1B,8BAA8B;QACrD,GAAGO,eAAe;QAClBoB,cAAcR;IAChB;IACA,MAAM,EAAES,OAAO,EAAEC,SAAS,EAAE,GAAGlC;IAC/B,MAAMmC,iBACJxB,mBAAmB,YAAYA,mBAAmB;IACpD,MAAMyB,UAAUlC,cAAcS,gBAAgBwB;IAC9C,MAAME,YAAYF,iBACdF,WAAYtB,mBAAmB,aAAa,CAACuB,YAC7C,CAACE;IAELhC,aAAa;QACX,IAAIkC,QAAQC,GAAG,CAACC,QAAQ,KAAK,QAAQ;YACnC;QACF;QAEA,IAAIC;QACJ,IAAI9B,mBAAmB,YAAYA,mBAAmB,WAAW;YAC/D,MAAM+B,WACJ/B,mBAAmB,WACfV,mBAAmB0C,cAAc,GACjC1C,mBAAmB2C,eAAe;YACxCH,QAAQ,CAAC,uBAAuB,EAAEC,SAAS,CAAC,CAAC;QAC/C,OAAO;YACLD,QAAQ9B;QACV;QAEA,MAAMkC,UAAUC,WAAWC,UAAU,CAAC;YACpC,IAAIC,QAAQ;YACZ,IAAK,IAAIC,IAAI,GAAGA,IAAIC,SAASC,WAAW,CAACC,MAAM,EAAEH,IAAK;gBACpD,MAAMI,QAAQH,SAASC,WAAW,CAACF,EAAE;gBAErC,IAAI;oBACF,MAAMK,QAAQD,MAAME,QAAQ;oBAC5B,KAAK,MAAMC,QAAQF,MAAO;wBACxB,IACEE,KAAKC,OAAO,CAACC,QAAQ,CAAC,kBACtBF,KAAKC,OAAO,CAACC,QAAQ,CAAC,CAAC,OAAO,EAAEjB,OAAO,GACvC;4BACAO,QAAQ;4BACR;wBACF;oBACF;gBACF,EAAE,OAAM;gBACN,EAAE;gBACJ;YACF;YAEA,IAAI,CAACA,SAAS,CAACzC,YAAY;gBACzBA,aAAa;gBACb,sCAAsC;gBACtCoD,QAAQC,KAAK,CACX,CAAC,0DAA0D,EAAEjD,eAAe,qDAAqD,CAAC,GAChI,oHACA,8HACA;YAEN;QACF,GAAG;QAEH,OAAO;YACLmC,WAAWe,YAAY,CAAChB;QAC1B;IACF,GAAG;QAAClC;KAAe;IAEnB,OAAO;QACLW;QACAe;QACAyB,YAAY/C,OAAO,CAACsB;QACpBjB;QACAC;QACAG;QACAE;QACAE;QACAE;QACAd,aAAa;YACX,GAAGA,WAAW;YACd,GAAIN,gBAAgBqB,eAAe,CAAC,CAAC;QACvC;QACAd,WAAW;YACT,GAAGA,SAAS;YACZ,GAAGc,YAAY;QACjB;QACAZ;QACA4C,oBAAoB;YAClBvC;YACAwC,cAAc,CAACtD;QACjB;QACAQ,gBAAgB;YACd,GAAGA,cAAc;YACjB+C;gBACE,IAAI5B,WAAW;oBACbhB;gBACF,OAAO;oBACLS;gBACF;YACF;YACAoC,WAAWpE,IAAIY,kBAAkB,YAAY;QAC/C;IACF;AACF"}
|
|
1
|
+
{"version":3,"sources":["../../src/layout/useExpandableLayout.ts"],"sourcesContent":["\"use client\";\n\nimport { cnb } from \"cnbuilder\";\n\nimport { useSsr } from \"../SsrProvider.js\";\nimport { useAppSize } from \"../media-queries/AppSizeProvider.js\";\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport { type AppSize } from \"../media-queries/appSize.js\";\nimport { MEDIA_QUERY_CONFIG } from \"../media-queries/config.js\";\nimport { useMediaQuery } from \"../media-queries/useMediaQuery.js\";\nimport { type CSSTransitionElementProps } from \"../transition/types.js\";\nimport {\n type CssPosition,\n type LiteralStringUnion,\n type UseStateInitializer,\n} from \"../types.js\";\nimport { useToggle } from \"../useToggle.js\";\nimport { useDevEffect } from \"../utils/useDevEffect.js\";\nimport { type LayoutNavProps } from \"./LayoutNav.js\";\nimport {\n type HorizontalLayoutTransitionOptions,\n useHorizontalLayoutTransition,\n} from \"./useHorizontalLayoutTransition.js\";\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport { type useResizableLayout } from \"./useResizableLayout.js\";\nimport {\n type ProvidedLayoutNavToggleProps,\n type ProvidedTemporaryLayoutAppBarProps,\n type ProvidedTemporaryLayoutMainProps,\n type TemporaryLayoutImplementation,\n type TemporaryLayoutOptions,\n useTemporaryLayout,\n} from \"./useTemporaryLayout.js\";\n\nlet loggedOnce = false;\n\n/**\n * @since 6.0.0\n */\nexport interface ExpandableLayoutOptions extends TemporaryLayoutOptions {\n /** @defaultValue `\"fixed\"` */\n appBarPosition?: CssPosition;\n\n /** @defaultValue `false` */\n defaultExpanded?: UseStateInitializer<boolean>;\n\n /**\n * Set this to `true` if the expandable navigation should be the full height\n * of the screen. This will also update the app bar so that it is not covered\n * by the navigation. The default behavior is to place the navigation below\n * the fixed header.\n *\n * Set this to `\"static\"` to make the navigation span the full height of the\n * screen and hide the button until the screen shrinks to the temporary\n * layout type.\n *\n * @defaultValue `false`\n */\n fullHeightNav?: boolean | \"static\";\n\n /** @see {@link HorizontalLayoutTransitionOptions} */\n transitionProps?: Omit<HorizontalLayoutTransitionOptions, \"transitionIn\">;\n\n /**\n * The default behavior is to use the temporary layout until the\n * {@link AppSize.isTablet} is `true`. Set this to `\"desktop\"` to use the\n * temporary layout until {@link AppSize.isDesktop} is `true`. Otherwise,\n * provide a media query string to use the temporary layout until the media\n * query matches\n *\n * @example Custom Media Query\n * ```tsx\n * useExpandableLayout({\n * ...options,\n * // display the expandable layout once the min-width is at least 1201px\n * temporaryUntil: \"screen and (min-width: 1201px)\",\n * });\n * ```\n *\n * @defaultValue `\"tablet\"`\n */\n temporaryUntil?: LiteralStringUnion<\"tablet\" | \"desktop\">;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface ProvidedLayoutMainProps\n extends\n ProvidedTemporaryLayoutMainProps,\n CSSTransitionElementProps<HTMLElement> {}\n\n/**\n * @since 6.0.0\n */\nexport type ProvidedLayoutNavProps = Pick<\n LayoutNavProps,\n \"expanded\" | \"appBarOffset\"\n>;\n\n/**\n * @since 6.0.0\n */\nexport type ProvidedLayoutAppBarProps = ProvidedTemporaryLayoutAppBarProps &\n Partial<CSSTransitionElementProps<HTMLElement>>;\n\n/**\n * @since 6.0.0\n */\nexport interface ProvidedExpandableLayoutNavToggleProps extends ProvidedLayoutNavToggleProps {\n className: string;\n}\n\n/**\n * @since 6.0.0\n */\nexport interface ExpandableLayoutImplementation extends TemporaryLayoutImplementation {\n temporary: boolean;\n persistent: boolean;\n expanded: boolean;\n expandNavigation: () => void;\n collapseNavigation: () => void;\n toggleNavigation: () => void;\n appBarProps: ProvidedLayoutAppBarProps;\n mainProps: ProvidedLayoutMainProps;\n navToggleProps: ProvidedExpandableLayoutNavToggleProps;\n expandableNavProps: ProvidedLayoutNavProps;\n}\n\n/**\n * @example Main Usage\n * ```tsx\n * import { AppBarTitle } from \"@react-md/core/app-bar/AppBarTitle\";\n * import { Button } from \"@react-md/core/button/Button\";\n * import { LayoutAppBar } from \"@react-md/core/layout/LayoutAppBar\";\n * import { LayoutNav } from \"@react-md/core/layout/LayoutNav\";\n * import { Main } from \"@react-md/core/layout/Main\";\n * import { useExpandableLayout } from \"@react-md/core/layout/useExpandableLayout\";\n * import { Sheet } from \"@react-md/core/sheet/Sheet\";\n * import { type ReactElement, type ReactNode } from \"react\";\n *\n * import { CustomNavigation } from \"./CustomNavigation\";\n *\n * export interface LayoutProps {\n * children: ReactNode;\n * }\n *\n * export function Layout(props: LayoutProps): ReactElement {\n * const { children } = props;\n *\n * // choose whichever one for your app\n * // nextjs app dir\n * const pathname = usePathname();\n * // nextjs pages\n * const { pathname } = useRouter();\n * // react router\n * const { pathname } = useHistory();\n *\n * const {\n * temporary,\n * appBarProps,\n * expandableNavProps,\n * mainProps,\n * navToggleProps,\n * temporaryNavProps,\n * windowSplitterProps,\n * } = useExpandableLayout({ pathname });\n *\n * return (\n * <>\n * <LayoutAppBar {...appBarProps}>\n * <Button {...navToggleProps} />\n * <AppBarTitle>Hello, world!</AppBarTitle>\n * </LayoutAppBar>\n * <LayoutNav {...expandableNavProps}>\n * <CustomNavigation />\n * </LayoutNav>\n * {temporary && (\n * <Sheet {...temporaryNavProps}>\n * <CustomNavigation />\n * </Sheet>\n * )}\n * <Main {...mainProps}>{children}</Main>\n * </>\n * );\n * }\n * ```\n *\n * If you have a large navigation panel, you can conditionally render the\n * `LayoutNav` with the `persistent` boolean returned by the hook which will\n * ensure that the DOM has rehydrated before unmounting to prevent SSR errors.\n *\n * @example Safely Conditionally Rendering\n * ```diff\n * const {\n * temporary,\n * + persistent,\n * appBarProps,\n * expandableNavProps,\n * mainProps,\n * navToggleProps,\n * temporaryNavProps,\n * windowSplitterProps,\n * } = useExpandableLayout({ pathname });\n *\n * return (\n * <>\n * <LayoutAppBar {...appBarProps}>\n * <Button {...navToggleProps} />\n * <AppBarTitle>Hello, world!</AppBarTitle>\n * </LayoutAppBar>\n * - <LayoutNav {...expandableNavProps}>\n * - <CustomNavigation />\n * - </LayoutNav>\n * + {persistent && (\n * + <LayoutNav {...expandableNavProps}>\n * + <CustomNavigation />\n * + </LayoutNav>\n * + )}\n * {temporary && (\n * <Sheet {...temporaryNavProps}>\n * <CustomNavigation />\n * </Sheet>\n * )}\n * <Main {...mainProps}>{children}</Main>\n * </>\n * );\n * ```\n *\n * @see {@link https://react-md.dev/getting-started/layout | Layout Demos}\n * @since 6.0.0\n * @see {@link useResizableLayout}\n */\nexport function useExpandableLayout(\n options: ExpandableLayoutOptions\n): ExpandableLayoutImplementation {\n const {\n fullHeightNav = false,\n temporaryUntil = \"tablet\",\n transitionProps,\n defaultExpanded = fullHeightNav === \"static\",\n ...temporaryOptions\n } = options;\n\n const ssr = useSsr();\n const {\n appBarProps,\n mainProps,\n navToggleProps,\n temporaryNavProps,\n hideTemporaryNav,\n showTemporaryNav,\n visible,\n } = useTemporaryLayout(temporaryOptions);\n\n const {\n toggled: expanded,\n enable: expandNavigation,\n disable: collapseNavigation,\n toggle: toggleNavigation,\n } = useToggle(defaultExpanded);\n const { elementProps } = useHorizontalLayoutTransition({\n ...transitionProps,\n transitionIn: expanded,\n });\n const { isPhone, isDesktop } = useAppSize();\n const isAppSizeMatch =\n temporaryUntil === \"tablet\" || temporaryUntil === \"desktop\";\n const matches = useMediaQuery(temporaryUntil, isAppSizeMatch);\n const temporary = isAppSizeMatch\n ? isPhone || (temporaryUntil === \"desktop\" && !isDesktop)\n : !matches;\n\n useDevEffect(() => {\n if (process.env.NODE_ENV === \"test\") {\n return;\n }\n\n let query: string;\n if (temporaryUntil === \"tablet\" || temporaryUntil === \"desktop\") {\n const minWidth =\n temporaryUntil === \"tablet\"\n ? MEDIA_QUERY_CONFIG.tabletMinWidth\n : MEDIA_QUERY_CONFIG.desktopMinWidth;\n query = `screen and (min-width: ${minWidth})`;\n } else {\n query = temporaryUntil;\n }\n\n const timeout = globalThis.setTimeout(() => {\n let found = false;\n for (let i = 0; i < document.styleSheets.length; i++) {\n const sheet = document.styleSheets[i];\n\n try {\n const rules = sheet.cssRules;\n for (const rule of rules) {\n if (\n rule.cssText.includes(\".rmd-layout\") &&\n rule.cssText.includes(`@media ${query}`)\n ) {\n found = true;\n return;\n }\n }\n } catch {\n //\n }\n }\n\n if (!found && !loggedOnce) {\n loggedOnce = true;\n // eslint-disable-next-line no-console\n console.error(\n `The react-md expandable layout has set \\`temporaryUntil: \"${temporaryUntil}\"\\` but the corresponding styles have not been found.` +\n \" This usually means the `$layout-navigation-breakpoint` or `temporaryUntil` value should be updated match.\\n\\n\" +\n \"See https://react-md.dev/getting-started/layout#updating-the-layout-to-be-temporary-until-a-specific-breakpoint-optional \" +\n \"for more information.\"\n );\n }\n }, 3000);\n\n return () => {\n globalThis.clearTimeout(timeout);\n };\n }, [temporaryUntil]);\n\n return {\n visible,\n temporary,\n persistent: ssr || !temporary,\n hideTemporaryNav,\n showTemporaryNav,\n expanded,\n expandNavigation,\n collapseNavigation,\n toggleNavigation,\n appBarProps: {\n ...appBarProps,\n ...(fullHeightNav ? elementProps : {}),\n },\n mainProps: {\n ...mainProps,\n ...elementProps,\n },\n temporaryNavProps,\n expandableNavProps: {\n expanded,\n appBarOffset: !fullHeightNav,\n },\n navToggleProps: {\n ...navToggleProps,\n onClick() {\n if (temporary) {\n showTemporaryNav();\n } else {\n toggleNavigation();\n }\n },\n className: cnb(fullHeightNav === \"static\" && \"rmd-layout-nav-toggle\"),\n },\n };\n}\n"],"names":["cnb","useSsr","useAppSize","MEDIA_QUERY_CONFIG","useMediaQuery","useToggle","useDevEffect","useHorizontalLayoutTransition","useTemporaryLayout","loggedOnce","useExpandableLayout","options","fullHeightNav","temporaryUntil","transitionProps","defaultExpanded","temporaryOptions","ssr","appBarProps","mainProps","navToggleProps","temporaryNavProps","hideTemporaryNav","showTemporaryNav","visible","toggled","expanded","enable","expandNavigation","disable","collapseNavigation","toggle","toggleNavigation","elementProps","transitionIn","isPhone","isDesktop","isAppSizeMatch","matches","temporary","process","env","NODE_ENV","query","minWidth","tabletMinWidth","desktopMinWidth","timeout","globalThis","setTimeout","found","i","document","styleSheets","length","sheet","rules","cssRules","rule","cssText","includes","console","error","clearTimeout","persistent","expandableNavProps","appBarOffset","onClick","className"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/menu/MenuItemButton.tsx"],"sourcesContent":["\"use client\";\n\nimport { type ReactElement, useEffect } from \"react\";\n\nimport { useHoverMode } from \"../hoverMode/useHoverMode.js\";\nimport { IconRotator } from \"../icon/IconRotator.js\";\nimport { getIcon } from \"../icon/config.js\";\nimport { useUserInteractionMode } from \"../interaction/UserInteractionModeProvider.js\";\nimport { useAppSize } from \"../media-queries/AppSizeProvider.js\";\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport { type BaseMenuButtonProps } from \"./MenuButton.js\";\nimport { useMenuConfiguration } from \"./MenuConfigurationProvider.js\";\nimport { MenuItem, type MenuItemProps } from \"./MenuItem.js\";\nimport { useMenuVisibility } from \"./MenuVisibilityProvider.js\";\nimport { useMenuBarContext } from \"./useMenuBarProvider.js\";\n\nconst noop = (): void => {\n // do nothing\n};\n\n/**\n * @internal\n * @since 5.0.0\n */\nexport interface MenuItemButtonProps\n extends BaseMenuButtonProps, MenuItemProps {}\n\n/**\n * **Client Component**\n *\n * This is just an internal component that handles rendering a submenu as a\n * menuitem for a `DropdownMenu` with a conditional dropdown icon.\n *\n * @internal\n * @since 5.0.0\n */\nexport function MenuItemButton(props: MenuItemButtonProps): ReactElement {\n const {\n ref,\n id: propId,\n children,\n height: propHeight,\n onClick = noop,\n onKeyDown = noop,\n onMouseEnter = noop,\n onMouseLeave = noop,\n rightAddon: propRightAddon,\n iconRotatorProps,\n disableDropdownIcon = propRightAddon !== undefined,\n ...remaining\n } = props;\n const { disabled } = props;\n\n const id = useEnsuredId(propId, \"menuitem\");\n const mode = useUserInteractionMode();\n const { renderAsSheet } = useMenuConfiguration();\n const { isPhone } = useAppSize();\n const isSheet =\n renderAsSheet === true || (renderAsSheet === \"phone\" && isPhone);\n const {\n root,\n menubar,\n activeId,\n enableHoverMode,\n disableHoverMode,\n startDisableTimer,\n clearDisableTimer,\n leaveTimeoutRef,\n hoverTimeoutRef,\n } = useMenuBarContext();\n const { visible, setVisible, defaultFocusIndex } = useMenuVisibility();\n const { startShowFlow, clearVisibilityTimeout } = useHoverMode({\n setVisible,\n enableHoverMode,\n disableHoverMode,\n startDisableTimer,\n leaveTimeoutRef,\n hoverTimeoutRef,\n clearDisableTimer,\n });\n const { horizontal } = useMenuConfiguration();\n\n useEffect(() => {\n setVisible(id === activeId);\n }, [activeId, defaultFocusIndex, id, menubar, setVisible]);\n\n let height = propHeight;\n let rightAddon = propRightAddon;\n const dropdownIcon = getIcon(root ? \"dropdown\" : \"forward\");\n if (!disableDropdownIcon) {\n if (!height && !props.leftAddon) {\n height = \"normal\";\n }\n\n rightAddon = (\n <IconRotator {...iconRotatorProps} rotated={visible}>\n {dropdownIcon}\n </IconRotator>\n );\n }\n\n const updateVisibility = (nextVisible: boolean, focusIndex = 0): void => {\n defaultFocusIndex.current = focusIndex;\n setVisible(nextVisible);\n if (!menubar) {\n return;\n }\n\n if (nextVisible) {\n enableHoverMode(id);\n } else {\n disableHoverMode();\n }\n };\n\n return (\n <MenuItem\n {...remaining}\n aria-haspopup={isSheet ? \"dialog\" : \"menu\"}\n aria-expanded={visible || undefined}\n id={id}\n ref={ref}\n rightAddon={rightAddon}\n onClick={(event) => {\n onClick(event);\n\n event.stopPropagation();\n updateVisibility(!visible);\n }}\n onKeyDown={(event) => {\n onKeyDown(event);\n\n switch (event.key) {\n case \"ArrowDown\":\n if (horizontal || root) {\n event.preventDefault();\n event.stopPropagation();\n updateVisibility(true);\n }\n break;\n case \"ArrowRight\":\n if (!horizontal && !root) {\n event.preventDefault();\n event.stopPropagation();\n updateVisibility(true);\n }\n break;\n }\n }}\n onMouseEnter={(event) => {\n onMouseEnter(event);\n if (mode === \"touch\" || disabled || !menubar) {\n return;\n }\n\n defaultFocusIndex.current = 0;\n startShowFlow(id);\n }}\n onMouseLeave={(event) => {\n onMouseLeave(event);\n if (mode === \"touch\" || disabled || !menubar) {\n return;\n }\n\n clearVisibilityTimeout();\n }}\n >\n {children}\n </MenuItem>\n );\n}\n"],"names":["useEffect","useHoverMode","IconRotator","getIcon","useUserInteractionMode","useAppSize","useEnsuredId","useMenuConfiguration","MenuItem","useMenuVisibility","useMenuBarContext","noop","MenuItemButton","props","ref","id","propId","children","height","propHeight","onClick","onKeyDown","onMouseEnter","onMouseLeave","rightAddon","propRightAddon","iconRotatorProps","disableDropdownIcon","undefined","remaining","disabled","mode","renderAsSheet","isPhone","isSheet","root","menubar","activeId","enableHoverMode","disableHoverMode","startDisableTimer","clearDisableTimer","leaveTimeoutRef","hoverTimeoutRef","visible","setVisible","defaultFocusIndex","startShowFlow","clearVisibilityTimeout","horizontal","dropdownIcon","leftAddon","rotated","updateVisibility","nextVisible","focusIndex","current","aria-haspopup","aria-expanded","event","stopPropagation","key","preventDefault"],"mappings":"AAAA;;AAEA,SAA4BA,SAAS,QAAQ,QAAQ;AAErD,SAASC,YAAY,QAAQ,+BAA+B;AAC5D,SAASC,WAAW,QAAQ,yBAAyB;AACrD,SAASC,OAAO,QAAQ,oBAAoB;AAC5C,SAASC,sBAAsB,QAAQ,gDAAgD;AACvF,SAASC,UAAU,QAAQ,sCAAsC;AACjE,SAASC,YAAY,QAAQ,qBAAqB;AAElD,SAASC,oBAAoB,QAAQ,iCAAiC;AACtE,SAASC,QAAQ,QAA4B,gBAAgB;AAC7D,SAASC,iBAAiB,QAAQ,8BAA8B;AAChE,SAASC,iBAAiB,QAAQ,0BAA0B;AAE5D,MAAMC,OAAO;AACX,aAAa;AACf;AASA;;;;;;;;CAQC,GACD,OAAO,SAASC,eAAeC,KAA0B;IACvD,MAAM,EACJC,GAAG,EACHC,IAAIC,MAAM,EACVC,QAAQ,EACRC,QAAQC,UAAU,EAClBC,UAAUT,IAAI,EACdU,YAAYV,IAAI,EAChBW,eAAeX,IAAI,EACnBY,eAAeZ,IAAI,EACnBa,YAAYC,cAAc,EAC1BC,gBAAgB,EAChBC,sBAAsBF,mBAAmBG,SAAS,EAClD,GAAGC,WACJ,GAAGhB;IACJ,MAAM,EAAEiB,QAAQ,EAAE,GAAGjB;IAErB,MAAME,KAAKT,aAAaU,QAAQ;IAChC,MAAMe,OAAO3B;IACb,MAAM,EAAE4B,aAAa,EAAE,GAAGzB;IAC1B,MAAM,EAAE0B,OAAO,EAAE,GAAG5B;IACpB,MAAM6B,UACJF,kBAAkB,QAASA,kBAAkB,WAAWC;IAC1D,MAAM,EACJE,IAAI,EACJC,OAAO,EACPC,QAAQ,EACRC,eAAe,EACfC,gBAAgB,EAChBC,iBAAiB,EACjBC,iBAAiB,EACjBC,eAAe,EACfC,eAAe,EAChB,GAAGjC;IACJ,MAAM,EAAEkC,OAAO,EAAEC,UAAU,EAAEC,iBAAiB,EAAE,GAAGrC;IACnD,MAAM,EAAEsC,aAAa,EAAEC,sBAAsB,EAAE,GAAG/C,aAAa;QAC7D4C;QACAP;QACAC;QACAC;QACAE;QACAC;QACAF;IACF;IACA,MAAM,EAAEQ,UAAU,EAAE,GAAG1C;IAEvBP,UAAU;QACR6C,WAAW9B,OAAOsB;IACpB,GAAG;QAACA;QAAUS;QAAmB/B;QAAIqB;QAASS;KAAW;IAEzD,IAAI3B,SAASC;IACb,IAAIK,aAAaC;IACjB,MAAMyB,eAAe/C,QAAQgC,OAAO,aAAa;IACjD,IAAI,CAACR,qBAAqB;QACxB,IAAI,CAACT,UAAU,CAACL,MAAMsC,SAAS,EAAE;YAC/BjC,SAAS;QACX;QAEAM,2BACE,KAACtB;YAAa,GAAGwB,gBAAgB;YAAE0B,SAASR;sBACzCM;;IAGP;IAEA,MAAMG,mBAAmB,CAACC,aAAsBC,aAAa,CAAC;QAC5DT,kBAAkBU,OAAO,GAAGD;QAC5BV,WAAWS;QACX,IAAI,CAAClB,SAAS;YACZ;QACF;QAEA,IAAIkB,aAAa;YACfhB,gBAAgBvB;QAClB,OAAO;YACLwB;QACF;IACF;IAEA,qBACE,KAAC/B;QACE,GAAGqB,SAAS;QACb4B,iBAAevB,UAAU,WAAW;QACpCwB,iBAAed,WAAWhB;QAC1Bb,IAAIA;QACJD,KAAKA;
|
|
1
|
+
{"version":3,"sources":["../../src/menu/MenuItemButton.tsx"],"sourcesContent":["\"use client\";\n\nimport { type ReactElement, useEffect } from \"react\";\n\nimport { useHoverMode } from \"../hoverMode/useHoverMode.js\";\nimport { IconRotator } from \"../icon/IconRotator.js\";\nimport { getIcon } from \"../icon/config.js\";\nimport { useUserInteractionMode } from \"../interaction/UserInteractionModeProvider.js\";\nimport { useAppSize } from \"../media-queries/AppSizeProvider.js\";\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport { type BaseMenuButtonProps } from \"./MenuButton.js\";\nimport { useMenuConfiguration } from \"./MenuConfigurationProvider.js\";\nimport { MenuItem, type MenuItemProps } from \"./MenuItem.js\";\nimport { useMenuVisibility } from \"./MenuVisibilityProvider.js\";\nimport { useMenuBarContext } from \"./useMenuBarProvider.js\";\n\nconst noop = (): void => {\n // do nothing\n};\n\n/**\n * @internal\n * @since 5.0.0\n */\nexport interface MenuItemButtonProps\n extends BaseMenuButtonProps, MenuItemProps {}\n\n/**\n * **Client Component**\n *\n * This is just an internal component that handles rendering a submenu as a\n * menuitem for a `DropdownMenu` with a conditional dropdown icon.\n *\n * @internal\n * @since 5.0.0\n */\nexport function MenuItemButton(props: MenuItemButtonProps): ReactElement {\n const {\n ref,\n id: propId,\n children,\n height: propHeight,\n onClick = noop,\n onKeyDown = noop,\n onMouseEnter = noop,\n onMouseLeave = noop,\n rightAddon: propRightAddon,\n iconRotatorProps,\n disableDropdownIcon = propRightAddon !== undefined,\n ...remaining\n } = props;\n const { disabled } = props;\n\n const id = useEnsuredId(propId, \"menuitem\");\n const mode = useUserInteractionMode();\n const { renderAsSheet } = useMenuConfiguration();\n const { isPhone } = useAppSize();\n const isSheet =\n renderAsSheet === true || (renderAsSheet === \"phone\" && isPhone);\n const {\n root,\n menubar,\n activeId,\n enableHoverMode,\n disableHoverMode,\n startDisableTimer,\n clearDisableTimer,\n leaveTimeoutRef,\n hoverTimeoutRef,\n } = useMenuBarContext();\n const { visible, setVisible, defaultFocusIndex } = useMenuVisibility();\n const { startShowFlow, clearVisibilityTimeout } = useHoverMode({\n setVisible,\n enableHoverMode,\n disableHoverMode,\n startDisableTimer,\n leaveTimeoutRef,\n hoverTimeoutRef,\n clearDisableTimer,\n });\n const { horizontal } = useMenuConfiguration();\n\n useEffect(() => {\n setVisible(id === activeId);\n }, [activeId, defaultFocusIndex, id, menubar, setVisible]);\n\n let height = propHeight;\n let rightAddon = propRightAddon;\n const dropdownIcon = getIcon(root ? \"dropdown\" : \"forward\");\n if (!disableDropdownIcon) {\n if (!height && !props.leftAddon) {\n height = \"normal\";\n }\n\n rightAddon = (\n <IconRotator {...iconRotatorProps} rotated={visible}>\n {dropdownIcon}\n </IconRotator>\n );\n }\n\n const updateVisibility = (nextVisible: boolean, focusIndex = 0): void => {\n defaultFocusIndex.current = focusIndex;\n setVisible(nextVisible);\n if (!menubar) {\n return;\n }\n\n if (nextVisible) {\n enableHoverMode(id);\n } else {\n disableHoverMode();\n }\n };\n\n return (\n <MenuItem\n {...remaining}\n aria-haspopup={isSheet ? \"dialog\" : \"menu\"}\n aria-expanded={visible || undefined}\n id={id}\n ref={ref}\n height={height}\n rightAddon={rightAddon}\n onClick={(event) => {\n onClick(event);\n\n event.stopPropagation();\n updateVisibility(!visible);\n }}\n onKeyDown={(event) => {\n onKeyDown(event);\n\n switch (event.key) {\n case \"ArrowDown\":\n if (horizontal || root) {\n event.preventDefault();\n event.stopPropagation();\n updateVisibility(true);\n }\n break;\n case \"ArrowRight\":\n if (!horizontal && !root) {\n event.preventDefault();\n event.stopPropagation();\n updateVisibility(true);\n }\n break;\n }\n }}\n onMouseEnter={(event) => {\n onMouseEnter(event);\n if (mode === \"touch\" || disabled || !menubar) {\n return;\n }\n\n defaultFocusIndex.current = 0;\n startShowFlow(id);\n }}\n onMouseLeave={(event) => {\n onMouseLeave(event);\n if (mode === \"touch\" || disabled || !menubar) {\n return;\n }\n\n clearVisibilityTimeout();\n }}\n >\n {children}\n </MenuItem>\n );\n}\n"],"names":["useEffect","useHoverMode","IconRotator","getIcon","useUserInteractionMode","useAppSize","useEnsuredId","useMenuConfiguration","MenuItem","useMenuVisibility","useMenuBarContext","noop","MenuItemButton","props","ref","id","propId","children","height","propHeight","onClick","onKeyDown","onMouseEnter","onMouseLeave","rightAddon","propRightAddon","iconRotatorProps","disableDropdownIcon","undefined","remaining","disabled","mode","renderAsSheet","isPhone","isSheet","root","menubar","activeId","enableHoverMode","disableHoverMode","startDisableTimer","clearDisableTimer","leaveTimeoutRef","hoverTimeoutRef","visible","setVisible","defaultFocusIndex","startShowFlow","clearVisibilityTimeout","horizontal","dropdownIcon","leftAddon","rotated","updateVisibility","nextVisible","focusIndex","current","aria-haspopup","aria-expanded","event","stopPropagation","key","preventDefault"],"mappings":"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"}
|
|
@@ -34,7 +34,7 @@ const noop = ()=>{
|
|
|
34
34
|
// elements to be removed from the DOM, a normal `<input type="file" />`
|
|
35
35
|
// can't be used. Instead, create a temporary file input element and
|
|
36
36
|
// click it to trigger the file upload behavior.
|
|
37
|
-
|
|
37
|
+
const input = document.createElement("input");
|
|
38
38
|
input.type = "file";
|
|
39
39
|
if (accept) {
|
|
40
40
|
input.accept = accept;
|
|
@@ -49,7 +49,6 @@ const noop = ()=>{
|
|
|
49
49
|
// @ts-expect-error
|
|
50
50
|
input.addEventListener("change", onChange);
|
|
51
51
|
input.click();
|
|
52
|
-
input = null;
|
|
53
52
|
},
|
|
54
53
|
children: children
|
|
55
54
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/menu/MenuItemFileInput.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n type ChangeEventHandler,\n type InputHTMLAttributes,\n type ReactElement,\n} from \"react\";\n\nimport { getIcon } from \"../icon/config.js\";\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport { MenuItem, type MenuItemProps } from \"./MenuItem.js\";\n\nconst noop = (): void => {\n // do nothing\n};\n\n/**\n * @since 6.0.0 Removed most of the shared `FileInputProps` from this\n * implementation.\n */\nexport interface MenuItemFileInputProps\n extends\n Omit<MenuItemProps, \"onChange\">,\n Pick<\n InputHTMLAttributes<HTMLInputElement>,\n \"accept\" | \"capture\" | \"multiple\"\n > {\n /**\n * A change event handler that should do something with the selected files.\n * Usually the `onChange` returned by `useFileUpload` or:\n *\n * ```ts\n * onChange={(event) => {\n * const { files } = event.currentTarget;\n * // do something with files\n * }}\n * ```\n *\n * This is actually a native `Event` and not a `SyntheticEvent` because the\n * file input is created through `document.createElement` instead of `React`.\n * You can still access the files through `event.currentTarget.files` like\n * normal.\n */\n onChange: ChangeEventHandler<HTMLInputElement>;\n\n /**\n * Set this to `true` if the `Menu` should not close when the file input's\n * menu item is clicked.\n *\n * @defaultValue `false`\n */\n preventMenuHideOnClick?: boolean;\n}\n\n/**\n * **Client Component**\n *\n * A wrapper for the `<input type=\"file\">` element that works within menus.\n *\n * @see {@link https://react-md.dev/components/menu#menuitemfileinput-example | DropdownMenu Demos}\n * @since 5.0.0\n * @since 6.0.0 No longer creates an invisible file input element within the\n * menu item. This allows the menu to be closed immediately when this menu item\n * is clicked.\n */\nexport function MenuItemFileInput(props: MenuItemFileInputProps): ReactElement {\n const {\n ref,\n id: propId,\n onClick = noop,\n onChange,\n accept,\n capture,\n multiple,\n children,\n leftAddon: propLeftAddon,\n preventMenuHideOnClick = false,\n ...remaining\n } = props;\n\n const id = useEnsuredId(propId, \"menu-item\");\n const leftAddon = getIcon(\"upload\", propLeftAddon);\n\n return (\n <MenuItem\n {...remaining}\n id={id}\n ref={ref}\n leftAddon={leftAddon}\n onClick={(event) => {\n onClick(event);\n\n if (preventMenuHideOnClick) {\n event.stopPropagation();\n }\n\n // Since the menu closes when the menu item is clicked causing the\n // elements to be removed from the DOM, a normal `<input type=\"file\" />`\n // can't be used. Instead, create a temporary file input element and\n // click it to trigger the file upload behavior.\n
|
|
1
|
+
{"version":3,"sources":["../../src/menu/MenuItemFileInput.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n type ChangeEventHandler,\n type InputHTMLAttributes,\n type ReactElement,\n} from \"react\";\n\nimport { getIcon } from \"../icon/config.js\";\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport { MenuItem, type MenuItemProps } from \"./MenuItem.js\";\n\nconst noop = (): void => {\n // do nothing\n};\n\n/**\n * @since 6.0.0 Removed most of the shared `FileInputProps` from this\n * implementation.\n */\nexport interface MenuItemFileInputProps\n extends\n Omit<MenuItemProps, \"onChange\">,\n Pick<\n InputHTMLAttributes<HTMLInputElement>,\n \"accept\" | \"capture\" | \"multiple\"\n > {\n /**\n * A change event handler that should do something with the selected files.\n * Usually the `onChange` returned by `useFileUpload` or:\n *\n * ```ts\n * onChange={(event) => {\n * const { files } = event.currentTarget;\n * // do something with files\n * }}\n * ```\n *\n * This is actually a native `Event` and not a `SyntheticEvent` because the\n * file input is created through `document.createElement` instead of `React`.\n * You can still access the files through `event.currentTarget.files` like\n * normal.\n */\n onChange: ChangeEventHandler<HTMLInputElement>;\n\n /**\n * Set this to `true` if the `Menu` should not close when the file input's\n * menu item is clicked.\n *\n * @defaultValue `false`\n */\n preventMenuHideOnClick?: boolean;\n}\n\n/**\n * **Client Component**\n *\n * A wrapper for the `<input type=\"file\">` element that works within menus.\n *\n * @see {@link https://react-md.dev/components/menu#menuitemfileinput-example | DropdownMenu Demos}\n * @since 5.0.0\n * @since 6.0.0 No longer creates an invisible file input element within the\n * menu item. This allows the menu to be closed immediately when this menu item\n * is clicked.\n */\nexport function MenuItemFileInput(props: MenuItemFileInputProps): ReactElement {\n const {\n ref,\n id: propId,\n onClick = noop,\n onChange,\n accept,\n capture,\n multiple,\n children,\n leftAddon: propLeftAddon,\n preventMenuHideOnClick = false,\n ...remaining\n } = props;\n\n const id = useEnsuredId(propId, \"menu-item\");\n const leftAddon = getIcon(\"upload\", propLeftAddon);\n\n return (\n <MenuItem\n {...remaining}\n id={id}\n ref={ref}\n leftAddon={leftAddon}\n onClick={(event) => {\n onClick(event);\n\n if (preventMenuHideOnClick) {\n event.stopPropagation();\n }\n\n // Since the menu closes when the menu item is clicked causing the\n // elements to be removed from the DOM, a normal `<input type=\"file\" />`\n // can't be used. Instead, create a temporary file input element and\n // click it to trigger the file upload behavior.\n const input = document.createElement(\"input\");\n input.type = \"file\";\n if (accept) {\n input.accept = accept;\n }\n if (multiple) {\n input.multiple = multiple;\n }\n if (capture) {\n input.capture = capture === true ? \"\" : capture;\n }\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n input.addEventListener(\"change\", onChange);\n input.click();\n }}\n >\n {children}\n </MenuItem>\n );\n}\n"],"names":["getIcon","useEnsuredId","MenuItem","noop","MenuItemFileInput","props","ref","id","propId","onClick","onChange","accept","capture","multiple","children","leftAddon","propLeftAddon","preventMenuHideOnClick","remaining","event","stopPropagation","input","document","createElement","type","addEventListener","click"],"mappings":"AAAA;;AAQA,SAASA,OAAO,QAAQ,oBAAoB;AAC5C,SAASC,YAAY,QAAQ,qBAAqB;AAClD,SAASC,QAAQ,QAA4B,gBAAgB;AAE7D,MAAMC,OAAO;AACX,aAAa;AACf;AAwCA;;;;;;;;;;CAUC,GACD,OAAO,SAASC,kBAAkBC,KAA6B;IAC7D,MAAM,EACJC,GAAG,EACHC,IAAIC,MAAM,EACVC,UAAUN,IAAI,EACdO,QAAQ,EACRC,MAAM,EACNC,OAAO,EACPC,QAAQ,EACRC,QAAQ,EACRC,WAAWC,aAAa,EACxBC,yBAAyB,KAAK,EAC9B,GAAGC,WACJ,GAAGb;IAEJ,MAAME,KAAKN,aAAaO,QAAQ;IAChC,MAAMO,YAAYf,QAAQ,UAAUgB;IAEpC,qBACE,KAACd;QACE,GAAGgB,SAAS;QACbX,IAAIA;QACJD,KAAKA;QACLS,WAAWA;QACXN,SAAS,CAACU;YACRV,QAAQU;YAER,IAAIF,wBAAwB;gBAC1BE,MAAMC,eAAe;YACvB;YAEA,kEAAkE;YAClE,wEAAwE;YACxE,oEAAoE;YACpE,gDAAgD;YAChD,MAAMC,QAAQC,SAASC,aAAa,CAAC;YACrCF,MAAMG,IAAI,GAAG;YACb,IAAIb,QAAQ;gBACVU,MAAMV,MAAM,GAAGA;YACjB;YACA,IAAIE,UAAU;gBACZQ,MAAMR,QAAQ,GAAGA;YACnB;YACA,IAAID,SAAS;gBACXS,MAAMT,OAAO,GAAGA,YAAY,OAAO,KAAKA;YAC1C;YAEA,6DAA6D;YAC7D,mBAAmB;YACnBS,MAAMI,gBAAgB,CAAC,UAAUf;YACjCW,MAAMK,KAAK;QACb;kBAECZ;;AAGP"}
|
|
@@ -24,7 +24,7 @@ const noop = ()=>{
|
|
|
24
24
|
*/ export function MenuItemInputToggle(props) {
|
|
25
25
|
const { ref, id: propId, type, disabled = false, checked, onCheckedChange, preventMenuHideOnClick = false, onClick = noop, className, tabIndex = -1, children, size = "auto", icon: propIcon, iconAfter = false, iconProps, iconStyle, iconClassName, checkedIcon, indeterminate, indeterminateIcon, addon, addonType, addonPosition, addonForceWrap, disableAddonCenteredMedia, ballProps, ballStyle, ballClassName, trackProps, trackStyle, trackClassName, ...remaining } = props;
|
|
26
26
|
const id = useEnsuredId(propId, "menu-item");
|
|
27
|
-
let icon
|
|
27
|
+
let icon;
|
|
28
28
|
if (type === "switch") {
|
|
29
29
|
icon = /*#__PURE__*/ _jsx(SwitchTrack, {
|
|
30
30
|
style: trackStyle,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/menu/MenuItemInputToggle.tsx"],"sourcesContent":["\"use client\";\n\nimport { cnb } from \"cnbuilder\";\nimport {\n type CSSProperties,\n type HTMLAttributes,\n type MouseEvent,\n type ReactElement,\n type ReactNode,\n type Ref,\n} from \"react\";\n\nimport {\n type ConfigurableInputToggleIconProps,\n type IndeterminateCheckboxProps,\n} from \"../form/InputToggle.js\";\nimport { InputToggleIcon } from \"../form/InputToggleIcon.js\";\nimport { SwitchTrack } from \"../form/SwitchTrack.js\";\nimport { type InputToggleSize } from \"../form/inputToggleStyles.js\";\nimport { ListItem } from \"../list/ListItem.js\";\nimport {\n type ListItemAddonPosition,\n type ListItemAddonType,\n type ListItemChildrenTextProps,\n type ListItemHeight,\n} from \"../list/types.js\";\nimport { type PropsWithRef } from \"../types.js\";\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport {\n menuItemInputToggle,\n menuItemInputToggleBall,\n menuItemInputToggleIcon,\n menuItemInputToggleTrack,\n} from \"./styles.js\";\n\nconst noop = (): void => {\n // do nothing\n};\n\n/**\n * @since 6.0.0\n */\nexport type MenuItemInputToggleCheckedCallback = (\n checked: boolean,\n event: MouseEvent<HTMLLIElement>\n) => void;\n\n/** @since 2.8.0 */\nexport interface BaseMenuItemInputToggleProps\n extends\n HTMLAttributes<HTMLLIElement>,\n ConfigurableInputToggleIconProps,\n ListItemChildrenTextProps {\n ref?: Ref<HTMLLIElement>;\n checked: boolean;\n onCheckedChange: MenuItemInputToggleCheckedCallback;\n\n /**\n * @defaultValue `\"menu-item-\" + useId()`\n */\n id?: string;\n\n /** @defaultValue `false` */\n disabled?: boolean;\n\n /**\n * Set this to `true` if the `Menu` should not close when the input toggle is\n * clicked. This can be useful when interacting with a checkbox group within a\n * menu or allowing the user to select multiple options before closing the\n * menu.\n *\n * @defaultValue `false`\n */\n preventMenuHideOnClick?: boolean;\n\n /**\n * This is set to `\"auto\"` by default so the icon shrinks back down to the\n * default icon size instead of relative to the current font size. You\n * probably don't want to change this since it'll also modify the height of\n * the menu item\n *\n * @defaultValue `\"auto\"`\n */\n size?: InputToggleSize;\n\n /** @defaultValue `\"auto\"` */\n height?: ListItemHeight;\n\n /** @defaultValue `false` */\n iconAfter?: boolean;\n\n addon?: ReactNode;\n addonType?: ListItemAddonType;\n addonPosition?: ListItemAddonPosition;\n\n /** @defaultValue `false` */\n addonForceWrap?: boolean;\n\n /** @defaultValue `false` */\n disableAddonCenteredMedia?: boolean;\n}\n\nexport interface MenuItemCheckboxProps\n extends BaseMenuItemInputToggleProps, IndeterminateCheckboxProps {}\n\nexport type MenuItemRadioProps = BaseMenuItemInputToggleProps;\n\n/**\n * @since 2.8.0\n * @since 6.0.0 Added additional props for styling the track and ball.\n */\nexport interface MenuItemSwitchProps extends BaseMenuItemInputToggleProps {\n trackProps?: PropsWithRef<HTMLAttributes<HTMLDivElement>>;\n trackStyle?: CSSProperties;\n trackClassName?: string;\n ballProps?: PropsWithRef<HTMLAttributes<HTMLSpanElement>>;\n ballStyle?: CSSProperties;\n ballClassName?: string;\n}\n\n/**\n * @since 2.8.0\n * @since 6.0.0 Updated to be a union of the different props to enforce the\n * correct props based on `type`\n */\nexport type MenuItemInputToggleProps =\n | (MenuItemCheckboxProps & { type: \"checkbox\" })\n | (MenuItemRadioProps & { type: \"radio\" })\n | (MenuItemSwitchProps & { type: \"switch\" });\n\n/**\n * **Client Component**\n *\n * This is a low-level component that should probably not be used externally and\n * instead the `MenuItemCheckbox`, `MenuItemRadio`, or `MenuItemSwitch` should\n * be used instead.\n *\n * @see {@link https://react-md.dev/components/menu | DropdownMenu Demos}\n * @see {@link MenuItemCheckbox} for checkbox examples\n * @see {@link MenuItemRadio} for radio examples\n * @see {@link MenuItemSwitch} for switch examples\n * @since 2.8.0\n */\nexport function MenuItemInputToggle(\n props: MenuItemInputToggleProps\n): ReactElement {\n const {\n ref,\n id: propId,\n type,\n disabled = false,\n checked,\n onCheckedChange,\n preventMenuHideOnClick = false,\n onClick = noop,\n className,\n tabIndex = -1,\n children,\n size = \"auto\",\n icon: propIcon,\n iconAfter = false,\n iconProps,\n iconStyle,\n iconClassName,\n checkedIcon,\n indeterminate,\n indeterminateIcon,\n addon,\n addonType,\n addonPosition,\n addonForceWrap,\n disableAddonCenteredMedia,\n ballProps,\n ballStyle,\n ballClassName,\n trackProps,\n trackStyle,\n trackClassName,\n ...remaining\n } = props as MenuItemSwitchProps &\n MenuItemCheckboxProps & { type: \"checkbox\" | \"radio\" | \"switch\" };\n const id = useEnsuredId(propId, \"menu-item\");\n\n let icon = propIcon;\n if (type === \"switch\") {\n icon = (\n <SwitchTrack\n style={trackStyle}\n {...trackProps}\n className={cnb(\n menuItemInputToggleTrack(),\n trackClassName,\n trackProps?.className\n )}\n active={checked}\n ballProps={ballProps}\n ballStyle={ballStyle}\n ballClassName={cnb(menuItemInputToggleBall(), ballClassName)}\n />\n );\n } else {\n icon = (\n <InputToggleIcon\n style={iconStyle}\n disableEm\n {...iconProps}\n className={cnb(\n menuItemInputToggleIcon(),\n iconClassName,\n iconProps?.className\n )}\n size={size}\n type={type}\n checked={checked}\n disabled={disabled}\n icon={propIcon}\n checkedIcon={checkedIcon}\n indeterminate={indeterminate}\n indeterminateIcon={indeterminateIcon}\n />\n );\n }\n\n let leftAddon: ReactNode;\n let leftAddonType: ListItemAddonType | undefined;\n let leftAddonPosition: ListItemAddonPosition | undefined;\n let leftAddonForceWrap: boolean | undefined;\n let disableLeftAddonCenteredMedia: boolean | undefined;\n let rightAddon: ReactNode;\n let rightAddonType: ListItemAddonType | undefined;\n let rightAddonPosition: ListItemAddonPosition | undefined;\n let rightAddonForceWrap: boolean | undefined;\n let disableRightAddonCenteredMedia: boolean | undefined;\n if (iconAfter) {\n leftAddon = addon;\n leftAddonType = addonType;\n leftAddonPosition = addonPosition;\n leftAddonForceWrap = addonForceWrap;\n disableLeftAddonCenteredMedia = disableAddonCenteredMedia;\n rightAddon = icon;\n } else {\n leftAddon = icon;\n rightAddon = addon;\n rightAddonType = addonType;\n rightAddonPosition = addonPosition;\n rightAddonForceWrap = addonForceWrap;\n disableRightAddonCenteredMedia = disableAddonCenteredMedia;\n }\n\n return (\n <ListItem\n {...remaining}\n // I'm not actually sure if this is correct\n aria-checked={indeterminate && checked ? \"mixed\" : checked}\n id={id}\n role={type === \"radio\" ? \"menuitemradio\" : \"menuitemcheckbox\"}\n onClick={(event) => {\n onClick(event);\n onCheckedChange(!checked, event);\n\n if (preventMenuHideOnClick) {\n event.stopPropagation();\n }\n }}\n ref={ref}\n className={menuItemInputToggle({ type, className })}\n disabled={disabled}\n tabIndex={tabIndex}\n leftAddon={leftAddon}\n leftAddonType={leftAddonType}\n leftAddonPosition={leftAddonPosition}\n leftAddonForceWrap={leftAddonForceWrap}\n disableLeftAddonCenteredMedia={disableLeftAddonCenteredMedia}\n rightAddon={rightAddon}\n rightAddonType={rightAddonType}\n rightAddonPosition={rightAddonPosition}\n rightAddonForceWrap={rightAddonForceWrap}\n disableRightAddonCenteredMedia={disableRightAddonCenteredMedia}\n >\n {children}\n </ListItem>\n );\n}\n"],"names":["cnb","InputToggleIcon","SwitchTrack","ListItem","useEnsuredId","menuItemInputToggle","menuItemInputToggleBall","menuItemInputToggleIcon","menuItemInputToggleTrack","noop","MenuItemInputToggle","props","ref","id","propId","type","disabled","checked","onCheckedChange","preventMenuHideOnClick","onClick","className","tabIndex","children","size","icon","propIcon","iconAfter","iconProps","iconStyle","iconClassName","checkedIcon","indeterminate","indeterminateIcon","addon","addonType","addonPosition","addonForceWrap","disableAddonCenteredMedia","ballProps","ballStyle","ballClassName","trackProps","trackStyle","trackClassName","remaining","style","active","disableEm","leftAddon","leftAddonType","leftAddonPosition","leftAddonForceWrap","disableLeftAddonCenteredMedia","rightAddon","rightAddonType","rightAddonPosition","rightAddonForceWrap","disableRightAddonCenteredMedia","aria-checked","role","event","stopPropagation"],"mappings":"AAAA;;AAEA,SAASA,GAAG,QAAQ,YAAY;AAchC,SAASC,eAAe,QAAQ,6BAA6B;AAC7D,SAASC,WAAW,QAAQ,yBAAyB;AAErD,SAASC,QAAQ,QAAQ,sBAAsB;AAQ/C,SAASC,YAAY,QAAQ,qBAAqB;AAClD,SACEC,mBAAmB,EACnBC,uBAAuB,EACvBC,uBAAuB,EACvBC,wBAAwB,QACnB,cAAc;AAErB,MAAMC,OAAO;AACX,aAAa;AACf;AA6FA;;;;;;;;;;;;CAYC,GACD,OAAO,SAASC,oBACdC,KAA+B;IAE/B,MAAM,EACJC,GAAG,EACHC,IAAIC,MAAM,EACVC,IAAI,EACJC,WAAW,KAAK,EAChBC,OAAO,EACPC,eAAe,EACfC,yBAAyB,KAAK,EAC9BC,UAAUX,IAAI,EACdY,SAAS,EACTC,WAAW,CAAC,CAAC,EACbC,QAAQ,EACRC,OAAO,MAAM,EACbC,MAAMC,QAAQ,EACdC,YAAY,KAAK,EACjBC,SAAS,EACTC,SAAS,EACTC,aAAa,EACbC,WAAW,EACXC,aAAa,EACbC,iBAAiB,EACjBC,KAAK,EACLC,SAAS,EACTC,aAAa,EACbC,cAAc,EACdC,yBAAyB,EACzBC,SAAS,EACTC,SAAS,EACTC,aAAa,EACbC,UAAU,EACVC,UAAU,EACVC,cAAc,EACd,GAAGC,WACJ,GAAGlC;IAEJ,MAAME,KAAKT,aAAaU,QAAQ;IAEhC,IAAIW,OAAOC;IACX,IAAIX,SAAS,UAAU;QACrBU,qBACE,KAACvB;YACC4C,OAAOH;YACN,GAAGD,UAAU;YACdrB,WAAWrB,IACTQ,4BACAoC,gBACAF,YAAYrB;YAEd0B,QAAQ9B;YACRsB,WAAWA;YACXC,WAAWA;YACXC,eAAezC,IAAIM,2BAA2BmC;;IAGpD,OAAO;QACLhB,qBACE,KAACxB;YACC6C,OAAOjB;YACPmB,SAAS;YACR,GAAGpB,SAAS;YACbP,WAAWrB,IACTO,2BACAuB,eACAF,WAAWP;YAEbG,MAAMA;YACNT,MAAMA;YACNE,SAASA;YACTD,UAAUA;YACVS,MAAMC;YACNK,aAAaA;YACbC,eAAeA;YACfC,mBAAmBA;;IAGzB;IAEA,IAAIgB;IACJ,IAAIC;IACJ,IAAIC;IACJ,IAAIC;IACJ,IAAIC;IACJ,IAAIC;IACJ,IAAIC;IACJ,IAAIC;IACJ,IAAIC;IACJ,IAAIC;IACJ,IAAI/B,WAAW;QACbsB,YAAYf;QACZgB,gBAAgBf;QAChBgB,oBAAoBf;QACpBgB,qBAAqBf;QACrBgB,gCAAgCf;QAChCgB,aAAa7B;IACf,OAAO;QACLwB,YAAYxB;QACZ6B,aAAapB;QACbqB,iBAAiBpB;QACjBqB,qBAAqBpB;QACrBqB,sBAAsBpB;QACtBqB,iCAAiCpB;IACnC;IAEA,qBACE,KAACnC;QACE,GAAG0C,SAAS;QACb,2CAA2C;QAC3Cc,gBAAc3B,iBAAiBf,UAAU,UAAUA;QACnDJ,IAAIA;QACJ+C,MAAM7C,SAAS,UAAU,kBAAkB;QAC3CK,SAAS,CAACyC;YACRzC,QAAQyC;YACR3C,gBAAgB,CAACD,SAAS4C;YAE1B,IAAI1C,wBAAwB;gBAC1B0C,MAAMC,eAAe;YACvB;QACF;QACAlD,KAAKA;QACLS,WAAWhB,oBAAoB;YAAEU;YAAMM;QAAU;QACjDL,UAAUA;QACVM,UAAUA;QACV2B,WAAWA;QACXC,eAAeA;QACfC,mBAAmBA;QACnBC,oBAAoBA;QACpBC,+BAA+BA;QAC/BC,YAAYA;QACZC,gBAAgBA;QAChBC,oBAAoBA;QACpBC,qBAAqBA;QACrBC,gCAAgCA;kBAE/BnC;;AAGP"}
|
|
1
|
+
{"version":3,"sources":["../../src/menu/MenuItemInputToggle.tsx"],"sourcesContent":["\"use client\";\n\nimport { cnb } from \"cnbuilder\";\nimport {\n type CSSProperties,\n type HTMLAttributes,\n type MouseEvent,\n type ReactElement,\n type ReactNode,\n type Ref,\n} from \"react\";\n\nimport {\n type ConfigurableInputToggleIconProps,\n type IndeterminateCheckboxProps,\n} from \"../form/InputToggle.js\";\nimport { InputToggleIcon } from \"../form/InputToggleIcon.js\";\nimport { SwitchTrack } from \"../form/SwitchTrack.js\";\nimport { type InputToggleSize } from \"../form/inputToggleStyles.js\";\nimport { ListItem } from \"../list/ListItem.js\";\nimport {\n type ListItemAddonPosition,\n type ListItemAddonType,\n type ListItemChildrenTextProps,\n type ListItemHeight,\n} from \"../list/types.js\";\nimport { type PropsWithRef } from \"../types.js\";\nimport { useEnsuredId } from \"../useEnsuredId.js\";\nimport {\n menuItemInputToggle,\n menuItemInputToggleBall,\n menuItemInputToggleIcon,\n menuItemInputToggleTrack,\n} from \"./styles.js\";\n\nconst noop = (): void => {\n // do nothing\n};\n\n/**\n * @since 6.0.0\n */\nexport type MenuItemInputToggleCheckedCallback = (\n checked: boolean,\n event: MouseEvent<HTMLLIElement>\n) => void;\n\n/** @since 2.8.0 */\nexport interface BaseMenuItemInputToggleProps\n extends\n HTMLAttributes<HTMLLIElement>,\n ConfigurableInputToggleIconProps,\n ListItemChildrenTextProps {\n ref?: Ref<HTMLLIElement>;\n checked: boolean;\n onCheckedChange: MenuItemInputToggleCheckedCallback;\n\n /**\n * @defaultValue `\"menu-item-\" + useId()`\n */\n id?: string;\n\n /** @defaultValue `false` */\n disabled?: boolean;\n\n /**\n * Set this to `true` if the `Menu` should not close when the input toggle is\n * clicked. This can be useful when interacting with a checkbox group within a\n * menu or allowing the user to select multiple options before closing the\n * menu.\n *\n * @defaultValue `false`\n */\n preventMenuHideOnClick?: boolean;\n\n /**\n * This is set to `\"auto\"` by default so the icon shrinks back down to the\n * default icon size instead of relative to the current font size. You\n * probably don't want to change this since it'll also modify the height of\n * the menu item\n *\n * @defaultValue `\"auto\"`\n */\n size?: InputToggleSize;\n\n /** @defaultValue `\"auto\"` */\n height?: ListItemHeight;\n\n /** @defaultValue `false` */\n iconAfter?: boolean;\n\n addon?: ReactNode;\n addonType?: ListItemAddonType;\n addonPosition?: ListItemAddonPosition;\n\n /** @defaultValue `false` */\n addonForceWrap?: boolean;\n\n /** @defaultValue `false` */\n disableAddonCenteredMedia?: boolean;\n}\n\nexport interface MenuItemCheckboxProps\n extends BaseMenuItemInputToggleProps, IndeterminateCheckboxProps {}\n\nexport type MenuItemRadioProps = BaseMenuItemInputToggleProps;\n\n/**\n * @since 2.8.0\n * @since 6.0.0 Added additional props for styling the track and ball.\n */\nexport interface MenuItemSwitchProps extends BaseMenuItemInputToggleProps {\n trackProps?: PropsWithRef<HTMLAttributes<HTMLDivElement>>;\n trackStyle?: CSSProperties;\n trackClassName?: string;\n ballProps?: PropsWithRef<HTMLAttributes<HTMLSpanElement>>;\n ballStyle?: CSSProperties;\n ballClassName?: string;\n}\n\n/**\n * @since 2.8.0\n * @since 6.0.0 Updated to be a union of the different props to enforce the\n * correct props based on `type`\n */\nexport type MenuItemInputToggleProps =\n | (MenuItemCheckboxProps & { type: \"checkbox\" })\n | (MenuItemRadioProps & { type: \"radio\" })\n | (MenuItemSwitchProps & { type: \"switch\" });\n\n/**\n * **Client Component**\n *\n * This is a low-level component that should probably not be used externally and\n * instead the `MenuItemCheckbox`, `MenuItemRadio`, or `MenuItemSwitch` should\n * be used instead.\n *\n * @see {@link https://react-md.dev/components/menu | DropdownMenu Demos}\n * @see {@link MenuItemCheckbox} for checkbox examples\n * @see {@link MenuItemRadio} for radio examples\n * @see {@link MenuItemSwitch} for switch examples\n * @since 2.8.0\n */\nexport function MenuItemInputToggle(\n props: MenuItemInputToggleProps\n): ReactElement {\n const {\n ref,\n id: propId,\n type,\n disabled = false,\n checked,\n onCheckedChange,\n preventMenuHideOnClick = false,\n onClick = noop,\n className,\n tabIndex = -1,\n children,\n size = \"auto\",\n icon: propIcon,\n iconAfter = false,\n iconProps,\n iconStyle,\n iconClassName,\n checkedIcon,\n indeterminate,\n indeterminateIcon,\n addon,\n addonType,\n addonPosition,\n addonForceWrap,\n disableAddonCenteredMedia,\n ballProps,\n ballStyle,\n ballClassName,\n trackProps,\n trackStyle,\n trackClassName,\n ...remaining\n } = props as MenuItemSwitchProps &\n MenuItemCheckboxProps & { type: \"checkbox\" | \"radio\" | \"switch\" };\n const id = useEnsuredId(propId, \"menu-item\");\n\n let icon: ReactElement;\n if (type === \"switch\") {\n icon = (\n <SwitchTrack\n style={trackStyle}\n {...trackProps}\n className={cnb(\n menuItemInputToggleTrack(),\n trackClassName,\n trackProps?.className\n )}\n active={checked}\n ballProps={ballProps}\n ballStyle={ballStyle}\n ballClassName={cnb(menuItemInputToggleBall(), ballClassName)}\n />\n );\n } else {\n icon = (\n <InputToggleIcon\n style={iconStyle}\n disableEm\n {...iconProps}\n className={cnb(\n menuItemInputToggleIcon(),\n iconClassName,\n iconProps?.className\n )}\n size={size}\n type={type}\n checked={checked}\n disabled={disabled}\n icon={propIcon}\n checkedIcon={checkedIcon}\n indeterminate={indeterminate}\n indeterminateIcon={indeterminateIcon}\n />\n );\n }\n\n let leftAddon: ReactNode;\n let leftAddonType: ListItemAddonType | undefined;\n let leftAddonPosition: ListItemAddonPosition | undefined;\n let leftAddonForceWrap: boolean | undefined;\n let disableLeftAddonCenteredMedia: boolean | undefined;\n let rightAddon: ReactNode;\n let rightAddonType: ListItemAddonType | undefined;\n let rightAddonPosition: ListItemAddonPosition | undefined;\n let rightAddonForceWrap: boolean | undefined;\n let disableRightAddonCenteredMedia: boolean | undefined;\n if (iconAfter) {\n leftAddon = addon;\n leftAddonType = addonType;\n leftAddonPosition = addonPosition;\n leftAddonForceWrap = addonForceWrap;\n disableLeftAddonCenteredMedia = disableAddonCenteredMedia;\n rightAddon = icon;\n } else {\n leftAddon = icon;\n rightAddon = addon;\n rightAddonType = addonType;\n rightAddonPosition = addonPosition;\n rightAddonForceWrap = addonForceWrap;\n disableRightAddonCenteredMedia = disableAddonCenteredMedia;\n }\n\n return (\n <ListItem\n {...remaining}\n // I'm not actually sure if this is correct\n aria-checked={indeterminate && checked ? \"mixed\" : checked}\n id={id}\n role={type === \"radio\" ? \"menuitemradio\" : \"menuitemcheckbox\"}\n onClick={(event) => {\n onClick(event);\n onCheckedChange(!checked, event);\n\n if (preventMenuHideOnClick) {\n event.stopPropagation();\n }\n }}\n ref={ref}\n className={menuItemInputToggle({ type, className })}\n disabled={disabled}\n tabIndex={tabIndex}\n leftAddon={leftAddon}\n leftAddonType={leftAddonType}\n leftAddonPosition={leftAddonPosition}\n leftAddonForceWrap={leftAddonForceWrap}\n disableLeftAddonCenteredMedia={disableLeftAddonCenteredMedia}\n rightAddon={rightAddon}\n rightAddonType={rightAddonType}\n rightAddonPosition={rightAddonPosition}\n rightAddonForceWrap={rightAddonForceWrap}\n disableRightAddonCenteredMedia={disableRightAddonCenteredMedia}\n >\n {children}\n </ListItem>\n );\n}\n"],"names":["cnb","InputToggleIcon","SwitchTrack","ListItem","useEnsuredId","menuItemInputToggle","menuItemInputToggleBall","menuItemInputToggleIcon","menuItemInputToggleTrack","noop","MenuItemInputToggle","props","ref","id","propId","type","disabled","checked","onCheckedChange","preventMenuHideOnClick","onClick","className","tabIndex","children","size","icon","propIcon","iconAfter","iconProps","iconStyle","iconClassName","checkedIcon","indeterminate","indeterminateIcon","addon","addonType","addonPosition","addonForceWrap","disableAddonCenteredMedia","ballProps","ballStyle","ballClassName","trackProps","trackStyle","trackClassName","remaining","style","active","disableEm","leftAddon","leftAddonType","leftAddonPosition","leftAddonForceWrap","disableLeftAddonCenteredMedia","rightAddon","rightAddonType","rightAddonPosition","rightAddonForceWrap","disableRightAddonCenteredMedia","aria-checked","role","event","stopPropagation"],"mappings":"AAAA;;AAEA,SAASA,GAAG,QAAQ,YAAY;AAchC,SAASC,eAAe,QAAQ,6BAA6B;AAC7D,SAASC,WAAW,QAAQ,yBAAyB;AAErD,SAASC,QAAQ,QAAQ,sBAAsB;AAQ/C,SAASC,YAAY,QAAQ,qBAAqB;AAClD,SACEC,mBAAmB,EACnBC,uBAAuB,EACvBC,uBAAuB,EACvBC,wBAAwB,QACnB,cAAc;AAErB,MAAMC,OAAO;AACX,aAAa;AACf;AA6FA;;;;;;;;;;;;CAYC,GACD,OAAO,SAASC,oBACdC,KAA+B;IAE/B,MAAM,EACJC,GAAG,EACHC,IAAIC,MAAM,EACVC,IAAI,EACJC,WAAW,KAAK,EAChBC,OAAO,EACPC,eAAe,EACfC,yBAAyB,KAAK,EAC9BC,UAAUX,IAAI,EACdY,SAAS,EACTC,WAAW,CAAC,CAAC,EACbC,QAAQ,EACRC,OAAO,MAAM,EACbC,MAAMC,QAAQ,EACdC,YAAY,KAAK,EACjBC,SAAS,EACTC,SAAS,EACTC,aAAa,EACbC,WAAW,EACXC,aAAa,EACbC,iBAAiB,EACjBC,KAAK,EACLC,SAAS,EACTC,aAAa,EACbC,cAAc,EACdC,yBAAyB,EACzBC,SAAS,EACTC,SAAS,EACTC,aAAa,EACbC,UAAU,EACVC,UAAU,EACVC,cAAc,EACd,GAAGC,WACJ,GAAGlC;IAEJ,MAAME,KAAKT,aAAaU,QAAQ;IAEhC,IAAIW;IACJ,IAAIV,SAAS,UAAU;QACrBU,qBACE,KAACvB;YACC4C,OAAOH;YACN,GAAGD,UAAU;YACdrB,WAAWrB,IACTQ,4BACAoC,gBACAF,YAAYrB;YAEd0B,QAAQ9B;YACRsB,WAAWA;YACXC,WAAWA;YACXC,eAAezC,IAAIM,2BAA2BmC;;IAGpD,OAAO;QACLhB,qBACE,KAACxB;YACC6C,OAAOjB;YACPmB,SAAS;YACR,GAAGpB,SAAS;YACbP,WAAWrB,IACTO,2BACAuB,eACAF,WAAWP;YAEbG,MAAMA;YACNT,MAAMA;YACNE,SAASA;YACTD,UAAUA;YACVS,MAAMC;YACNK,aAAaA;YACbC,eAAeA;YACfC,mBAAmBA;;IAGzB;IAEA,IAAIgB;IACJ,IAAIC;IACJ,IAAIC;IACJ,IAAIC;IACJ,IAAIC;IACJ,IAAIC;IACJ,IAAIC;IACJ,IAAIC;IACJ,IAAIC;IACJ,IAAIC;IACJ,IAAI/B,WAAW;QACbsB,YAAYf;QACZgB,gBAAgBf;QAChBgB,oBAAoBf;QACpBgB,qBAAqBf;QACrBgB,gCAAgCf;QAChCgB,aAAa7B;IACf,OAAO;QACLwB,YAAYxB;QACZ6B,aAAapB;QACbqB,iBAAiBpB;QACjBqB,qBAAqBpB;QACrBqB,sBAAsBpB;QACtBqB,iCAAiCpB;IACnC;IAEA,qBACE,KAACnC;QACE,GAAG0C,SAAS;QACb,2CAA2C;QAC3Cc,gBAAc3B,iBAAiBf,UAAU,UAAUA;QACnDJ,IAAIA;QACJ+C,MAAM7C,SAAS,UAAU,kBAAkB;QAC3CK,SAAS,CAACyC;YACRzC,QAAQyC;YACR3C,gBAAgB,CAACD,SAAS4C;YAE1B,IAAI1C,wBAAwB;gBAC1B0C,MAAMC,eAAe;YACvB;QACF;QACAlD,KAAKA;QACLS,WAAWhB,oBAAoB;YAAEU;YAAMM;QAAU;QACjDL,UAAUA;QACVM,UAAUA;QACV2B,WAAWA;QACXC,eAAeA;QACfC,mBAAmBA;QACnBC,oBAAoBA;QACpBC,+BAA+BA;QAC/BC,YAAYA;QACZC,gBAAgBA;QAChBC,oBAAoBA;QACpBC,qBAAqBA;QACrBC,gCAAgCA;kBAE/BnC;;AAGP"}
|