@vector-im/compound-web 8.3.5 → 8.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Form/Controls/Checkbox/Checkbox.js +1 -1
- package/dist/components/Form/Controls/Checkbox/Checkbox.module.css.cjs +3 -3
- package/dist/components/Form/Controls/Checkbox/Checkbox.module.css.js +3 -3
- package/dist/components/Form/Controls/EditInPlace/EditInPlace.cjs.map +1 -1
- package/dist/components/Form/Controls/EditInPlace/EditInPlace.js.map +1 -1
- package/dist/components/Form/Controls/Radio/Radio.module.css.cjs +3 -3
- package/dist/components/Form/Controls/Radio/Radio.module.css.js +3 -3
- package/dist/components/Form/Controls/SettingsToggle/SettingsToggle.js +1 -1
- package/dist/components/Form/index.cjs +14 -14
- package/dist/components/Form/index.js +5 -5
- package/dist/components/Menu/ContextMenu.cjs +1 -2
- package/dist/components/Menu/ContextMenu.cjs.map +1 -1
- package/dist/components/Menu/ContextMenu.d.ts.map +1 -1
- package/dist/components/Menu/ContextMenu.js +1 -2
- package/dist/components/Menu/ContextMenu.js.map +1 -1
- package/dist/components/Menu/FloatingMenu.cjs.map +1 -1
- package/dist/components/Menu/FloatingMenu.d.ts.map +1 -1
- package/dist/components/Menu/FloatingMenu.js.map +1 -1
- package/dist/components/Menu/FloatingMenu.module.css.cjs +2 -2
- package/dist/components/Menu/FloatingMenu.module.css.js +2 -2
- package/dist/components/Menu/Menu.cjs +10 -1
- package/dist/components/Menu/Menu.cjs.map +1 -1
- package/dist/components/Menu/Menu.d.ts +4 -0
- package/dist/components/Menu/Menu.d.ts.map +1 -1
- package/dist/components/Menu/Menu.js +10 -1
- package/dist/components/Menu/Menu.js.map +1 -1
- package/dist/components/ReleaseAnnouncement/ReleaseAnnouncementContext.d.ts.map +1 -1
- package/dist/components/ReleaseAnnouncement/useReleaseAnnouncement.d.ts.map +1 -1
- package/dist/components/ReleaseAnnouncement/useReleaseAnnouncement.js +1 -1
- package/dist/components/Tooltip/TooltipContext.d.ts.map +1 -1
- package/dist/components/Tooltip/useTooltip.d.ts.map +1 -1
- package/dist/components/Tooltip/useTooltip.js +1 -1
- package/dist/index.cjs +59 -59
- package/dist/index.js +22 -22
- package/dist/style.css +346 -359
- package/package.json +7 -7
- package/src/components/Form/Controls/Checkbox/Checkbox.module.css +4 -0
- package/src/components/Form/Controls/EditInPlace/EditInPlace.tsx +1 -1
- package/src/components/Form/Controls/Radio/Radio.module.css +4 -0
- package/src/components/Menu/ContextMenu.tsx +1 -2
- package/src/components/Menu/FloatingMenu.module.css +0 -11
- package/src/components/Menu/FloatingMenu.tsx +1 -0
- package/src/components/Menu/Menu.tsx +11 -1
- package/dist/components/Menu/ContextMenu.module.css.cjs +0 -9
- package/dist/components/Menu/ContextMenu.module.css.cjs.map +0 -1
- package/dist/components/Menu/ContextMenu.module.css.js +0 -9
- package/dist/components/Menu/ContextMenu.module.css.js.map +0 -1
- package/src/components/Menu/ContextMenu.module.css +0 -10
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
3
|
-
const container = "
|
|
4
|
-
const input = "
|
|
5
|
-
const ui = "
|
|
3
|
+
const container = "_container_153f2_10";
|
|
4
|
+
const input = "_input_153f2_18";
|
|
5
|
+
const ui = "_ui_153f2_19";
|
|
6
6
|
const styles = {
|
|
7
7
|
container,
|
|
8
8
|
input,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EditInPlace.cjs","sources":["../../../../../src/components/Form/Controls/EditInPlace/EditInPlace.tsx"],"sourcesContent":["/*\nCopyright 2024 New Vector Ltd.\n\nSPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport React, {\n forwardRef,\n useCallback,\n useRef,\n useState,\n useEffect,\n useReducer,\n} from \"react\";\nimport { Submit, ValidityState } from \"@radix-ui/react-form\";\nimport CheckIcon from \"@vector-im/compound-design-tokens/assets/web/icons/check\";\nimport CancelIcon from \"@vector-im/compound-design-tokens/assets/web/icons/close\";\n\nimport styles from \"./EditInPlace.module.css\";\n\nimport {\n Field,\n HelpMessage,\n Label,\n LoadingMessage,\n Root,\n SuccessMessage,\n TextControl,\n} from \"../..\";\nimport { Button, Tooltip } from \"../../../..\";\n\ntype Props = {\n /**\n * The label for the control\n */\n label: string;\n\n /**\n * The CSS class name.\n */\n className?: string;\n\n /**\n * Callback for when the user confirms the change\n */\n onSave?: (e: React.FormEvent<HTMLFormElement>) => Promise<void> | void;\n\n /**\n * Callback for when the user wishes to cancel the change\n */\n onCancel?: (e: React.FormEvent<HTMLFormElement>) => void;\n\n /**\n * onInput event handler on the text control\n */\n onInput?: (e: React.ChangeEvent<HTMLInputElement>) => void;\n\n /**\n * Callback for when the server validation errors should be cleared.\n */\n onClearServerErrors?: () => void;\n\n /**\n * Whether the field is in an error state according to the server validation.\n *\n * For validation messages, use native validations properties directly, or add custom error messages as children.\n */\n serverInvalid?: boolean;\n\n /**\n * Label to be displayed by the green check at the bottom. Will only be displayed\n * for 2 seconds after the onSave callback promise resolves successfully.\n */\n savedLabel?: string;\n\n /**\n * The label for the save button\n */\n saveButtonLabel: string;\n\n /**\n * The label for the 'in progress' saving caption\n */\n savingLabel: string;\n\n /**\n * The label for the cancel button\n */\n cancelButtonLabel: string;\n\n /**\n * Label to be displayed under the input as a help text\n */\n helpLabel?: string;\n\n /**\n * If true, disabled the entire component to disallow editing.\n */\n disabled?: boolean;\n} & React.ComponentProps<typeof TextControl>;\n\nenum State {\n /** No changes on the input has been made */\n Initial,\n\n /** The input has been changed */\n Dirty,\n\n /** The input is being saved */\n Saving,\n\n /** The input has been saved */\n Saved,\n}\n\nenum Event {\n Touch, // The user 'touched' the control\n Save, // The user has clicked the save button\n Saved, // The onSave callback finished successfully\n SaveError, // The onSave callback finished with an error\n Cancel, // The user has clicked the cancel button\n SavedTimeout, // The user has clicked the save button and the saved label has been shown for 2 seconds\n}\n\nfunction reducer(state: State, action: Event): State {\n switch (action) {\n case Event.Touch:\n if (state === State.Initial || state === State.Saved) return State.Dirty;\n else return state;\n\n case Event.Save:\n return State.Saving;\n\n case Event.Cancel:\n return State.Initial;\n\n case Event.Saved:\n if (state === State.Saving) return State.Saved;\n else return state;\n\n case Event.SaveError:\n if (state === State.Saving) return State.Initial;\n else return state;\n\n case Event.SavedTimeout:\n if (state === State.Saved) return State.Initial;\n else return state;\n }\n\n assertNever(action);\n}\n\nfunction assertNever(value: never): never {\n throw new Error(`Unreachable value: ${value}`);\n}\n\n/**\n * A text box with save/cancel buttons that appear when the field is active.\n * Since thios control has its own 'save' button, it should *not* appear as part\n * of a larger form: it exists as its own form that submits separately.\n */\nexport const EditInPlace = forwardRef<HTMLInputElement, Props>(\n function EditInPlace(\n {\n className,\n label,\n onSave,\n onCancel,\n onInput,\n onClearServerErrors,\n serverInvalid,\n saveButtonLabel,\n cancelButtonLabel,\n savedLabel,\n savingLabel,\n helpLabel,\n disabled,\n children,\n ...props\n },\n ref,\n ) {\n const [state, dispatch] = useReducer(reducer, State.Initial);\n\n // Tracks the focus state of the form\n // This uses a `ref` to make sure the onFocus/onBlur callback don't trigger unnecessary re-renders\n // and a state to track the focus state and hide the buttons when the form is not focused\n const isFocusWithinRef = useRef(false);\n const [isFocusWithin, setFocusWithin] = useState(false);\n\n const shouldShowSaveButton =\n state === State.Dirty || state === State.Saving || isFocusWithin;\n\n const hideTimer = useRef<ReturnType<typeof setTimeout> | undefined>(\n undefined,\n );\n\n useEffect(() => {\n // Start a timer when we switch to the saved state\n if (state === State.Saved) {\n hideTimer.current = setTimeout(() => {\n dispatch(Event.SavedTimeout);\n hideTimer.current = undefined;\n }, 2000);\n }\n\n return () => {\n // Clear any timers that may have been set\n if (hideTimer.current) clearTimeout(hideTimer.current);\n hideTimer.current = undefined;\n };\n }, [state]);\n\n const formRef = useRef<HTMLFormElement>(null);\n const saveButtonRef = useRef<HTMLButtonElement>(null);\n const cancelButtonRef = useRef<HTMLButtonElement>(null);\n\n const onFocus = useCallback(() => {\n if (isFocusWithinRef.current) return;\n isFocusWithinRef.current = true;\n setFocusWithin(true);\n }, [isFocusWithin, setFocusWithin]);\n\n const onBlur = useCallback(\n (e: React.FocusEvent) => {\n if (!isFocusWithinRef.current) return;\n // If the user switched to another element within the form\n // consider that we're still focused within the form\n if (e.currentTarget.contains(e.relatedTarget)) return;\n\n isFocusWithinRef.current = false;\n setFocusWithin(false);\n },\n [isFocusWithin, setFocusWithin],\n );\n\n const onInputHandler = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n dispatch(Event.Touch);\n onInput?.(e);\n },\n [dispatch, onInput],\n );\n\n const onFormSubmit = useCallback(\n async (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n\n // Prevent submitting the form if the user has not yet entered any text\n if (state === State.Initial) {\n return;\n }\n\n try {\n dispatch(Event.Save);\n saveButtonRef.current?.blur();\n await onSave?.(e);\n dispatch(Event.Saved);\n } catch {\n // We don't really need to do anything here, we just don't want to display the\n // 'saved' label, obviously. The user of the component can update the error to\n // show what failed.\n dispatch(Event.SaveError);\n }\n },\n [onSave, state, hideTimer],\n );\n\n const onFormReset = useCallback(\n (e: React.FormEvent<HTMLFormElement>) => {\n cancelButtonRef.current?.blur();\n onCancel?.(e);\n dispatch(Event.Cancel);\n },\n [cancelButtonRef, onCancel],\n );\n\n return (\n <Root\n className={className}\n onSubmit={onFormSubmit}\n onReset={onFormReset}\n onFocus={onFocus}\n onBlur={onBlur}\n onClearServerErrors={onClearServerErrors}\n ref={formRef}\n >\n <Field name=\"input\" serverInvalid={serverInvalid}>\n <Label>{label}</Label>\n <div className={styles.controls}>\n <TextControl\n ref={ref}\n {...props}\n onInput={onInputHandler}\n disabled={disabled || state === State.Saving}\n />\n\n {shouldShowSaveButton && (\n <div className={styles[\"button-group\"]}>\n <Tooltip label={saveButtonLabel}>\n <Submit asChild>\n <Button\n type=\"submit\"\n kind=\"primary\"\n size=\"sm\"\n ref={saveButtonRef}\n disabled={state !== State.Dirty}\n iconOnly\n Icon={CheckIcon}\n />\n </Submit>\n </Tooltip>\n\n <Tooltip label={cancelButtonLabel}>\n <Button\n type=\"reset\"\n kind=\"secondary\"\n size=\"sm\"\n ref={cancelButtonRef}\n className={styles.button}\n disabled={state === State.Saving}\n iconOnly\n Icon={CancelIcon}\n />\n </Tooltip>\n </div>\n )}\n </div>\n\n {/*\n During the loading saving state, we only show the saving message.\n Else, we show whatever children were passed on, as they will have other validation messages\n */}\n {state === State.Saving ? (\n <LoadingMessage>{savingLabel}</LoadingMessage>\n ) : (\n children\n )}\n\n {savedLabel && state === State.Saved && (\n <SuccessMessage>{savedLabel}</SuccessMessage>\n )}\n\n {/*\n We show the help message only if:\n - the helpLabel is set\n - the form hasn't been validated yet\n - the 'serverInvalid' prop is not set\n - we're in the initial or dirty state\n */}\n {helpLabel && (state === State.Initial || state === State.Dirty) && (\n <ValidityState>\n {(validity) =>\n (validity === undefined || validity.valid) &&\n !serverInvalid && <HelpMessage>{helpLabel}</HelpMessage>\n }\n </ValidityState>\n )}\n </Field>\n </Root>\n );\n },\n);\n"],"names":["forwardRef","EditInPlace","useReducer","useRef","useState","useEffect","useCallback","jsx","Root","jsxs","Field","Label","styles","TextControl","Tooltip","Submit","Button","CancelIcon","LoadingMessage","SuccessMessage","ValidityState","HelpMessage"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"EditInPlace.cjs","sources":["../../../../../src/components/Form/Controls/EditInPlace/EditInPlace.tsx"],"sourcesContent":["/*\nCopyright 2024 New Vector Ltd.\n\nSPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport React, {\n forwardRef,\n useCallback,\n useRef,\n useState,\n useEffect,\n useReducer,\n} from \"react\";\nimport { Submit, ValidityState } from \"@radix-ui/react-form\";\nimport CheckIcon from \"@vector-im/compound-design-tokens/assets/web/icons/check\";\nimport CancelIcon from \"@vector-im/compound-design-tokens/assets/web/icons/close\";\n\nimport styles from \"./EditInPlace.module.css\";\n\nimport {\n Field,\n HelpMessage,\n Label,\n LoadingMessage,\n Root,\n SuccessMessage,\n TextControl,\n} from \"../..\";\nimport { Button, Tooltip } from \"../../../..\";\n\ntype Props = {\n /**\n * The label for the control\n */\n label: string;\n\n /**\n * The CSS class name.\n */\n className?: string;\n\n /**\n * Callback for when the user confirms the change\n */\n onSave?: (e: React.FormEvent<HTMLFormElement>) => Promise<void> | void;\n\n /**\n * Callback for when the user wishes to cancel the change\n */\n onCancel?: (e: React.FormEvent<HTMLFormElement>) => void;\n\n /**\n * onInput event handler on the text control\n */\n onInput?: (e: React.ChangeEvent<HTMLInputElement>) => void;\n\n /**\n * Callback for when the server validation errors should be cleared.\n */\n onClearServerErrors?: () => void;\n\n /**\n * Whether the field is in an error state according to the server validation.\n *\n * For validation messages, use native validations properties directly, or add custom error messages as children.\n */\n serverInvalid?: boolean;\n\n /**\n * Label to be displayed by the green check at the bottom. Will only be displayed\n * for 2 seconds after the onSave callback promise resolves successfully.\n */\n savedLabel?: string;\n\n /**\n * The label for the save button\n */\n saveButtonLabel: string;\n\n /**\n * The label for the 'in progress' saving caption\n */\n savingLabel: string;\n\n /**\n * The label for the cancel button\n */\n cancelButtonLabel: string;\n\n /**\n * Label to be displayed under the input as a help text\n */\n helpLabel?: string;\n\n /**\n * If true, disabled the entire component to disallow editing.\n */\n disabled?: boolean;\n} & React.ComponentProps<typeof TextControl>;\n\nenum State {\n /** No changes on the input has been made */\n Initial,\n\n /** The input has been changed */\n Dirty,\n\n /** The input is being saved */\n Saving,\n\n /** The input has been saved */\n Saved,\n}\n\nenum Event {\n Touch, // The user 'touched' the control\n Save, // The user has clicked the save button\n Saved, // The onSave callback finished successfully\n SaveError, // The onSave callback finished with an error\n Cancel, // The user has clicked the cancel button\n SavedTimeout, // The user has clicked the save button and the saved label has been shown for 2 seconds\n}\n\nfunction reducer(state: State, action: Event): State {\n switch (action) {\n case Event.Touch:\n if (state === State.Initial || state === State.Saved) return State.Dirty;\n else return state;\n\n case Event.Save:\n return State.Saving;\n\n case Event.Cancel:\n return State.Initial;\n\n case Event.Saved:\n if (state === State.Saving) return State.Saved;\n else return state;\n\n case Event.SaveError:\n if (state === State.Saving) return State.Initial;\n else return state;\n\n case Event.SavedTimeout:\n if (state === State.Saved) return State.Initial;\n else return state;\n }\n\n assertNever(action);\n}\n\nfunction assertNever(value: never): never {\n throw new Error(`Unreachable value: ${value}`);\n}\n\n/**\n * A text box with save/cancel buttons that appear when the field is active.\n * Since thios control has its own 'save' button, it should *not* appear as part\n * of a larger form: it exists as its own form that submits separately.\n */\nexport const EditInPlace = forwardRef<HTMLInputElement, Props>(\n function EditInPlace(\n {\n className,\n label,\n onSave,\n onCancel,\n onInput,\n onClearServerErrors,\n serverInvalid,\n saveButtonLabel,\n cancelButtonLabel,\n savedLabel,\n savingLabel,\n helpLabel,\n disabled,\n children,\n ...props\n },\n ref,\n ) {\n const [state, dispatch] = useReducer(reducer, State.Initial);\n\n // Tracks the focus state of the form\n // This uses a `ref` to make sure the onFocus/onBlur callback don't trigger unnecessary re-renders\n // and a state to track the focus state and hide the buttons when the form is not focused\n const isFocusWithinRef = useRef(false);\n const [isFocusWithin, setFocusWithin] = useState(false);\n\n const shouldShowSaveButton =\n state === State.Dirty || state === State.Saving || isFocusWithin;\n\n const hideTimer = useRef<ReturnType<typeof setTimeout> | undefined>(\n undefined,\n );\n\n useEffect(() => {\n // Start a timer when we switch to the saved state\n if (state === State.Saved) {\n hideTimer.current = setTimeout(() => {\n dispatch(Event.SavedTimeout);\n hideTimer.current = undefined;\n }, 2000);\n }\n\n return () => {\n // Clear any timers that may have been set\n if (hideTimer.current) clearTimeout(hideTimer.current);\n hideTimer.current = undefined;\n };\n }, [state]);\n\n const formRef = useRef<HTMLFormElement>(null);\n const saveButtonRef = useRef<HTMLButtonElement>(null);\n const cancelButtonRef = useRef<HTMLButtonElement>(null);\n\n const onFocus = useCallback(() => {\n if (isFocusWithinRef.current) return;\n isFocusWithinRef.current = true;\n setFocusWithin(true);\n }, [isFocusWithin, setFocusWithin]);\n\n const onBlur = useCallback(\n (e: React.FocusEvent) => {\n if (!isFocusWithinRef.current) return;\n // If the user switched to another element within the form\n // consider that we're still focused within the form\n if (e.currentTarget.contains(e.relatedTarget)) return;\n\n isFocusWithinRef.current = false;\n setFocusWithin(false);\n },\n [isFocusWithin, setFocusWithin],\n );\n\n const onInputHandler = useCallback(\n (e: React.InputEvent<HTMLInputElement>) => {\n dispatch(Event.Touch);\n onInput?.(e);\n },\n [dispatch, onInput],\n );\n\n const onFormSubmit = useCallback(\n async (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n\n // Prevent submitting the form if the user has not yet entered any text\n if (state === State.Initial) {\n return;\n }\n\n try {\n dispatch(Event.Save);\n saveButtonRef.current?.blur();\n await onSave?.(e);\n dispatch(Event.Saved);\n } catch {\n // We don't really need to do anything here, we just don't want to display the\n // 'saved' label, obviously. The user of the component can update the error to\n // show what failed.\n dispatch(Event.SaveError);\n }\n },\n [onSave, state, hideTimer],\n );\n\n const onFormReset = useCallback(\n (e: React.FormEvent<HTMLFormElement>) => {\n cancelButtonRef.current?.blur();\n onCancel?.(e);\n dispatch(Event.Cancel);\n },\n [cancelButtonRef, onCancel],\n );\n\n return (\n <Root\n className={className}\n onSubmit={onFormSubmit}\n onReset={onFormReset}\n onFocus={onFocus}\n onBlur={onBlur}\n onClearServerErrors={onClearServerErrors}\n ref={formRef}\n >\n <Field name=\"input\" serverInvalid={serverInvalid}>\n <Label>{label}</Label>\n <div className={styles.controls}>\n <TextControl\n ref={ref}\n {...props}\n onInput={onInputHandler}\n disabled={disabled || state === State.Saving}\n />\n\n {shouldShowSaveButton && (\n <div className={styles[\"button-group\"]}>\n <Tooltip label={saveButtonLabel}>\n <Submit asChild>\n <Button\n type=\"submit\"\n kind=\"primary\"\n size=\"sm\"\n ref={saveButtonRef}\n disabled={state !== State.Dirty}\n iconOnly\n Icon={CheckIcon}\n />\n </Submit>\n </Tooltip>\n\n <Tooltip label={cancelButtonLabel}>\n <Button\n type=\"reset\"\n kind=\"secondary\"\n size=\"sm\"\n ref={cancelButtonRef}\n className={styles.button}\n disabled={state === State.Saving}\n iconOnly\n Icon={CancelIcon}\n />\n </Tooltip>\n </div>\n )}\n </div>\n\n {/*\n During the loading saving state, we only show the saving message.\n Else, we show whatever children were passed on, as they will have other validation messages\n */}\n {state === State.Saving ? (\n <LoadingMessage>{savingLabel}</LoadingMessage>\n ) : (\n children\n )}\n\n {savedLabel && state === State.Saved && (\n <SuccessMessage>{savedLabel}</SuccessMessage>\n )}\n\n {/*\n We show the help message only if:\n - the helpLabel is set\n - the form hasn't been validated yet\n - the 'serverInvalid' prop is not set\n - we're in the initial or dirty state\n */}\n {helpLabel && (state === State.Initial || state === State.Dirty) && (\n <ValidityState>\n {(validity) =>\n (validity === undefined || validity.valid) &&\n !serverInvalid && <HelpMessage>{helpLabel}</HelpMessage>\n }\n </ValidityState>\n )}\n </Field>\n </Root>\n );\n },\n);\n"],"names":["forwardRef","EditInPlace","useReducer","useRef","useState","useEffect","useCallback","jsx","Root","jsxs","Field","Label","styles","TextControl","Tooltip","Submit","Button","CancelIcon","LoadingMessage","SuccessMessage","ValidityState","HelpMessage"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EditInPlace.js","sources":["../../../../../src/components/Form/Controls/EditInPlace/EditInPlace.tsx"],"sourcesContent":["/*\nCopyright 2024 New Vector Ltd.\n\nSPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport React, {\n forwardRef,\n useCallback,\n useRef,\n useState,\n useEffect,\n useReducer,\n} from \"react\";\nimport { Submit, ValidityState } from \"@radix-ui/react-form\";\nimport CheckIcon from \"@vector-im/compound-design-tokens/assets/web/icons/check\";\nimport CancelIcon from \"@vector-im/compound-design-tokens/assets/web/icons/close\";\n\nimport styles from \"./EditInPlace.module.css\";\n\nimport {\n Field,\n HelpMessage,\n Label,\n LoadingMessage,\n Root,\n SuccessMessage,\n TextControl,\n} from \"../..\";\nimport { Button, Tooltip } from \"../../../..\";\n\ntype Props = {\n /**\n * The label for the control\n */\n label: string;\n\n /**\n * The CSS class name.\n */\n className?: string;\n\n /**\n * Callback for when the user confirms the change\n */\n onSave?: (e: React.FormEvent<HTMLFormElement>) => Promise<void> | void;\n\n /**\n * Callback for when the user wishes to cancel the change\n */\n onCancel?: (e: React.FormEvent<HTMLFormElement>) => void;\n\n /**\n * onInput event handler on the text control\n */\n onInput?: (e: React.ChangeEvent<HTMLInputElement>) => void;\n\n /**\n * Callback for when the server validation errors should be cleared.\n */\n onClearServerErrors?: () => void;\n\n /**\n * Whether the field is in an error state according to the server validation.\n *\n * For validation messages, use native validations properties directly, or add custom error messages as children.\n */\n serverInvalid?: boolean;\n\n /**\n * Label to be displayed by the green check at the bottom. Will only be displayed\n * for 2 seconds after the onSave callback promise resolves successfully.\n */\n savedLabel?: string;\n\n /**\n * The label for the save button\n */\n saveButtonLabel: string;\n\n /**\n * The label for the 'in progress' saving caption\n */\n savingLabel: string;\n\n /**\n * The label for the cancel button\n */\n cancelButtonLabel: string;\n\n /**\n * Label to be displayed under the input as a help text\n */\n helpLabel?: string;\n\n /**\n * If true, disabled the entire component to disallow editing.\n */\n disabled?: boolean;\n} & React.ComponentProps<typeof TextControl>;\n\nenum State {\n /** No changes on the input has been made */\n Initial,\n\n /** The input has been changed */\n Dirty,\n\n /** The input is being saved */\n Saving,\n\n /** The input has been saved */\n Saved,\n}\n\nenum Event {\n Touch, // The user 'touched' the control\n Save, // The user has clicked the save button\n Saved, // The onSave callback finished successfully\n SaveError, // The onSave callback finished with an error\n Cancel, // The user has clicked the cancel button\n SavedTimeout, // The user has clicked the save button and the saved label has been shown for 2 seconds\n}\n\nfunction reducer(state: State, action: Event): State {\n switch (action) {\n case Event.Touch:\n if (state === State.Initial || state === State.Saved) return State.Dirty;\n else return state;\n\n case Event.Save:\n return State.Saving;\n\n case Event.Cancel:\n return State.Initial;\n\n case Event.Saved:\n if (state === State.Saving) return State.Saved;\n else return state;\n\n case Event.SaveError:\n if (state === State.Saving) return State.Initial;\n else return state;\n\n case Event.SavedTimeout:\n if (state === State.Saved) return State.Initial;\n else return state;\n }\n\n assertNever(action);\n}\n\nfunction assertNever(value: never): never {\n throw new Error(`Unreachable value: ${value}`);\n}\n\n/**\n * A text box with save/cancel buttons that appear when the field is active.\n * Since thios control has its own 'save' button, it should *not* appear as part\n * of a larger form: it exists as its own form that submits separately.\n */\nexport const EditInPlace = forwardRef<HTMLInputElement, Props>(\n function EditInPlace(\n {\n className,\n label,\n onSave,\n onCancel,\n onInput,\n onClearServerErrors,\n serverInvalid,\n saveButtonLabel,\n cancelButtonLabel,\n savedLabel,\n savingLabel,\n helpLabel,\n disabled,\n children,\n ...props\n },\n ref,\n ) {\n const [state, dispatch] = useReducer(reducer, State.Initial);\n\n // Tracks the focus state of the form\n // This uses a `ref` to make sure the onFocus/onBlur callback don't trigger unnecessary re-renders\n // and a state to track the focus state and hide the buttons when the form is not focused\n const isFocusWithinRef = useRef(false);\n const [isFocusWithin, setFocusWithin] = useState(false);\n\n const shouldShowSaveButton =\n state === State.Dirty || state === State.Saving || isFocusWithin;\n\n const hideTimer = useRef<ReturnType<typeof setTimeout> | undefined>(\n undefined,\n );\n\n useEffect(() => {\n // Start a timer when we switch to the saved state\n if (state === State.Saved) {\n hideTimer.current = setTimeout(() => {\n dispatch(Event.SavedTimeout);\n hideTimer.current = undefined;\n }, 2000);\n }\n\n return () => {\n // Clear any timers that may have been set\n if (hideTimer.current) clearTimeout(hideTimer.current);\n hideTimer.current = undefined;\n };\n }, [state]);\n\n const formRef = useRef<HTMLFormElement>(null);\n const saveButtonRef = useRef<HTMLButtonElement>(null);\n const cancelButtonRef = useRef<HTMLButtonElement>(null);\n\n const onFocus = useCallback(() => {\n if (isFocusWithinRef.current) return;\n isFocusWithinRef.current = true;\n setFocusWithin(true);\n }, [isFocusWithin, setFocusWithin]);\n\n const onBlur = useCallback(\n (e: React.FocusEvent) => {\n if (!isFocusWithinRef.current) return;\n // If the user switched to another element within the form\n // consider that we're still focused within the form\n if (e.currentTarget.contains(e.relatedTarget)) return;\n\n isFocusWithinRef.current = false;\n setFocusWithin(false);\n },\n [isFocusWithin, setFocusWithin],\n );\n\n const onInputHandler = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n dispatch(Event.Touch);\n onInput?.(e);\n },\n [dispatch, onInput],\n );\n\n const onFormSubmit = useCallback(\n async (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n\n // Prevent submitting the form if the user has not yet entered any text\n if (state === State.Initial) {\n return;\n }\n\n try {\n dispatch(Event.Save);\n saveButtonRef.current?.blur();\n await onSave?.(e);\n dispatch(Event.Saved);\n } catch {\n // We don't really need to do anything here, we just don't want to display the\n // 'saved' label, obviously. The user of the component can update the error to\n // show what failed.\n dispatch(Event.SaveError);\n }\n },\n [onSave, state, hideTimer],\n );\n\n const onFormReset = useCallback(\n (e: React.FormEvent<HTMLFormElement>) => {\n cancelButtonRef.current?.blur();\n onCancel?.(e);\n dispatch(Event.Cancel);\n },\n [cancelButtonRef, onCancel],\n );\n\n return (\n <Root\n className={className}\n onSubmit={onFormSubmit}\n onReset={onFormReset}\n onFocus={onFocus}\n onBlur={onBlur}\n onClearServerErrors={onClearServerErrors}\n ref={formRef}\n >\n <Field name=\"input\" serverInvalid={serverInvalid}>\n <Label>{label}</Label>\n <div className={styles.controls}>\n <TextControl\n ref={ref}\n {...props}\n onInput={onInputHandler}\n disabled={disabled || state === State.Saving}\n />\n\n {shouldShowSaveButton && (\n <div className={styles[\"button-group\"]}>\n <Tooltip label={saveButtonLabel}>\n <Submit asChild>\n <Button\n type=\"submit\"\n kind=\"primary\"\n size=\"sm\"\n ref={saveButtonRef}\n disabled={state !== State.Dirty}\n iconOnly\n Icon={CheckIcon}\n />\n </Submit>\n </Tooltip>\n\n <Tooltip label={cancelButtonLabel}>\n <Button\n type=\"reset\"\n kind=\"secondary\"\n size=\"sm\"\n ref={cancelButtonRef}\n className={styles.button}\n disabled={state === State.Saving}\n iconOnly\n Icon={CancelIcon}\n />\n </Tooltip>\n </div>\n )}\n </div>\n\n {/*\n During the loading saving state, we only show the saving message.\n Else, we show whatever children were passed on, as they will have other validation messages\n */}\n {state === State.Saving ? (\n <LoadingMessage>{savingLabel}</LoadingMessage>\n ) : (\n children\n )}\n\n {savedLabel && state === State.Saved && (\n <SuccessMessage>{savedLabel}</SuccessMessage>\n )}\n\n {/*\n We show the help message only if:\n - the helpLabel is set\n - the form hasn't been validated yet\n - the 'serverInvalid' prop is not set\n - we're in the initial or dirty state\n */}\n {helpLabel && (state === State.Initial || state === State.Dirty) && (\n <ValidityState>\n {(validity) =>\n (validity === undefined || validity.valid) &&\n !serverInvalid && <HelpMessage>{helpLabel}</HelpMessage>\n }\n </ValidityState>\n )}\n </Field>\n </Root>\n );\n },\n);\n"],"names":["EditInPlace","CancelIcon"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"EditInPlace.js","sources":["../../../../../src/components/Form/Controls/EditInPlace/EditInPlace.tsx"],"sourcesContent":["/*\nCopyright 2024 New Vector Ltd.\n\nSPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport React, {\n forwardRef,\n useCallback,\n useRef,\n useState,\n useEffect,\n useReducer,\n} from \"react\";\nimport { Submit, ValidityState } from \"@radix-ui/react-form\";\nimport CheckIcon from \"@vector-im/compound-design-tokens/assets/web/icons/check\";\nimport CancelIcon from \"@vector-im/compound-design-tokens/assets/web/icons/close\";\n\nimport styles from \"./EditInPlace.module.css\";\n\nimport {\n Field,\n HelpMessage,\n Label,\n LoadingMessage,\n Root,\n SuccessMessage,\n TextControl,\n} from \"../..\";\nimport { Button, Tooltip } from \"../../../..\";\n\ntype Props = {\n /**\n * The label for the control\n */\n label: string;\n\n /**\n * The CSS class name.\n */\n className?: string;\n\n /**\n * Callback for when the user confirms the change\n */\n onSave?: (e: React.FormEvent<HTMLFormElement>) => Promise<void> | void;\n\n /**\n * Callback for when the user wishes to cancel the change\n */\n onCancel?: (e: React.FormEvent<HTMLFormElement>) => void;\n\n /**\n * onInput event handler on the text control\n */\n onInput?: (e: React.ChangeEvent<HTMLInputElement>) => void;\n\n /**\n * Callback for when the server validation errors should be cleared.\n */\n onClearServerErrors?: () => void;\n\n /**\n * Whether the field is in an error state according to the server validation.\n *\n * For validation messages, use native validations properties directly, or add custom error messages as children.\n */\n serverInvalid?: boolean;\n\n /**\n * Label to be displayed by the green check at the bottom. Will only be displayed\n * for 2 seconds after the onSave callback promise resolves successfully.\n */\n savedLabel?: string;\n\n /**\n * The label for the save button\n */\n saveButtonLabel: string;\n\n /**\n * The label for the 'in progress' saving caption\n */\n savingLabel: string;\n\n /**\n * The label for the cancel button\n */\n cancelButtonLabel: string;\n\n /**\n * Label to be displayed under the input as a help text\n */\n helpLabel?: string;\n\n /**\n * If true, disabled the entire component to disallow editing.\n */\n disabled?: boolean;\n} & React.ComponentProps<typeof TextControl>;\n\nenum State {\n /** No changes on the input has been made */\n Initial,\n\n /** The input has been changed */\n Dirty,\n\n /** The input is being saved */\n Saving,\n\n /** The input has been saved */\n Saved,\n}\n\nenum Event {\n Touch, // The user 'touched' the control\n Save, // The user has clicked the save button\n Saved, // The onSave callback finished successfully\n SaveError, // The onSave callback finished with an error\n Cancel, // The user has clicked the cancel button\n SavedTimeout, // The user has clicked the save button and the saved label has been shown for 2 seconds\n}\n\nfunction reducer(state: State, action: Event): State {\n switch (action) {\n case Event.Touch:\n if (state === State.Initial || state === State.Saved) return State.Dirty;\n else return state;\n\n case Event.Save:\n return State.Saving;\n\n case Event.Cancel:\n return State.Initial;\n\n case Event.Saved:\n if (state === State.Saving) return State.Saved;\n else return state;\n\n case Event.SaveError:\n if (state === State.Saving) return State.Initial;\n else return state;\n\n case Event.SavedTimeout:\n if (state === State.Saved) return State.Initial;\n else return state;\n }\n\n assertNever(action);\n}\n\nfunction assertNever(value: never): never {\n throw new Error(`Unreachable value: ${value}`);\n}\n\n/**\n * A text box with save/cancel buttons that appear when the field is active.\n * Since thios control has its own 'save' button, it should *not* appear as part\n * of a larger form: it exists as its own form that submits separately.\n */\nexport const EditInPlace = forwardRef<HTMLInputElement, Props>(\n function EditInPlace(\n {\n className,\n label,\n onSave,\n onCancel,\n onInput,\n onClearServerErrors,\n serverInvalid,\n saveButtonLabel,\n cancelButtonLabel,\n savedLabel,\n savingLabel,\n helpLabel,\n disabled,\n children,\n ...props\n },\n ref,\n ) {\n const [state, dispatch] = useReducer(reducer, State.Initial);\n\n // Tracks the focus state of the form\n // This uses a `ref` to make sure the onFocus/onBlur callback don't trigger unnecessary re-renders\n // and a state to track the focus state and hide the buttons when the form is not focused\n const isFocusWithinRef = useRef(false);\n const [isFocusWithin, setFocusWithin] = useState(false);\n\n const shouldShowSaveButton =\n state === State.Dirty || state === State.Saving || isFocusWithin;\n\n const hideTimer = useRef<ReturnType<typeof setTimeout> | undefined>(\n undefined,\n );\n\n useEffect(() => {\n // Start a timer when we switch to the saved state\n if (state === State.Saved) {\n hideTimer.current = setTimeout(() => {\n dispatch(Event.SavedTimeout);\n hideTimer.current = undefined;\n }, 2000);\n }\n\n return () => {\n // Clear any timers that may have been set\n if (hideTimer.current) clearTimeout(hideTimer.current);\n hideTimer.current = undefined;\n };\n }, [state]);\n\n const formRef = useRef<HTMLFormElement>(null);\n const saveButtonRef = useRef<HTMLButtonElement>(null);\n const cancelButtonRef = useRef<HTMLButtonElement>(null);\n\n const onFocus = useCallback(() => {\n if (isFocusWithinRef.current) return;\n isFocusWithinRef.current = true;\n setFocusWithin(true);\n }, [isFocusWithin, setFocusWithin]);\n\n const onBlur = useCallback(\n (e: React.FocusEvent) => {\n if (!isFocusWithinRef.current) return;\n // If the user switched to another element within the form\n // consider that we're still focused within the form\n if (e.currentTarget.contains(e.relatedTarget)) return;\n\n isFocusWithinRef.current = false;\n setFocusWithin(false);\n },\n [isFocusWithin, setFocusWithin],\n );\n\n const onInputHandler = useCallback(\n (e: React.InputEvent<HTMLInputElement>) => {\n dispatch(Event.Touch);\n onInput?.(e);\n },\n [dispatch, onInput],\n );\n\n const onFormSubmit = useCallback(\n async (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n\n // Prevent submitting the form if the user has not yet entered any text\n if (state === State.Initial) {\n return;\n }\n\n try {\n dispatch(Event.Save);\n saveButtonRef.current?.blur();\n await onSave?.(e);\n dispatch(Event.Saved);\n } catch {\n // We don't really need to do anything here, we just don't want to display the\n // 'saved' label, obviously. The user of the component can update the error to\n // show what failed.\n dispatch(Event.SaveError);\n }\n },\n [onSave, state, hideTimer],\n );\n\n const onFormReset = useCallback(\n (e: React.FormEvent<HTMLFormElement>) => {\n cancelButtonRef.current?.blur();\n onCancel?.(e);\n dispatch(Event.Cancel);\n },\n [cancelButtonRef, onCancel],\n );\n\n return (\n <Root\n className={className}\n onSubmit={onFormSubmit}\n onReset={onFormReset}\n onFocus={onFocus}\n onBlur={onBlur}\n onClearServerErrors={onClearServerErrors}\n ref={formRef}\n >\n <Field name=\"input\" serverInvalid={serverInvalid}>\n <Label>{label}</Label>\n <div className={styles.controls}>\n <TextControl\n ref={ref}\n {...props}\n onInput={onInputHandler}\n disabled={disabled || state === State.Saving}\n />\n\n {shouldShowSaveButton && (\n <div className={styles[\"button-group\"]}>\n <Tooltip label={saveButtonLabel}>\n <Submit asChild>\n <Button\n type=\"submit\"\n kind=\"primary\"\n size=\"sm\"\n ref={saveButtonRef}\n disabled={state !== State.Dirty}\n iconOnly\n Icon={CheckIcon}\n />\n </Submit>\n </Tooltip>\n\n <Tooltip label={cancelButtonLabel}>\n <Button\n type=\"reset\"\n kind=\"secondary\"\n size=\"sm\"\n ref={cancelButtonRef}\n className={styles.button}\n disabled={state === State.Saving}\n iconOnly\n Icon={CancelIcon}\n />\n </Tooltip>\n </div>\n )}\n </div>\n\n {/*\n During the loading saving state, we only show the saving message.\n Else, we show whatever children were passed on, as they will have other validation messages\n */}\n {state === State.Saving ? (\n <LoadingMessage>{savingLabel}</LoadingMessage>\n ) : (\n children\n )}\n\n {savedLabel && state === State.Saved && (\n <SuccessMessage>{savedLabel}</SuccessMessage>\n )}\n\n {/*\n We show the help message only if:\n - the helpLabel is set\n - the form hasn't been validated yet\n - the 'serverInvalid' prop is not set\n - we're in the initial or dirty state\n */}\n {helpLabel && (state === State.Initial || state === State.Dirty) && (\n <ValidityState>\n {(validity) =>\n (validity === undefined || validity.valid) &&\n !serverInvalid && <HelpMessage>{helpLabel}</HelpMessage>\n }\n </ValidityState>\n )}\n </Field>\n </Root>\n );\n },\n);\n"],"names":["EditInPlace","CancelIcon"],"mappings":"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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
3
|
-
const container = "
|
|
4
|
-
const input = "
|
|
5
|
-
const ui = "
|
|
3
|
+
const container = "_container_1ug7n_10";
|
|
4
|
+
const input = "_input_1ug7n_18";
|
|
5
|
+
const ui = "_ui_1ug7n_19";
|
|
6
6
|
const styles = {
|
|
7
7
|
container,
|
|
8
8
|
input,
|
|
@@ -8,14 +8,14 @@ const reactForm = require("@radix-ui/react-form");
|
|
|
8
8
|
const Message = require("./Message.cjs");
|
|
9
9
|
const Submit = require("./Submit.cjs");
|
|
10
10
|
const Action = require("./Controls/Action/Action.cjs");
|
|
11
|
-
const Password = require("./Controls/Password/Password.cjs");
|
|
12
|
-
const Text = require("./Controls/Text/Text.cjs");
|
|
13
|
-
const MFA = require("./Controls/MFA/MFA.cjs");
|
|
14
11
|
const Checkbox = require("./Controls/Checkbox/Checkbox.cjs");
|
|
15
|
-
const Radio = require("./Controls/Radio/Radio.cjs");
|
|
16
|
-
const Toggle = require("./Controls/Toggle/Toggle.cjs");
|
|
17
12
|
const EditInPlace = require("./Controls/EditInPlace/EditInPlace.cjs");
|
|
13
|
+
const MFA = require("./Controls/MFA/MFA.cjs");
|
|
14
|
+
const Password = require("./Controls/Password/Password.cjs");
|
|
15
|
+
const Radio = require("./Controls/Radio/Radio.cjs");
|
|
18
16
|
const SettingsToggle = require("./Controls/SettingsToggle/SettingsToggle.cjs");
|
|
17
|
+
const Text = require("./Controls/Text/Text.cjs");
|
|
18
|
+
const Toggle = require("./Controls/Toggle/Toggle.cjs");
|
|
19
19
|
exports.Root = Root.Root;
|
|
20
20
|
exports.Field = Field.Field;
|
|
21
21
|
exports.InlineField = InlineField.InlineField;
|
|
@@ -35,19 +35,19 @@ exports.SuccessMessage = Message.SuccessMessage;
|
|
|
35
35
|
exports.Submit = Submit.Submit;
|
|
36
36
|
exports.ActionControl = Action.ActionControl;
|
|
37
37
|
exports.ActionInput = Action.ActionInput;
|
|
38
|
-
exports.PasswordControl = Password.PasswordControl;
|
|
39
|
-
exports.PasswordInput = Password.PasswordInput;
|
|
40
|
-
exports.TextControl = Text.TextControl;
|
|
41
|
-
exports.TextInput = Text.TextInput;
|
|
42
|
-
exports.MFAControl = MFA.MFAControl;
|
|
43
|
-
exports.MFAInput = MFA.MFAInput;
|
|
44
38
|
exports.CheckboxControl = Checkbox.CheckboxControl;
|
|
45
39
|
exports.CheckboxInput = Checkbox.CheckboxInput;
|
|
40
|
+
exports.EditInPlace = EditInPlace.EditInPlace;
|
|
41
|
+
exports.MFAControl = MFA.MFAControl;
|
|
42
|
+
exports.MFAInput = MFA.MFAInput;
|
|
43
|
+
exports.PasswordControl = Password.PasswordControl;
|
|
44
|
+
exports.PasswordInput = Password.PasswordInput;
|
|
46
45
|
exports.RadioControl = Radio.RadioControl;
|
|
47
46
|
exports.RadioInput = Radio.RadioInput;
|
|
48
|
-
exports.ToggleControl = Toggle.ToggleControl;
|
|
49
|
-
exports.ToggleInput = Toggle.ToggleInput;
|
|
50
|
-
exports.EditInPlace = EditInPlace.EditInPlace;
|
|
51
47
|
exports.SettingsToggleControl = SettingsToggle.SettingsToggleControl;
|
|
52
48
|
exports.SettingsToggleInput = SettingsToggle.SettingsToggleInput;
|
|
49
|
+
exports.TextControl = Text.TextControl;
|
|
50
|
+
exports.TextInput = Text.TextInput;
|
|
51
|
+
exports.ToggleControl = Toggle.ToggleControl;
|
|
52
|
+
exports.ToggleInput = Toggle.ToggleInput;
|
|
53
53
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -6,14 +6,14 @@ import { Message, ValidityState } from "@radix-ui/react-form";
|
|
|
6
6
|
import { ErrorMessage, HelpMessage, LoadingMessage, SuccessMessage } from "./Message.js";
|
|
7
7
|
import { Submit } from "./Submit.js";
|
|
8
8
|
import { ActionControl, ActionInput } from "./Controls/Action/Action.js";
|
|
9
|
-
import { PasswordControl, PasswordInput } from "./Controls/Password/Password.js";
|
|
10
|
-
import { TextControl, TextInput } from "./Controls/Text/Text.js";
|
|
11
|
-
import { MFAControl, MFAInput } from "./Controls/MFA/MFA.js";
|
|
12
9
|
import { CheckboxControl, CheckboxInput } from "./Controls/Checkbox/Checkbox.js";
|
|
13
|
-
import { RadioControl, RadioInput } from "./Controls/Radio/Radio.js";
|
|
14
|
-
import { ToggleControl, ToggleInput } from "./Controls/Toggle/Toggle.js";
|
|
15
10
|
import { EditInPlace } from "./Controls/EditInPlace/EditInPlace.js";
|
|
11
|
+
import { MFAControl, MFAInput } from "./Controls/MFA/MFA.js";
|
|
12
|
+
import { PasswordControl, PasswordInput } from "./Controls/Password/Password.js";
|
|
13
|
+
import { RadioControl, RadioInput } from "./Controls/Radio/Radio.js";
|
|
16
14
|
import { SettingsToggleControl, SettingsToggleInput } from "./Controls/SettingsToggle/SettingsToggle.js";
|
|
15
|
+
import { TextControl, TextInput } from "./Controls/Text/Text.js";
|
|
16
|
+
import { ToggleControl, ToggleInput } from "./Controls/Toggle/Toggle.js";
|
|
17
17
|
export {
|
|
18
18
|
ActionControl,
|
|
19
19
|
ActionInput,
|
|
@@ -7,7 +7,6 @@ const FloatingMenu = require("./FloatingMenu.cjs");
|
|
|
7
7
|
const vaul = require("vaul");
|
|
8
8
|
const classNames = require("classnames");
|
|
9
9
|
const DrawerMenu_module = require("./DrawerMenu.module.css.cjs");
|
|
10
|
-
const ContextMenu_module = require("./ContextMenu.module.css.cjs");
|
|
11
10
|
const MenuContext = require("./MenuContext.cjs");
|
|
12
11
|
const DrawerMenu = require("./DrawerMenu.cjs");
|
|
13
12
|
const platform = require("../../utils/platform.cjs");
|
|
@@ -58,7 +57,7 @@ const ContextMenu = ({
|
|
|
58
57
|
] }) })
|
|
59
58
|
] }) : /* @__PURE__ */ jsxRuntime.jsxs(reactContextMenu.Root, { onOpenChange, children: [
|
|
60
59
|
trigger,
|
|
61
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactContextMenu.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(reactContextMenu.Content, { asChild: true,
|
|
60
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactContextMenu.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(reactContextMenu.Content, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(FloatingMenu.FloatingMenu, { showTitle, title, children }) }) })
|
|
62
61
|
] });
|
|
63
62
|
};
|
|
64
63
|
exports.ContextMenu = ContextMenu;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContextMenu.cjs","sources":["../../../src/components/Menu/ContextMenu.tsx"],"sourcesContent":["/*\nCopyright 2023 New Vector Ltd.\n\nSPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport React, {\n type FC,\n type ReactNode,\n useCallback,\n useMemo,\n useState,\n} from \"react\";\nimport {\n Root,\n Trigger,\n Portal,\n Content,\n ContextMenuItem,\n} from \"@radix-ui/react-context-menu\";\nimport { FloatingMenu } from \"./FloatingMenu\";\nimport { Drawer } from \"vaul\";\nimport classnames from \"classnames\";\nimport drawerStyles from \"./DrawerMenu.module.css\";\nimport
|
|
1
|
+
{"version":3,"file":"ContextMenu.cjs","sources":["../../../src/components/Menu/ContextMenu.tsx"],"sourcesContent":["/*\nCopyright 2023 New Vector Ltd.\n\nSPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport React, {\n type FC,\n type ReactNode,\n useCallback,\n useMemo,\n useState,\n} from \"react\";\nimport {\n Root,\n Trigger,\n Portal,\n Content,\n ContextMenuItem,\n} from \"@radix-ui/react-context-menu\";\nimport { FloatingMenu } from \"./FloatingMenu\";\nimport { Drawer } from \"vaul\";\nimport classnames from \"classnames\";\nimport drawerStyles from \"./DrawerMenu.module.css\";\nimport {\n MenuContext,\n type MenuData,\n type MenuItemWrapperProps,\n} from \"./MenuContext\";\nimport { DrawerMenu } from \"./DrawerMenu\";\nimport { getPlatform } from \"../../utils/platform\";\n\ninterface Props {\n /**\n * The menu title.\n */\n title: string;\n /**\n * Wether the title is displayed.\n * @default true\n */\n showTitle?: boolean;\n /**\n * Event handler called when the open state of the menu changes.\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * The trigger that can be right-clicked or long-pressed to open the menu.\n * This must be a component that accepts a ref and spreads props.\n * https://www.radix-ui.com/primitives/docs/guides/composition\n */\n trigger: ReactNode;\n /**\n * Whether the functionality of this menu is available through some other\n * keyboard-accessible means. Preferably this should be true, because context\n * menus are potentially difficult to discover, but if false the trigger will\n * become focusable so that it can be opened via keyboard navigation.\n */\n hasAccessibleAlternative: boolean;\n /**\n * The menu contents.\n */\n children: ReactNode;\n}\n\nconst ContextMenuItemWrapper: FC<MenuItemWrapperProps> = ({\n onSelect,\n children,\n}) => (\n <ContextMenuItem onSelect={onSelect ?? undefined} asChild>\n {children}\n </ContextMenuItem>\n);\n\n/**\n * A menu opened by right-clicking or long-pressing another UI element.\n */\nexport const ContextMenu: FC<Props> = ({\n title,\n showTitle = true,\n onOpenChange: onOpenChangeProp,\n trigger: triggerProp,\n hasAccessibleAlternative,\n children: childrenProp,\n}) => {\n const [open, setOpen] = useState(false);\n const onOpenChange = useCallback(\n (value: boolean) => {\n setOpen(value);\n onOpenChangeProp?.(value);\n },\n [setOpen, onOpenChangeProp],\n );\n\n // Normally, the menu takes the form of a floating box. But on Android and\n // iOS, the menu should morph into a drawer\n const platform = getPlatform();\n const drawer = platform === \"android\" || platform === \"ios\";\n const context: MenuData = useMemo(\n () => ({\n MenuItemWrapper: drawer ? null : ContextMenuItemWrapper,\n onOpenChange,\n }),\n [onOpenChange],\n );\n const children = (\n <MenuContext.Provider value={context}>{childrenProp}</MenuContext.Provider>\n );\n\n const trigger = (\n <Trigger\n aria-haspopup=\"menu\"\n tabIndex={hasAccessibleAlternative ? undefined : 0}\n asChild\n >\n {triggerProp}\n </Trigger>\n );\n\n // This is a small hack: Vaul drawers only support buttons as triggers, so\n // we end up mounting an empty Radix context menu tree alongside the\n // drawer tree, purely so we can use its Trigger component (which supports\n // touch for free). The resulting behavior and DOM tree looks exactly the\n // same as if Vaul provided a long-press trigger of its own, so I think\n // this is fine.\n return drawer ? (\n <>\n <Root onOpenChange={onOpenChange}>{trigger}</Root>\n <Drawer.Root open={open} onOpenChange={onOpenChange}>\n <Drawer.Portal>\n <Drawer.Overlay className={classnames(drawerStyles.bg)} />\n <Drawer.Content asChild>\n <DrawerMenu title={title}>{children}</DrawerMenu>\n </Drawer.Content>\n </Drawer.Portal>\n </Drawer.Root>\n </>\n ) : (\n <Root onOpenChange={onOpenChange}>\n {trigger}\n <Portal>\n <Content asChild>\n <FloatingMenu showTitle={showTitle} title={title}>\n {children}\n </FloatingMenu>\n </Content>\n </Portal>\n </Root>\n );\n};\n"],"names":["ContextMenuItem","useState","useCallback","platform","getPlatform","useMemo","jsx","MenuContext","Trigger","jsxs","Fragment","Root","Drawer","classnames","drawerStyles","DrawerMenu","Portal","Content","FloatingMenu"],"mappings":";;;;;;;;;;;;AAkEA,MAAM,yBAAmD,CAAC;AAAA,EACxD;AAAA,EACA;AACF,qCACGA,kCAAA,EAAgB,UAAU,YAAY,QAAW,SAAO,MACtD,UACH;AAMK,MAAM,cAAyB,CAAC;AAAA,EACrC;AAAA,EACA,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,SAAS;AAAA,EACT;AAAA,EACA,UAAU;AACZ,MAAM;AACJ,QAAM,CAAC,MAAM,OAAO,IAAIC,MAAAA,SAAS,KAAK;AACtC,QAAM,eAAeC,MAAAA;AAAAA,IACnB,CAAC,UAAmB;AAClB,cAAQ,KAAK;AACb,yBAAmB,KAAK;AAAA,IAC1B;AAAA,IACA,CAAC,SAAS,gBAAgB;AAAA,EAAA;AAK5B,QAAMC,aAAWC,SAAAA,YAAA;AACjB,QAAM,SAASD,eAAa,aAAaA,eAAa;AACtD,QAAM,UAAoBE,MAAAA;AAAAA,IACxB,OAAO;AAAA,MACL,iBAAiB,SAAS,OAAO;AAAA,MACjC;AAAA,IAAA;AAAA,IAEF,CAAC,YAAY;AAAA,EAAA;AAEf,QAAM,WACJC,+BAACC,YAAAA,YAAY,UAAZ,EAAqB,OAAO,SAAU,UAAA,cAAa;AAGtD,QAAM,UACJD,2BAAAA;AAAAA,IAACE,iBAAAA;AAAAA,IAAA;AAAA,MACC,iBAAc;AAAA,MACd,UAAU,2BAA2B,SAAY;AAAA,MACjD,SAAO;AAAA,MAEN,UAAA;AAAA,IAAA;AAAA,EAAA;AAUL,SAAO,SACLC,2BAAAA,KAAAC,WAAAA,UAAA,EACE,UAAA;AAAA,IAAAJ,2BAAAA,IAACK,iBAAAA,MAAA,EAAK,cAA6B,UAAA,QAAA,CAAQ;AAAA,IAC3CL,2BAAAA,IAACM,KAAAA,OAAO,MAAP,EAAY,MAAY,cACvB,UAAAH,gCAACG,KAAAA,OAAO,QAAP,EACC,UAAA;AAAA,MAAAN,+BAACM,KAAAA,OAAO,SAAP,EAAe,WAAWC,WAAWC,kBAAAA,QAAa,EAAE,GAAG;AAAA,MACxDR,2BAAAA,IAACM,KAAAA,OAAO,SAAP,EAAe,SAAO,MACrB,UAAAN,2BAAAA,IAACS,WAAAA,YAAA,EAAW,OAAe,SAAA,CAAS,EAAA,CACtC;AAAA,IAAA,EAAA,CACF,EAAA,CACF;AAAA,EAAA,EAAA,CACF,IAEAN,2BAAAA,KAACE,iBAAAA,MAAA,EAAK,cACH,UAAA;AAAA,IAAA;AAAA,IACDL,2BAAAA,IAACU,iBAAAA,QAAA,EACC,UAAAV,2BAAAA,IAACW,iBAAAA,SAAA,EAAQ,SAAO,MACd,UAAAX,2BAAAA,IAACY,aAAAA,cAAA,EAAa,WAAsB,OACjC,SAAA,CACH,EAAA,CACF,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContextMenu.d.ts","sourceRoot":"","sources":["../../../src/components/Menu/ContextMenu.tsx"],"names":[],"mappings":"AAOA,OAAc,EACZ,KAAK,EAAE,EACP,KAAK,SAAS,EAIf,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"ContextMenu.d.ts","sourceRoot":"","sources":["../../../src/components/Menu/ContextMenu.tsx"],"names":[],"mappings":"AAOA,OAAc,EACZ,KAAK,EAAE,EACP,KAAK,SAAS,EAIf,MAAM,OAAO,CAAC;AAoBf,UAAU,KAAK;IACb;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC;;;;OAIG;IACH,OAAO,EAAE,SAAS,CAAC;IACnB;;;;;OAKG;IACH,wBAAwB,EAAE,OAAO,CAAC;IAClC;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AAWD;;GAEG;AACH,eAAO,MAAM,WAAW,EAAE,EAAE,CAAC,KAAK,CAwEjC,CAAC"}
|
|
@@ -5,7 +5,6 @@ import { FloatingMenu } from "./FloatingMenu.js";
|
|
|
5
5
|
import { Drawer } from "vaul";
|
|
6
6
|
import classNames from "classnames";
|
|
7
7
|
import drawerMenu from "./DrawerMenu.module.css.js";
|
|
8
|
-
import contextStyles from "./ContextMenu.module.css.js";
|
|
9
8
|
import { MenuContext } from "./MenuContext.js";
|
|
10
9
|
import { DrawerMenu } from "./DrawerMenu.js";
|
|
11
10
|
import { getPlatform } from "../../utils/platform.js";
|
|
@@ -56,7 +55,7 @@ const ContextMenu = ({
|
|
|
56
55
|
] }) })
|
|
57
56
|
] }) : /* @__PURE__ */ jsxs(Root, { onOpenChange, children: [
|
|
58
57
|
trigger,
|
|
59
|
-
/* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(Content, { asChild: true,
|
|
58
|
+
/* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(Content, { asChild: true, children: /* @__PURE__ */ jsx(FloatingMenu, { showTitle, title, children }) }) })
|
|
60
59
|
] });
|
|
61
60
|
};
|
|
62
61
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContextMenu.js","sources":["../../../src/components/Menu/ContextMenu.tsx"],"sourcesContent":["/*\nCopyright 2023 New Vector Ltd.\n\nSPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport React, {\n type FC,\n type ReactNode,\n useCallback,\n useMemo,\n useState,\n} from \"react\";\nimport {\n Root,\n Trigger,\n Portal,\n Content,\n ContextMenuItem,\n} from \"@radix-ui/react-context-menu\";\nimport { FloatingMenu } from \"./FloatingMenu\";\nimport { Drawer } from \"vaul\";\nimport classnames from \"classnames\";\nimport drawerStyles from \"./DrawerMenu.module.css\";\nimport
|
|
1
|
+
{"version":3,"file":"ContextMenu.js","sources":["../../../src/components/Menu/ContextMenu.tsx"],"sourcesContent":["/*\nCopyright 2023 New Vector Ltd.\n\nSPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport React, {\n type FC,\n type ReactNode,\n useCallback,\n useMemo,\n useState,\n} from \"react\";\nimport {\n Root,\n Trigger,\n Portal,\n Content,\n ContextMenuItem,\n} from \"@radix-ui/react-context-menu\";\nimport { FloatingMenu } from \"./FloatingMenu\";\nimport { Drawer } from \"vaul\";\nimport classnames from \"classnames\";\nimport drawerStyles from \"./DrawerMenu.module.css\";\nimport {\n MenuContext,\n type MenuData,\n type MenuItemWrapperProps,\n} from \"./MenuContext\";\nimport { DrawerMenu } from \"./DrawerMenu\";\nimport { getPlatform } from \"../../utils/platform\";\n\ninterface Props {\n /**\n * The menu title.\n */\n title: string;\n /**\n * Wether the title is displayed.\n * @default true\n */\n showTitle?: boolean;\n /**\n * Event handler called when the open state of the menu changes.\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * The trigger that can be right-clicked or long-pressed to open the menu.\n * This must be a component that accepts a ref and spreads props.\n * https://www.radix-ui.com/primitives/docs/guides/composition\n */\n trigger: ReactNode;\n /**\n * Whether the functionality of this menu is available through some other\n * keyboard-accessible means. Preferably this should be true, because context\n * menus are potentially difficult to discover, but if false the trigger will\n * become focusable so that it can be opened via keyboard navigation.\n */\n hasAccessibleAlternative: boolean;\n /**\n * The menu contents.\n */\n children: ReactNode;\n}\n\nconst ContextMenuItemWrapper: FC<MenuItemWrapperProps> = ({\n onSelect,\n children,\n}) => (\n <ContextMenuItem onSelect={onSelect ?? undefined} asChild>\n {children}\n </ContextMenuItem>\n);\n\n/**\n * A menu opened by right-clicking or long-pressing another UI element.\n */\nexport const ContextMenu: FC<Props> = ({\n title,\n showTitle = true,\n onOpenChange: onOpenChangeProp,\n trigger: triggerProp,\n hasAccessibleAlternative,\n children: childrenProp,\n}) => {\n const [open, setOpen] = useState(false);\n const onOpenChange = useCallback(\n (value: boolean) => {\n setOpen(value);\n onOpenChangeProp?.(value);\n },\n [setOpen, onOpenChangeProp],\n );\n\n // Normally, the menu takes the form of a floating box. But on Android and\n // iOS, the menu should morph into a drawer\n const platform = getPlatform();\n const drawer = platform === \"android\" || platform === \"ios\";\n const context: MenuData = useMemo(\n () => ({\n MenuItemWrapper: drawer ? null : ContextMenuItemWrapper,\n onOpenChange,\n }),\n [onOpenChange],\n );\n const children = (\n <MenuContext.Provider value={context}>{childrenProp}</MenuContext.Provider>\n );\n\n const trigger = (\n <Trigger\n aria-haspopup=\"menu\"\n tabIndex={hasAccessibleAlternative ? undefined : 0}\n asChild\n >\n {triggerProp}\n </Trigger>\n );\n\n // This is a small hack: Vaul drawers only support buttons as triggers, so\n // we end up mounting an empty Radix context menu tree alongside the\n // drawer tree, purely so we can use its Trigger component (which supports\n // touch for free). The resulting behavior and DOM tree looks exactly the\n // same as if Vaul provided a long-press trigger of its own, so I think\n // this is fine.\n return drawer ? (\n <>\n <Root onOpenChange={onOpenChange}>{trigger}</Root>\n <Drawer.Root open={open} onOpenChange={onOpenChange}>\n <Drawer.Portal>\n <Drawer.Overlay className={classnames(drawerStyles.bg)} />\n <Drawer.Content asChild>\n <DrawerMenu title={title}>{children}</DrawerMenu>\n </Drawer.Content>\n </Drawer.Portal>\n </Drawer.Root>\n </>\n ) : (\n <Root onOpenChange={onOpenChange}>\n {trigger}\n <Portal>\n <Content asChild>\n <FloatingMenu showTitle={showTitle} title={title}>\n {children}\n </FloatingMenu>\n </Content>\n </Portal>\n </Root>\n );\n};\n"],"names":["classnames","drawerStyles"],"mappings":";;;;;;;;;;AAkEA,MAAM,yBAAmD,CAAC;AAAA,EACxD;AAAA,EACA;AACF,0BACG,iBAAA,EAAgB,UAAU,YAAY,QAAW,SAAO,MACtD,UACH;AAMK,MAAM,cAAyB,CAAC;AAAA,EACrC;AAAA,EACA,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,SAAS;AAAA,EACT;AAAA,EACA,UAAU;AACZ,MAAM;AACJ,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,KAAK;AACtC,QAAM,eAAe;AAAA,IACnB,CAAC,UAAmB;AAClB,cAAQ,KAAK;AACb,yBAAmB,KAAK;AAAA,IAC1B;AAAA,IACA,CAAC,SAAS,gBAAgB;AAAA,EAAA;AAK5B,QAAM,WAAW,YAAA;AACjB,QAAM,SAAS,aAAa,aAAa,aAAa;AACtD,QAAM,UAAoB;AAAA,IACxB,OAAO;AAAA,MACL,iBAAiB,SAAS,OAAO;AAAA,MACjC;AAAA,IAAA;AAAA,IAEF,CAAC,YAAY;AAAA,EAAA;AAEf,QAAM,WACJ,oBAAC,YAAY,UAAZ,EAAqB,OAAO,SAAU,UAAA,cAAa;AAGtD,QAAM,UACJ;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,iBAAc;AAAA,MACd,UAAU,2BAA2B,SAAY;AAAA,MACjD,SAAO;AAAA,MAEN,UAAA;AAAA,IAAA;AAAA,EAAA;AAUL,SAAO,SACL,qBAAA,UAAA,EACE,UAAA;AAAA,IAAA,oBAAC,MAAA,EAAK,cAA6B,UAAA,QAAA,CAAQ;AAAA,IAC3C,oBAAC,OAAO,MAAP,EAAY,MAAY,cACvB,UAAA,qBAAC,OAAO,QAAP,EACC,UAAA;AAAA,MAAA,oBAAC,OAAO,SAAP,EAAe,WAAWA,WAAWC,WAAa,EAAE,GAAG;AAAA,MACxD,oBAAC,OAAO,SAAP,EAAe,SAAO,MACrB,UAAA,oBAAC,YAAA,EAAW,OAAe,SAAA,CAAS,EAAA,CACtC;AAAA,IAAA,EAAA,CACF,EAAA,CACF;AAAA,EAAA,EAAA,CACF,IAEA,qBAAC,MAAA,EAAK,cACH,UAAA;AAAA,IAAA;AAAA,IACD,oBAAC,QAAA,EACC,UAAA,oBAAC,SAAA,EAAQ,SAAO,MACd,UAAA,oBAAC,cAAA,EAAa,WAAsB,OACjC,SAAA,CACH,EAAA,CACF,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FloatingMenu.cjs","sources":["../../../src/components/Menu/FloatingMenu.tsx"],"sourcesContent":["/*\nCopyright 2023 New Vector Ltd.\n\nSPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport classnames from \"classnames\";\nimport React, {\n type ComponentPropsWithoutRef,\n type ReactNode,\n forwardRef,\n useId,\n} from \"react\";\nimport styles from \"./FloatingMenu.module.css\";\nimport { MenuTitle } from \"./MenuTitle.tsx\";\n\ninterface Props extends ComponentPropsWithoutRef<\"div\"> {\n /**\n * The menu title.\n */\n title: string;\n /**\n * Whether to show the title. If false, the title will be hidden but still used as a label for screen readers.\n */\n showTitle?: boolean;\n /**\n * The CSS class.\n */\n className?: string;\n /**\n * The menu contents.\n */\n children: ReactNode;\n}\n\n/**\n * A menu in a floating box, as commonly seen on desktop.\n */\n// This an internal component not intended for export! Consumers should use it\n// via the Menu or ContextMenu components.\nexport const FloatingMenu = forwardRef<HTMLDivElement, Props>(\n ({ title, showTitle = true, className, children, ...props }, ref) => {\n const titleId = useId();\n return (\n <div\n role=\"menu\"\n ref={ref}\n aria-label={showTitle ? undefined : title}\n aria-labelledby={showTitle ? titleId : undefined}\n className={classnames(className, styles.menu)}\n {...props}\n >\n {showTitle && (\n <MenuTitle className={styles.title} title={title} id={titleId} />\n )}\n {children}\n </div>\n );\n },\n);\n\nFloatingMenu.displayName = \"FloatingMenu\";\n"],"names":["forwardRef","useId","jsxs","classnames","styles","MenuTitle"],"mappings":";;;;;;;AAyCO,MAAM,eAAeA,MAAAA;AAAAA,EAC1B,CAAC,EAAE,OAAO,YAAY,MAAM,WAAW,UAAU,GAAG,MAAA,GAAS,QAAQ;AACnE,UAAM,UAAUC,MAAAA,MAAA;
|
|
1
|
+
{"version":3,"file":"FloatingMenu.cjs","sources":["../../../src/components/Menu/FloatingMenu.tsx"],"sourcesContent":["/*\nCopyright 2023 New Vector Ltd.\n\nSPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport classnames from \"classnames\";\nimport React, {\n type ComponentPropsWithoutRef,\n type ReactNode,\n forwardRef,\n useId,\n} from \"react\";\nimport styles from \"./FloatingMenu.module.css\";\nimport { MenuTitle } from \"./MenuTitle.tsx\";\n\ninterface Props extends ComponentPropsWithoutRef<\"div\"> {\n /**\n * The menu title.\n */\n title: string;\n /**\n * Whether to show the title. If false, the title will be hidden but still used as a label for screen readers.\n */\n showTitle?: boolean;\n /**\n * The CSS class.\n */\n className?: string;\n /**\n * The menu contents.\n */\n children: ReactNode;\n}\n\n/**\n * A menu in a floating box, as commonly seen on desktop.\n */\n// This an internal component not intended for export! Consumers should use it\n// via the Menu or ContextMenu components.\nexport const FloatingMenu = forwardRef<HTMLDivElement, Props>(\n ({ title, showTitle = true, className, children, ...props }, ref) => {\n const titleId = useId();\n\n return (\n <div\n role=\"menu\"\n ref={ref}\n aria-label={showTitle ? undefined : title}\n aria-labelledby={showTitle ? titleId : undefined}\n className={classnames(className, styles.menu)}\n {...props}\n >\n {showTitle && (\n <MenuTitle className={styles.title} title={title} id={titleId} />\n )}\n {children}\n </div>\n );\n },\n);\n\nFloatingMenu.displayName = \"FloatingMenu\";\n"],"names":["forwardRef","useId","jsxs","classnames","styles","MenuTitle"],"mappings":";;;;;;;AAyCO,MAAM,eAAeA,MAAAA;AAAAA,EAC1B,CAAC,EAAE,OAAO,YAAY,MAAM,WAAW,UAAU,GAAG,MAAA,GAAS,QAAQ;AACnE,UAAM,UAAUC,MAAAA,MAAA;AAEhB,WACEC,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL;AAAA,QACA,cAAY,YAAY,SAAY;AAAA,QACpC,mBAAiB,YAAY,UAAU;AAAA,QACvC,WAAWC,WAAW,WAAWC,oBAAAA,QAAO,IAAI;AAAA,QAC3C,GAAG;AAAA,QAEH,UAAA;AAAA,UAAA,4CACEC,UAAAA,WAAA,EAAU,WAAWD,4BAAO,OAAO,OAAc,IAAI,SAAS;AAAA,UAEhE;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAGP;AACF;AAEA,aAAa,cAAc;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FloatingMenu.d.ts","sourceRoot":"","sources":["../../../src/components/Menu/FloatingMenu.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,EACZ,KAAK,wBAAwB,EAC7B,KAAK,SAAS,EAGf,MAAM,OAAO,CAAC;AAIf,UAAU,KAAM,SAAQ,wBAAwB,CAAC,KAAK,CAAC;IACrD;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;GAEG;AAGH,eAAO,MAAM,YAAY,
|
|
1
|
+
{"version":3,"file":"FloatingMenu.d.ts","sourceRoot":"","sources":["../../../src/components/Menu/FloatingMenu.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,EACZ,KAAK,wBAAwB,EAC7B,KAAK,SAAS,EAGf,MAAM,OAAO,CAAC;AAIf,UAAU,KAAM,SAAQ,wBAAwB,CAAC,KAAK,CAAC;IACrD;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;GAEG;AAGH,eAAO,MAAM,YAAY,8EAoBxB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FloatingMenu.js","sources":["../../../src/components/Menu/FloatingMenu.tsx"],"sourcesContent":["/*\nCopyright 2023 New Vector Ltd.\n\nSPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport classnames from \"classnames\";\nimport React, {\n type ComponentPropsWithoutRef,\n type ReactNode,\n forwardRef,\n useId,\n} from \"react\";\nimport styles from \"./FloatingMenu.module.css\";\nimport { MenuTitle } from \"./MenuTitle.tsx\";\n\ninterface Props extends ComponentPropsWithoutRef<\"div\"> {\n /**\n * The menu title.\n */\n title: string;\n /**\n * Whether to show the title. If false, the title will be hidden but still used as a label for screen readers.\n */\n showTitle?: boolean;\n /**\n * The CSS class.\n */\n className?: string;\n /**\n * The menu contents.\n */\n children: ReactNode;\n}\n\n/**\n * A menu in a floating box, as commonly seen on desktop.\n */\n// This an internal component not intended for export! Consumers should use it\n// via the Menu or ContextMenu components.\nexport const FloatingMenu = forwardRef<HTMLDivElement, Props>(\n ({ title, showTitle = true, className, children, ...props }, ref) => {\n const titleId = useId();\n return (\n <div\n role=\"menu\"\n ref={ref}\n aria-label={showTitle ? undefined : title}\n aria-labelledby={showTitle ? titleId : undefined}\n className={classnames(className, styles.menu)}\n {...props}\n >\n {showTitle && (\n <MenuTitle className={styles.title} title={title} id={titleId} />\n )}\n {children}\n </div>\n );\n },\n);\n\nFloatingMenu.displayName = \"FloatingMenu\";\n"],"names":["classnames"],"mappings":";;;;;AAyCO,MAAM,eAAe;AAAA,EAC1B,CAAC,EAAE,OAAO,YAAY,MAAM,WAAW,UAAU,GAAG,MAAA,GAAS,QAAQ;AACnE,UAAM,UAAU,MAAA;
|
|
1
|
+
{"version":3,"file":"FloatingMenu.js","sources":["../../../src/components/Menu/FloatingMenu.tsx"],"sourcesContent":["/*\nCopyright 2023 New Vector Ltd.\n\nSPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport classnames from \"classnames\";\nimport React, {\n type ComponentPropsWithoutRef,\n type ReactNode,\n forwardRef,\n useId,\n} from \"react\";\nimport styles from \"./FloatingMenu.module.css\";\nimport { MenuTitle } from \"./MenuTitle.tsx\";\n\ninterface Props extends ComponentPropsWithoutRef<\"div\"> {\n /**\n * The menu title.\n */\n title: string;\n /**\n * Whether to show the title. If false, the title will be hidden but still used as a label for screen readers.\n */\n showTitle?: boolean;\n /**\n * The CSS class.\n */\n className?: string;\n /**\n * The menu contents.\n */\n children: ReactNode;\n}\n\n/**\n * A menu in a floating box, as commonly seen on desktop.\n */\n// This an internal component not intended for export! Consumers should use it\n// via the Menu or ContextMenu components.\nexport const FloatingMenu = forwardRef<HTMLDivElement, Props>(\n ({ title, showTitle = true, className, children, ...props }, ref) => {\n const titleId = useId();\n\n return (\n <div\n role=\"menu\"\n ref={ref}\n aria-label={showTitle ? undefined : title}\n aria-labelledby={showTitle ? titleId : undefined}\n className={classnames(className, styles.menu)}\n {...props}\n >\n {showTitle && (\n <MenuTitle className={styles.title} title={title} id={titleId} />\n )}\n {children}\n </div>\n );\n },\n);\n\nFloatingMenu.displayName = \"FloatingMenu\";\n"],"names":["classnames"],"mappings":";;;;;AAyCO,MAAM,eAAe;AAAA,EAC1B,CAAC,EAAE,OAAO,YAAY,MAAM,WAAW,UAAU,GAAG,MAAA,GAAS,QAAQ;AACnE,UAAM,UAAU,MAAA;AAEhB,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL;AAAA,QACA,cAAY,YAAY,SAAY;AAAA,QACpC,mBAAiB,YAAY,UAAU;AAAA,QACvC,WAAWA,WAAW,WAAW,OAAO,IAAI;AAAA,QAC3C,GAAG;AAAA,QAEH,UAAA;AAAA,UAAA,iCACE,WAAA,EAAU,WAAW,OAAO,OAAO,OAAc,IAAI,SAAS;AAAA,UAEhE;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAGP;AACF;AAEA,aAAa,cAAc;"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
3
|
-
const menu = "
|
|
4
|
-
const title = "
|
|
3
|
+
const menu = "_menu_1w1u7_8";
|
|
4
|
+
const title = "_title_1w1u7_63";
|
|
5
5
|
const styles = {
|
|
6
6
|
menu,
|
|
7
7
|
title
|
|
@@ -15,6 +15,7 @@ const DropdownMenuItemWrapper = ({
|
|
|
15
15
|
children
|
|
16
16
|
}) => /* @__PURE__ */ jsxRuntime.jsx(reactDropdownMenu.DropdownMenuItem, { onSelect: onSelect ?? void 0, asChild: true, children });
|
|
17
17
|
const Menu = ({
|
|
18
|
+
className,
|
|
18
19
|
title,
|
|
19
20
|
showTitle = true,
|
|
20
21
|
open,
|
|
@@ -42,7 +43,15 @@ const Menu = ({
|
|
|
42
43
|
] })
|
|
43
44
|
] }) : /* @__PURE__ */ jsxRuntime.jsxs(reactDropdownMenu.Root, { open, onOpenChange, children: [
|
|
44
45
|
/* @__PURE__ */ jsxRuntime.jsx(reactDropdownMenu.Trigger, { asChild: true, children: trigger }),
|
|
45
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactDropdownMenu.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(reactDropdownMenu.Content, { asChild: true, side, align, sideOffset: 8, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
46
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactDropdownMenu.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(reactDropdownMenu.Content, { asChild: true, side, align, sideOffset: 8, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
47
|
+
FloatingMenu.FloatingMenu,
|
|
48
|
+
{
|
|
49
|
+
className,
|
|
50
|
+
title,
|
|
51
|
+
showTitle,
|
|
52
|
+
children
|
|
53
|
+
}
|
|
54
|
+
) }) })
|
|
46
55
|
] });
|
|
47
56
|
};
|
|
48
57
|
exports.Menu = Menu;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Menu.cjs","sources":["../../../src/components/Menu/Menu.tsx"],"sourcesContent":["/*\nCopyright 2023 New Vector Ltd.\n\nSPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport React, { type FC, type ReactNode, useMemo } from \"react\";\nimport {\n Root,\n Trigger,\n Portal,\n Content,\n DropdownMenuItem,\n} from \"@radix-ui/react-dropdown-menu\";\nimport { FloatingMenu } from \"./FloatingMenu\";\nimport { Drawer } from \"vaul\";\nimport classnames from \"classnames\";\nimport drawerMenu from \"./DrawerMenu.module.css\";\nimport {\n MenuContext,\n type MenuData,\n type MenuItemWrapperProps,\n} from \"./MenuContext\";\nimport { DrawerMenu } from \"./DrawerMenu\";\nimport { getPlatform } from \"../../utils/platform\";\n\ninterface Props {\n /**\n * The menu title. This can be hidden with `showTitle={false}` in which case it will only\n * be a label for screen readers.\n */\n title: string;\n /**\n * Controls whether the title is displayed (see `title` prop). Titles are only displayed on\n * web: on mobile, this parameter is ignored.\n */\n showTitle?: boolean;\n /**\n * Whether the menu is open.\n */\n open: boolean;\n /**\n * Event handler called when the open state of the menu changes. This includes\n * anything like clicking the trigger, selecting a menu item, or dismissing\n * the menu with the mouse or keyboard.\n */\n onOpenChange: (open: boolean) => void;\n /**\n * The button that opens the menu. This must be a component that accepts a ref\n * and spreads props.\n * https://www.radix-ui.com/primitives/docs/guides/composition\n */\n trigger: ReactNode;\n /**\n * The menu contents.\n */\n children: ReactNode;\n /**\n * The side of the trigger on which to place the menu. Note that the menu may\n * still end up on a different side than the one you request if there isn't\n * enough space.\n * @default bottom\n */\n side?: \"top\" | \"right\" | \"bottom\" | \"left\";\n /**\n * The edge along which the menu and trigger will be aligned.\n * @default center\n */\n align?: \"start\" | \"center\" | \"end\";\n}\n\nconst DropdownMenuItemWrapper: FC<MenuItemWrapperProps> = ({\n onSelect,\n children,\n}) => (\n <DropdownMenuItem onSelect={onSelect ?? undefined} asChild>\n {children}\n </DropdownMenuItem>\n);\n\n/**\n * A menu opened by pressing a button.\n */\nexport const Menu: FC<Props> = ({\n title,\n showTitle = true,\n open,\n onOpenChange,\n trigger,\n children: childrenProp,\n side = \"bottom\",\n align = \"center\",\n}) => {\n // Normally, the menu takes the form of a floating box. But on Android and\n // iOS, the menu should morph into a drawer\n const platform = getPlatform();\n const drawer = platform === \"android\" || platform === \"ios\";\n const context: MenuData = useMemo(\n () => ({\n MenuItemWrapper: drawer ? null : DropdownMenuItemWrapper,\n onOpenChange,\n }),\n [onOpenChange],\n );\n const children = (\n <MenuContext.Provider value={context}>{childrenProp}</MenuContext.Provider>\n );\n\n return drawer ? (\n <Drawer.Root open={open} onOpenChange={onOpenChange}>\n <Drawer.Trigger asChild>{trigger}</Drawer.Trigger>\n <Drawer.Portal>\n <Drawer.Overlay className={classnames(drawerMenu.bg)} />\n <Drawer.Content asChild>\n <DrawerMenu title={title}>{children}</DrawerMenu>\n </Drawer.Content>\n </Drawer.Portal>\n </Drawer.Root>\n ) : (\n <Root open={open} onOpenChange={onOpenChange}>\n <Trigger asChild>{trigger}</Trigger>\n <Portal>\n <Content asChild side={side} align={align} sideOffset={8}>\n <FloatingMenu
|
|
1
|
+
{"version":3,"file":"Menu.cjs","sources":["../../../src/components/Menu/Menu.tsx"],"sourcesContent":["/*\nCopyright 2023 New Vector Ltd.\n\nSPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport React, { type FC, type ReactNode, useMemo } from \"react\";\nimport {\n Root,\n Trigger,\n Portal,\n Content,\n DropdownMenuItem,\n} from \"@radix-ui/react-dropdown-menu\";\nimport { FloatingMenu } from \"./FloatingMenu\";\nimport { Drawer } from \"vaul\";\nimport classnames from \"classnames\";\nimport drawerMenu from \"./DrawerMenu.module.css\";\nimport {\n MenuContext,\n type MenuData,\n type MenuItemWrapperProps,\n} from \"./MenuContext\";\nimport { DrawerMenu } from \"./DrawerMenu\";\nimport { getPlatform } from \"../../utils/platform\";\n\ninterface Props {\n /**\n * CSS classes for the menu.\n */\n className?: string;\n\n /**\n * The menu title. This can be hidden with `showTitle={false}` in which case it will only\n * be a label for screen readers.\n */\n title: string;\n /**\n * Controls whether the title is displayed (see `title` prop). Titles are only displayed on\n * web: on mobile, this parameter is ignored.\n */\n showTitle?: boolean;\n /**\n * Whether the menu is open.\n */\n open: boolean;\n /**\n * Event handler called when the open state of the menu changes. This includes\n * anything like clicking the trigger, selecting a menu item, or dismissing\n * the menu with the mouse or keyboard.\n */\n onOpenChange: (open: boolean) => void;\n /**\n * The button that opens the menu. This must be a component that accepts a ref\n * and spreads props.\n * https://www.radix-ui.com/primitives/docs/guides/composition\n */\n trigger: ReactNode;\n /**\n * The menu contents.\n */\n children: ReactNode;\n /**\n * The side of the trigger on which to place the menu. Note that the menu may\n * still end up on a different side than the one you request if there isn't\n * enough space.\n * @default bottom\n */\n side?: \"top\" | \"right\" | \"bottom\" | \"left\";\n /**\n * The edge along which the menu and trigger will be aligned.\n * @default center\n */\n align?: \"start\" | \"center\" | \"end\";\n}\n\nconst DropdownMenuItemWrapper: FC<MenuItemWrapperProps> = ({\n onSelect,\n children,\n}) => (\n <DropdownMenuItem onSelect={onSelect ?? undefined} asChild>\n {children}\n </DropdownMenuItem>\n);\n\n/**\n * A menu opened by pressing a button.\n */\nexport const Menu: FC<Props> = ({\n className,\n title,\n showTitle = true,\n open,\n onOpenChange,\n trigger,\n children: childrenProp,\n side = \"bottom\",\n align = \"center\",\n}) => {\n // Normally, the menu takes the form of a floating box. But on Android and\n // iOS, the menu should morph into a drawer\n const platform = getPlatform();\n const drawer = platform === \"android\" || platform === \"ios\";\n const context: MenuData = useMemo(\n () => ({\n MenuItemWrapper: drawer ? null : DropdownMenuItemWrapper,\n onOpenChange,\n }),\n [onOpenChange],\n );\n const children = (\n <MenuContext.Provider value={context}>{childrenProp}</MenuContext.Provider>\n );\n\n return drawer ? (\n <Drawer.Root open={open} onOpenChange={onOpenChange}>\n <Drawer.Trigger asChild>{trigger}</Drawer.Trigger>\n <Drawer.Portal>\n <Drawer.Overlay className={classnames(drawerMenu.bg)} />\n <Drawer.Content asChild>\n <DrawerMenu title={title}>{children}</DrawerMenu>\n </Drawer.Content>\n </Drawer.Portal>\n </Drawer.Root>\n ) : (\n <Root open={open} onOpenChange={onOpenChange}>\n <Trigger asChild>{trigger}</Trigger>\n <Portal>\n <Content asChild side={side} align={align} sideOffset={8}>\n <FloatingMenu\n className={className}\n title={title}\n showTitle={showTitle}\n >\n {children}\n </FloatingMenu>\n </Content>\n </Portal>\n </Root>\n );\n};\n"],"names":["DropdownMenuItem","platform","getPlatform","useMemo","jsx","MenuContext","jsxs","Drawer","classnames","drawerMenu","DrawerMenu","Root","Trigger","Portal","Content","FloatingMenu"],"mappings":";;;;;;;;;;;;AA6EA,MAAM,0BAAoD,CAAC;AAAA,EACzD;AAAA,EACA;AACF,qCACGA,oCAAA,EAAiB,UAAU,YAAY,QAAW,SAAO,MACvD,UACH;AAMK,MAAM,OAAkB,CAAC;AAAA,EAC9B;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,OAAO;AAAA,EACP,QAAQ;AACV,MAAM;AAGJ,QAAMC,aAAWC,SAAAA,YAAA;AACjB,QAAM,SAASD,eAAa,aAAaA,eAAa;AACtD,QAAM,UAAoBE,MAAAA;AAAAA,IACxB,OAAO;AAAA,MACL,iBAAiB,SAAS,OAAO;AAAA,MACjC;AAAA,IAAA;AAAA,IAEF,CAAC,YAAY;AAAA,EAAA;AAEf,QAAM,WACJC,+BAACC,YAAAA,YAAY,UAAZ,EAAqB,OAAO,SAAU,UAAA,cAAa;AAGtD,SAAO,SACLC,2BAAAA,KAACC,KAAAA,OAAO,MAAP,EAAY,MAAY,cACvB,UAAA;AAAA,IAAAH,2BAAAA,IAACG,KAAAA,OAAO,SAAP,EAAe,SAAO,MAAE,UAAA,SAAQ;AAAA,IACjCD,2BAAAA,KAACC,KAAAA,OAAO,QAAP,EACC,UAAA;AAAA,MAAAH,+BAACG,KAAAA,OAAO,SAAP,EAAe,WAAWC,WAAWC,kBAAAA,QAAW,EAAE,GAAG;AAAA,MACtDL,2BAAAA,IAACG,KAAAA,OAAO,SAAP,EAAe,SAAO,MACrB,UAAAH,2BAAAA,IAACM,WAAAA,YAAA,EAAW,OAAe,SAAA,CAAS,EAAA,CACtC;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,EAAA,CACF,IAEAJ,2BAAAA,KAACK,kBAAAA,MAAA,EAAK,MAAY,cAChB,UAAA;AAAA,IAAAP,2BAAAA,IAACQ,kBAAAA,SAAA,EAAQ,SAAO,MAAE,UAAA,SAAQ;AAAA,IAC1BR,2BAAAA,IAACS,kBAAAA,UACC,UAAAT,2BAAAA,IAACU,kBAAAA,SAAA,EAAQ,SAAO,MAAC,MAAY,OAAc,YAAY,GACrD,UAAAV,2BAAAA;AAAAA,MAACW,aAAAA;AAAAA,MAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QAEC;AAAA,MAAA;AAAA,IAAA,GAEL,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Menu.d.ts","sourceRoot":"","sources":["../../../src/components/Menu/Menu.tsx"],"names":[],"mappings":"AAOA,OAAc,EAAE,KAAK,EAAE,EAAE,KAAK,SAAS,EAAW,MAAM,OAAO,CAAC;AAoBhE,UAAU,KAAK;IACb;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,IAAI,EAAE,OAAO,CAAC;IACd;;;;OAIG;IACH,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC;;;;OAIG;IACH,OAAO,EAAE,SAAS,CAAC;IACnB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;IACpB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC3C;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;CACpC;AAWD;;GAEG;AACH,eAAO,MAAM,IAAI,EAAE,EAAE,CAAC,KAAK,
|
|
1
|
+
{"version":3,"file":"Menu.d.ts","sourceRoot":"","sources":["../../../src/components/Menu/Menu.tsx"],"names":[],"mappings":"AAOA,OAAc,EAAE,KAAK,EAAE,EAAE,KAAK,SAAS,EAAW,MAAM,OAAO,CAAC;AAoBhE,UAAU,KAAK;IACb;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,IAAI,EAAE,OAAO,CAAC;IACd;;;;OAIG;IACH,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC;;;;OAIG;IACH,OAAO,EAAE,SAAS,CAAC;IACnB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;IACpB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC3C;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;CACpC;AAWD;;GAEG;AACH,eAAO,MAAM,IAAI,EAAE,EAAE,CAAC,KAAK,CAoD1B,CAAC"}
|
|
@@ -13,6 +13,7 @@ const DropdownMenuItemWrapper = ({
|
|
|
13
13
|
children
|
|
14
14
|
}) => /* @__PURE__ */ jsx(DropdownMenuItem, { onSelect: onSelect ?? void 0, asChild: true, children });
|
|
15
15
|
const Menu = ({
|
|
16
|
+
className,
|
|
16
17
|
title,
|
|
17
18
|
showTitle = true,
|
|
18
19
|
open,
|
|
@@ -40,7 +41,15 @@ const Menu = ({
|
|
|
40
41
|
] })
|
|
41
42
|
] }) : /* @__PURE__ */ jsxs(Root, { open, onOpenChange, children: [
|
|
42
43
|
/* @__PURE__ */ jsx(Trigger, { asChild: true, children: trigger }),
|
|
43
|
-
/* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(Content, { asChild: true, side, align, sideOffset: 8, children: /* @__PURE__ */ jsx(
|
|
44
|
+
/* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(Content, { asChild: true, side, align, sideOffset: 8, children: /* @__PURE__ */ jsx(
|
|
45
|
+
FloatingMenu,
|
|
46
|
+
{
|
|
47
|
+
className,
|
|
48
|
+
title,
|
|
49
|
+
showTitle,
|
|
50
|
+
children
|
|
51
|
+
}
|
|
52
|
+
) }) })
|
|
44
53
|
] });
|
|
45
54
|
};
|
|
46
55
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Menu.js","sources":["../../../src/components/Menu/Menu.tsx"],"sourcesContent":["/*\nCopyright 2023 New Vector Ltd.\n\nSPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport React, { type FC, type ReactNode, useMemo } from \"react\";\nimport {\n Root,\n Trigger,\n Portal,\n Content,\n DropdownMenuItem,\n} from \"@radix-ui/react-dropdown-menu\";\nimport { FloatingMenu } from \"./FloatingMenu\";\nimport { Drawer } from \"vaul\";\nimport classnames from \"classnames\";\nimport drawerMenu from \"./DrawerMenu.module.css\";\nimport {\n MenuContext,\n type MenuData,\n type MenuItemWrapperProps,\n} from \"./MenuContext\";\nimport { DrawerMenu } from \"./DrawerMenu\";\nimport { getPlatform } from \"../../utils/platform\";\n\ninterface Props {\n /**\n * The menu title. This can be hidden with `showTitle={false}` in which case it will only\n * be a label for screen readers.\n */\n title: string;\n /**\n * Controls whether the title is displayed (see `title` prop). Titles are only displayed on\n * web: on mobile, this parameter is ignored.\n */\n showTitle?: boolean;\n /**\n * Whether the menu is open.\n */\n open: boolean;\n /**\n * Event handler called when the open state of the menu changes. This includes\n * anything like clicking the trigger, selecting a menu item, or dismissing\n * the menu with the mouse or keyboard.\n */\n onOpenChange: (open: boolean) => void;\n /**\n * The button that opens the menu. This must be a component that accepts a ref\n * and spreads props.\n * https://www.radix-ui.com/primitives/docs/guides/composition\n */\n trigger: ReactNode;\n /**\n * The menu contents.\n */\n children: ReactNode;\n /**\n * The side of the trigger on which to place the menu. Note that the menu may\n * still end up on a different side than the one you request if there isn't\n * enough space.\n * @default bottom\n */\n side?: \"top\" | \"right\" | \"bottom\" | \"left\";\n /**\n * The edge along which the menu and trigger will be aligned.\n * @default center\n */\n align?: \"start\" | \"center\" | \"end\";\n}\n\nconst DropdownMenuItemWrapper: FC<MenuItemWrapperProps> = ({\n onSelect,\n children,\n}) => (\n <DropdownMenuItem onSelect={onSelect ?? undefined} asChild>\n {children}\n </DropdownMenuItem>\n);\n\n/**\n * A menu opened by pressing a button.\n */\nexport const Menu: FC<Props> = ({\n title,\n showTitle = true,\n open,\n onOpenChange,\n trigger,\n children: childrenProp,\n side = \"bottom\",\n align = \"center\",\n}) => {\n // Normally, the menu takes the form of a floating box. But on Android and\n // iOS, the menu should morph into a drawer\n const platform = getPlatform();\n const drawer = platform === \"android\" || platform === \"ios\";\n const context: MenuData = useMemo(\n () => ({\n MenuItemWrapper: drawer ? null : DropdownMenuItemWrapper,\n onOpenChange,\n }),\n [onOpenChange],\n );\n const children = (\n <MenuContext.Provider value={context}>{childrenProp}</MenuContext.Provider>\n );\n\n return drawer ? (\n <Drawer.Root open={open} onOpenChange={onOpenChange}>\n <Drawer.Trigger asChild>{trigger}</Drawer.Trigger>\n <Drawer.Portal>\n <Drawer.Overlay className={classnames(drawerMenu.bg)} />\n <Drawer.Content asChild>\n <DrawerMenu title={title}>{children}</DrawerMenu>\n </Drawer.Content>\n </Drawer.Portal>\n </Drawer.Root>\n ) : (\n <Root open={open} onOpenChange={onOpenChange}>\n <Trigger asChild>{trigger}</Trigger>\n <Portal>\n <Content asChild side={side} align={align} sideOffset={8}>\n <FloatingMenu
|
|
1
|
+
{"version":3,"file":"Menu.js","sources":["../../../src/components/Menu/Menu.tsx"],"sourcesContent":["/*\nCopyright 2023 New Vector Ltd.\n\nSPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport React, { type FC, type ReactNode, useMemo } from \"react\";\nimport {\n Root,\n Trigger,\n Portal,\n Content,\n DropdownMenuItem,\n} from \"@radix-ui/react-dropdown-menu\";\nimport { FloatingMenu } from \"./FloatingMenu\";\nimport { Drawer } from \"vaul\";\nimport classnames from \"classnames\";\nimport drawerMenu from \"./DrawerMenu.module.css\";\nimport {\n MenuContext,\n type MenuData,\n type MenuItemWrapperProps,\n} from \"./MenuContext\";\nimport { DrawerMenu } from \"./DrawerMenu\";\nimport { getPlatform } from \"../../utils/platform\";\n\ninterface Props {\n /**\n * CSS classes for the menu.\n */\n className?: string;\n\n /**\n * The menu title. This can be hidden with `showTitle={false}` in which case it will only\n * be a label for screen readers.\n */\n title: string;\n /**\n * Controls whether the title is displayed (see `title` prop). Titles are only displayed on\n * web: on mobile, this parameter is ignored.\n */\n showTitle?: boolean;\n /**\n * Whether the menu is open.\n */\n open: boolean;\n /**\n * Event handler called when the open state of the menu changes. This includes\n * anything like clicking the trigger, selecting a menu item, or dismissing\n * the menu with the mouse or keyboard.\n */\n onOpenChange: (open: boolean) => void;\n /**\n * The button that opens the menu. This must be a component that accepts a ref\n * and spreads props.\n * https://www.radix-ui.com/primitives/docs/guides/composition\n */\n trigger: ReactNode;\n /**\n * The menu contents.\n */\n children: ReactNode;\n /**\n * The side of the trigger on which to place the menu. Note that the menu may\n * still end up on a different side than the one you request if there isn't\n * enough space.\n * @default bottom\n */\n side?: \"top\" | \"right\" | \"bottom\" | \"left\";\n /**\n * The edge along which the menu and trigger will be aligned.\n * @default center\n */\n align?: \"start\" | \"center\" | \"end\";\n}\n\nconst DropdownMenuItemWrapper: FC<MenuItemWrapperProps> = ({\n onSelect,\n children,\n}) => (\n <DropdownMenuItem onSelect={onSelect ?? undefined} asChild>\n {children}\n </DropdownMenuItem>\n);\n\n/**\n * A menu opened by pressing a button.\n */\nexport const Menu: FC<Props> = ({\n className,\n title,\n showTitle = true,\n open,\n onOpenChange,\n trigger,\n children: childrenProp,\n side = \"bottom\",\n align = \"center\",\n}) => {\n // Normally, the menu takes the form of a floating box. But on Android and\n // iOS, the menu should morph into a drawer\n const platform = getPlatform();\n const drawer = platform === \"android\" || platform === \"ios\";\n const context: MenuData = useMemo(\n () => ({\n MenuItemWrapper: drawer ? null : DropdownMenuItemWrapper,\n onOpenChange,\n }),\n [onOpenChange],\n );\n const children = (\n <MenuContext.Provider value={context}>{childrenProp}</MenuContext.Provider>\n );\n\n return drawer ? (\n <Drawer.Root open={open} onOpenChange={onOpenChange}>\n <Drawer.Trigger asChild>{trigger}</Drawer.Trigger>\n <Drawer.Portal>\n <Drawer.Overlay className={classnames(drawerMenu.bg)} />\n <Drawer.Content asChild>\n <DrawerMenu title={title}>{children}</DrawerMenu>\n </Drawer.Content>\n </Drawer.Portal>\n </Drawer.Root>\n ) : (\n <Root open={open} onOpenChange={onOpenChange}>\n <Trigger asChild>{trigger}</Trigger>\n <Portal>\n <Content asChild side={side} align={align} sideOffset={8}>\n <FloatingMenu\n className={className}\n title={title}\n showTitle={showTitle}\n >\n {children}\n </FloatingMenu>\n </Content>\n </Portal>\n </Root>\n );\n};\n"],"names":["classnames"],"mappings":";;;;;;;;;;AA6EA,MAAM,0BAAoD,CAAC;AAAA,EACzD;AAAA,EACA;AACF,0BACG,kBAAA,EAAiB,UAAU,YAAY,QAAW,SAAO,MACvD,UACH;AAMK,MAAM,OAAkB,CAAC;AAAA,EAC9B;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,OAAO;AAAA,EACP,QAAQ;AACV,MAAM;AAGJ,QAAM,WAAW,YAAA;AACjB,QAAM,SAAS,aAAa,aAAa,aAAa;AACtD,QAAM,UAAoB;AAAA,IACxB,OAAO;AAAA,MACL,iBAAiB,SAAS,OAAO;AAAA,MACjC;AAAA,IAAA;AAAA,IAEF,CAAC,YAAY;AAAA,EAAA;AAEf,QAAM,WACJ,oBAAC,YAAY,UAAZ,EAAqB,OAAO,SAAU,UAAA,cAAa;AAGtD,SAAO,SACL,qBAAC,OAAO,MAAP,EAAY,MAAY,cACvB,UAAA;AAAA,IAAA,oBAAC,OAAO,SAAP,EAAe,SAAO,MAAE,UAAA,SAAQ;AAAA,IACjC,qBAAC,OAAO,QAAP,EACC,UAAA;AAAA,MAAA,oBAAC,OAAO,SAAP,EAAe,WAAWA,WAAW,WAAW,EAAE,GAAG;AAAA,MACtD,oBAAC,OAAO,SAAP,EAAe,SAAO,MACrB,UAAA,oBAAC,YAAA,EAAW,OAAe,SAAA,CAAS,EAAA,CACtC;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,EAAA,CACF,IAEA,qBAAC,MAAA,EAAK,MAAY,cAChB,UAAA;AAAA,IAAA,oBAAC,SAAA,EAAQ,SAAO,MAAE,UAAA,SAAQ;AAAA,IAC1B,oBAAC,UACC,UAAA,oBAAC,SAAA,EAAQ,SAAO,MAAC,MAAY,OAAc,YAAY,GACrD,UAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QAEC;AAAA,MAAA;AAAA,IAAA,GAEL,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReleaseAnnouncementContext.d.ts","sourceRoot":"","sources":["../../../src/components/ReleaseAnnouncement/ReleaseAnnouncementContext.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAElE,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,sBAAsB,CAAC,GAAG,IAAI,CAAC;AACpE;;GAEG;AACH,eAAO,MAAM,0BAA0B,sCAAmC,CAAC;AAE3E;;GAEG;AACH,wBAAgB,6BAA6B;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"ReleaseAnnouncementContext.d.ts","sourceRoot":"","sources":["../../../src/components/ReleaseAnnouncement/ReleaseAnnouncementContext.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAElE,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,sBAAsB,CAAC,GAAG,IAAI,CAAC;AACpE;;GAEG;AACH,eAAO,MAAM,0BAA0B,sCAAmC,CAAC;AAE3E;;GAEG;AACH,wBAAgB,6BAA6B;;;;;;;;;iCAW0qnC,CAAC;gCAAyF,CAAC;4BAAyF,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAD34nC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useReleaseAnnouncement.d.ts","sourceRoot":"","sources":["../../../src/components/ReleaseAnnouncement/useReleaseAnnouncement.tsx"],"names":[],"mappings":"AAOA,OAAO,EAKL,KAAK,SAAS,EAMf,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,KAAK,iBAAiB,EAAmB,MAAM,OAAO,CAAC;AAEhE,UAAU,2BAA2B;IACnC;;OAEG;IACH,IAAI,EAAE,OAAO,CAAC;IACd;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,SAAS,EAAE,SAAS,CAAC;IACrB;;OAEG;IACH,OAAO,EAAE,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;IAC9C;;OAEG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,IAAI,EACJ,MAAM,EACN,WAAW,EACX,UAAU,EACV,SAAS,EACT,OAAO,EACP,YAAY,GACb,EAAE,2BAA2B;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"useReleaseAnnouncement.d.ts","sourceRoot":"","sources":["../../../src/components/ReleaseAnnouncement/useReleaseAnnouncement.tsx"],"names":[],"mappings":"AAOA,OAAO,EAKL,KAAK,SAAS,EAMf,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,KAAK,iBAAiB,EAAmB,MAAM,OAAO,CAAC;AAEhE,UAAU,2BAA2B;IACnC;;OAEG;IACH,IAAI,EAAE,OAAO,CAAC;IACd;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,SAAS,EAAE,SAAS,CAAC;IACrB;;OAEG;IACH,OAAO,EAAE,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;IAC9C;;OAEG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,IAAI,EACJ,MAAM,EACN,WAAW,EACX,UAAU,EACV,SAAS,EACT,OAAO,EACP,YAAY,GACb,EAAE,2BAA2B;;;;;;;;;iCA0D6kkC,CAAC;gCAAyF,CAAC;4BAAyF,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAD/xkC"}
|